PluginProbe
MLSImport: IDX Plugin & MLS Plugin for Real Estate Listings / 7.0.6
MLSImport: IDX Plugin & MLS Plugin for Real Estate Listings v7.0.6
7.2 7.1.2 7.1.1 7.1 7.0.4 7.0.6 7.0.7 6.3.8 6.3.7 6.3.6 6.3.5 6.3.4 6.3.3 6.3.1 trunk 5.7.3 5.7.5 5.8.1 5.8.2 5.8.3 5.8.4 5.8.6 6.0.4 6.0.5 6.0.7 All 35 releases
mlsimport / phpunit.phar

phpunit.phar in MLSImport: IDX Plugin & MLS Plugin for Real Estate Listings 7.0.6, at phpunit.phar

110,425 lines 5.0 MB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 #!/usr/bin/env php
2 <?php
3 if (!version_compare(PHP_VERSION, PHP_VERSION, '=')) {
4 fwrite(
5 STDERR,
6 sprintf(
7 '%s declares an invalid value for PHP_VERSION.' . PHP_EOL .
8 'This breaks fundamental functionality such as version_compare().' . PHP_EOL .
9 'Please use a different PHP interpreter.' . PHP_EOL,
10
11 PHP_BINARY
12 )
13 );
14
15 die(1);
16 }
17
18 if (version_compare('8.1.0', PHP_VERSION, '>')) {
19 fwrite(
20 STDERR,
21 sprintf(
22 'PHPUnit 10.5.63 by Sebastian Bergmann and contributors.' . PHP_EOL . PHP_EOL .
23 'This version of PHPUnit requires PHP >= 8.1.' . PHP_EOL .
24 'You are using PHP %s (%s).' . PHP_EOL,
25 PHP_VERSION,
26 PHP_BINARY
27 )
28 );
29
30 die(1);
31 }
32
33 $requiredExtensions = ['ctype', 'dom', 'json', 'libxml', 'mbstring', 'tokenizer', 'xml', 'xmlwriter'];
34
35 $unavailableExtensions = array_filter(
36 $requiredExtensions,
37 static function ($extension) {
38 return !extension_loaded($extension);
39 }
40 );
41
42 if ([] !== $unavailableExtensions) {
43 fwrite(
44 STDERR,
45 sprintf(
46 'PHPUnit requires the "%s" extensions, but the "%s" %s not available.' . PHP_EOL,
47 implode('", "', $requiredExtensions),
48 implode('", "', $unavailableExtensions),
49 count($unavailableExtensions) === 1 ? 'extension is' : 'extensions are'
50 )
51 );
52
53 die(1);
54 }
55
56 unset($requiredExtensions, $unavailableExtensions);
57
58 if (__FILE__ === realpath($_SERVER['SCRIPT_NAME'])) {
59 $execute = true;
60 } else {
61 $execute = false;
62 }
63
64 $options = getopt('', array('composer-lock', 'manifest', 'sbom'));
65
66 if (isset($options['composer-lock'])) {
67 $printComposerLock = true;
68 } elseif (isset($options['manifest'])) {
69 $printManifest = true;
70 } elseif (isset($options['sbom'])) {
71 $printSbom = true;
72 }
73
74 unset($options);
75
76 define('__PHPUNIT_PHAR__', str_replace(DIRECTORY_SEPARATOR, '/', __FILE__));
77 define('__PHPUNIT_PHAR_ROOT__', 'phar://phpunit-10.5.63.phar');
78
79 Phar::mapPhar('phpunit-10.5.63.phar');
80
81 spl_autoload_register(
82 function ($class) {
83 static $classes = null;
84
85 if ($classes === null) {
86 $classes = ['PHPUnitPHAR\\DeepCopy\\DeepCopy' => '/myclabs-deep-copy/DeepCopy/DeepCopy.php',
87 'PHPUnitPHAR\\DeepCopy\\Exception\\CloneException' => '/myclabs-deep-copy/DeepCopy/Exception/CloneException.php',
88 'PHPUnitPHAR\\DeepCopy\\Exception\\PropertyException' => '/myclabs-deep-copy/DeepCopy/Exception/PropertyException.php',
89 'PHPUnitPHAR\\DeepCopy\\Filter\\ChainableFilter' => '/myclabs-deep-copy/DeepCopy/Filter/ChainableFilter.php',
90 'PHPUnitPHAR\\DeepCopy\\Filter\\Doctrine\\DoctrineCollectionFilter' => '/myclabs-deep-copy/DeepCopy/Filter/Doctrine/DoctrineCollectionFilter.php',
91 'PHPUnitPHAR\\DeepCopy\\Filter\\Doctrine\\DoctrineEmptyCollectionFilter' => '/myclabs-deep-copy/DeepCopy/Filter/Doctrine/DoctrineEmptyCollectionFilter.php',
92 'PHPUnitPHAR\\DeepCopy\\Filter\\Doctrine\\DoctrineProxyFilter' => '/myclabs-deep-copy/DeepCopy/Filter/Doctrine/DoctrineProxyFilter.php',
93 'PHPUnitPHAR\\DeepCopy\\Filter\\Filter' => '/myclabs-deep-copy/DeepCopy/Filter/Filter.php',
94 'PHPUnitPHAR\\DeepCopy\\Filter\\KeepFilter' => '/myclabs-deep-copy/DeepCopy/Filter/KeepFilter.php',
95 'PHPUnitPHAR\\DeepCopy\\Filter\\ReplaceFilter' => '/myclabs-deep-copy/DeepCopy/Filter/ReplaceFilter.php',
96 'PHPUnitPHAR\\DeepCopy\\Filter\\SetNullFilter' => '/myclabs-deep-copy/DeepCopy/Filter/SetNullFilter.php',
97 'PHPUnitPHAR\\DeepCopy\\Matcher\\Doctrine\\DoctrineProxyMatcher' => '/myclabs-deep-copy/DeepCopy/Matcher/Doctrine/DoctrineProxyMatcher.php',
98 'PHPUnitPHAR\\DeepCopy\\Matcher\\Matcher' => '/myclabs-deep-copy/DeepCopy/Matcher/Matcher.php',
99 'PHPUnitPHAR\\DeepCopy\\Matcher\\PropertyMatcher' => '/myclabs-deep-copy/DeepCopy/Matcher/PropertyMatcher.php',
100 'PHPUnitPHAR\\DeepCopy\\Matcher\\PropertyNameMatcher' => '/myclabs-deep-copy/DeepCopy/Matcher/PropertyNameMatcher.php',
101 'PHPUnitPHAR\\DeepCopy\\Matcher\\PropertyTypeMatcher' => '/myclabs-deep-copy/DeepCopy/Matcher/PropertyTypeMatcher.php',
102 'PHPUnitPHAR\\DeepCopy\\Reflection\\ReflectionHelper' => '/myclabs-deep-copy/DeepCopy/Reflection/ReflectionHelper.php',
103 'PHPUnitPHAR\\DeepCopy\\TypeFilter\\Date\\DateIntervalFilter' => '/myclabs-deep-copy/DeepCopy/TypeFilter/Date/DateIntervalFilter.php',
104 'PHPUnitPHAR\\DeepCopy\\TypeFilter\\Date\\DatePeriodFilter' => '/myclabs-deep-copy/DeepCopy/TypeFilter/Date/DatePeriodFilter.php',
105 'PHPUnitPHAR\\DeepCopy\\TypeFilter\\ReplaceFilter' => '/myclabs-deep-copy/DeepCopy/TypeFilter/ReplaceFilter.php',
106 'PHPUnitPHAR\\DeepCopy\\TypeFilter\\ShallowCopyFilter' => '/myclabs-deep-copy/DeepCopy/TypeFilter/ShallowCopyFilter.php',
107 'PHPUnitPHAR\\DeepCopy\\TypeFilter\\Spl\\ArrayObjectFilter' => '/myclabs-deep-copy/DeepCopy/TypeFilter/Spl/ArrayObjectFilter.php',
108 'PHPUnitPHAR\\DeepCopy\\TypeFilter\\Spl\\SplDoublyLinkedList' => '/myclabs-deep-copy/DeepCopy/TypeFilter/Spl/SplDoublyLinkedList.php',
109 'PHPUnitPHAR\\DeepCopy\\TypeFilter\\Spl\\SplDoublyLinkedListFilter' => '/myclabs-deep-copy/DeepCopy/TypeFilter/Spl/SplDoublyLinkedListFilter.php',
110 'PHPUnitPHAR\\DeepCopy\\TypeFilter\\TypeFilter' => '/myclabs-deep-copy/DeepCopy/TypeFilter/TypeFilter.php',
111 'PHPUnitPHAR\\DeepCopy\\TypeMatcher\\TypeMatcher' => '/myclabs-deep-copy/DeepCopy/TypeMatcher/TypeMatcher.php',
112 'PHPUnitPHAR\\PharIo\\Manifest\\Application' => '/phar-io-manifest/values/Application.php',
113 'PHPUnitPHAR\\PharIo\\Manifest\\ApplicationName' => '/phar-io-manifest/values/ApplicationName.php',
114 'PHPUnitPHAR\\PharIo\\Manifest\\Author' => '/phar-io-manifest/values/Author.php',
115 'PHPUnitPHAR\\PharIo\\Manifest\\AuthorCollection' => '/phar-io-manifest/values/AuthorCollection.php',
116 'PHPUnitPHAR\\PharIo\\Manifest\\AuthorCollectionIterator' => '/phar-io-manifest/values/AuthorCollectionIterator.php',
117 'PHPUnitPHAR\\PharIo\\Manifest\\AuthorElement' => '/phar-io-manifest/xml/AuthorElement.php',
118 'PHPUnitPHAR\\PharIo\\Manifest\\AuthorElementCollection' => '/phar-io-manifest/xml/AuthorElementCollection.php',
119 'PHPUnitPHAR\\PharIo\\Manifest\\BundledComponent' => '/phar-io-manifest/values/BundledComponent.php',
120 'PHPUnitPHAR\\PharIo\\Manifest\\BundledComponentCollection' => '/phar-io-manifest/values/BundledComponentCollection.php',
121 'PHPUnitPHAR\\PharIo\\Manifest\\BundledComponentCollectionIterator' => '/phar-io-manifest/values/BundledComponentCollectionIterator.php',
122 'PHPUnitPHAR\\PharIo\\Manifest\\BundlesElement' => '/phar-io-manifest/xml/BundlesElement.php',
123 'PHPUnitPHAR\\PharIo\\Manifest\\ComponentElement' => '/phar-io-manifest/xml/ComponentElement.php',
124 'PHPUnitPHAR\\PharIo\\Manifest\\ComponentElementCollection' => '/phar-io-manifest/xml/ComponentElementCollection.php',
125 'PHPUnitPHAR\\PharIo\\Manifest\\ContainsElement' => '/phar-io-manifest/xml/ContainsElement.php',
126 'PHPUnitPHAR\\PharIo\\Manifest\\CopyrightElement' => '/phar-io-manifest/xml/CopyrightElement.php',
127 'PHPUnitPHAR\\PharIo\\Manifest\\CopyrightInformation' => '/phar-io-manifest/values/CopyrightInformation.php',
128 'PHPUnitPHAR\\PharIo\\Manifest\\ElementCollection' => '/phar-io-manifest/xml/ElementCollection.php',
129 'PHPUnitPHAR\\PharIo\\Manifest\\ElementCollectionException' => '/phar-io-manifest/exceptions/ElementCollectionException.php',
130 'PHPUnitPHAR\\PharIo\\Manifest\\Email' => '/phar-io-manifest/values/Email.php',
131 'PHPUnitPHAR\\PharIo\\Manifest\\Exception' => '/phar-io-manifest/exceptions/Exception.php',
132 'PHPUnitPHAR\\PharIo\\Manifest\\ExtElement' => '/phar-io-manifest/xml/ExtElement.php',
133 'PHPUnitPHAR\\PharIo\\Manifest\\ExtElementCollection' => '/phar-io-manifest/xml/ExtElementCollection.php',
134 'PHPUnitPHAR\\PharIo\\Manifest\\Extension' => '/phar-io-manifest/values/Extension.php',
135 'PHPUnitPHAR\\PharIo\\Manifest\\ExtensionElement' => '/phar-io-manifest/xml/ExtensionElement.php',
136 'PHPUnitPHAR\\PharIo\\Manifest\\InvalidApplicationNameException' => '/phar-io-manifest/exceptions/InvalidApplicationNameException.php',
137 'PHPUnitPHAR\\PharIo\\Manifest\\InvalidEmailException' => '/phar-io-manifest/exceptions/InvalidEmailException.php',
138 'PHPUnitPHAR\\PharIo\\Manifest\\InvalidUrlException' => '/phar-io-manifest/exceptions/InvalidUrlException.php',
139 'PHPUnitPHAR\\PharIo\\Manifest\\Library' => '/phar-io-manifest/values/Library.php',
140 'PHPUnitPHAR\\PharIo\\Manifest\\License' => '/phar-io-manifest/values/License.php',
141 'PHPUnitPHAR\\PharIo\\Manifest\\LicenseElement' => '/phar-io-manifest/xml/LicenseElement.php',
142 'PHPUnitPHAR\\PharIo\\Manifest\\Manifest' => '/phar-io-manifest/values/Manifest.php',
143 'PHPUnitPHAR\\PharIo\\Manifest\\ManifestDocument' => '/phar-io-manifest/xml/ManifestDocument.php',
144 'PHPUnitPHAR\\PharIo\\Manifest\\ManifestDocumentException' => '/phar-io-manifest/exceptions/ManifestDocumentException.php',
145 'PHPUnitPHAR\\PharIo\\Manifest\\ManifestDocumentLoadingException' => '/phar-io-manifest/exceptions/ManifestDocumentLoadingException.php',
146 'PHPUnitPHAR\\PharIo\\Manifest\\ManifestDocumentMapper' => '/phar-io-manifest/ManifestDocumentMapper.php',
147 'PHPUnitPHAR\\PharIo\\Manifest\\ManifestDocumentMapperException' => '/phar-io-manifest/exceptions/ManifestDocumentMapperException.php',
148 'PHPUnitPHAR\\PharIo\\Manifest\\ManifestElement' => '/phar-io-manifest/xml/ManifestElement.php',
149 'PHPUnitPHAR\\PharIo\\Manifest\\ManifestElementException' => '/phar-io-manifest/exceptions/ManifestElementException.php',
150 'PHPUnitPHAR\\PharIo\\Manifest\\ManifestLoader' => '/phar-io-manifest/ManifestLoader.php',
151 'PHPUnitPHAR\\PharIo\\Manifest\\ManifestLoaderException' => '/phar-io-manifest/exceptions/ManifestLoaderException.php',
152 'PHPUnitPHAR\\PharIo\\Manifest\\ManifestSerializer' => '/phar-io-manifest/ManifestSerializer.php',
153 'PHPUnitPHAR\\PharIo\\Manifest\\NoEmailAddressException' => '/phar-io-manifest/exceptions/NoEmailAddressException.php',
154 'PHPUnitPHAR\\PharIo\\Manifest\\PhpElement' => '/phar-io-manifest/xml/PhpElement.php',
155 'PHPUnitPHAR\\PharIo\\Manifest\\PhpExtensionRequirement' => '/phar-io-manifest/values/PhpExtensionRequirement.php',
156 'PHPUnitPHAR\\PharIo\\Manifest\\PhpVersionRequirement' => '/phar-io-manifest/values/PhpVersionRequirement.php',
157 'PHPUnitPHAR\\PharIo\\Manifest\\Requirement' => '/phar-io-manifest/values/Requirement.php',
158 'PHPUnitPHAR\\PharIo\\Manifest\\RequirementCollection' => '/phar-io-manifest/values/RequirementCollection.php',
159 'PHPUnitPHAR\\PharIo\\Manifest\\RequirementCollectionIterator' => '/phar-io-manifest/values/RequirementCollectionIterator.php',
160 'PHPUnitPHAR\\PharIo\\Manifest\\RequiresElement' => '/phar-io-manifest/xml/RequiresElement.php',
161 'PHPUnitPHAR\\PharIo\\Manifest\\Type' => '/phar-io-manifest/values/Type.php',
162 'PHPUnitPHAR\\PharIo\\Manifest\\Url' => '/phar-io-manifest/values/Url.php',
163 'PHPUnitPHAR\\PharIo\\Version\\AbstractVersionConstraint' => '/phar-io-version/constraints/AbstractVersionConstraint.php',
164 'PHPUnitPHAR\\PharIo\\Version\\AndVersionConstraintGroup' => '/phar-io-version/constraints/AndVersionConstraintGroup.php',
165 'PHPUnitPHAR\\PharIo\\Version\\AnyVersionConstraint' => '/phar-io-version/constraints/AnyVersionConstraint.php',
166 'PHPUnitPHAR\\PharIo\\Version\\BuildMetaData' => '/phar-io-version/BuildMetaData.php',
167 'PHPUnitPHAR\\PharIo\\Version\\ExactVersionConstraint' => '/phar-io-version/constraints/ExactVersionConstraint.php',
168 'PHPUnitPHAR\\PharIo\\Version\\Exception' => '/phar-io-version/exceptions/Exception.php',
169 'PHPUnitPHAR\\PharIo\\Version\\GreaterThanOrEqualToVersionConstraint' => '/phar-io-version/constraints/GreaterThanOrEqualToVersionConstraint.php',
170 'PHPUnitPHAR\\PharIo\\Version\\InvalidPreReleaseSuffixException' => '/phar-io-version/exceptions/InvalidPreReleaseSuffixException.php',
171 'PHPUnitPHAR\\PharIo\\Version\\InvalidVersionException' => '/phar-io-version/exceptions/InvalidVersionException.php',
172 'PHPUnitPHAR\\PharIo\\Version\\NoBuildMetaDataException' => '/phar-io-version/exceptions/NoBuildMetaDataException.php',
173 'PHPUnitPHAR\\PharIo\\Version\\NoPreReleaseSuffixException' => '/phar-io-version/exceptions/NoPreReleaseSuffixException.php',
174 'PHPUnitPHAR\\PharIo\\Version\\OrVersionConstraintGroup' => '/phar-io-version/constraints/OrVersionConstraintGroup.php',
175 'PHPUnitPHAR\\PharIo\\Version\\PreReleaseSuffix' => '/phar-io-version/PreReleaseSuffix.php',
176 'PHPUnitPHAR\\PharIo\\Version\\SpecificMajorAndMinorVersionConstraint' => '/phar-io-version/constraints/SpecificMajorAndMinorVersionConstraint.php',
177 'PHPUnitPHAR\\PharIo\\Version\\SpecificMajorVersionConstraint' => '/phar-io-version/constraints/SpecificMajorVersionConstraint.php',
178 'PHPUnitPHAR\\PharIo\\Version\\UnsupportedVersionConstraintException' => '/phar-io-version/exceptions/UnsupportedVersionConstraintException.php',
179 'PHPUnitPHAR\\PharIo\\Version\\Version' => '/phar-io-version/Version.php',
180 'PHPUnitPHAR\\PharIo\\Version\\VersionConstraint' => '/phar-io-version/constraints/VersionConstraint.php',
181 'PHPUnitPHAR\\PharIo\\Version\\VersionConstraintParser' => '/phar-io-version/VersionConstraintParser.php',
182 'PHPUnitPHAR\\PharIo\\Version\\VersionConstraintValue' => '/phar-io-version/VersionConstraintValue.php',
183 'PHPUnitPHAR\\PharIo\\Version\\VersionNumber' => '/phar-io-version/VersionNumber.php',
184 'PHPUnitPHAR\\PhpParser\\Builder' => '/nikic-php-parser/PhpParser/Builder.php',
185 'PHPUnitPHAR\\PhpParser\\BuilderFactory' => '/nikic-php-parser/PhpParser/BuilderFactory.php',
186 'PHPUnitPHAR\\PhpParser\\BuilderHelpers' => '/nikic-php-parser/PhpParser/BuilderHelpers.php',
187 'PHPUnitPHAR\\PhpParser\\Builder\\ClassConst' => '/nikic-php-parser/PhpParser/Builder/ClassConst.php',
188 'PHPUnitPHAR\\PhpParser\\Builder\\Class_' => '/nikic-php-parser/PhpParser/Builder/Class_.php',
189 'PHPUnitPHAR\\PhpParser\\Builder\\Declaration' => '/nikic-php-parser/PhpParser/Builder/Declaration.php',
190 'PHPUnitPHAR\\PhpParser\\Builder\\EnumCase' => '/nikic-php-parser/PhpParser/Builder/EnumCase.php',
191 'PHPUnitPHAR\\PhpParser\\Builder\\Enum_' => '/nikic-php-parser/PhpParser/Builder/Enum_.php',
192 'PHPUnitPHAR\\PhpParser\\Builder\\FunctionLike' => '/nikic-php-parser/PhpParser/Builder/FunctionLike.php',
193 'PHPUnitPHAR\\PhpParser\\Builder\\Function_' => '/nikic-php-parser/PhpParser/Builder/Function_.php',
194 'PHPUnitPHAR\\PhpParser\\Builder\\Interface_' => '/nikic-php-parser/PhpParser/Builder/Interface_.php',
195 'PHPUnitPHAR\\PhpParser\\Builder\\Method' => '/nikic-php-parser/PhpParser/Builder/Method.php',
196 'PHPUnitPHAR\\PhpParser\\Builder\\Namespace_' => '/nikic-php-parser/PhpParser/Builder/Namespace_.php',
197 'PHPUnitPHAR\\PhpParser\\Builder\\Param' => '/nikic-php-parser/PhpParser/Builder/Param.php',
198 'PHPUnitPHAR\\PhpParser\\Builder\\Property' => '/nikic-php-parser/PhpParser/Builder/Property.php',
199 'PHPUnitPHAR\\PhpParser\\Builder\\TraitUse' => '/nikic-php-parser/PhpParser/Builder/TraitUse.php',
200 'PHPUnitPHAR\\PhpParser\\Builder\\TraitUseAdaptation' => '/nikic-php-parser/PhpParser/Builder/TraitUseAdaptation.php',
201 'PHPUnitPHAR\\PhpParser\\Builder\\Trait_' => '/nikic-php-parser/PhpParser/Builder/Trait_.php',
202 'PHPUnitPHAR\\PhpParser\\Builder\\Use_' => '/nikic-php-parser/PhpParser/Builder/Use_.php',
203 'PHPUnitPHAR\\PhpParser\\Comment' => '/nikic-php-parser/PhpParser/Comment.php',
204 'PHPUnitPHAR\\PhpParser\\Comment\\Doc' => '/nikic-php-parser/PhpParser/Comment/Doc.php',
205 'PHPUnitPHAR\\PhpParser\\ConstExprEvaluationException' => '/nikic-php-parser/PhpParser/ConstExprEvaluationException.php',
206 'PHPUnitPHAR\\PhpParser\\ConstExprEvaluator' => '/nikic-php-parser/PhpParser/ConstExprEvaluator.php',
207 'PHPUnitPHAR\\PhpParser\\Error' => '/nikic-php-parser/PhpParser/Error.php',
208 'PHPUnitPHAR\\PhpParser\\ErrorHandler' => '/nikic-php-parser/PhpParser/ErrorHandler.php',
209 'PHPUnitPHAR\\PhpParser\\ErrorHandler\\Collecting' => '/nikic-php-parser/PhpParser/ErrorHandler/Collecting.php',
210 'PHPUnitPHAR\\PhpParser\\ErrorHandler\\Throwing' => '/nikic-php-parser/PhpParser/ErrorHandler/Throwing.php',
211 'PHPUnitPHAR\\PhpParser\\Internal\\DiffElem' => '/nikic-php-parser/PhpParser/Internal/DiffElem.php',
212 'PHPUnitPHAR\\PhpParser\\Internal\\Differ' => '/nikic-php-parser/PhpParser/Internal/Differ.php',
213 'PHPUnitPHAR\\PhpParser\\Internal\\PrintableNewAnonClassNode' => '/nikic-php-parser/PhpParser/Internal/PrintableNewAnonClassNode.php',
214 'PHPUnitPHAR\\PhpParser\\Internal\\TokenPolyfill' => '/nikic-php-parser/PhpParser/Internal/TokenPolyfill.php',
215 'PHPUnitPHAR\\PhpParser\\Internal\\TokenStream' => '/nikic-php-parser/PhpParser/Internal/TokenStream.php',
216 'PHPUnitPHAR\\PhpParser\\JsonDecoder' => '/nikic-php-parser/PhpParser/JsonDecoder.php',
217 'PHPUnitPHAR\\PhpParser\\Lexer' => '/nikic-php-parser/PhpParser/Lexer.php',
218 'PHPUnitPHAR\\PhpParser\\Lexer\\Emulative' => '/nikic-php-parser/PhpParser/Lexer/Emulative.php',
219 'PHPUnitPHAR\\PhpParser\\Lexer\\TokenEmulator\\AsymmetricVisibilityTokenEmulator' => '/nikic-php-parser/PhpParser/Lexer/TokenEmulator/AsymmetricVisibilityTokenEmulator.php',
220 'PHPUnitPHAR\\PhpParser\\Lexer\\TokenEmulator\\AttributeEmulator' => '/nikic-php-parser/PhpParser/Lexer/TokenEmulator/AttributeEmulator.php',
221 'PHPUnitPHAR\\PhpParser\\Lexer\\TokenEmulator\\EnumTokenEmulator' => '/nikic-php-parser/PhpParser/Lexer/TokenEmulator/EnumTokenEmulator.php',
222 'PHPUnitPHAR\\PhpParser\\Lexer\\TokenEmulator\\ExplicitOctalEmulator' => '/nikic-php-parser/PhpParser/Lexer/TokenEmulator/ExplicitOctalEmulator.php',
223 'PHPUnitPHAR\\PhpParser\\Lexer\\TokenEmulator\\KeywordEmulator' => '/nikic-php-parser/PhpParser/Lexer/TokenEmulator/KeywordEmulator.php',
224 'PHPUnitPHAR\\PhpParser\\Lexer\\TokenEmulator\\MatchTokenEmulator' => '/nikic-php-parser/PhpParser/Lexer/TokenEmulator/MatchTokenEmulator.php',
225 'PHPUnitPHAR\\PhpParser\\Lexer\\TokenEmulator\\NullsafeTokenEmulator' => '/nikic-php-parser/PhpParser/Lexer/TokenEmulator/NullsafeTokenEmulator.php',
226 'PHPUnitPHAR\\PhpParser\\Lexer\\TokenEmulator\\PipeOperatorEmulator' => '/nikic-php-parser/PhpParser/Lexer/TokenEmulator/PipeOperatorEmulator.php',
227 'PHPUnitPHAR\\PhpParser\\Lexer\\TokenEmulator\\PropertyTokenEmulator' => '/nikic-php-parser/PhpParser/Lexer/TokenEmulator/PropertyTokenEmulator.php',
228 'PHPUnitPHAR\\PhpParser\\Lexer\\TokenEmulator\\ReadonlyFunctionTokenEmulator' => '/nikic-php-parser/PhpParser/Lexer/TokenEmulator/ReadonlyFunctionTokenEmulator.php',
229 'PHPUnitPHAR\\PhpParser\\Lexer\\TokenEmulator\\ReadonlyTokenEmulator' => '/nikic-php-parser/PhpParser/Lexer/TokenEmulator/ReadonlyTokenEmulator.php',
230 'PHPUnitPHAR\\PhpParser\\Lexer\\TokenEmulator\\ReverseEmulator' => '/nikic-php-parser/PhpParser/Lexer/TokenEmulator/ReverseEmulator.php',
231 'PHPUnitPHAR\\PhpParser\\Lexer\\TokenEmulator\\TokenEmulator' => '/nikic-php-parser/PhpParser/Lexer/TokenEmulator/TokenEmulator.php',
232 'PHPUnitPHAR\\PhpParser\\Lexer\\TokenEmulator\\VoidCastEmulator' => '/nikic-php-parser/PhpParser/Lexer/TokenEmulator/VoidCastEmulator.php',
233 'PHPUnitPHAR\\PhpParser\\Modifiers' => '/nikic-php-parser/PhpParser/Modifiers.php',
234 'PHPUnitPHAR\\PhpParser\\NameContext' => '/nikic-php-parser/PhpParser/NameContext.php',
235 'PHPUnitPHAR\\PhpParser\\Node' => '/nikic-php-parser/PhpParser/Node.php',
236 'PHPUnitPHAR\\PhpParser\\NodeAbstract' => '/nikic-php-parser/PhpParser/NodeAbstract.php',
237 'PHPUnitPHAR\\PhpParser\\NodeDumper' => '/nikic-php-parser/PhpParser/NodeDumper.php',
238 'PHPUnitPHAR\\PhpParser\\NodeFinder' => '/nikic-php-parser/PhpParser/NodeFinder.php',
239 'PHPUnitPHAR\\PhpParser\\NodeTraverser' => '/nikic-php-parser/PhpParser/NodeTraverser.php',
240 'PHPUnitPHAR\\PhpParser\\NodeTraverserInterface' => '/nikic-php-parser/PhpParser/NodeTraverserInterface.php',
241 'PHPUnitPHAR\\PhpParser\\NodeVisitor' => '/nikic-php-parser/PhpParser/NodeVisitor.php',
242 'PHPUnitPHAR\\PhpParser\\NodeVisitorAbstract' => '/nikic-php-parser/PhpParser/NodeVisitorAbstract.php',
243 'PHPUnitPHAR\\PhpParser\\NodeVisitor\\CloningVisitor' => '/nikic-php-parser/PhpParser/NodeVisitor/CloningVisitor.php',
244 'PHPUnitPHAR\\PhpParser\\NodeVisitor\\CommentAnnotatingVisitor' => '/nikic-php-parser/PhpParser/NodeVisitor/CommentAnnotatingVisitor.php',
245 'PHPUnitPHAR\\PhpParser\\NodeVisitor\\FindingVisitor' => '/nikic-php-parser/PhpParser/NodeVisitor/FindingVisitor.php',
246 'PHPUnitPHAR\\PhpParser\\NodeVisitor\\FirstFindingVisitor' => '/nikic-php-parser/PhpParser/NodeVisitor/FirstFindingVisitor.php',
247 'PHPUnitPHAR\\PhpParser\\NodeVisitor\\NameResolver' => '/nikic-php-parser/PhpParser/NodeVisitor/NameResolver.php',
248 'PHPUnitPHAR\\PhpParser\\NodeVisitor\\NodeConnectingVisitor' => '/nikic-php-parser/PhpParser/NodeVisitor/NodeConnectingVisitor.php',
249 'PHPUnitPHAR\\PhpParser\\NodeVisitor\\ParentConnectingVisitor' => '/nikic-php-parser/PhpParser/NodeVisitor/ParentConnectingVisitor.php',
250 'PHPUnitPHAR\\PhpParser\\Node\\Arg' => '/nikic-php-parser/PhpParser/Node/Arg.php',
251 'PHPUnitPHAR\\PhpParser\\Node\\ArrayItem' => '/nikic-php-parser/PhpParser/Node/ArrayItem.php',
252 'PHPUnitPHAR\\PhpParser\\Node\\Attribute' => '/nikic-php-parser/PhpParser/Node/Attribute.php',
253 'PHPUnitPHAR\\PhpParser\\Node\\AttributeGroup' => '/nikic-php-parser/PhpParser/Node/AttributeGroup.php',
254 'PHPUnitPHAR\\PhpParser\\Node\\ClosureUse' => '/nikic-php-parser/PhpParser/Node/ClosureUse.php',
255 'PHPUnitPHAR\\PhpParser\\Node\\ComplexType' => '/nikic-php-parser/PhpParser/Node/ComplexType.php',
256 'PHPUnitPHAR\\PhpParser\\Node\\Const_' => '/nikic-php-parser/PhpParser/Node/Const_.php',
257 'PHPUnitPHAR\\PhpParser\\Node\\DeclareItem' => '/nikic-php-parser/PhpParser/Node/DeclareItem.php',
258 'PHPUnitPHAR\\PhpParser\\Node\\Expr' => '/nikic-php-parser/PhpParser/Node/Expr.php',
259 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\ArrayDimFetch' => '/nikic-php-parser/PhpParser/Node/Expr/ArrayDimFetch.php',
260 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\Array_' => '/nikic-php-parser/PhpParser/Node/Expr/Array_.php',
261 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\ArrowFunction' => '/nikic-php-parser/PhpParser/Node/Expr/ArrowFunction.php',
262 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\Assign' => '/nikic-php-parser/PhpParser/Node/Expr/Assign.php',
263 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\AssignOp' => '/nikic-php-parser/PhpParser/Node/Expr/AssignOp.php',
264 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\AssignOp\\BitwiseAnd' => '/nikic-php-parser/PhpParser/Node/Expr/AssignOp/BitwiseAnd.php',
265 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\AssignOp\\BitwiseOr' => '/nikic-php-parser/PhpParser/Node/Expr/AssignOp/BitwiseOr.php',
266 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\AssignOp\\BitwiseXor' => '/nikic-php-parser/PhpParser/Node/Expr/AssignOp/BitwiseXor.php',
267 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\AssignOp\\Coalesce' => '/nikic-php-parser/PhpParser/Node/Expr/AssignOp/Coalesce.php',
268 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\AssignOp\\Concat' => '/nikic-php-parser/PhpParser/Node/Expr/AssignOp/Concat.php',
269 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\AssignOp\\Div' => '/nikic-php-parser/PhpParser/Node/Expr/AssignOp/Div.php',
270 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\AssignOp\\Minus' => '/nikic-php-parser/PhpParser/Node/Expr/AssignOp/Minus.php',
271 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\AssignOp\\Mod' => '/nikic-php-parser/PhpParser/Node/Expr/AssignOp/Mod.php',
272 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\AssignOp\\Mul' => '/nikic-php-parser/PhpParser/Node/Expr/AssignOp/Mul.php',
273 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\AssignOp\\Plus' => '/nikic-php-parser/PhpParser/Node/Expr/AssignOp/Plus.php',
274 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\AssignOp\\Pow' => '/nikic-php-parser/PhpParser/Node/Expr/AssignOp/Pow.php',
275 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\AssignOp\\ShiftLeft' => '/nikic-php-parser/PhpParser/Node/Expr/AssignOp/ShiftLeft.php',
276 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\AssignOp\\ShiftRight' => '/nikic-php-parser/PhpParser/Node/Expr/AssignOp/ShiftRight.php',
277 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\AssignRef' => '/nikic-php-parser/PhpParser/Node/Expr/AssignRef.php',
278 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BinaryOp' => '/nikic-php-parser/PhpParser/Node/Expr/BinaryOp.php',
279 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BinaryOp\\BitwiseAnd' => '/nikic-php-parser/PhpParser/Node/Expr/BinaryOp/BitwiseAnd.php',
280 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BinaryOp\\BitwiseOr' => '/nikic-php-parser/PhpParser/Node/Expr/BinaryOp/BitwiseOr.php',
281 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BinaryOp\\BitwiseXor' => '/nikic-php-parser/PhpParser/Node/Expr/BinaryOp/BitwiseXor.php',
282 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BinaryOp\\BooleanAnd' => '/nikic-php-parser/PhpParser/Node/Expr/BinaryOp/BooleanAnd.php',
283 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BinaryOp\\BooleanOr' => '/nikic-php-parser/PhpParser/Node/Expr/BinaryOp/BooleanOr.php',
284 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BinaryOp\\Coalesce' => '/nikic-php-parser/PhpParser/Node/Expr/BinaryOp/Coalesce.php',
285 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BinaryOp\\Concat' => '/nikic-php-parser/PhpParser/Node/Expr/BinaryOp/Concat.php',
286 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BinaryOp\\Div' => '/nikic-php-parser/PhpParser/Node/Expr/BinaryOp/Div.php',
287 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BinaryOp\\Equal' => '/nikic-php-parser/PhpParser/Node/Expr/BinaryOp/Equal.php',
288 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BinaryOp\\Greater' => '/nikic-php-parser/PhpParser/Node/Expr/BinaryOp/Greater.php',
289 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BinaryOp\\GreaterOrEqual' => '/nikic-php-parser/PhpParser/Node/Expr/BinaryOp/GreaterOrEqual.php',
290 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BinaryOp\\Identical' => '/nikic-php-parser/PhpParser/Node/Expr/BinaryOp/Identical.php',
291 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BinaryOp\\LogicalAnd' => '/nikic-php-parser/PhpParser/Node/Expr/BinaryOp/LogicalAnd.php',
292 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BinaryOp\\LogicalOr' => '/nikic-php-parser/PhpParser/Node/Expr/BinaryOp/LogicalOr.php',
293 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BinaryOp\\LogicalXor' => '/nikic-php-parser/PhpParser/Node/Expr/BinaryOp/LogicalXor.php',
294 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BinaryOp\\Minus' => '/nikic-php-parser/PhpParser/Node/Expr/BinaryOp/Minus.php',
295 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BinaryOp\\Mod' => '/nikic-php-parser/PhpParser/Node/Expr/BinaryOp/Mod.php',
296 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BinaryOp\\Mul' => '/nikic-php-parser/PhpParser/Node/Expr/BinaryOp/Mul.php',
297 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BinaryOp\\NotEqual' => '/nikic-php-parser/PhpParser/Node/Expr/BinaryOp/NotEqual.php',
298 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BinaryOp\\NotIdentical' => '/nikic-php-parser/PhpParser/Node/Expr/BinaryOp/NotIdentical.php',
299 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BinaryOp\\Pipe' => '/nikic-php-parser/PhpParser/Node/Expr/BinaryOp/Pipe.php',
300 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BinaryOp\\Plus' => '/nikic-php-parser/PhpParser/Node/Expr/BinaryOp/Plus.php',
301 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BinaryOp\\Pow' => '/nikic-php-parser/PhpParser/Node/Expr/BinaryOp/Pow.php',
302 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BinaryOp\\ShiftLeft' => '/nikic-php-parser/PhpParser/Node/Expr/BinaryOp/ShiftLeft.php',
303 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BinaryOp\\ShiftRight' => '/nikic-php-parser/PhpParser/Node/Expr/BinaryOp/ShiftRight.php',
304 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BinaryOp\\Smaller' => '/nikic-php-parser/PhpParser/Node/Expr/BinaryOp/Smaller.php',
305 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BinaryOp\\SmallerOrEqual' => '/nikic-php-parser/PhpParser/Node/Expr/BinaryOp/SmallerOrEqual.php',
306 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BinaryOp\\Spaceship' => '/nikic-php-parser/PhpParser/Node/Expr/BinaryOp/Spaceship.php',
307 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BitwiseNot' => '/nikic-php-parser/PhpParser/Node/Expr/BitwiseNot.php',
308 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BooleanNot' => '/nikic-php-parser/PhpParser/Node/Expr/BooleanNot.php',
309 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\CallLike' => '/nikic-php-parser/PhpParser/Node/Expr/CallLike.php',
310 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\Cast' => '/nikic-php-parser/PhpParser/Node/Expr/Cast.php',
311 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\Cast\\Array_' => '/nikic-php-parser/PhpParser/Node/Expr/Cast/Array_.php',
312 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\Cast\\Bool_' => '/nikic-php-parser/PhpParser/Node/Expr/Cast/Bool_.php',
313 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\Cast\\Double' => '/nikic-php-parser/PhpParser/Node/Expr/Cast/Double.php',
314 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\Cast\\Int_' => '/nikic-php-parser/PhpParser/Node/Expr/Cast/Int_.php',
315 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\Cast\\Object_' => '/nikic-php-parser/PhpParser/Node/Expr/Cast/Object_.php',
316 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\Cast\\String_' => '/nikic-php-parser/PhpParser/Node/Expr/Cast/String_.php',
317 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\Cast\\Unset_' => '/nikic-php-parser/PhpParser/Node/Expr/Cast/Unset_.php',
318 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\Cast\\Void_' => '/nikic-php-parser/PhpParser/Node/Expr/Cast/Void_.php',
319 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\ClassConstFetch' => '/nikic-php-parser/PhpParser/Node/Expr/ClassConstFetch.php',
320 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\Clone_' => '/nikic-php-parser/PhpParser/Node/Expr/Clone_.php',
321 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\Closure' => '/nikic-php-parser/PhpParser/Node/Expr/Closure.php',
322 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\ConstFetch' => '/nikic-php-parser/PhpParser/Node/Expr/ConstFetch.php',
323 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\Empty_' => '/nikic-php-parser/PhpParser/Node/Expr/Empty_.php',
324 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\Error' => '/nikic-php-parser/PhpParser/Node/Expr/Error.php',
325 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\ErrorSuppress' => '/nikic-php-parser/PhpParser/Node/Expr/ErrorSuppress.php',
326 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\Eval_' => '/nikic-php-parser/PhpParser/Node/Expr/Eval_.php',
327 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\Exit_' => '/nikic-php-parser/PhpParser/Node/Expr/Exit_.php',
328 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\FuncCall' => '/nikic-php-parser/PhpParser/Node/Expr/FuncCall.php',
329 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\Include_' => '/nikic-php-parser/PhpParser/Node/Expr/Include_.php',
330 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\Instanceof_' => '/nikic-php-parser/PhpParser/Node/Expr/Instanceof_.php',
331 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\Isset_' => '/nikic-php-parser/PhpParser/Node/Expr/Isset_.php',
332 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\List_' => '/nikic-php-parser/PhpParser/Node/Expr/List_.php',
333 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\Match_' => '/nikic-php-parser/PhpParser/Node/Expr/Match_.php',
334 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\MethodCall' => '/nikic-php-parser/PhpParser/Node/Expr/MethodCall.php',
335 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\New_' => '/nikic-php-parser/PhpParser/Node/Expr/New_.php',
336 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\NullsafeMethodCall' => '/nikic-php-parser/PhpParser/Node/Expr/NullsafeMethodCall.php',
337 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\NullsafePropertyFetch' => '/nikic-php-parser/PhpParser/Node/Expr/NullsafePropertyFetch.php',
338 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\PostDec' => '/nikic-php-parser/PhpParser/Node/Expr/PostDec.php',
339 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\PostInc' => '/nikic-php-parser/PhpParser/Node/Expr/PostInc.php',
340 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\PreDec' => '/nikic-php-parser/PhpParser/Node/Expr/PreDec.php',
341 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\PreInc' => '/nikic-php-parser/PhpParser/Node/Expr/PreInc.php',
342 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\Print_' => '/nikic-php-parser/PhpParser/Node/Expr/Print_.php',
343 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\PropertyFetch' => '/nikic-php-parser/PhpParser/Node/Expr/PropertyFetch.php',
344 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\ShellExec' => '/nikic-php-parser/PhpParser/Node/Expr/ShellExec.php',
345 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\StaticCall' => '/nikic-php-parser/PhpParser/Node/Expr/StaticCall.php',
346 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\StaticPropertyFetch' => '/nikic-php-parser/PhpParser/Node/Expr/StaticPropertyFetch.php',
347 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\Ternary' => '/nikic-php-parser/PhpParser/Node/Expr/Ternary.php',
348 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\Throw_' => '/nikic-php-parser/PhpParser/Node/Expr/Throw_.php',
349 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\UnaryMinus' => '/nikic-php-parser/PhpParser/Node/Expr/UnaryMinus.php',
350 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\UnaryPlus' => '/nikic-php-parser/PhpParser/Node/Expr/UnaryPlus.php',
351 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\Variable' => '/nikic-php-parser/PhpParser/Node/Expr/Variable.php',
352 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\YieldFrom' => '/nikic-php-parser/PhpParser/Node/Expr/YieldFrom.php',
353 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\Yield_' => '/nikic-php-parser/PhpParser/Node/Expr/Yield_.php',
354 'PHPUnitPHAR\\PhpParser\\Node\\FunctionLike' => '/nikic-php-parser/PhpParser/Node/FunctionLike.php',
355 'PHPUnitPHAR\\PhpParser\\Node\\Identifier' => '/nikic-php-parser/PhpParser/Node/Identifier.php',
356 'PHPUnitPHAR\\PhpParser\\Node\\InterpolatedStringPart' => '/nikic-php-parser/PhpParser/Node/InterpolatedStringPart.php',
357 'PHPUnitPHAR\\PhpParser\\Node\\IntersectionType' => '/nikic-php-parser/PhpParser/Node/IntersectionType.php',
358 'PHPUnitPHAR\\PhpParser\\Node\\MatchArm' => '/nikic-php-parser/PhpParser/Node/MatchArm.php',
359 'PHPUnitPHAR\\PhpParser\\Node\\Name' => '/nikic-php-parser/PhpParser/Node/Name.php',
360 'PHPUnitPHAR\\PhpParser\\Node\\Name\\FullyQualified' => '/nikic-php-parser/PhpParser/Node/Name/FullyQualified.php',
361 'PHPUnitPHAR\\PhpParser\\Node\\Name\\Relative' => '/nikic-php-parser/PhpParser/Node/Name/Relative.php',
362 'PHPUnitPHAR\\PhpParser\\Node\\NullableType' => '/nikic-php-parser/PhpParser/Node/NullableType.php',
363 'PHPUnitPHAR\\PhpParser\\Node\\Param' => '/nikic-php-parser/PhpParser/Node/Param.php',
364 'PHPUnitPHAR\\PhpParser\\Node\\PropertyHook' => '/nikic-php-parser/PhpParser/Node/PropertyHook.php',
365 'PHPUnitPHAR\\PhpParser\\Node\\PropertyItem' => '/nikic-php-parser/PhpParser/Node/PropertyItem.php',
366 'PHPUnitPHAR\\PhpParser\\Node\\Scalar' => '/nikic-php-parser/PhpParser/Node/Scalar.php',
367 'PHPUnitPHAR\\PhpParser\\Node\\Scalar\\Float_' => '/nikic-php-parser/PhpParser/Node/Scalar/Float_.php',
368 'PHPUnitPHAR\\PhpParser\\Node\\Scalar\\Int_' => '/nikic-php-parser/PhpParser/Node/Scalar/Int_.php',
369 'PHPUnitPHAR\\PhpParser\\Node\\Scalar\\InterpolatedString' => '/nikic-php-parser/PhpParser/Node/Scalar/InterpolatedString.php',
370 'PHPUnitPHAR\\PhpParser\\Node\\Scalar\\MagicConst' => '/nikic-php-parser/PhpParser/Node/Scalar/MagicConst.php',
371 'PHPUnitPHAR\\PhpParser\\Node\\Scalar\\MagicConst\\Class_' => '/nikic-php-parser/PhpParser/Node/Scalar/MagicConst/Class_.php',
372 'PHPUnitPHAR\\PhpParser\\Node\\Scalar\\MagicConst\\Dir' => '/nikic-php-parser/PhpParser/Node/Scalar/MagicConst/Dir.php',
373 'PHPUnitPHAR\\PhpParser\\Node\\Scalar\\MagicConst\\File' => '/nikic-php-parser/PhpParser/Node/Scalar/MagicConst/File.php',
374 'PHPUnitPHAR\\PhpParser\\Node\\Scalar\\MagicConst\\Function_' => '/nikic-php-parser/PhpParser/Node/Scalar/MagicConst/Function_.php',
375 'PHPUnitPHAR\\PhpParser\\Node\\Scalar\\MagicConst\\Line' => '/nikic-php-parser/PhpParser/Node/Scalar/MagicConst/Line.php',
376 'PHPUnitPHAR\\PhpParser\\Node\\Scalar\\MagicConst\\Method' => '/nikic-php-parser/PhpParser/Node/Scalar/MagicConst/Method.php',
377 'PHPUnitPHAR\\PhpParser\\Node\\Scalar\\MagicConst\\Namespace_' => '/nikic-php-parser/PhpParser/Node/Scalar/MagicConst/Namespace_.php',
378 'PHPUnitPHAR\\PhpParser\\Node\\Scalar\\MagicConst\\Property' => '/nikic-php-parser/PhpParser/Node/Scalar/MagicConst/Property.php',
379 'PHPUnitPHAR\\PhpParser\\Node\\Scalar\\MagicConst\\Trait_' => '/nikic-php-parser/PhpParser/Node/Scalar/MagicConst/Trait_.php',
380 'PHPUnitPHAR\\PhpParser\\Node\\Scalar\\String_' => '/nikic-php-parser/PhpParser/Node/Scalar/String_.php',
381 'PHPUnitPHAR\\PhpParser\\Node\\StaticVar' => '/nikic-php-parser/PhpParser/Node/StaticVar.php',
382 'PHPUnitPHAR\\PhpParser\\Node\\Stmt' => '/nikic-php-parser/PhpParser/Node/Stmt.php',
383 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\Block' => '/nikic-php-parser/PhpParser/Node/Stmt/Block.php',
384 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\Break_' => '/nikic-php-parser/PhpParser/Node/Stmt/Break_.php',
385 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\Case_' => '/nikic-php-parser/PhpParser/Node/Stmt/Case_.php',
386 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\Catch_' => '/nikic-php-parser/PhpParser/Node/Stmt/Catch_.php',
387 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\ClassConst' => '/nikic-php-parser/PhpParser/Node/Stmt/ClassConst.php',
388 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\ClassLike' => '/nikic-php-parser/PhpParser/Node/Stmt/ClassLike.php',
389 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\ClassMethod' => '/nikic-php-parser/PhpParser/Node/Stmt/ClassMethod.php',
390 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\Class_' => '/nikic-php-parser/PhpParser/Node/Stmt/Class_.php',
391 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\Const_' => '/nikic-php-parser/PhpParser/Node/Stmt/Const_.php',
392 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\Continue_' => '/nikic-php-parser/PhpParser/Node/Stmt/Continue_.php',
393 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\Declare_' => '/nikic-php-parser/PhpParser/Node/Stmt/Declare_.php',
394 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\Do_' => '/nikic-php-parser/PhpParser/Node/Stmt/Do_.php',
395 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\Echo_' => '/nikic-php-parser/PhpParser/Node/Stmt/Echo_.php',
396 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\ElseIf_' => '/nikic-php-parser/PhpParser/Node/Stmt/ElseIf_.php',
397 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\Else_' => '/nikic-php-parser/PhpParser/Node/Stmt/Else_.php',
398 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\EnumCase' => '/nikic-php-parser/PhpParser/Node/Stmt/EnumCase.php',
399 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\Enum_' => '/nikic-php-parser/PhpParser/Node/Stmt/Enum_.php',
400 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\Expression' => '/nikic-php-parser/PhpParser/Node/Stmt/Expression.php',
401 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\Finally_' => '/nikic-php-parser/PhpParser/Node/Stmt/Finally_.php',
402 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\For_' => '/nikic-php-parser/PhpParser/Node/Stmt/For_.php',
403 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\Foreach_' => '/nikic-php-parser/PhpParser/Node/Stmt/Foreach_.php',
404 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\Function_' => '/nikic-php-parser/PhpParser/Node/Stmt/Function_.php',
405 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\Global_' => '/nikic-php-parser/PhpParser/Node/Stmt/Global_.php',
406 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\Goto_' => '/nikic-php-parser/PhpParser/Node/Stmt/Goto_.php',
407 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\GroupUse' => '/nikic-php-parser/PhpParser/Node/Stmt/GroupUse.php',
408 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\HaltCompiler' => '/nikic-php-parser/PhpParser/Node/Stmt/HaltCompiler.php',
409 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\If_' => '/nikic-php-parser/PhpParser/Node/Stmt/If_.php',
410 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\InlineHTML' => '/nikic-php-parser/PhpParser/Node/Stmt/InlineHTML.php',
411 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\Interface_' => '/nikic-php-parser/PhpParser/Node/Stmt/Interface_.php',
412 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\Label' => '/nikic-php-parser/PhpParser/Node/Stmt/Label.php',
413 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\Namespace_' => '/nikic-php-parser/PhpParser/Node/Stmt/Namespace_.php',
414 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\Nop' => '/nikic-php-parser/PhpParser/Node/Stmt/Nop.php',
415 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\Property' => '/nikic-php-parser/PhpParser/Node/Stmt/Property.php',
416 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\Return_' => '/nikic-php-parser/PhpParser/Node/Stmt/Return_.php',
417 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\Static_' => '/nikic-php-parser/PhpParser/Node/Stmt/Static_.php',
418 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\Switch_' => '/nikic-php-parser/PhpParser/Node/Stmt/Switch_.php',
419 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\TraitUse' => '/nikic-php-parser/PhpParser/Node/Stmt/TraitUse.php',
420 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\TraitUseAdaptation' => '/nikic-php-parser/PhpParser/Node/Stmt/TraitUseAdaptation.php',
421 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\TraitUseAdaptation\\Alias' => '/nikic-php-parser/PhpParser/Node/Stmt/TraitUseAdaptation/Alias.php',
422 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\TraitUseAdaptation\\Precedence' => '/nikic-php-parser/PhpParser/Node/Stmt/TraitUseAdaptation/Precedence.php',
423 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\Trait_' => '/nikic-php-parser/PhpParser/Node/Stmt/Trait_.php',
424 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\TryCatch' => '/nikic-php-parser/PhpParser/Node/Stmt/TryCatch.php',
425 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\Unset_' => '/nikic-php-parser/PhpParser/Node/Stmt/Unset_.php',
426 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\Use_' => '/nikic-php-parser/PhpParser/Node/Stmt/Use_.php',
427 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\While_' => '/nikic-php-parser/PhpParser/Node/Stmt/While_.php',
428 'PHPUnitPHAR\\PhpParser\\Node\\UnionType' => '/nikic-php-parser/PhpParser/Node/UnionType.php',
429 'PHPUnitPHAR\\PhpParser\\Node\\UseItem' => '/nikic-php-parser/PhpParser/Node/UseItem.php',
430 'PHPUnitPHAR\\PhpParser\\Node\\VarLikeIdentifier' => '/nikic-php-parser/PhpParser/Node/VarLikeIdentifier.php',
431 'PHPUnitPHAR\\PhpParser\\Node\\VariadicPlaceholder' => '/nikic-php-parser/PhpParser/Node/VariadicPlaceholder.php',
432 'PHPUnitPHAR\\PhpParser\\Parser' => '/nikic-php-parser/PhpParser/Parser.php',
433 'PHPUnitPHAR\\PhpParser\\ParserAbstract' => '/nikic-php-parser/PhpParser/ParserAbstract.php',
434 'PHPUnitPHAR\\PhpParser\\ParserFactory' => '/nikic-php-parser/PhpParser/ParserFactory.php',
435 'PHPUnitPHAR\\PhpParser\\Parser\\Php7' => '/nikic-php-parser/PhpParser/Parser/Php7.php',
436 'PHPUnitPHAR\\PhpParser\\Parser\\Php8' => '/nikic-php-parser/PhpParser/Parser/Php8.php',
437 'PHPUnitPHAR\\PhpParser\\PhpVersion' => '/nikic-php-parser/PhpParser/PhpVersion.php',
438 'PHPUnitPHAR\\PhpParser\\PrettyPrinter' => '/nikic-php-parser/PhpParser/PrettyPrinter.php',
439 'PHPUnitPHAR\\PhpParser\\PrettyPrinterAbstract' => '/nikic-php-parser/PhpParser/PrettyPrinterAbstract.php',
440 'PHPUnitPHAR\\PhpParser\\PrettyPrinter\\Standard' => '/nikic-php-parser/PhpParser/PrettyPrinter/Standard.php',
441 'PHPUnitPHAR\\PhpParser\\Token' => '/nikic-php-parser/PhpParser/Token.php',
442 'PHPUnitPHAR\\SebastianBergmann\\CliParser\\AmbiguousOptionException' => '/sebastian-cli-parser/exceptions/AmbiguousOptionException.php',
443 'PHPUnitPHAR\\SebastianBergmann\\CliParser\\Exception' => '/sebastian-cli-parser/exceptions/Exception.php',
444 'PHPUnitPHAR\\SebastianBergmann\\CliParser\\OptionDoesNotAllowArgumentException' => '/sebastian-cli-parser/exceptions/OptionDoesNotAllowArgumentException.php',
445 'PHPUnitPHAR\\SebastianBergmann\\CliParser\\Parser' => '/sebastian-cli-parser/Parser.php',
446 'PHPUnitPHAR\\SebastianBergmann\\CliParser\\RequiredOptionArgumentMissingException' => '/sebastian-cli-parser/exceptions/RequiredOptionArgumentMissingException.php',
447 'PHPUnitPHAR\\SebastianBergmann\\CliParser\\UnknownOptionException' => '/sebastian-cli-parser/exceptions/UnknownOptionException.php',
448 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\BranchAndPathCoverageNotSupportedException' => '/php-code-coverage/Exception/BranchAndPathCoverageNotSupportedException.php',
449 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\CodeCoverage' => '/php-code-coverage/CodeCoverage.php',
450 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Data\\ProcessedCodeCoverageData' => '/php-code-coverage/Data/ProcessedCodeCoverageData.php',
451 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Data\\RawCodeCoverageData' => '/php-code-coverage/Data/RawCodeCoverageData.php',
452 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\DeadCodeDetectionNotSupportedException' => '/php-code-coverage/Exception/DeadCodeDetectionNotSupportedException.php',
453 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Driver\\Driver' => '/php-code-coverage/Driver/Driver.php',
454 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Driver\\PathExistsButIsNotDirectoryException' => '/php-code-coverage/Exception/PathExistsButIsNotDirectoryException.php',
455 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Driver\\PcovDriver' => '/php-code-coverage/Driver/PcovDriver.php',
456 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Driver\\PcovNotAvailableException' => '/php-code-coverage/Exception/PcovNotAvailableException.php',
457 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Driver\\Selector' => '/php-code-coverage/Driver/Selector.php',
458 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Driver\\WriteOperationFailedException' => '/php-code-coverage/Exception/WriteOperationFailedException.php',
459 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Driver\\XdebugDriver' => '/php-code-coverage/Driver/XdebugDriver.php',
460 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Driver\\XdebugNotAvailableException' => '/php-code-coverage/Exception/XdebugNotAvailableException.php',
461 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Driver\\XdebugNotEnabledException' => '/php-code-coverage/Exception/XdebugNotEnabledException.php',
462 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Exception' => '/php-code-coverage/Exception/Exception.php',
463 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\FileCouldNotBeWrittenException' => '/php-code-coverage/Exception/FileCouldNotBeWrittenException.php',
464 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Filter' => '/php-code-coverage/Filter.php',
465 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\InvalidArgumentException' => '/php-code-coverage/Exception/InvalidArgumentException.php',
466 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\NoCodeCoverageDriverAvailableException' => '/php-code-coverage/Exception/NoCodeCoverageDriverAvailableException.php',
467 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\NoCodeCoverageDriverWithPathCoverageSupportAvailableException' => '/php-code-coverage/Exception/NoCodeCoverageDriverWithPathCoverageSupportAvailableException.php',
468 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Node\\AbstractNode' => '/php-code-coverage/Node/AbstractNode.php',
469 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Node\\Builder' => '/php-code-coverage/Node/Builder.php',
470 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Node\\CrapIndex' => '/php-code-coverage/Node/CrapIndex.php',
471 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Node\\Directory' => '/php-code-coverage/Node/Directory.php',
472 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Node\\File' => '/php-code-coverage/Node/File.php',
473 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Node\\Iterator' => '/php-code-coverage/Node/Iterator.php',
474 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\ParserException' => '/php-code-coverage/Exception/ParserException.php',
475 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\ReflectionException' => '/php-code-coverage/Exception/ReflectionException.php',
476 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\ReportAlreadyFinalizedException' => '/php-code-coverage/Exception/ReportAlreadyFinalizedException.php',
477 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Report\\Clover' => '/php-code-coverage/Report/Clover.php',
478 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Report\\Cobertura' => '/php-code-coverage/Report/Cobertura.php',
479 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Report\\Crap4j' => '/php-code-coverage/Report/Crap4j.php',
480 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Report\\Html\\Colors' => '/php-code-coverage/Report/Html/Colors.php',
481 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Report\\Html\\CustomCssFile' => '/php-code-coverage/Report/Html/CustomCssFile.php',
482 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Report\\Html\\Dashboard' => '/php-code-coverage/Report/Html/Renderer/Dashboard.php',
483 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Report\\Html\\Directory' => '/php-code-coverage/Report/Html/Renderer/Directory.php',
484 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Report\\Html\\Facade' => '/php-code-coverage/Report/Html/Facade.php',
485 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Report\\Html\\File' => '/php-code-coverage/Report/Html/Renderer/File.php',
486 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Report\\Html\\Renderer' => '/php-code-coverage/Report/Html/Renderer.php',
487 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Report\\PHP' => '/php-code-coverage/Report/PHP.php',
488 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Report\\Text' => '/php-code-coverage/Report/Text.php',
489 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Report\\Thresholds' => '/php-code-coverage/Report/Thresholds.php',
490 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Report\\Xml\\BuildInformation' => '/php-code-coverage/Report/Xml/BuildInformation.php',
491 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Report\\Xml\\Coverage' => '/php-code-coverage/Report/Xml/Coverage.php',
492 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Report\\Xml\\Directory' => '/php-code-coverage/Report/Xml/Directory.php',
493 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Report\\Xml\\Facade' => '/php-code-coverage/Report/Xml/Facade.php',
494 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Report\\Xml\\File' => '/php-code-coverage/Report/Xml/File.php',
495 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Report\\Xml\\Method' => '/php-code-coverage/Report/Xml/Method.php',
496 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Report\\Xml\\Node' => '/php-code-coverage/Report/Xml/Node.php',
497 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Report\\Xml\\Project' => '/php-code-coverage/Report/Xml/Project.php',
498 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Report\\Xml\\Report' => '/php-code-coverage/Report/Xml/Report.php',
499 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Report\\Xml\\Source' => '/php-code-coverage/Report/Xml/Source.php',
500 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Report\\Xml\\Tests' => '/php-code-coverage/Report/Xml/Tests.php',
501 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Report\\Xml\\Totals' => '/php-code-coverage/Report/Xml/Totals.php',
502 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Report\\Xml\\Unit' => '/php-code-coverage/Report/Xml/Unit.php',
503 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\StaticAnalysisCacheNotConfiguredException' => '/php-code-coverage/Exception/StaticAnalysisCacheNotConfiguredException.php',
504 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\StaticAnalysis\\CacheWarmer' => '/php-code-coverage/StaticAnalysis/CacheWarmer.php',
505 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\StaticAnalysis\\CachingFileAnalyser' => '/php-code-coverage/StaticAnalysis/CachingFileAnalyser.php',
506 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\StaticAnalysis\\CodeUnitFindingVisitor' => '/php-code-coverage/StaticAnalysis/CodeUnitFindingVisitor.php',
507 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\StaticAnalysis\\ExecutableLinesFindingVisitor' => '/php-code-coverage/StaticAnalysis/ExecutableLinesFindingVisitor.php',
508 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\StaticAnalysis\\FileAnalyser' => '/php-code-coverage/StaticAnalysis/FileAnalyser.php',
509 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\StaticAnalysis\\IgnoredLinesFindingVisitor' => '/php-code-coverage/StaticAnalysis/IgnoredLinesFindingVisitor.php',
510 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\StaticAnalysis\\ParsingFileAnalyser' => '/php-code-coverage/StaticAnalysis/ParsingFileAnalyser.php',
511 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\TestIdMissingException' => '/php-code-coverage/Exception/TestIdMissingException.php',
512 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Test\\TestSize\\Known' => '/php-code-coverage/TestSize/Known.php',
513 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Test\\TestSize\\Large' => '/php-code-coverage/TestSize/Large.php',
514 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Test\\TestSize\\Medium' => '/php-code-coverage/TestSize/Medium.php',
515 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Test\\TestSize\\Small' => '/php-code-coverage/TestSize/Small.php',
516 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Test\\TestSize\\TestSize' => '/php-code-coverage/TestSize/TestSize.php',
517 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Test\\TestSize\\Unknown' => '/php-code-coverage/TestSize/Unknown.php',
518 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Test\\TestStatus\\Failure' => '/php-code-coverage/TestStatus/Failure.php',
519 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Test\\TestStatus\\Known' => '/php-code-coverage/TestStatus/Known.php',
520 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Test\\TestStatus\\Success' => '/php-code-coverage/TestStatus/Success.php',
521 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Test\\TestStatus\\TestStatus' => '/php-code-coverage/TestStatus/TestStatus.php',
522 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Test\\TestStatus\\Unknown' => '/php-code-coverage/TestStatus/Unknown.php',
523 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\UnintentionallyCoveredCodeException' => '/php-code-coverage/Exception/UnintentionallyCoveredCodeException.php',
524 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Util\\DirectoryCouldNotBeCreatedException' => '/php-code-coverage/Exception/DirectoryCouldNotBeCreatedException.php',
525 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Util\\Filesystem' => '/php-code-coverage/Util/Filesystem.php',
526 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Util\\Percentage' => '/php-code-coverage/Util/Percentage.php',
527 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Version' => '/php-code-coverage/Version.php',
528 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\XmlException' => '/php-code-coverage/Exception/XmlException.php',
529 'PHPUnitPHAR\\SebastianBergmann\\CodeUnitReverseLookup\\Wizard' => '/sebastian-code-unit-reverse-lookup/Wizard.php',
530 'PHPUnitPHAR\\SebastianBergmann\\CodeUnit\\ClassMethodUnit' => '/sebastian-code-unit/ClassMethodUnit.php',
531 'PHPUnitPHAR\\SebastianBergmann\\CodeUnit\\ClassUnit' => '/sebastian-code-unit/ClassUnit.php',
532 'PHPUnitPHAR\\SebastianBergmann\\CodeUnit\\CodeUnit' => '/sebastian-code-unit/CodeUnit.php',
533 'PHPUnitPHAR\\SebastianBergmann\\CodeUnit\\CodeUnitCollection' => '/sebastian-code-unit/CodeUnitCollection.php',
534 'PHPUnitPHAR\\SebastianBergmann\\CodeUnit\\CodeUnitCollectionIterator' => '/sebastian-code-unit/CodeUnitCollectionIterator.php',
535 'PHPUnitPHAR\\SebastianBergmann\\CodeUnit\\Exception' => '/sebastian-code-unit/exceptions/Exception.php',
536 'PHPUnitPHAR\\SebastianBergmann\\CodeUnit\\FileUnit' => '/sebastian-code-unit/FileUnit.php',
537 'PHPUnitPHAR\\SebastianBergmann\\CodeUnit\\FunctionUnit' => '/sebastian-code-unit/FunctionUnit.php',
538 'PHPUnitPHAR\\SebastianBergmann\\CodeUnit\\InterfaceMethodUnit' => '/sebastian-code-unit/InterfaceMethodUnit.php',
539 'PHPUnitPHAR\\SebastianBergmann\\CodeUnit\\InterfaceUnit' => '/sebastian-code-unit/InterfaceUnit.php',
540 'PHPUnitPHAR\\SebastianBergmann\\CodeUnit\\InvalidCodeUnitException' => '/sebastian-code-unit/exceptions/InvalidCodeUnitException.php',
541 'PHPUnitPHAR\\SebastianBergmann\\CodeUnit\\Mapper' => '/sebastian-code-unit/Mapper.php',
542 'PHPUnitPHAR\\SebastianBergmann\\CodeUnit\\NoTraitException' => '/sebastian-code-unit/exceptions/NoTraitException.php',
543 'PHPUnitPHAR\\SebastianBergmann\\CodeUnit\\ReflectionException' => '/sebastian-code-unit/exceptions/ReflectionException.php',
544 'PHPUnitPHAR\\SebastianBergmann\\CodeUnit\\TraitMethodUnit' => '/sebastian-code-unit/TraitMethodUnit.php',
545 'PHPUnitPHAR\\SebastianBergmann\\CodeUnit\\TraitUnit' => '/sebastian-code-unit/TraitUnit.php',
546 'PHPUnitPHAR\\SebastianBergmann\\Comparator\\ArrayComparator' => '/sebastian-comparator/ArrayComparator.php',
547 'PHPUnitPHAR\\SebastianBergmann\\Comparator\\Comparator' => '/sebastian-comparator/Comparator.php',
548 'PHPUnitPHAR\\SebastianBergmann\\Comparator\\ComparisonFailure' => '/sebastian-comparator/ComparisonFailure.php',
549 'PHPUnitPHAR\\SebastianBergmann\\Comparator\\DOMNodeComparator' => '/sebastian-comparator/DOMNodeComparator.php',
550 'PHPUnitPHAR\\SebastianBergmann\\Comparator\\DateTimeComparator' => '/sebastian-comparator/DateTimeComparator.php',
551 'PHPUnitPHAR\\SebastianBergmann\\Comparator\\Exception' => '/sebastian-comparator/exceptions/Exception.php',
552 'PHPUnitPHAR\\SebastianBergmann\\Comparator\\ExceptionComparator' => '/sebastian-comparator/ExceptionComparator.php',
553 'PHPUnitPHAR\\SebastianBergmann\\Comparator\\Factory' => '/sebastian-comparator/Factory.php',
554 'PHPUnitPHAR\\SebastianBergmann\\Comparator\\MockObjectComparator' => '/sebastian-comparator/MockObjectComparator.php',
555 'PHPUnitPHAR\\SebastianBergmann\\Comparator\\NumericComparator' => '/sebastian-comparator/NumericComparator.php',
556 'PHPUnitPHAR\\SebastianBergmann\\Comparator\\ObjectComparator' => '/sebastian-comparator/ObjectComparator.php',
557 'PHPUnitPHAR\\SebastianBergmann\\Comparator\\ResourceComparator' => '/sebastian-comparator/ResourceComparator.php',
558 'PHPUnitPHAR\\SebastianBergmann\\Comparator\\RuntimeException' => '/sebastian-comparator/exceptions/RuntimeException.php',
559 'PHPUnitPHAR\\SebastianBergmann\\Comparator\\ScalarComparator' => '/sebastian-comparator/ScalarComparator.php',
560 'PHPUnitPHAR\\SebastianBergmann\\Comparator\\SplObjectStorageComparator' => '/sebastian-comparator/SplObjectStorageComparator.php',
561 'PHPUnitPHAR\\SebastianBergmann\\Comparator\\TypeComparator' => '/sebastian-comparator/TypeComparator.php',
562 'PHPUnitPHAR\\SebastianBergmann\\Complexity\\Calculator' => '/sebastian-complexity/Calculator.php',
563 'PHPUnitPHAR\\SebastianBergmann\\Complexity\\Complexity' => '/sebastian-complexity/Complexity/Complexity.php',
564 'PHPUnitPHAR\\SebastianBergmann\\Complexity\\ComplexityCalculatingVisitor' => '/sebastian-complexity/Visitor/ComplexityCalculatingVisitor.php',
565 'PHPUnitPHAR\\SebastianBergmann\\Complexity\\ComplexityCollection' => '/sebastian-complexity/Complexity/ComplexityCollection.php',
566 'PHPUnitPHAR\\SebastianBergmann\\Complexity\\ComplexityCollectionIterator' => '/sebastian-complexity/Complexity/ComplexityCollectionIterator.php',
567 'PHPUnitPHAR\\SebastianBergmann\\Complexity\\CyclomaticComplexityCalculatingVisitor' => '/sebastian-complexity/Visitor/CyclomaticComplexityCalculatingVisitor.php',
568 'PHPUnitPHAR\\SebastianBergmann\\Complexity\\Exception' => '/sebastian-complexity/Exception/Exception.php',
569 'PHPUnitPHAR\\SebastianBergmann\\Complexity\\RuntimeException' => '/sebastian-complexity/Exception/RuntimeException.php',
570 'PHPUnitPHAR\\SebastianBergmann\\Diff\\Chunk' => '/sebastian-diff/Chunk.php',
571 'PHPUnitPHAR\\SebastianBergmann\\Diff\\ConfigurationException' => '/sebastian-diff/Exception/ConfigurationException.php',
572 'PHPUnitPHAR\\SebastianBergmann\\Diff\\Diff' => '/sebastian-diff/Diff.php',
573 'PHPUnitPHAR\\SebastianBergmann\\Diff\\Differ' => '/sebastian-diff/Differ.php',
574 'PHPUnitPHAR\\SebastianBergmann\\Diff\\Exception' => '/sebastian-diff/Exception/Exception.php',
575 'PHPUnitPHAR\\SebastianBergmann\\Diff\\InvalidArgumentException' => '/sebastian-diff/Exception/InvalidArgumentException.php',
576 'PHPUnitPHAR\\SebastianBergmann\\Diff\\Line' => '/sebastian-diff/Line.php',
577 'PHPUnitPHAR\\SebastianBergmann\\Diff\\LongestCommonSubsequenceCalculator' => '/sebastian-diff/LongestCommonSubsequenceCalculator.php',
578 'PHPUnitPHAR\\SebastianBergmann\\Diff\\MemoryEfficientLongestCommonSubsequenceCalculator' => '/sebastian-diff/MemoryEfficientLongestCommonSubsequenceCalculator.php',
579 'PHPUnitPHAR\\SebastianBergmann\\Diff\\Output\\AbstractChunkOutputBuilder' => '/sebastian-diff/Output/AbstractChunkOutputBuilder.php',
580 'PHPUnitPHAR\\SebastianBergmann\\Diff\\Output\\DiffOnlyOutputBuilder' => '/sebastian-diff/Output/DiffOnlyOutputBuilder.php',
581 'PHPUnitPHAR\\SebastianBergmann\\Diff\\Output\\DiffOutputBuilderInterface' => '/sebastian-diff/Output/DiffOutputBuilderInterface.php',
582 'PHPUnitPHAR\\SebastianBergmann\\Diff\\Output\\StrictUnifiedDiffOutputBuilder' => '/sebastian-diff/Output/StrictUnifiedDiffOutputBuilder.php',
583 'PHPUnitPHAR\\SebastianBergmann\\Diff\\Output\\UnifiedDiffOutputBuilder' => '/sebastian-diff/Output/UnifiedDiffOutputBuilder.php',
584 'PHPUnitPHAR\\SebastianBergmann\\Diff\\Parser' => '/sebastian-diff/Parser.php',
585 'PHPUnitPHAR\\SebastianBergmann\\Diff\\TimeEfficientLongestCommonSubsequenceCalculator' => '/sebastian-diff/TimeEfficientLongestCommonSubsequenceCalculator.php',
586 'PHPUnitPHAR\\SebastianBergmann\\Environment\\Console' => '/sebastian-environment/Console.php',
587 'PHPUnitPHAR\\SebastianBergmann\\Environment\\Runtime' => '/sebastian-environment/Runtime.php',
588 'PHPUnitPHAR\\SebastianBergmann\\Exporter\\Exporter' => '/sebastian-exporter/Exporter.php',
589 'PHPUnitPHAR\\SebastianBergmann\\FileIterator\\ExcludeIterator' => '/php-file-iterator/ExcludeIterator.php',
590 'PHPUnitPHAR\\SebastianBergmann\\FileIterator\\Facade' => '/php-file-iterator/Facade.php',
591 'PHPUnitPHAR\\SebastianBergmann\\FileIterator\\Factory' => '/php-file-iterator/Factory.php',
592 'PHPUnitPHAR\\SebastianBergmann\\FileIterator\\Iterator' => '/php-file-iterator/Iterator.php',
593 'PHPUnitPHAR\\SebastianBergmann\\GlobalState\\CodeExporter' => '/sebastian-global-state/CodeExporter.php',
594 'PHPUnitPHAR\\SebastianBergmann\\GlobalState\\Exception' => '/sebastian-global-state/exceptions/Exception.php',
595 'PHPUnitPHAR\\SebastianBergmann\\GlobalState\\ExcludeList' => '/sebastian-global-state/ExcludeList.php',
596 'PHPUnitPHAR\\SebastianBergmann\\GlobalState\\Restorer' => '/sebastian-global-state/Restorer.php',
597 'PHPUnitPHAR\\SebastianBergmann\\GlobalState\\RuntimeException' => '/sebastian-global-state/exceptions/RuntimeException.php',
598 'PHPUnitPHAR\\SebastianBergmann\\GlobalState\\Snapshot' => '/sebastian-global-state/Snapshot.php',
599 'PHPUnitPHAR\\SebastianBergmann\\Invoker\\Exception' => '/php-invoker/exceptions/Exception.php',
600 'PHPUnitPHAR\\SebastianBergmann\\Invoker\\Invoker' => '/php-invoker/Invoker.php',
601 'PHPUnitPHAR\\SebastianBergmann\\Invoker\\ProcessControlExtensionNotLoadedException' => '/php-invoker/exceptions/ProcessControlExtensionNotLoadedException.php',
602 'PHPUnitPHAR\\SebastianBergmann\\Invoker\\TimeoutException' => '/php-invoker/exceptions/TimeoutException.php',
603 'PHPUnitPHAR\\SebastianBergmann\\LinesOfCode\\Counter' => '/sebastian-lines-of-code/Counter.php',
604 'PHPUnitPHAR\\SebastianBergmann\\LinesOfCode\\Exception' => '/sebastian-lines-of-code/Exception/Exception.php',
605 'PHPUnitPHAR\\SebastianBergmann\\LinesOfCode\\IllogicalValuesException' => '/sebastian-lines-of-code/Exception/IllogicalValuesException.php',
606 'PHPUnitPHAR\\SebastianBergmann\\LinesOfCode\\LineCountingVisitor' => '/sebastian-lines-of-code/LineCountingVisitor.php',
607 'PHPUnitPHAR\\SebastianBergmann\\LinesOfCode\\LinesOfCode' => '/sebastian-lines-of-code/LinesOfCode.php',
608 'PHPUnitPHAR\\SebastianBergmann\\LinesOfCode\\NegativeValueException' => '/sebastian-lines-of-code/Exception/NegativeValueException.php',
609 'PHPUnitPHAR\\SebastianBergmann\\LinesOfCode\\RuntimeException' => '/sebastian-lines-of-code/Exception/RuntimeException.php',
610 'PHPUnitPHAR\\SebastianBergmann\\ObjectEnumerator\\Enumerator' => '/sebastian-object-enumerator/Enumerator.php',
611 'PHPUnitPHAR\\SebastianBergmann\\ObjectReflector\\ObjectReflector' => '/sebastian-object-reflector/ObjectReflector.php',
612 'PHPUnitPHAR\\SebastianBergmann\\RecursionContext\\Context' => '/sebastian-recursion-context/Context.php',
613 'PHPUnitPHAR\\SebastianBergmann\\Template\\Exception' => '/php-text-template/exceptions/Exception.php',
614 'PHPUnitPHAR\\SebastianBergmann\\Template\\InvalidArgumentException' => '/php-text-template/exceptions/InvalidArgumentException.php',
615 'PHPUnitPHAR\\SebastianBergmann\\Template\\RuntimeException' => '/php-text-template/exceptions/RuntimeException.php',
616 'PHPUnitPHAR\\SebastianBergmann\\Template\\Template' => '/php-text-template/Template.php',
617 'PHPUnitPHAR\\SebastianBergmann\\Timer\\Duration' => '/php-timer/Duration.php',
618 'PHPUnitPHAR\\SebastianBergmann\\Timer\\Exception' => '/php-timer/exceptions/Exception.php',
619 'PHPUnitPHAR\\SebastianBergmann\\Timer\\NoActiveTimerException' => '/php-timer/exceptions/NoActiveTimerException.php',
620 'PHPUnitPHAR\\SebastianBergmann\\Timer\\ResourceUsageFormatter' => '/php-timer/ResourceUsageFormatter.php',
621 'PHPUnitPHAR\\SebastianBergmann\\Timer\\TimeSinceStartOfRequestNotAvailableException' => '/php-timer/exceptions/TimeSinceStartOfRequestNotAvailableException.php',
622 'PHPUnitPHAR\\SebastianBergmann\\Timer\\Timer' => '/php-timer/Timer.php',
623 'PHPUnitPHAR\\SebastianBergmann\\Type\\CallableType' => '/sebastian-type/type/CallableType.php',
624 'PHPUnitPHAR\\SebastianBergmann\\Type\\Exception' => '/sebastian-type/exception/Exception.php',
625 'PHPUnitPHAR\\SebastianBergmann\\Type\\FalseType' => '/sebastian-type/type/FalseType.php',
626 'PHPUnitPHAR\\SebastianBergmann\\Type\\GenericObjectType' => '/sebastian-type/type/GenericObjectType.php',
627 'PHPUnitPHAR\\SebastianBergmann\\Type\\IntersectionType' => '/sebastian-type/type/IntersectionType.php',
628 'PHPUnitPHAR\\SebastianBergmann\\Type\\IterableType' => '/sebastian-type/type/IterableType.php',
629 'PHPUnitPHAR\\SebastianBergmann\\Type\\MixedType' => '/sebastian-type/type/MixedType.php',
630 'PHPUnitPHAR\\SebastianBergmann\\Type\\NeverType' => '/sebastian-type/type/NeverType.php',
631 'PHPUnitPHAR\\SebastianBergmann\\Type\\NullType' => '/sebastian-type/type/NullType.php',
632 'PHPUnitPHAR\\SebastianBergmann\\Type\\ObjectType' => '/sebastian-type/type/ObjectType.php',
633 'PHPUnitPHAR\\SebastianBergmann\\Type\\Parameter' => '/sebastian-type/Parameter.php',
634 'PHPUnitPHAR\\SebastianBergmann\\Type\\ReflectionMapper' => '/sebastian-type/ReflectionMapper.php',
635 'PHPUnitPHAR\\SebastianBergmann\\Type\\RuntimeException' => '/sebastian-type/exception/RuntimeException.php',
636 'PHPUnitPHAR\\SebastianBergmann\\Type\\SimpleType' => '/sebastian-type/type/SimpleType.php',
637 'PHPUnitPHAR\\SebastianBergmann\\Type\\StaticType' => '/sebastian-type/type/StaticType.php',
638 'PHPUnitPHAR\\SebastianBergmann\\Type\\TrueType' => '/sebastian-type/type/TrueType.php',
639 'PHPUnitPHAR\\SebastianBergmann\\Type\\Type' => '/sebastian-type/type/Type.php',
640 'PHPUnitPHAR\\SebastianBergmann\\Type\\TypeName' => '/sebastian-type/TypeName.php',
641 'PHPUnitPHAR\\SebastianBergmann\\Type\\UnionType' => '/sebastian-type/type/UnionType.php',
642 'PHPUnitPHAR\\SebastianBergmann\\Type\\UnknownType' => '/sebastian-type/type/UnknownType.php',
643 'PHPUnitPHAR\\SebastianBergmann\\Type\\VoidType' => '/sebastian-type/type/VoidType.php',
644 'PHPUnitPHAR\\SebastianBergmann\\Version' => '/sebastian-version/Version.php',
645 'PHPUnitPHAR\\TheSeer\\Tokenizer\\Exception' => '/theseer-tokenizer/Exception.php',
646 'PHPUnitPHAR\\TheSeer\\Tokenizer\\NamespaceUri' => '/theseer-tokenizer/NamespaceUri.php',
647 'PHPUnitPHAR\\TheSeer\\Tokenizer\\NamespaceUriException' => '/theseer-tokenizer/NamespaceUriException.php',
648 'PHPUnitPHAR\\TheSeer\\Tokenizer\\Token' => '/theseer-tokenizer/Token.php',
649 'PHPUnitPHAR\\TheSeer\\Tokenizer\\TokenCollection' => '/theseer-tokenizer/TokenCollection.php',
650 'PHPUnitPHAR\\TheSeer\\Tokenizer\\TokenCollectionException' => '/theseer-tokenizer/TokenCollectionException.php',
651 'PHPUnitPHAR\\TheSeer\\Tokenizer\\Tokenizer' => '/theseer-tokenizer/Tokenizer.php',
652 'PHPUnitPHAR\\TheSeer\\Tokenizer\\XMLSerializer' => '/theseer-tokenizer/XMLSerializer.php',
653 'PHPUnit\\Event\\Application\\Finished' => '/phpunit/Event/Events/Application/Finished.php',
654 'PHPUnit\\Event\\Application\\FinishedSubscriber' => '/phpunit/Event/Events/Application/FinishedSubscriber.php',
655 'PHPUnit\\Event\\Application\\Started' => '/phpunit/Event/Events/Application/Started.php',
656 'PHPUnit\\Event\\Application\\StartedSubscriber' => '/phpunit/Event/Events/Application/StartedSubscriber.php',
657 'PHPUnit\\Event\\Code\\ClassMethod' => '/phpunit/Event/Value/ClassMethod.php',
658 'PHPUnit\\Event\\Code\\ComparisonFailure' => '/phpunit/Event/Value/ComparisonFailure.php',
659 'PHPUnit\\Event\\Code\\ComparisonFailureBuilder' => '/phpunit/Event/Value/ComparisonFailureBuilder.php',
660 'PHPUnit\\Event\\Code\\NoTestCaseObjectOnCallStackException' => '/phpunit/Event/Exception/NoTestCaseObjectOnCallStackException.php',
661 'PHPUnit\\Event\\Code\\Phpt' => '/phpunit/Event/Value/Test/Phpt.php',
662 'PHPUnit\\Event\\Code\\Test' => '/phpunit/Event/Value/Test/Test.php',
663 'PHPUnit\\Event\\Code\\TestCollection' => '/phpunit/Event/Value/Test/TestCollection.php',
664 'PHPUnit\\Event\\Code\\TestCollectionIterator' => '/phpunit/Event/Value/Test/TestCollectionIterator.php',
665 'PHPUnit\\Event\\Code\\TestDox' => '/phpunit/Event/Value/Test/TestDox.php',
666 'PHPUnit\\Event\\Code\\TestDoxBuilder' => '/phpunit/Event/Value/Test/TestDoxBuilder.php',
667 'PHPUnit\\Event\\Code\\TestMethod' => '/phpunit/Event/Value/Test/TestMethod.php',
668 'PHPUnit\\Event\\Code\\TestMethodBuilder' => '/phpunit/Event/Value/Test/TestMethodBuilder.php',
669 'PHPUnit\\Event\\Code\\Throwable' => '/phpunit/Event/Value/Throwable.php',
670 'PHPUnit\\Event\\Code\\ThrowableBuilder' => '/phpunit/Event/Value/ThrowableBuilder.php',
671 'PHPUnit\\Event\\CollectingDispatcher' => '/phpunit/Event/Dispatcher/CollectingDispatcher.php',
672 'PHPUnit\\Event\\DeferringDispatcher' => '/phpunit/Event/Dispatcher/DeferringDispatcher.php',
673 'PHPUnit\\Event\\DirectDispatcher' => '/phpunit/Event/Dispatcher/DirectDispatcher.php',
674 'PHPUnit\\Event\\Dispatcher' => '/phpunit/Event/Dispatcher/Dispatcher.php',
675 'PHPUnit\\Event\\DispatchingEmitter' => '/phpunit/Event/Emitter/DispatchingEmitter.php',
676 'PHPUnit\\Event\\Emitter' => '/phpunit/Event/Emitter/Emitter.php',
677 'PHPUnit\\Event\\Event' => '/phpunit/Event/Events/Event.php',
678 'PHPUnit\\Event\\EventAlreadyAssignedException' => '/phpunit/Event/Exception/EventAlreadyAssignedException.php',
679 'PHPUnit\\Event\\EventCollection' => '/phpunit/Event/Events/EventCollection.php',
680 'PHPUnit\\Event\\EventCollectionIterator' => '/phpunit/Event/Events/EventCollectionIterator.php',
681 'PHPUnit\\Event\\EventFacadeIsSealedException' => '/phpunit/Event/Exception/EventFacadeIsSealedException.php',
682 'PHPUnit\\Event\\Exception' => '/phpunit/Event/Exception/Exception.php',
683 'PHPUnit\\Event\\Facade' => '/phpunit/Event/Facade.php',
684 'PHPUnit\\Event\\InvalidArgumentException' => '/phpunit/Event/Exception/InvalidArgumentException.php',
685 'PHPUnit\\Event\\InvalidEventException' => '/phpunit/Event/Exception/InvalidEventException.php',
686 'PHPUnit\\Event\\InvalidSubscriberException' => '/phpunit/Event/Exception/InvalidSubscriberException.php',
687 'PHPUnit\\Event\\MapError' => '/phpunit/Event/Exception/MapError.php',
688 'PHPUnit\\Event\\NoPreviousThrowableException' => '/phpunit/Event/Exception/NoPreviousThrowableException.php',
689 'PHPUnit\\Event\\RuntimeException' => '/phpunit/Event/Exception/RuntimeException.php',
690 'PHPUnit\\Event\\Runtime\\OperatingSystem' => '/phpunit/Event/Value/Runtime/OperatingSystem.php',
691 'PHPUnit\\Event\\Runtime\\PHP' => '/phpunit/Event/Value/Runtime/PHP.php',
692 'PHPUnit\\Event\\Runtime\\PHPUnit' => '/phpunit/Event/Value/Runtime/PHPUnit.php',
693 'PHPUnit\\Event\\Runtime\\Runtime' => '/phpunit/Event/Value/Runtime/Runtime.php',
694 'PHPUnit\\Event\\SubscribableDispatcher' => '/phpunit/Event/Dispatcher/SubscribableDispatcher.php',
695 'PHPUnit\\Event\\Subscriber' => '/phpunit/Event/Subscriber.php',
696 'PHPUnit\\Event\\SubscriberTypeAlreadyRegisteredException' => '/phpunit/Event/Exception/SubscriberTypeAlreadyRegisteredException.php',
697 'PHPUnit\\Event\\Telemetry\\Duration' => '/phpunit/Event/Value/Telemetry/Duration.php',
698 'PHPUnit\\Event\\Telemetry\\GarbageCollectorStatus' => '/phpunit/Event/Value/Telemetry/GarbageCollectorStatus.php',
699 'PHPUnit\\Event\\Telemetry\\GarbageCollectorStatusProvider' => '/phpunit/Event/Value/Telemetry/GarbageCollectorStatusProvider.php',
700 'PHPUnit\\Event\\Telemetry\\HRTime' => '/phpunit/Event/Value/Telemetry/HRTime.php',
701 'PHPUnit\\Event\\Telemetry\\Info' => '/phpunit/Event/Value/Telemetry/Info.php',
702 'PHPUnit\\Event\\Telemetry\\MemoryMeter' => '/phpunit/Event/Value/Telemetry/MemoryMeter.php',
703 'PHPUnit\\Event\\Telemetry\\MemoryUsage' => '/phpunit/Event/Value/Telemetry/MemoryUsage.php',
704 'PHPUnit\\Event\\Telemetry\\Php81GarbageCollectorStatusProvider' => '/phpunit/Event/Value/Telemetry/Php81GarbageCollectorStatusProvider.php',
705 'PHPUnit\\Event\\Telemetry\\Php83GarbageCollectorStatusProvider' => '/phpunit/Event/Value/Telemetry/Php83GarbageCollectorStatusProvider.php',
706 'PHPUnit\\Event\\Telemetry\\Snapshot' => '/phpunit/Event/Value/Telemetry/Snapshot.php',
707 'PHPUnit\\Event\\Telemetry\\StopWatch' => '/phpunit/Event/Value/Telemetry/StopWatch.php',
708 'PHPUnit\\Event\\Telemetry\\System' => '/phpunit/Event/Value/Telemetry/System.php',
709 'PHPUnit\\Event\\Telemetry\\SystemMemoryMeter' => '/phpunit/Event/Value/Telemetry/SystemMemoryMeter.php',
710 'PHPUnit\\Event\\Telemetry\\SystemStopWatch' => '/phpunit/Event/Value/Telemetry/SystemStopWatch.php',
711 'PHPUnit\\Event\\Telemetry\\SystemStopWatchWithOffset' => '/phpunit/Event/Value/Telemetry/SystemStopWatchWithOffset.php',
712 'PHPUnit\\Event\\TestData\\DataFromDataProvider' => '/phpunit/Event/Value/Test/TestData/DataFromDataProvider.php',
713 'PHPUnit\\Event\\TestData\\DataFromTestDependency' => '/phpunit/Event/Value/Test/TestData/DataFromTestDependency.php',
714 'PHPUnit\\Event\\TestData\\MoreThanOneDataSetFromDataProviderException' => '/phpunit/Event/Exception/MoreThanOneDataSetFromDataProviderException.php',
715 'PHPUnit\\Event\\TestData\\NoDataSetFromDataProviderException' => '/phpunit/Event/Exception/NoDataSetFromDataProviderException.php',
716 'PHPUnit\\Event\\TestData\\TestData' => '/phpunit/Event/Value/Test/TestData/TestData.php',
717 'PHPUnit\\Event\\TestData\\TestDataCollection' => '/phpunit/Event/Value/Test/TestData/TestDataCollection.php',
718 'PHPUnit\\Event\\TestData\\TestDataCollectionIterator' => '/phpunit/Event/Value/Test/TestData/TestDataCollectionIterator.php',
719 'PHPUnit\\Event\\TestRunner\\BootstrapFinished' => '/phpunit/Event/Events/TestRunner/BootstrapFinished.php',
720 'PHPUnit\\Event\\TestRunner\\BootstrapFinishedSubscriber' => '/phpunit/Event/Events/TestRunner/BootstrapFinishedSubscriber.php',
721 'PHPUnit\\Event\\TestRunner\\Configured' => '/phpunit/Event/Events/TestRunner/Configured.php',
722 'PHPUnit\\Event\\TestRunner\\ConfiguredSubscriber' => '/phpunit/Event/Events/TestRunner/ConfiguredSubscriber.php',
723 'PHPUnit\\Event\\TestRunner\\DeprecationTriggered' => '/phpunit/Event/Events/TestRunner/DeprecationTriggered.php',
724 'PHPUnit\\Event\\TestRunner\\DeprecationTriggeredSubscriber' => '/phpunit/Event/Events/TestRunner/DeprecationTriggeredSubscriber.php',
725 'PHPUnit\\Event\\TestRunner\\EventFacadeSealed' => '/phpunit/Event/Events/TestRunner/EventFacadeSealed.php',
726 'PHPUnit\\Event\\TestRunner\\EventFacadeSealedSubscriber' => '/phpunit/Event/Events/TestRunner/EventFacadeSealedSubscriber.php',
727 'PHPUnit\\Event\\TestRunner\\ExecutionAborted' => '/phpunit/Event/Events/TestRunner/ExecutionAborted.php',
728 'PHPUnit\\Event\\TestRunner\\ExecutionAbortedSubscriber' => '/phpunit/Event/Events/TestRunner/ExecutionAbortedSubscriber.php',
729 'PHPUnit\\Event\\TestRunner\\ExecutionFinished' => '/phpunit/Event/Events/TestRunner/ExecutionFinished.php',
730 'PHPUnit\\Event\\TestRunner\\ExecutionFinishedSubscriber' => '/phpunit/Event/Events/TestRunner/ExecutionFinishedSubscriber.php',
731 'PHPUnit\\Event\\TestRunner\\ExecutionStarted' => '/phpunit/Event/Events/TestRunner/ExecutionStarted.php',
732 'PHPUnit\\Event\\TestRunner\\ExecutionStartedSubscriber' => '/phpunit/Event/Events/TestRunner/ExecutionStartedSubscriber.php',
733 'PHPUnit\\Event\\TestRunner\\ExtensionBootstrapped' => '/phpunit/Event/Events/TestRunner/ExtensionBootstrapped.php',
734 'PHPUnit\\Event\\TestRunner\\ExtensionBootstrappedSubscriber' => '/phpunit/Event/Events/TestRunner/ExtensionBootstrappedSubscriber.php',
735 'PHPUnit\\Event\\TestRunner\\ExtensionLoadedFromPhar' => '/phpunit/Event/Events/TestRunner/ExtensionLoadedFromPhar.php',
736 'PHPUnit\\Event\\TestRunner\\ExtensionLoadedFromPharSubscriber' => '/phpunit/Event/Events/TestRunner/ExtensionLoadedFromPharSubscriber.php',
737 'PHPUnit\\Event\\TestRunner\\Finished' => '/phpunit/Event/Events/TestRunner/Finished.php',
738 'PHPUnit\\Event\\TestRunner\\FinishedSubscriber' => '/phpunit/Event/Events/TestRunner/FinishedSubscriber.php',
739 'PHPUnit\\Event\\TestRunner\\GarbageCollectionDisabled' => '/phpunit/Event/Events/TestRunner/GarbageCollectionDisabled.php',
740 'PHPUnit\\Event\\TestRunner\\GarbageCollectionDisabledSubscriber' => '/phpunit/Event/Events/TestRunner/GarbageCollectionDisabledSubscriber.php',
741 'PHPUnit\\Event\\TestRunner\\GarbageCollectionEnabled' => '/phpunit/Event/Events/TestRunner/GarbageCollectionEnabled.php',
742 'PHPUnit\\Event\\TestRunner\\GarbageCollectionEnabledSubscriber' => '/phpunit/Event/Events/TestRunner/GarbageCollectionEnabledSubscriber.php',
743 'PHPUnit\\Event\\TestRunner\\GarbageCollectionTriggered' => '/phpunit/Event/Events/TestRunner/GarbageCollectionTriggered.php',
744 'PHPUnit\\Event\\TestRunner\\GarbageCollectionTriggeredSubscriber' => '/phpunit/Event/Events/TestRunner/GarbageCollectionTriggeredSubscriber.php',
745 'PHPUnit\\Event\\TestRunner\\Started' => '/phpunit/Event/Events/TestRunner/Started.php',
746 'PHPUnit\\Event\\TestRunner\\StartedSubscriber' => '/phpunit/Event/Events/TestRunner/StartedSubscriber.php',
747 'PHPUnit\\Event\\TestRunner\\WarningTriggered' => '/phpunit/Event/Events/TestRunner/WarningTriggered.php',
748 'PHPUnit\\Event\\TestRunner\\WarningTriggeredSubscriber' => '/phpunit/Event/Events/TestRunner/WarningTriggeredSubscriber.php',
749 'PHPUnit\\Event\\TestSuite\\Filtered' => '/phpunit/Event/Events/TestSuite/Filtered.php',
750 'PHPUnit\\Event\\TestSuite\\FilteredSubscriber' => '/phpunit/Event/Events/TestSuite/FilteredSubscriber.php',
751 'PHPUnit\\Event\\TestSuite\\Finished' => '/phpunit/Event/Events/TestSuite/Finished.php',
752 'PHPUnit\\Event\\TestSuite\\FinishedSubscriber' => '/phpunit/Event/Events/TestSuite/FinishedSubscriber.php',
753 'PHPUnit\\Event\\TestSuite\\Loaded' => '/phpunit/Event/Events/TestSuite/Loaded.php',
754 'PHPUnit\\Event\\TestSuite\\LoadedSubscriber' => '/phpunit/Event/Events/TestSuite/LoadedSubscriber.php',
755 'PHPUnit\\Event\\TestSuite\\Skipped' => '/phpunit/Event/Events/TestSuite/Skipped.php',
756 'PHPUnit\\Event\\TestSuite\\SkippedSubscriber' => '/phpunit/Event/Events/TestSuite/SkippedSubscriber.php',
757 'PHPUnit\\Event\\TestSuite\\Sorted' => '/phpunit/Event/Events/TestSuite/Sorted.php',
758 'PHPUnit\\Event\\TestSuite\\SortedSubscriber' => '/phpunit/Event/Events/TestSuite/SortedSubscriber.php',
759 'PHPUnit\\Event\\TestSuite\\Started' => '/phpunit/Event/Events/TestSuite/Started.php',
760 'PHPUnit\\Event\\TestSuite\\StartedSubscriber' => '/phpunit/Event/Events/TestSuite/StartedSubscriber.php',
761 'PHPUnit\\Event\\TestSuite\\TestSuite' => '/phpunit/Event/Value/TestSuite/TestSuite.php',
762 'PHPUnit\\Event\\TestSuite\\TestSuiteBuilder' => '/phpunit/Event/Value/TestSuite/TestSuiteBuilder.php',
763 'PHPUnit\\Event\\TestSuite\\TestSuiteForTestClass' => '/phpunit/Event/Value/TestSuite/TestSuiteForTestClass.php',
764 'PHPUnit\\Event\\TestSuite\\TestSuiteForTestMethodWithDataProvider' => '/phpunit/Event/Value/TestSuite/TestSuiteForTestMethodWithDataProvider.php',
765 'PHPUnit\\Event\\TestSuite\\TestSuiteWithName' => '/phpunit/Event/Value/TestSuite/TestSuiteWithName.php',
766 'PHPUnit\\Event\\Test\\AfterLastTestMethodCalled' => '/phpunit/Event/Events/Test/HookMethod/AfterLastTestMethodCalled.php',
767 'PHPUnit\\Event\\Test\\AfterLastTestMethodCalledSubscriber' => '/phpunit/Event/Events/Test/HookMethod/AfterLastTestMethodCalledSubscriber.php',
768 'PHPUnit\\Event\\Test\\AfterLastTestMethodErrored' => '/phpunit/Event/Events/Test/HookMethod/AfterLastTestMethodErrored.php',
769 'PHPUnit\\Event\\Test\\AfterLastTestMethodErroredSubscriber' => '/phpunit/Event/Events/Test/HookMethod/AfterLastTestMethodErroredSubscriber.php',
770 'PHPUnit\\Event\\Test\\AfterLastTestMethodFinished' => '/phpunit/Event/Events/Test/HookMethod/AfterLastTestMethodFinished.php',
771 'PHPUnit\\Event\\Test\\AfterLastTestMethodFinishedSubscriber' => '/phpunit/Event/Events/Test/HookMethod/AfterLastTestMethodFinishedSubscriber.php',
772 'PHPUnit\\Event\\Test\\AfterTestMethodCalled' => '/phpunit/Event/Events/Test/HookMethod/AfterTestMethodCalled.php',
773 'PHPUnit\\Event\\Test\\AfterTestMethodCalledSubscriber' => '/phpunit/Event/Events/Test/HookMethod/AfterTestMethodCalledSubscriber.php',
774 'PHPUnit\\Event\\Test\\AfterTestMethodErrored' => '/phpunit/Event/Events/Test/HookMethod/AfterTestMethodErrored.php',
775 'PHPUnit\\Event\\Test\\AfterTestMethodErroredSubscriber' => '/phpunit/Event/Events/Test/HookMethod/AfterTestMethodErroredSubscriber.php',
776 'PHPUnit\\Event\\Test\\AfterTestMethodFinished' => '/phpunit/Event/Events/Test/HookMethod/AfterTestMethodFinished.php',
777 'PHPUnit\\Event\\Test\\AfterTestMethodFinishedSubscriber' => '/phpunit/Event/Events/Test/HookMethod/AfterTestMethodFinishedSubscriber.php',
778 'PHPUnit\\Event\\Test\\AssertionFailed' => '/phpunit/Event/Events/Test/Assertion/AssertionFailed.php',
779 'PHPUnit\\Event\\Test\\AssertionFailedSubscriber' => '/phpunit/Event/Events/Test/Assertion/AssertionFailedSubscriber.php',
780 'PHPUnit\\Event\\Test\\AssertionSucceeded' => '/phpunit/Event/Events/Test/Assertion/AssertionSucceeded.php',
781 'PHPUnit\\Event\\Test\\AssertionSucceededSubscriber' => '/phpunit/Event/Events/Test/Assertion/AssertionSucceededSubscriber.php',
782 'PHPUnit\\Event\\Test\\BeforeFirstTestMethodCalled' => '/phpunit/Event/Events/Test/HookMethod/BeforeFirstTestMethodCalled.php',
783 'PHPUnit\\Event\\Test\\BeforeFirstTestMethodCalledSubscriber' => '/phpunit/Event/Events/Test/HookMethod/BeforeFirstTestMethodCalledSubscriber.php',
784 'PHPUnit\\Event\\Test\\BeforeFirstTestMethodErrored' => '/phpunit/Event/Events/Test/HookMethod/BeforeFirstTestMethodErrored.php',
785 'PHPUnit\\Event\\Test\\BeforeFirstTestMethodErroredSubscriber' => '/phpunit/Event/Events/Test/HookMethod/BeforeFirstTestMethodErroredSubscriber.php',
786 'PHPUnit\\Event\\Test\\BeforeFirstTestMethodFinished' => '/phpunit/Event/Events/Test/HookMethod/BeforeFirstTestMethodFinished.php',
787 'PHPUnit\\Event\\Test\\BeforeFirstTestMethodFinishedSubscriber' => '/phpunit/Event/Events/Test/HookMethod/BeforeFirstTestMethodFinishedSubscriber.php',
788 'PHPUnit\\Event\\Test\\BeforeTestMethodCalled' => '/phpunit/Event/Events/Test/HookMethod/BeforeTestMethodCalled.php',
789 'PHPUnit\\Event\\Test\\BeforeTestMethodCalledSubscriber' => '/phpunit/Event/Events/Test/HookMethod/BeforeTestMethodCalledSubscriber.php',
790 'PHPUnit\\Event\\Test\\BeforeTestMethodErrored' => '/phpunit/Event/Events/Test/HookMethod/BeforeTestMethodErrored.php',
791 'PHPUnit\\Event\\Test\\BeforeTestMethodErroredSubscriber' => '/phpunit/Event/Events/Test/HookMethod/BeforeTestMethodErroredSubscriber.php',
792 'PHPUnit\\Event\\Test\\BeforeTestMethodFinished' => '/phpunit/Event/Events/Test/HookMethod/BeforeTestMethodFinished.php',
793 'PHPUnit\\Event\\Test\\BeforeTestMethodFinishedSubscriber' => '/phpunit/Event/Events/Test/HookMethod/BeforeTestMethodFinishedSubscriber.php',
794 'PHPUnit\\Event\\Test\\ComparatorRegistered' => '/phpunit/Event/Events/Test/ComparatorRegistered.php',
795 'PHPUnit\\Event\\Test\\ComparatorRegisteredSubscriber' => '/phpunit/Event/Events/Test/ComparatorRegisteredSubscriber.php',
796 'PHPUnit\\Event\\Test\\ConsideredRisky' => '/phpunit/Event/Events/Test/Issue/ConsideredRisky.php',
797 'PHPUnit\\Event\\Test\\ConsideredRiskySubscriber' => '/phpunit/Event/Events/Test/Issue/ConsideredRiskySubscriber.php',
798 'PHPUnit\\Event\\Test\\DataProviderMethodCalled' => '/phpunit/Event/Events/Test/Lifecycle/DataProviderMethodCalled.php',
799 'PHPUnit\\Event\\Test\\DataProviderMethodCalledSubscriber' => '/phpunit/Event/Events/Test/Lifecycle/DataProviderMethodCalledSubscriber.php',
800 'PHPUnit\\Event\\Test\\DataProviderMethodFinished' => '/phpunit/Event/Events/Test/Lifecycle/DataProviderMethodFinished.php',
801 'PHPUnit\\Event\\Test\\DataProviderMethodFinishedSubscriber' => '/phpunit/Event/Events/Test/Lifecycle/DataProviderMethodFinishedSubscriber.php',
802 'PHPUnit\\Event\\Test\\DeprecationTriggered' => '/phpunit/Event/Events/Test/Issue/DeprecationTriggered.php',
803 'PHPUnit\\Event\\Test\\DeprecationTriggeredSubscriber' => '/phpunit/Event/Events/Test/Issue/DeprecationTriggeredSubscriber.php',
804 'PHPUnit\\Event\\Test\\ErrorTriggered' => '/phpunit/Event/Events/Test/Issue/ErrorTriggered.php',
805 'PHPUnit\\Event\\Test\\ErrorTriggeredSubscriber' => '/phpunit/Event/Events/Test/Issue/ErrorTriggeredSubscriber.php',
806 'PHPUnit\\Event\\Test\\Errored' => '/phpunit/Event/Events/Test/Outcome/Errored.php',
807 'PHPUnit\\Event\\Test\\ErroredSubscriber' => '/phpunit/Event/Events/Test/Outcome/ErroredSubscriber.php',
808 'PHPUnit\\Event\\Test\\Failed' => '/phpunit/Event/Events/Test/Outcome/Failed.php',
809 'PHPUnit\\Event\\Test\\FailedSubscriber' => '/phpunit/Event/Events/Test/Outcome/FailedSubscriber.php',
810 'PHPUnit\\Event\\Test\\Finished' => '/phpunit/Event/Events/Test/Lifecycle/Finished.php',
811 'PHPUnit\\Event\\Test\\FinishedSubscriber' => '/phpunit/Event/Events/Test/Lifecycle/FinishedSubscriber.php',
812 'PHPUnit\\Event\\Test\\MarkedIncomplete' => '/phpunit/Event/Events/Test/Outcome/MarkedIncomplete.php',
813 'PHPUnit\\Event\\Test\\MarkedIncompleteSubscriber' => '/phpunit/Event/Events/Test/Outcome/MarkedIncompleteSubscriber.php',
814 'PHPUnit\\Event\\Test\\MockObjectCreated' => '/phpunit/Event/Events/Test/TestDouble/MockObjectCreated.php',
815 'PHPUnit\\Event\\Test\\MockObjectCreatedSubscriber' => '/phpunit/Event/Events/Test/TestDouble/MockObjectCreatedSubscriber.php',
816 'PHPUnit\\Event\\Test\\MockObjectForAbstractClassCreated' => '/phpunit/Event/Events/Test/TestDouble/MockObjectForAbstractClassCreated.php',
817 'PHPUnit\\Event\\Test\\MockObjectForAbstractClassCreatedSubscriber' => '/phpunit/Event/Events/Test/TestDouble/MockObjectForAbstractClassCreatedSubscriber.php',
818 'PHPUnit\\Event\\Test\\MockObjectForIntersectionOfInterfacesCreated' => '/phpunit/Event/Events/Test/TestDouble/MockObjectForIntersectionOfInterfacesCreated.php',
819 'PHPUnit\\Event\\Test\\MockObjectForIntersectionOfInterfacesCreatedSubscriber' => '/phpunit/Event/Events/Test/TestDouble/MockObjectForIntersectionOfInterfacesCreatedSubscriber.php',
820 'PHPUnit\\Event\\Test\\MockObjectForTraitCreated' => '/phpunit/Event/Events/Test/TestDouble/MockObjectForTraitCreated.php',
821 'PHPUnit\\Event\\Test\\MockObjectForTraitCreatedSubscriber' => '/phpunit/Event/Events/Test/TestDouble/MockObjectForTraitCreatedSubscriber.php',
822 'PHPUnit\\Event\\Test\\MockObjectFromWsdlCreated' => '/phpunit/Event/Events/Test/TestDouble/MockObjectFromWsdlCreated.php',
823 'PHPUnit\\Event\\Test\\MockObjectFromWsdlCreatedSubscriber' => '/phpunit/Event/Events/Test/TestDouble/MockObjectFromWsdlCreatedSubscriber.php',
824 'PHPUnit\\Event\\Test\\NoComparisonFailureException' => '/phpunit/Event/Exception/NoComparisonFailureException.php',
825 'PHPUnit\\Event\\Test\\NoticeTriggered' => '/phpunit/Event/Events/Test/Issue/NoticeTriggered.php',
826 'PHPUnit\\Event\\Test\\NoticeTriggeredSubscriber' => '/phpunit/Event/Events/Test/Issue/NoticeTriggeredSubscriber.php',
827 'PHPUnit\\Event\\Test\\PartialMockObjectCreated' => '/phpunit/Event/Events/Test/TestDouble/PartialMockObjectCreated.php',
828 'PHPUnit\\Event\\Test\\PartialMockObjectCreatedSubscriber' => '/phpunit/Event/Events/Test/TestDouble/PartialMockObjectCreatedSubscriber.php',
829 'PHPUnit\\Event\\Test\\Passed' => '/phpunit/Event/Events/Test/Outcome/Passed.php',
830 'PHPUnit\\Event\\Test\\PassedSubscriber' => '/phpunit/Event/Events/Test/Outcome/PassedSubscriber.php',
831 'PHPUnit\\Event\\Test\\PhpDeprecationTriggered' => '/phpunit/Event/Events/Test/Issue/PhpDeprecationTriggered.php',
832 'PHPUnit\\Event\\Test\\PhpDeprecationTriggeredSubscriber' => '/phpunit/Event/Events/Test/Issue/PhpDeprecationTriggeredSubscriber.php',
833 'PHPUnit\\Event\\Test\\PhpNoticeTriggered' => '/phpunit/Event/Events/Test/Issue/PhpNoticeTriggered.php',
834 'PHPUnit\\Event\\Test\\PhpNoticeTriggeredSubscriber' => '/phpunit/Event/Events/Test/Issue/PhpNoticeTriggeredSubscriber.php',
835 'PHPUnit\\Event\\Test\\PhpWarningTriggered' => '/phpunit/Event/Events/Test/Issue/PhpWarningTriggered.php',
836 'PHPUnit\\Event\\Test\\PhpWarningTriggeredSubscriber' => '/phpunit/Event/Events/Test/Issue/PhpWarningTriggeredSubscriber.php',
837 'PHPUnit\\Event\\Test\\PhpunitDeprecationTriggered' => '/phpunit/Event/Events/Test/Issue/PhpunitDeprecationTriggered.php',
838 'PHPUnit\\Event\\Test\\PhpunitDeprecationTriggeredSubscriber' => '/phpunit/Event/Events/Test/Issue/PhpunitDeprecationTriggeredSubscriber.php',
839 'PHPUnit\\Event\\Test\\PhpunitErrorTriggered' => '/phpunit/Event/Events/Test/Issue/PhpunitErrorTriggered.php',
840 'PHPUnit\\Event\\Test\\PhpunitErrorTriggeredSubscriber' => '/phpunit/Event/Events/Test/Issue/PhpunitErrorTriggeredSubscriber.php',
841 'PHPUnit\\Event\\Test\\PhpunitWarningTriggered' => '/phpunit/Event/Events/Test/Issue/PhpunitWarningTriggered.php',
842 'PHPUnit\\Event\\Test\\PhpunitWarningTriggeredSubscriber' => '/phpunit/Event/Events/Test/Issue/PhpunitWarningTriggeredSubscriber.php',
843 'PHPUnit\\Event\\Test\\PostConditionCalled' => '/phpunit/Event/Events/Test/HookMethod/PostConditionCalled.php',
844 'PHPUnit\\Event\\Test\\PostConditionCalledSubscriber' => '/phpunit/Event/Events/Test/HookMethod/PostConditionCalledSubscriber.php',
845 'PHPUnit\\Event\\Test\\PostConditionErrored' => '/phpunit/Event/Events/Test/HookMethod/PostConditionErrored.php',
846 'PHPUnit\\Event\\Test\\PostConditionErroredSubscriber' => '/phpunit/Event/Events/Test/HookMethod/PostConditionErroredSubscriber.php',
847 'PHPUnit\\Event\\Test\\PostConditionFinished' => '/phpunit/Event/Events/Test/HookMethod/PostConditionFinished.php',
848 'PHPUnit\\Event\\Test\\PostConditionFinishedSubscriber' => '/phpunit/Event/Events/Test/HookMethod/PostConditionFinishedSubscriber.php',
849 'PHPUnit\\Event\\Test\\PreConditionCalled' => '/phpunit/Event/Events/Test/HookMethod/PreConditionCalled.php',
850 'PHPUnit\\Event\\Test\\PreConditionCalledSubscriber' => '/phpunit/Event/Events/Test/HookMethod/PreConditionCalledSubscriber.php',
851 'PHPUnit\\Event\\Test\\PreConditionErrored' => '/phpunit/Event/Events/Test/HookMethod/PreConditionErrored.php',
852 'PHPUnit\\Event\\Test\\PreConditionErroredSubscriber' => '/phpunit/Event/Events/Test/HookMethod/PreConditionErroredSubscriber.php',
853 'PHPUnit\\Event\\Test\\PreConditionFinished' => '/phpunit/Event/Events/Test/HookMethod/PreConditionFinished.php',
854 'PHPUnit\\Event\\Test\\PreConditionFinishedSubscriber' => '/phpunit/Event/Events/Test/HookMethod/PreConditionFinishedSubscriber.php',
855 'PHPUnit\\Event\\Test\\PreparationFailed' => '/phpunit/Event/Events/Test/Lifecycle/PreparationFailed.php',
856 'PHPUnit\\Event\\Test\\PreparationFailedSubscriber' => '/phpunit/Event/Events/Test/Lifecycle/PreparationFailedSubscriber.php',
857 'PHPUnit\\Event\\Test\\PreparationStarted' => '/phpunit/Event/Events/Test/Lifecycle/PreparationStarted.php',
858 'PHPUnit\\Event\\Test\\PreparationStartedSubscriber' => '/phpunit/Event/Events/Test/Lifecycle/PreparationStartedSubscriber.php',
859 'PHPUnit\\Event\\Test\\Prepared' => '/phpunit/Event/Events/Test/Lifecycle/Prepared.php',
860 'PHPUnit\\Event\\Test\\PreparedSubscriber' => '/phpunit/Event/Events/Test/Lifecycle/PreparedSubscriber.php',
861 'PHPUnit\\Event\\Test\\PrintedUnexpectedOutput' => '/phpunit/Event/Events/Test/PrintedUnexpectedOutput.php',
862 'PHPUnit\\Event\\Test\\PrintedUnexpectedOutputSubscriber' => '/phpunit/Event/Events/Test/PrintedUnexpectedOutputSubscriber.php',
863 'PHPUnit\\Event\\Test\\Skipped' => '/phpunit/Event/Events/Test/Outcome/Skipped.php',
864 'PHPUnit\\Event\\Test\\SkippedSubscriber' => '/phpunit/Event/Events/Test/Outcome/SkippedSubscriber.php',
865 'PHPUnit\\Event\\Test\\TestProxyCreated' => '/phpunit/Event/Events/Test/TestDouble/TestProxyCreated.php',
866 'PHPUnit\\Event\\Test\\TestProxyCreatedSubscriber' => '/phpunit/Event/Events/Test/TestDouble/TestProxyCreatedSubscriber.php',
867 'PHPUnit\\Event\\Test\\TestStubCreated' => '/phpunit/Event/Events/Test/TestDouble/TestStubCreated.php',
868 'PHPUnit\\Event\\Test\\TestStubCreatedSubscriber' => '/phpunit/Event/Events/Test/TestDouble/TestStubCreatedSubscriber.php',
869 'PHPUnit\\Event\\Test\\TestStubForIntersectionOfInterfacesCreated' => '/phpunit/Event/Events/Test/TestDouble/TestStubForIntersectionOfInterfacesCreated.php',
870 'PHPUnit\\Event\\Test\\TestStubForIntersectionOfInterfacesCreatedSubscriber' => '/phpunit/Event/Events/Test/TestDouble/TestStubForIntersectionOfInterfacesCreatedSubscriber.php',
871 'PHPUnit\\Event\\Test\\WarningTriggered' => '/phpunit/Event/Events/Test/Issue/WarningTriggered.php',
872 'PHPUnit\\Event\\Test\\WarningTriggeredSubscriber' => '/phpunit/Event/Events/Test/Issue/WarningTriggeredSubscriber.php',
873 'PHPUnit\\Event\\Tracer\\Tracer' => '/phpunit/Event/Tracer.php',
874 'PHPUnit\\Event\\TypeMap' => '/phpunit/Event/TypeMap.php',
875 'PHPUnit\\Event\\UnknownEventException' => '/phpunit/Event/Exception/UnknownEventException.php',
876 'PHPUnit\\Event\\UnknownEventTypeException' => '/phpunit/Event/Exception/UnknownEventTypeException.php',
877 'PHPUnit\\Event\\UnknownSubscriberException' => '/phpunit/Event/Exception/UnknownSubscriberException.php',
878 'PHPUnit\\Event\\UnknownSubscriberTypeException' => '/phpunit/Event/Exception/UnknownSubscriberTypeException.php',
879 'PHPUnit\\Exception' => '/phpunit/Exception.php',
880 'PHPUnit\\Framework\\ActualValueIsNotAnObjectException' => '/phpunit/Framework/Exception/ObjectEquals/ActualValueIsNotAnObjectException.php',
881 'PHPUnit\\Framework\\Assert' => '/phpunit/Framework/Assert.php',
882 'PHPUnit\\Framework\\AssertionFailedError' => '/phpunit/Framework/Exception/AssertionFailedError.php',
883 'PHPUnit\\Framework\\Attributes\\After' => '/phpunit/Framework/Attributes/After.php',
884 'PHPUnit\\Framework\\Attributes\\AfterClass' => '/phpunit/Framework/Attributes/AfterClass.php',
885 'PHPUnit\\Framework\\Attributes\\BackupGlobals' => '/phpunit/Framework/Attributes/BackupGlobals.php',
886 'PHPUnit\\Framework\\Attributes\\BackupStaticProperties' => '/phpunit/Framework/Attributes/BackupStaticProperties.php',
887 'PHPUnit\\Framework\\Attributes\\Before' => '/phpunit/Framework/Attributes/Before.php',
888 'PHPUnit\\Framework\\Attributes\\BeforeClass' => '/phpunit/Framework/Attributes/BeforeClass.php',
889 'PHPUnit\\Framework\\Attributes\\CodeCoverageIgnore' => '/phpunit/Framework/Attributes/CodeCoverageIgnore.php',
890 'PHPUnit\\Framework\\Attributes\\CoversClass' => '/phpunit/Framework/Attributes/CoversClass.php',
891 'PHPUnit\\Framework\\Attributes\\CoversFunction' => '/phpunit/Framework/Attributes/CoversFunction.php',
892 'PHPUnit\\Framework\\Attributes\\CoversNothing' => '/phpunit/Framework/Attributes/CoversNothing.php',
893 'PHPUnit\\Framework\\Attributes\\DataProvider' => '/phpunit/Framework/Attributes/DataProvider.php',
894 'PHPUnit\\Framework\\Attributes\\DataProviderExternal' => '/phpunit/Framework/Attributes/DataProviderExternal.php',
895 'PHPUnit\\Framework\\Attributes\\Depends' => '/phpunit/Framework/Attributes/Depends.php',
896 'PHPUnit\\Framework\\Attributes\\DependsExternal' => '/phpunit/Framework/Attributes/DependsExternal.php',
897 'PHPUnit\\Framework\\Attributes\\DependsExternalUsingDeepClone' => '/phpunit/Framework/Attributes/DependsExternalUsingDeepClone.php',
898 'PHPUnit\\Framework\\Attributes\\DependsExternalUsingShallowClone' => '/phpunit/Framework/Attributes/DependsExternalUsingShallowClone.php',
899 'PHPUnit\\Framework\\Attributes\\DependsOnClass' => '/phpunit/Framework/Attributes/DependsOnClass.php',
900 'PHPUnit\\Framework\\Attributes\\DependsOnClassUsingDeepClone' => '/phpunit/Framework/Attributes/DependsOnClassUsingDeepClone.php',
901 'PHPUnit\\Framework\\Attributes\\DependsOnClassUsingShallowClone' => '/phpunit/Framework/Attributes/DependsOnClassUsingShallowClone.php',
902 'PHPUnit\\Framework\\Attributes\\DependsUsingDeepClone' => '/phpunit/Framework/Attributes/DependsUsingDeepClone.php',
903 'PHPUnit\\Framework\\Attributes\\DependsUsingShallowClone' => '/phpunit/Framework/Attributes/DependsUsingShallowClone.php',
904 'PHPUnit\\Framework\\Attributes\\DoesNotPerformAssertions' => '/phpunit/Framework/Attributes/DoesNotPerformAssertions.php',
905 'PHPUnit\\Framework\\Attributes\\ExcludeGlobalVariableFromBackup' => '/phpunit/Framework/Attributes/ExcludeGlobalVariableFromBackup.php',
906 'PHPUnit\\Framework\\Attributes\\ExcludeStaticPropertyFromBackup' => '/phpunit/Framework/Attributes/ExcludeStaticPropertyFromBackup.php',
907 'PHPUnit\\Framework\\Attributes\\Group' => '/phpunit/Framework/Attributes/Group.php',
908 'PHPUnit\\Framework\\Attributes\\IgnoreClassForCodeCoverage' => '/phpunit/Framework/Attributes/IgnoreClassForCodeCoverage.php',
909 'PHPUnit\\Framework\\Attributes\\IgnoreDeprecations' => '/phpunit/Framework/Attributes/IgnoreDeprecations.php',
910 'PHPUnit\\Framework\\Attributes\\IgnoreFunctionForCodeCoverage' => '/phpunit/Framework/Attributes/IgnoreFunctionForCodeCoverage.php',
911 'PHPUnit\\Framework\\Attributes\\IgnoreMethodForCodeCoverage' => '/phpunit/Framework/Attributes/IgnoreMethodForCodeCoverage.php',
912 'PHPUnit\\Framework\\Attributes\\Large' => '/phpunit/Framework/Attributes/Large.php',
913 'PHPUnit\\Framework\\Attributes\\Medium' => '/phpunit/Framework/Attributes/Medium.php',
914 'PHPUnit\\Framework\\Attributes\\PostCondition' => '/phpunit/Framework/Attributes/PostCondition.php',
915 'PHPUnit\\Framework\\Attributes\\PreCondition' => '/phpunit/Framework/Attributes/PreCondition.php',
916 'PHPUnit\\Framework\\Attributes\\PreserveGlobalState' => '/phpunit/Framework/Attributes/PreserveGlobalState.php',
917 'PHPUnit\\Framework\\Attributes\\RequiresFunction' => '/phpunit/Framework/Attributes/RequiresFunction.php',
918 'PHPUnit\\Framework\\Attributes\\RequiresMethod' => '/phpunit/Framework/Attributes/RequiresMethod.php',
919 'PHPUnit\\Framework\\Attributes\\RequiresOperatingSystem' => '/phpunit/Framework/Attributes/RequiresOperatingSystem.php',
920 'PHPUnit\\Framework\\Attributes\\RequiresOperatingSystemFamily' => '/phpunit/Framework/Attributes/RequiresOperatingSystemFamily.php',
921 'PHPUnit\\Framework\\Attributes\\RequiresPhp' => '/phpunit/Framework/Attributes/RequiresPhp.php',
922 'PHPUnit\\Framework\\Attributes\\RequiresPhpExtension' => '/phpunit/Framework/Attributes/RequiresPhpExtension.php',
923 'PHPUnit\\Framework\\Attributes\\RequiresPhpunit' => '/phpunit/Framework/Attributes/RequiresPhpunit.php',
924 'PHPUnit\\Framework\\Attributes\\RequiresSetting' => '/phpunit/Framework/Attributes/RequiresSetting.php',
925 'PHPUnit\\Framework\\Attributes\\RunClassInSeparateProcess' => '/phpunit/Framework/Attributes/RunClassInSeparateProcess.php',
926 'PHPUnit\\Framework\\Attributes\\RunInSeparateProcess' => '/phpunit/Framework/Attributes/RunInSeparateProcess.php',
927 'PHPUnit\\Framework\\Attributes\\RunTestsInSeparateProcesses' => '/phpunit/Framework/Attributes/RunTestsInSeparateProcesses.php',
928 'PHPUnit\\Framework\\Attributes\\Small' => '/phpunit/Framework/Attributes/Small.php',
929 'PHPUnit\\Framework\\Attributes\\Test' => '/phpunit/Framework/Attributes/Test.php',
930 'PHPUnit\\Framework\\Attributes\\TestDox' => '/phpunit/Framework/Attributes/TestDox.php',
931 'PHPUnit\\Framework\\Attributes\\TestWith' => '/phpunit/Framework/Attributes/TestWith.php',
932 'PHPUnit\\Framework\\Attributes\\TestWithJson' => '/phpunit/Framework/Attributes/TestWithJson.php',
933 'PHPUnit\\Framework\\Attributes\\Ticket' => '/phpunit/Framework/Attributes/Ticket.php',
934 'PHPUnit\\Framework\\Attributes\\UsesClass' => '/phpunit/Framework/Attributes/UsesClass.php',
935 'PHPUnit\\Framework\\Attributes\\UsesFunction' => '/phpunit/Framework/Attributes/UsesFunction.php',
936 'PHPUnit\\Framework\\Attributes\\WithoutErrorHandler' => '/phpunit/Framework/Attributes/WithoutErrorHandler.php',
937 'PHPUnit\\Framework\\CodeCoverageException' => '/phpunit/Framework/Exception/CodeCoverageException.php',
938 'PHPUnit\\Framework\\ComparisonMethodDoesNotAcceptParameterTypeException' => '/phpunit/Framework/Exception/ObjectEquals/ComparisonMethodDoesNotAcceptParameterTypeException.php',
939 'PHPUnit\\Framework\\ComparisonMethodDoesNotDeclareBoolReturnTypeException' => '/phpunit/Framework/Exception/ObjectEquals/ComparisonMethodDoesNotDeclareBoolReturnTypeException.php',
940 'PHPUnit\\Framework\\ComparisonMethodDoesNotDeclareExactlyOneParameterException' => '/phpunit/Framework/Exception/ObjectEquals/ComparisonMethodDoesNotDeclareExactlyOneParameterException.php',
941 'PHPUnit\\Framework\\ComparisonMethodDoesNotDeclareParameterTypeException' => '/phpunit/Framework/Exception/ObjectEquals/ComparisonMethodDoesNotDeclareParameterTypeException.php',
942 'PHPUnit\\Framework\\ComparisonMethodDoesNotExistException' => '/phpunit/Framework/Exception/ObjectEquals/ComparisonMethodDoesNotExistException.php',
943 'PHPUnit\\Framework\\Constraint\\ArrayHasKey' => '/phpunit/Framework/Constraint/Traversable/ArrayHasKey.php',
944 'PHPUnit\\Framework\\Constraint\\BinaryOperator' => '/phpunit/Framework/Constraint/Operator/BinaryOperator.php',
945 'PHPUnit\\Framework\\Constraint\\Callback' => '/phpunit/Framework/Constraint/Callback.php',
946 'PHPUnit\\Framework\\Constraint\\Constraint' => '/phpunit/Framework/Constraint/Constraint.php',
947 'PHPUnit\\Framework\\Constraint\\Count' => '/phpunit/Framework/Constraint/Cardinality/Count.php',
948 'PHPUnit\\Framework\\Constraint\\DirectoryExists' => '/phpunit/Framework/Constraint/Filesystem/DirectoryExists.php',
949 'PHPUnit\\Framework\\Constraint\\Exception' => '/phpunit/Framework/Constraint/Exception/Exception.php',
950 'PHPUnit\\Framework\\Constraint\\ExceptionCode' => '/phpunit/Framework/Constraint/Exception/ExceptionCode.php',
951 'PHPUnit\\Framework\\Constraint\\ExceptionMessageIsOrContains' => '/phpunit/Framework/Constraint/Exception/ExceptionMessageIsOrContains.php',
952 'PHPUnit\\Framework\\Constraint\\ExceptionMessageMatchesRegularExpression' => '/phpunit/Framework/Constraint/Exception/ExceptionMessageMatchesRegularExpression.php',
953 'PHPUnit\\Framework\\Constraint\\FileExists' => '/phpunit/Framework/Constraint/Filesystem/FileExists.php',
954 'PHPUnit\\Framework\\Constraint\\GreaterThan' => '/phpunit/Framework/Constraint/Cardinality/GreaterThan.php',
955 'PHPUnit\\Framework\\Constraint\\IsAnything' => '/phpunit/Framework/Constraint/IsAnything.php',
956 'PHPUnit\\Framework\\Constraint\\IsEmpty' => '/phpunit/Framework/Constraint/Cardinality/IsEmpty.php',
957 'PHPUnit\\Framework\\Constraint\\IsEqual' => '/phpunit/Framework/Constraint/Equality/IsEqual.php',
958 'PHPUnit\\Framework\\Constraint\\IsEqualCanonicalizing' => '/phpunit/Framework/Constraint/Equality/IsEqualCanonicalizing.php',
959 'PHPUnit\\Framework\\Constraint\\IsEqualIgnoringCase' => '/phpunit/Framework/Constraint/Equality/IsEqualIgnoringCase.php',
960 'PHPUnit\\Framework\\Constraint\\IsEqualWithDelta' => '/phpunit/Framework/Constraint/Equality/IsEqualWithDelta.php',
961 'PHPUnit\\Framework\\Constraint\\IsFalse' => '/phpunit/Framework/Constraint/Boolean/IsFalse.php',
962 'PHPUnit\\Framework\\Constraint\\IsFinite' => '/phpunit/Framework/Constraint/Math/IsFinite.php',
963 'PHPUnit\\Framework\\Constraint\\IsIdentical' => '/phpunit/Framework/Constraint/IsIdentical.php',
964 'PHPUnit\\Framework\\Constraint\\IsInfinite' => '/phpunit/Framework/Constraint/Math/IsInfinite.php',
965 'PHPUnit\\Framework\\Constraint\\IsInstanceOf' => '/phpunit/Framework/Constraint/Type/IsInstanceOf.php',
966 'PHPUnit\\Framework\\Constraint\\IsJson' => '/phpunit/Framework/Constraint/String/IsJson.php',
967 'PHPUnit\\Framework\\Constraint\\IsList' => '/phpunit/Framework/Constraint/Traversable/IsList.php',
968 'PHPUnit\\Framework\\Constraint\\IsNan' => '/phpunit/Framework/Constraint/Math/IsNan.php',
969 'PHPUnit\\Framework\\Constraint\\IsNull' => '/phpunit/Framework/Constraint/Type/IsNull.php',
970 'PHPUnit\\Framework\\Constraint\\IsReadable' => '/phpunit/Framework/Constraint/Filesystem/IsReadable.php',
971 'PHPUnit\\Framework\\Constraint\\IsTrue' => '/phpunit/Framework/Constraint/Boolean/IsTrue.php',
972 'PHPUnit\\Framework\\Constraint\\IsType' => '/phpunit/Framework/Constraint/Type/IsType.php',
973 'PHPUnit\\Framework\\Constraint\\IsWritable' => '/phpunit/Framework/Constraint/Filesystem/IsWritable.php',
974 'PHPUnit\\Framework\\Constraint\\JsonMatches' => '/phpunit/Framework/Constraint/JsonMatches.php',
975 'PHPUnit\\Framework\\Constraint\\LessThan' => '/phpunit/Framework/Constraint/Cardinality/LessThan.php',
976 'PHPUnit\\Framework\\Constraint\\LogicalAnd' => '/phpunit/Framework/Constraint/Operator/LogicalAnd.php',
977 'PHPUnit\\Framework\\Constraint\\LogicalNot' => '/phpunit/Framework/Constraint/Operator/LogicalNot.php',
978 'PHPUnit\\Framework\\Constraint\\LogicalOr' => '/phpunit/Framework/Constraint/Operator/LogicalOr.php',
979 'PHPUnit\\Framework\\Constraint\\LogicalXor' => '/phpunit/Framework/Constraint/Operator/LogicalXor.php',
980 'PHPUnit\\Framework\\Constraint\\ObjectEquals' => '/phpunit/Framework/Constraint/Object/ObjectEquals.php',
981 'PHPUnit\\Framework\\Constraint\\ObjectHasProperty' => '/phpunit/Framework/Constraint/Object/ObjectHasProperty.php',
982 'PHPUnit\\Framework\\Constraint\\Operator' => '/phpunit/Framework/Constraint/Operator/Operator.php',
983 'PHPUnit\\Framework\\Constraint\\RegularExpression' => '/phpunit/Framework/Constraint/String/RegularExpression.php',
984 'PHPUnit\\Framework\\Constraint\\SameSize' => '/phpunit/Framework/Constraint/Cardinality/SameSize.php',
985 'PHPUnit\\Framework\\Constraint\\StringContains' => '/phpunit/Framework/Constraint/String/StringContains.php',
986 'PHPUnit\\Framework\\Constraint\\StringEndsWith' => '/phpunit/Framework/Constraint/String/StringEndsWith.php',
987 'PHPUnit\\Framework\\Constraint\\StringEqualsStringIgnoringLineEndings' => '/phpunit/Framework/Constraint/String/StringEqualsStringIgnoringLineEndings.php',
988 'PHPUnit\\Framework\\Constraint\\StringMatchesFormatDescription' => '/phpunit/Framework/Constraint/String/StringMatchesFormatDescription.php',
989 'PHPUnit\\Framework\\Constraint\\StringStartsWith' => '/phpunit/Framework/Constraint/String/StringStartsWith.php',
990 'PHPUnit\\Framework\\Constraint\\TraversableContains' => '/phpunit/Framework/Constraint/Traversable/TraversableContains.php',
991 'PHPUnit\\Framework\\Constraint\\TraversableContainsEqual' => '/phpunit/Framework/Constraint/Traversable/TraversableContainsEqual.php',
992 'PHPUnit\\Framework\\Constraint\\TraversableContainsIdentical' => '/phpunit/Framework/Constraint/Traversable/TraversableContainsIdentical.php',
993 'PHPUnit\\Framework\\Constraint\\TraversableContainsOnly' => '/phpunit/Framework/Constraint/Traversable/TraversableContainsOnly.php',
994 'PHPUnit\\Framework\\Constraint\\UnaryOperator' => '/phpunit/Framework/Constraint/Operator/UnaryOperator.php',
995 'PHPUnit\\Framework\\DataProviderTestSuite' => '/phpunit/Framework/DataProviderTestSuite.php',
996 'PHPUnit\\Framework\\EmptyStringException' => '/phpunit/Framework/Exception/EmptyStringException.php',
997 'PHPUnit\\Framework\\Exception' => '/phpunit/Framework/Exception/Exception.php',
998 'PHPUnit\\Framework\\ExecutionOrderDependency' => '/phpunit/Framework/ExecutionOrderDependency.php',
999 'PHPUnit\\Framework\\ExpectationFailedException' => '/phpunit/Framework/Exception/ExpectationFailedException.php',
1000 'PHPUnit\\Framework\\GeneratorNotSupportedException' => '/phpunit/Framework/Exception/GeneratorNotSupportedException.php',
1001 'PHPUnit\\Framework\\IncompleteTest' => '/phpunit/Framework/Exception/Incomplete/IncompleteTest.php',
1002 'PHPUnit\\Framework\\IncompleteTestError' => '/phpunit/Framework/Exception/Incomplete/IncompleteTestError.php',
1003 'PHPUnit\\Framework\\InvalidArgumentException' => '/phpunit/Framework/Exception/InvalidArgumentException.php',
1004 'PHPUnit\\Framework\\InvalidCoversTargetException' => '/phpunit/Framework/Exception/InvalidCoversTargetException.php',
1005 'PHPUnit\\Framework\\InvalidDataProviderException' => '/phpunit/Framework/Exception/InvalidDataProviderException.php',
1006 'PHPUnit\\Framework\\InvalidDependencyException' => '/phpunit/Framework/Exception/InvalidDependencyException.php',
1007 'PHPUnit\\Framework\\MockObject\\BadMethodCallException' => '/phpunit/Framework/MockObject/Exception/BadMethodCallException.php',
1008 'PHPUnit\\Framework\\MockObject\\Builder\\Identity' => '/phpunit/Framework/MockObject/Runtime/Builder/Identity.php',
1009 'PHPUnit\\Framework\\MockObject\\Builder\\InvocationMocker' => '/phpunit/Framework/MockObject/Runtime/Builder/InvocationMocker.php',
1010 'PHPUnit\\Framework\\MockObject\\Builder\\InvocationStubber' => '/phpunit/Framework/MockObject/Runtime/Builder/InvocationStubber.php',
1011 'PHPUnit\\Framework\\MockObject\\Builder\\MethodNameMatch' => '/phpunit/Framework/MockObject/Runtime/Builder/MethodNameMatch.php',
1012 'PHPUnit\\Framework\\MockObject\\Builder\\ParametersMatch' => '/phpunit/Framework/MockObject/Runtime/Builder/ParametersMatch.php',
1013 'PHPUnit\\Framework\\MockObject\\Builder\\Stub' => '/phpunit/Framework/MockObject/Runtime/Builder/Stub.php',
1014 'PHPUnit\\Framework\\MockObject\\CannotUseOnlyMethodsException' => '/phpunit/Framework/MockObject/Exception/CannotUseOnlyMethodsException.php',
1015 'PHPUnit\\Framework\\MockObject\\ConfigurableMethod' => '/phpunit/Framework/MockObject/ConfigurableMethod.php',
1016 'PHPUnit\\Framework\\MockObject\\DoubledCloneMethod' => '/phpunit/Framework/MockObject/Runtime/Api/DoubledCloneMethod.php',
1017 'PHPUnit\\Framework\\MockObject\\Exception' => '/phpunit/Framework/MockObject/Exception/Exception.php',
1018 'PHPUnit\\Framework\\MockObject\\Generator\\CannotUseAddMethodsException' => '/phpunit/Framework/MockObject/Generator/Exception/CannotUseAddMethodsException.php',
1019 'PHPUnit\\Framework\\MockObject\\Generator\\ClassIsEnumerationException' => '/phpunit/Framework/MockObject/Generator/Exception/ClassIsEnumerationException.php',
1020 'PHPUnit\\Framework\\MockObject\\Generator\\ClassIsFinalException' => '/phpunit/Framework/MockObject/Generator/Exception/ClassIsFinalException.php',
1021 'PHPUnit\\Framework\\MockObject\\Generator\\ClassIsReadonlyException' => '/phpunit/Framework/MockObject/Generator/Exception/ClassIsReadonlyException.php',
1022 'PHPUnit\\Framework\\MockObject\\Generator\\DuplicateMethodException' => '/phpunit/Framework/MockObject/Generator/Exception/DuplicateMethodException.php',
1023 'PHPUnit\\Framework\\MockObject\\Generator\\Exception' => '/phpunit/Framework/MockObject/Generator/Exception/Exception.php',
1024 'PHPUnit\\Framework\\MockObject\\Generator\\Generator' => '/phpunit/Framework/MockObject/Generator/Generator.php',
1025 'PHPUnit\\Framework\\MockObject\\Generator\\InvalidMethodNameException' => '/phpunit/Framework/MockObject/Generator/Exception/InvalidMethodNameException.php',
1026 'PHPUnit\\Framework\\MockObject\\Generator\\MockClass' => '/phpunit/Framework/MockObject/Generator/MockClass.php',
1027 'PHPUnit\\Framework\\MockObject\\Generator\\MockMethod' => '/phpunit/Framework/MockObject/Generator/MockMethod.php',
1028 'PHPUnit\\Framework\\MockObject\\Generator\\MockMethodSet' => '/phpunit/Framework/MockObject/Generator/MockMethodSet.php',
1029 'PHPUnit\\Framework\\MockObject\\Generator\\MockTrait' => '/phpunit/Framework/MockObject/Generator/MockTrait.php',
1030 'PHPUnit\\Framework\\MockObject\\Generator\\MockType' => '/phpunit/Framework/MockObject/Generator/MockType.php',
1031 'PHPUnit\\Framework\\MockObject\\Generator\\NameAlreadyInUseException' => '/phpunit/Framework/MockObject/Generator/Exception/NameAlreadyInUseException.php',
1032 'PHPUnit\\Framework\\MockObject\\Generator\\OriginalConstructorInvocationRequiredException' => '/phpunit/Framework/MockObject/Generator/Exception/OriginalConstructorInvocationRequiredException.php',
1033 'PHPUnit\\Framework\\MockObject\\Generator\\ReflectionException' => '/phpunit/Framework/MockObject/Generator/Exception/ReflectionException.php',
1034 'PHPUnit\\Framework\\MockObject\\Generator\\RuntimeException' => '/phpunit/Framework/MockObject/Generator/Exception/RuntimeException.php',
1035 'PHPUnit\\Framework\\MockObject\\Generator\\SoapExtensionNotAvailableException' => '/phpunit/Framework/MockObject/Generator/Exception/SoapExtensionNotAvailableException.php',
1036 'PHPUnit\\Framework\\MockObject\\Generator\\TemplateLoader' => '/phpunit/Framework/MockObject/Generator/TemplateLoader.php',
1037 'PHPUnit\\Framework\\MockObject\\Generator\\UnknownClassException' => '/phpunit/Framework/MockObject/Generator/Exception/UnknownClassException.php',
1038 'PHPUnit\\Framework\\MockObject\\Generator\\UnknownTraitException' => '/phpunit/Framework/MockObject/Generator/Exception/UnknownTraitException.php',
1039 'PHPUnit\\Framework\\MockObject\\Generator\\UnknownTypeException' => '/phpunit/Framework/MockObject/Generator/Exception/UnknownTypeException.php',
1040 'PHPUnit\\Framework\\MockObject\\IncompatibleReturnValueException' => '/phpunit/Framework/MockObject/Exception/IncompatibleReturnValueException.php',
1041 'PHPUnit\\Framework\\MockObject\\Invocation' => '/phpunit/Framework/MockObject/Runtime/Invocation.php',
1042 'PHPUnit\\Framework\\MockObject\\InvocationHandler' => '/phpunit/Framework/MockObject/Runtime/InvocationHandler.php',
1043 'PHPUnit\\Framework\\MockObject\\MatchBuilderNotFoundException' => '/phpunit/Framework/MockObject/Exception/MatchBuilderNotFoundException.php',
1044 'PHPUnit\\Framework\\MockObject\\Matcher' => '/phpunit/Framework/MockObject/Runtime/Matcher.php',
1045 'PHPUnit\\Framework\\MockObject\\MatcherAlreadyRegisteredException' => '/phpunit/Framework/MockObject/Exception/MatcherAlreadyRegisteredException.php',
1046 'PHPUnit\\Framework\\MockObject\\Method' => '/phpunit/Framework/MockObject/Runtime/Api/Method.php',
1047 'PHPUnit\\Framework\\MockObject\\MethodCannotBeConfiguredException' => '/phpunit/Framework/MockObject/Exception/MethodCannotBeConfiguredException.php',
1048 'PHPUnit\\Framework\\MockObject\\MethodNameAlreadyConfiguredException' => '/phpunit/Framework/MockObject/Exception/MethodNameAlreadyConfiguredException.php',
1049 'PHPUnit\\Framework\\MockObject\\MethodNameConstraint' => '/phpunit/Framework/MockObject/Runtime/MethodNameConstraint.php',
1050 'PHPUnit\\Framework\\MockObject\\MethodNameNotConfiguredException' => '/phpunit/Framework/MockObject/Exception/MethodNameNotConfiguredException.php',
1051 'PHPUnit\\Framework\\MockObject\\MethodParametersAlreadyConfiguredException' => '/phpunit/Framework/MockObject/Exception/MethodParametersAlreadyConfiguredException.php',
1052 'PHPUnit\\Framework\\MockObject\\MockBuilder' => '/phpunit/Framework/MockObject/MockBuilder.php',
1053 'PHPUnit\\Framework\\MockObject\\MockObject' => '/phpunit/Framework/MockObject/Runtime/Interface/MockObject.php',
1054 'PHPUnit\\Framework\\MockObject\\MockObjectApi' => '/phpunit/Framework/MockObject/Runtime/Api/MockObjectApi.php',
1055 'PHPUnit\\Framework\\MockObject\\MockObjectInternal' => '/phpunit/Framework/MockObject/Runtime/Interface/MockObjectInternal.php',
1056 'PHPUnit\\Framework\\MockObject\\NeverReturningMethodException' => '/phpunit/Framework/MockObject/Exception/NeverReturningMethodException.php',
1057 'PHPUnit\\Framework\\MockObject\\NoMoreReturnValuesConfiguredException' => '/phpunit/Framework/MockObject/Exception/NoMoreReturnValuesConfiguredException.php',
1058 'PHPUnit\\Framework\\MockObject\\ProxiedCloneMethod' => '/phpunit/Framework/MockObject/Runtime/Api/ProxiedCloneMethod.php',
1059 'PHPUnit\\Framework\\MockObject\\ReturnValueGenerator' => '/phpunit/Framework/MockObject/Runtime/ReturnValueGenerator.php',
1060 'PHPUnit\\Framework\\MockObject\\ReturnValueNotConfiguredException' => '/phpunit/Framework/MockObject/Exception/ReturnValueNotConfiguredException.php',
1061 'PHPUnit\\Framework\\MockObject\\Rule\\AnyInvokedCount' => '/phpunit/Framework/MockObject/Runtime/Rule/AnyInvokedCount.php',
1062 'PHPUnit\\Framework\\MockObject\\Rule\\AnyParameters' => '/phpunit/Framework/MockObject/Runtime/Rule/AnyParameters.php',
1063 'PHPUnit\\Framework\\MockObject\\Rule\\InvocationOrder' => '/phpunit/Framework/MockObject/Runtime/Rule/InvocationOrder.php',
1064 'PHPUnit\\Framework\\MockObject\\Rule\\InvokedAtLeastCount' => '/phpunit/Framework/MockObject/Runtime/Rule/InvokedAtLeastCount.php',
1065 'PHPUnit\\Framework\\MockObject\\Rule\\InvokedAtLeastOnce' => '/phpunit/Framework/MockObject/Runtime/Rule/InvokedAtLeastOnce.php',
1066 'PHPUnit\\Framework\\MockObject\\Rule\\InvokedAtMostCount' => '/phpunit/Framework/MockObject/Runtime/Rule/InvokedAtMostCount.php',
1067 'PHPUnit\\Framework\\MockObject\\Rule\\InvokedCount' => '/phpunit/Framework/MockObject/Runtime/Rule/InvokedCount.php',
1068 'PHPUnit\\Framework\\MockObject\\Rule\\MethodName' => '/phpunit/Framework/MockObject/Runtime/Rule/MethodName.php',
1069 'PHPUnit\\Framework\\MockObject\\Rule\\Parameters' => '/phpunit/Framework/MockObject/Runtime/Rule/Parameters.php',
1070 'PHPUnit\\Framework\\MockObject\\Rule\\ParametersRule' => '/phpunit/Framework/MockObject/Runtime/Rule/ParametersRule.php',
1071 'PHPUnit\\Framework\\MockObject\\RuntimeException' => '/phpunit/Framework/MockObject/Exception/RuntimeException.php',
1072 'PHPUnit\\Framework\\MockObject\\Stub' => '/phpunit/Framework/MockObject/Runtime/Interface/Stub.php',
1073 'PHPUnit\\Framework\\MockObject\\StubApi' => '/phpunit/Framework/MockObject/Runtime/Api/StubApi.php',
1074 'PHPUnit\\Framework\\MockObject\\StubInternal' => '/phpunit/Framework/MockObject/Runtime/Interface/StubInternal.php',
1075 'PHPUnit\\Framework\\MockObject\\Stub\\ConsecutiveCalls' => '/phpunit/Framework/MockObject/Runtime/Stub/ConsecutiveCalls.php',
1076 'PHPUnit\\Framework\\MockObject\\Stub\\Exception' => '/phpunit/Framework/MockObject/Runtime/Stub/Exception.php',
1077 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnArgument' => '/phpunit/Framework/MockObject/Runtime/Stub/ReturnArgument.php',
1078 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnCallback' => '/phpunit/Framework/MockObject/Runtime/Stub/ReturnCallback.php',
1079 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnReference' => '/phpunit/Framework/MockObject/Runtime/Stub/ReturnReference.php',
1080 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnSelf' => '/phpunit/Framework/MockObject/Runtime/Stub/ReturnSelf.php',
1081 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnStub' => '/phpunit/Framework/MockObject/Runtime/Stub/ReturnStub.php',
1082 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnValueMap' => '/phpunit/Framework/MockObject/Runtime/Stub/ReturnValueMap.php',
1083 'PHPUnit\\Framework\\MockObject\\Stub\\Stub' => '/phpunit/Framework/MockObject/Runtime/Stub/Stub.php',
1084 'PHPUnit\\Framework\\NoChildTestSuiteException' => '/phpunit/Framework/Exception/NoChildTestSuiteException.php',
1085 'PHPUnit\\Framework\\PhptAssertionFailedError' => '/phpunit/Framework/Exception/PhptAssertionFailedError.php',
1086 'PHPUnit\\Framework\\ProcessIsolationException' => '/phpunit/Framework/Exception/ProcessIsolationException.php',
1087 'PHPUnit\\Framework\\Reorderable' => '/phpunit/Framework/Reorderable.php',
1088 'PHPUnit\\Framework\\SelfDescribing' => '/phpunit/Framework/SelfDescribing.php',
1089 'PHPUnit\\Framework\\SkippedTest' => '/phpunit/Framework/Exception/Skipped/SkippedTest.php',
1090 'PHPUnit\\Framework\\SkippedTestSuiteError' => '/phpunit/Framework/Exception/Skipped/SkippedTestSuiteError.php',
1091 'PHPUnit\\Framework\\SkippedWithMessageException' => '/phpunit/Framework/Exception/Skipped/SkippedWithMessageException.php',
1092 'PHPUnit\\Framework\\Test' => '/phpunit/Framework/Test.php',
1093 'PHPUnit\\Framework\\TestBuilder' => '/phpunit/Framework/TestBuilder.php',
1094 'PHPUnit\\Framework\\TestCase' => '/phpunit/Framework/TestCase.php',
1095 'PHPUnit\\Framework\\TestRunner' => '/phpunit/Framework/TestRunner.php',
1096 'PHPUnit\\Framework\\TestSize\\Known' => '/phpunit/Framework/TestSize/Known.php',
1097 'PHPUnit\\Framework\\TestSize\\Large' => '/phpunit/Framework/TestSize/Large.php',
1098 'PHPUnit\\Framework\\TestSize\\Medium' => '/phpunit/Framework/TestSize/Medium.php',
1099 'PHPUnit\\Framework\\TestSize\\Small' => '/phpunit/Framework/TestSize/Small.php',
1100 'PHPUnit\\Framework\\TestSize\\TestSize' => '/phpunit/Framework/TestSize/TestSize.php',
1101 'PHPUnit\\Framework\\TestSize\\Unknown' => '/phpunit/Framework/TestSize/Unknown.php',
1102 'PHPUnit\\Framework\\TestStatus\\Deprecation' => '/phpunit/Framework/TestStatus/Deprecation.php',
1103 'PHPUnit\\Framework\\TestStatus\\Error' => '/phpunit/Framework/TestStatus/Error.php',
1104 'PHPUnit\\Framework\\TestStatus\\Failure' => '/phpunit/Framework/TestStatus/Failure.php',
1105 'PHPUnit\\Framework\\TestStatus\\Incomplete' => '/phpunit/Framework/TestStatus/Incomplete.php',
1106 'PHPUnit\\Framework\\TestStatus\\Known' => '/phpunit/Framework/TestStatus/Known.php',
1107 'PHPUnit\\Framework\\TestStatus\\Notice' => '/phpunit/Framework/TestStatus/Notice.php',
1108 'PHPUnit\\Framework\\TestStatus\\Risky' => '/phpunit/Framework/TestStatus/Risky.php',
1109 'PHPUnit\\Framework\\TestStatus\\Skipped' => '/phpunit/Framework/TestStatus/Skipped.php',
1110 'PHPUnit\\Framework\\TestStatus\\Success' => '/phpunit/Framework/TestStatus/Success.php',
1111 'PHPUnit\\Framework\\TestStatus\\TestStatus' => '/phpunit/Framework/TestStatus/TestStatus.php',
1112 'PHPUnit\\Framework\\TestStatus\\Unknown' => '/phpunit/Framework/TestStatus/Unknown.php',
1113 'PHPUnit\\Framework\\TestStatus\\Warning' => '/phpunit/Framework/TestStatus/Warning.php',
1114 'PHPUnit\\Framework\\TestSuite' => '/phpunit/Framework/TestSuite.php',
1115 'PHPUnit\\Framework\\TestSuiteIterator' => '/phpunit/Framework/TestSuiteIterator.php',
1116 'PHPUnit\\Framework\\UnknownClassOrInterfaceException' => '/phpunit/Framework/Exception/UnknownClassOrInterfaceException.php',
1117 'PHPUnit\\Framework\\UnknownTypeException' => '/phpunit/Framework/Exception/UnknownTypeException.php',
1118 'PHPUnit\\Logging\\EventLogger' => '/phpunit/Logging/EventLogger.php',
1119 'PHPUnit\\Logging\\JUnit\\JunitXmlLogger' => '/phpunit/Logging/JUnit/JunitXmlLogger.php',
1120 'PHPUnit\\Logging\\JUnit\\Subscriber' => '/phpunit/Logging/JUnit/Subscriber/Subscriber.php',
1121 'PHPUnit\\Logging\\JUnit\\TestErroredSubscriber' => '/phpunit/Logging/JUnit/Subscriber/TestErroredSubscriber.php',
1122 'PHPUnit\\Logging\\JUnit\\TestFailedSubscriber' => '/phpunit/Logging/JUnit/Subscriber/TestFailedSubscriber.php',
1123 'PHPUnit\\Logging\\JUnit\\TestFinishedSubscriber' => '/phpunit/Logging/JUnit/Subscriber/TestFinishedSubscriber.php',
1124 'PHPUnit\\Logging\\JUnit\\TestMarkedIncompleteSubscriber' => '/phpunit/Logging/JUnit/Subscriber/TestMarkedIncompleteSubscriber.php',
1125 'PHPUnit\\Logging\\JUnit\\TestPreparationFailedSubscriber' => '/phpunit/Logging/JUnit/Subscriber/TestPreparationFailedSubscriber.php',
1126 'PHPUnit\\Logging\\JUnit\\TestPreparationStartedSubscriber' => '/phpunit/Logging/JUnit/Subscriber/TestPreparationStartedSubscriber.php',
1127 'PHPUnit\\Logging\\JUnit\\TestPreparedSubscriber' => '/phpunit/Logging/JUnit/Subscriber/TestPreparedSubscriber.php',
1128 'PHPUnit\\Logging\\JUnit\\TestPrintedUnexpectedOutputSubscriber' => '/phpunit/Logging/JUnit/Subscriber/TestPrintedUnexpectedOutputSubscriber.php',
1129 'PHPUnit\\Logging\\JUnit\\TestRunnerExecutionFinishedSubscriber' => '/phpunit/Logging/JUnit/Subscriber/TestRunnerExecutionFinishedSubscriber.php',
1130 'PHPUnit\\Logging\\JUnit\\TestSkippedSubscriber' => '/phpunit/Logging/JUnit/Subscriber/TestSkippedSubscriber.php',
1131 'PHPUnit\\Logging\\JUnit\\TestSuiteFinishedSubscriber' => '/phpunit/Logging/JUnit/Subscriber/TestSuiteFinishedSubscriber.php',
1132 'PHPUnit\\Logging\\JUnit\\TestSuiteStartedSubscriber' => '/phpunit/Logging/JUnit/Subscriber/TestSuiteStartedSubscriber.php',
1133 'PHPUnit\\Logging\\TeamCity\\Subscriber' => '/phpunit/Logging/TeamCity/Subscriber/Subscriber.php',
1134 'PHPUnit\\Logging\\TeamCity\\TeamCityLogger' => '/phpunit/Logging/TeamCity/TeamCityLogger.php',
1135 'PHPUnit\\Logging\\TeamCity\\TestConsideredRiskySubscriber' => '/phpunit/Logging/TeamCity/Subscriber/TestConsideredRiskySubscriber.php',
1136 'PHPUnit\\Logging\\TeamCity\\TestErroredSubscriber' => '/phpunit/Logging/TeamCity/Subscriber/TestErroredSubscriber.php',
1137 'PHPUnit\\Logging\\TeamCity\\TestFailedSubscriber' => '/phpunit/Logging/TeamCity/Subscriber/TestFailedSubscriber.php',
1138 'PHPUnit\\Logging\\TeamCity\\TestFinishedSubscriber' => '/phpunit/Logging/TeamCity/Subscriber/TestFinishedSubscriber.php',
1139 'PHPUnit\\Logging\\TeamCity\\TestMarkedIncompleteSubscriber' => '/phpunit/Logging/TeamCity/Subscriber/TestMarkedIncompleteSubscriber.php',
1140 'PHPUnit\\Logging\\TeamCity\\TestPreparedSubscriber' => '/phpunit/Logging/TeamCity/Subscriber/TestPreparedSubscriber.php',
1141 'PHPUnit\\Logging\\TeamCity\\TestRunnerExecutionFinishedSubscriber' => '/phpunit/Logging/TeamCity/Subscriber/TestRunnerExecutionFinishedSubscriber.php',
1142 'PHPUnit\\Logging\\TeamCity\\TestSkippedSubscriber' => '/phpunit/Logging/TeamCity/Subscriber/TestSkippedSubscriber.php',
1143 'PHPUnit\\Logging\\TeamCity\\TestSuiteBeforeFirstTestMethodErroredSubscriber' => '/phpunit/Logging/TeamCity/Subscriber/TestSuiteBeforeFirstTestMethodErroredSubscriber.php',
1144 'PHPUnit\\Logging\\TeamCity\\TestSuiteFinishedSubscriber' => '/phpunit/Logging/TeamCity/Subscriber/TestSuiteFinishedSubscriber.php',
1145 'PHPUnit\\Logging\\TeamCity\\TestSuiteSkippedSubscriber' => '/phpunit/Logging/TeamCity/Subscriber/TestSuiteSkippedSubscriber.php',
1146 'PHPUnit\\Logging\\TeamCity\\TestSuiteStartedSubscriber' => '/phpunit/Logging/TeamCity/Subscriber/TestSuiteStartedSubscriber.php',
1147 'PHPUnit\\Logging\\TestDox\\HtmlRenderer' => '/phpunit/Logging/TestDox/HtmlRenderer.php',
1148 'PHPUnit\\Logging\\TestDox\\NamePrettifier' => '/phpunit/Logging/TestDox/NamePrettifier.php',
1149 'PHPUnit\\Logging\\TestDox\\PlainTextRenderer' => '/phpunit/Logging/TestDox/PlainTextRenderer.php',
1150 'PHPUnit\\Logging\\TestDox\\Subscriber' => '/phpunit/Logging/TestDox/TestResult/Subscriber/Subscriber.php',
1151 'PHPUnit\\Logging\\TestDox\\TestConsideredRiskySubscriber' => '/phpunit/Logging/TestDox/TestResult/Subscriber/TestConsideredRiskySubscriber.php',
1152 'PHPUnit\\Logging\\TestDox\\TestErroredSubscriber' => '/phpunit/Logging/TestDox/TestResult/Subscriber/TestErroredSubscriber.php',
1153 'PHPUnit\\Logging\\TestDox\\TestFailedSubscriber' => '/phpunit/Logging/TestDox/TestResult/Subscriber/TestFailedSubscriber.php',
1154 'PHPUnit\\Logging\\TestDox\\TestFinishedSubscriber' => '/phpunit/Logging/TestDox/TestResult/Subscriber/TestFinishedSubscriber.php',
1155 'PHPUnit\\Logging\\TestDox\\TestMarkedIncompleteSubscriber' => '/phpunit/Logging/TestDox/TestResult/Subscriber/TestMarkedIncompleteSubscriber.php',
1156 'PHPUnit\\Logging\\TestDox\\TestPassedSubscriber' => '/phpunit/Logging/TestDox/TestResult/Subscriber/TestPassedSubscriber.php',
1157 'PHPUnit\\Logging\\TestDox\\TestPreparedSubscriber' => '/phpunit/Logging/TestDox/TestResult/Subscriber/TestPreparedSubscriber.php',
1158 'PHPUnit\\Logging\\TestDox\\TestResult' => '/phpunit/Logging/TestDox/TestResult/TestResult.php',
1159 'PHPUnit\\Logging\\TestDox\\TestResultCollection' => '/phpunit/Logging/TestDox/TestResult/TestResultCollection.php',
1160 'PHPUnit\\Logging\\TestDox\\TestResultCollectionIterator' => '/phpunit/Logging/TestDox/TestResult/TestResultCollectionIterator.php',
1161 'PHPUnit\\Logging\\TestDox\\TestResultCollector' => '/phpunit/Logging/TestDox/TestResult/TestResultCollector.php',
1162 'PHPUnit\\Logging\\TestDox\\TestSkippedSubscriber' => '/phpunit/Logging/TestDox/TestResult/Subscriber/TestSkippedSubscriber.php',
1163 'PHPUnit\\Logging\\TestDox\\TestTriggeredDeprecationSubscriber' => '/phpunit/Logging/TestDox/TestResult/Subscriber/TestTriggeredDeprecationSubscriber.php',
1164 'PHPUnit\\Logging\\TestDox\\TestTriggeredNoticeSubscriber' => '/phpunit/Logging/TestDox/TestResult/Subscriber/TestTriggeredNoticeSubscriber.php',
1165 'PHPUnit\\Logging\\TestDox\\TestTriggeredPhpDeprecationSubscriber' => '/phpunit/Logging/TestDox/TestResult/Subscriber/TestTriggeredPhpDeprecationSubscriber.php',
1166 'PHPUnit\\Logging\\TestDox\\TestTriggeredPhpNoticeSubscriber' => '/phpunit/Logging/TestDox/TestResult/Subscriber/TestTriggeredPhpNoticeSubscriber.php',
1167 'PHPUnit\\Logging\\TestDox\\TestTriggeredPhpWarningSubscriber' => '/phpunit/Logging/TestDox/TestResult/Subscriber/TestTriggeredPhpWarningSubscriber.php',
1168 'PHPUnit\\Logging\\TestDox\\TestTriggeredPhpunitDeprecationSubscriber' => '/phpunit/Logging/TestDox/TestResult/Subscriber/TestTriggeredPhpunitDeprecationSubscriber.php',
1169 'PHPUnit\\Logging\\TestDox\\TestTriggeredPhpunitErrorSubscriber' => '/phpunit/Logging/TestDox/TestResult/Subscriber/TestTriggeredPhpunitErrorSubscriber.php',
1170 'PHPUnit\\Logging\\TestDox\\TestTriggeredPhpunitWarningSubscriber' => '/phpunit/Logging/TestDox/TestResult/Subscriber/TestTriggeredPhpunitWarningSubscriber.php',
1171 'PHPUnit\\Logging\\TestDox\\TestTriggeredWarningSubscriber' => '/phpunit/Logging/TestDox/TestResult/Subscriber/TestTriggeredWarningSubscriber.php',
1172 'PHPUnit\\Metadata\\After' => '/phpunit/Metadata/After.php',
1173 'PHPUnit\\Metadata\\AfterClass' => '/phpunit/Metadata/AfterClass.php',
1174 'PHPUnit\\Metadata\\Annotation\\Parser\\DocBlock' => '/phpunit/Metadata/Parser/Annotation/DocBlock.php',
1175 'PHPUnit\\Metadata\\Annotation\\Parser\\Registry' => '/phpunit/Metadata/Parser/Annotation/Registry.php',
1176 'PHPUnit\\Metadata\\AnnotationsAreNotSupportedForInternalClassesException' => '/phpunit/Metadata/Exception/AnnotationsAreNotSupportedForInternalClassesException.php',
1177 'PHPUnit\\Metadata\\Api\\CodeCoverage' => '/phpunit/Metadata/Api/CodeCoverage.php',
1178 'PHPUnit\\Metadata\\Api\\DataProvider' => '/phpunit/Metadata/Api/DataProvider.php',
1179 'PHPUnit\\Metadata\\Api\\Dependencies' => '/phpunit/Metadata/Api/Dependencies.php',
1180 'PHPUnit\\Metadata\\Api\\Groups' => '/phpunit/Metadata/Api/Groups.php',
1181 'PHPUnit\\Metadata\\Api\\HookMethods' => '/phpunit/Metadata/Api/HookMethods.php',
1182 'PHPUnit\\Metadata\\Api\\Requirements' => '/phpunit/Metadata/Api/Requirements.php',
1183 'PHPUnit\\Metadata\\BackupGlobals' => '/phpunit/Metadata/BackupGlobals.php',
1184 'PHPUnit\\Metadata\\BackupStaticProperties' => '/phpunit/Metadata/BackupStaticProperties.php',
1185 'PHPUnit\\Metadata\\Before' => '/phpunit/Metadata/Before.php',
1186 'PHPUnit\\Metadata\\BeforeClass' => '/phpunit/Metadata/BeforeClass.php',
1187 'PHPUnit\\Metadata\\Covers' => '/phpunit/Metadata/Covers.php',
1188 'PHPUnit\\Metadata\\CoversClass' => '/phpunit/Metadata/CoversClass.php',
1189 'PHPUnit\\Metadata\\CoversDefaultClass' => '/phpunit/Metadata/CoversDefaultClass.php',
1190 'PHPUnit\\Metadata\\CoversFunction' => '/phpunit/Metadata/CoversFunction.php',
1191 'PHPUnit\\Metadata\\CoversNothing' => '/phpunit/Metadata/CoversNothing.php',
1192 'PHPUnit\\Metadata\\DataProvider' => '/phpunit/Metadata/DataProvider.php',
1193 'PHPUnit\\Metadata\\DependsOnClass' => '/phpunit/Metadata/DependsOnClass.php',
1194 'PHPUnit\\Metadata\\DependsOnMethod' => '/phpunit/Metadata/DependsOnMethod.php',
1195 'PHPUnit\\Metadata\\DoesNotPerformAssertions' => '/phpunit/Metadata/DoesNotPerformAssertions.php',
1196 'PHPUnit\\Metadata\\Exception' => '/phpunit/Metadata/Exception/Exception.php',
1197 'PHPUnit\\Metadata\\ExcludeGlobalVariableFromBackup' => '/phpunit/Metadata/ExcludeGlobalVariableFromBackup.php',
1198 'PHPUnit\\Metadata\\ExcludeStaticPropertyFromBackup' => '/phpunit/Metadata/ExcludeStaticPropertyFromBackup.php',
1199 'PHPUnit\\Metadata\\Group' => '/phpunit/Metadata/Group.php',
1200 'PHPUnit\\Metadata\\IgnoreClassForCodeCoverage' => '/phpunit/Metadata/IgnoreClassForCodeCoverage.php',
1201 'PHPUnit\\Metadata\\IgnoreDeprecations' => '/phpunit/Metadata/IgnoreDeprecations.php',
1202 'PHPUnit\\Metadata\\IgnoreFunctionForCodeCoverage' => '/phpunit/Metadata/IgnoreFunctionForCodeCoverage.php',
1203 'PHPUnit\\Metadata\\IgnoreMethodForCodeCoverage' => '/phpunit/Metadata/IgnoreMethodForCodeCoverage.php',
1204 'PHPUnit\\Metadata\\InvalidAttributeException' => '/phpunit/Metadata/Exception/InvalidAttributeException.php',
1205 'PHPUnit\\Metadata\\InvalidVersionRequirementException' => '/phpunit/Metadata/Exception/InvalidVersionRequirementException.php',
1206 'PHPUnit\\Metadata\\Metadata' => '/phpunit/Metadata/Metadata.php',
1207 'PHPUnit\\Metadata\\MetadataCollection' => '/phpunit/Metadata/MetadataCollection.php',
1208 'PHPUnit\\Metadata\\MetadataCollectionIterator' => '/phpunit/Metadata/MetadataCollectionIterator.php',
1209 'PHPUnit\\Metadata\\NoVersionRequirementException' => '/phpunit/Metadata/Exception/NoVersionRequirementException.php',
1210 'PHPUnit\\Metadata\\Parser\\AnnotationParser' => '/phpunit/Metadata/Parser/AnnotationParser.php',
1211 'PHPUnit\\Metadata\\Parser\\AttributeParser' => '/phpunit/Metadata/Parser/AttributeParser.php',
1212 'PHPUnit\\Metadata\\Parser\\CachingParser' => '/phpunit/Metadata/Parser/CachingParser.php',
1213 'PHPUnit\\Metadata\\Parser\\Parser' => '/phpunit/Metadata/Parser/Parser.php',
1214 'PHPUnit\\Metadata\\Parser\\ParserChain' => '/phpunit/Metadata/Parser/ParserChain.php',
1215 'PHPUnit\\Metadata\\Parser\\Registry' => '/phpunit/Metadata/Parser/Registry.php',
1216 'PHPUnit\\Metadata\\PostCondition' => '/phpunit/Metadata/PostCondition.php',
1217 'PHPUnit\\Metadata\\PreCondition' => '/phpunit/Metadata/PreCondition.php',
1218 'PHPUnit\\Metadata\\PreserveGlobalState' => '/phpunit/Metadata/PreserveGlobalState.php',
1219 'PHPUnit\\Metadata\\ReflectionException' => '/phpunit/Metadata/Exception/ReflectionException.php',
1220 'PHPUnit\\Metadata\\RequiresFunction' => '/phpunit/Metadata/RequiresFunction.php',
1221 'PHPUnit\\Metadata\\RequiresMethod' => '/phpunit/Metadata/RequiresMethod.php',
1222 'PHPUnit\\Metadata\\RequiresOperatingSystem' => '/phpunit/Metadata/RequiresOperatingSystem.php',
1223 'PHPUnit\\Metadata\\RequiresOperatingSystemFamily' => '/phpunit/Metadata/RequiresOperatingSystemFamily.php',
1224 'PHPUnit\\Metadata\\RequiresPhp' => '/phpunit/Metadata/RequiresPhp.php',
1225 'PHPUnit\\Metadata\\RequiresPhpExtension' => '/phpunit/Metadata/RequiresPhpExtension.php',
1226 'PHPUnit\\Metadata\\RequiresPhpunit' => '/phpunit/Metadata/RequiresPhpunit.php',
1227 'PHPUnit\\Metadata\\RequiresSetting' => '/phpunit/Metadata/RequiresSetting.php',
1228 'PHPUnit\\Metadata\\RunClassInSeparateProcess' => '/phpunit/Metadata/RunClassInSeparateProcess.php',
1229 'PHPUnit\\Metadata\\RunInSeparateProcess' => '/phpunit/Metadata/RunInSeparateProcess.php',
1230 'PHPUnit\\Metadata\\RunTestsInSeparateProcesses' => '/phpunit/Metadata/RunTestsInSeparateProcesses.php',
1231 'PHPUnit\\Metadata\\Test' => '/phpunit/Metadata/Test.php',
1232 'PHPUnit\\Metadata\\TestDox' => '/phpunit/Metadata/TestDox.php',
1233 'PHPUnit\\Metadata\\TestWith' => '/phpunit/Metadata/TestWith.php',
1234 'PHPUnit\\Metadata\\Uses' => '/phpunit/Metadata/Uses.php',
1235 'PHPUnit\\Metadata\\UsesClass' => '/phpunit/Metadata/UsesClass.php',
1236 'PHPUnit\\Metadata\\UsesDefaultClass' => '/phpunit/Metadata/UsesDefaultClass.php',
1237 'PHPUnit\\Metadata\\UsesFunction' => '/phpunit/Metadata/UsesFunction.php',
1238 'PHPUnit\\Metadata\\Version\\ComparisonRequirement' => '/phpunit/Metadata/Version/ComparisonRequirement.php',
1239 'PHPUnit\\Metadata\\Version\\ConstraintRequirement' => '/phpunit/Metadata/Version/ConstraintRequirement.php',
1240 'PHPUnit\\Metadata\\Version\\Requirement' => '/phpunit/Metadata/Version/Requirement.php',
1241 'PHPUnit\\Metadata\\WithoutErrorHandler' => '/phpunit/Metadata/WithoutErrorHandler.php',
1242 'PHPUnit\\Runner\\Baseline\\Baseline' => '/phpunit/Runner/Baseline/Baseline.php',
1243 'PHPUnit\\Runner\\Baseline\\CannotLoadBaselineException' => '/phpunit/Runner/Baseline/Exception/CannotLoadBaselineException.php',
1244 'PHPUnit\\Runner\\Baseline\\FileDoesNotHaveLineException' => '/phpunit/Runner/Baseline/Exception/FileDoesNotHaveLineException.php',
1245 'PHPUnit\\Runner\\Baseline\\Generator' => '/phpunit/Runner/Baseline/Generator.php',
1246 'PHPUnit\\Runner\\Baseline\\Issue' => '/phpunit/Runner/Baseline/Issue.php',
1247 'PHPUnit\\Runner\\Baseline\\Reader' => '/phpunit/Runner/Baseline/Reader.php',
1248 'PHPUnit\\Runner\\Baseline\\RelativePathCalculator' => '/phpunit/Runner/Baseline/RelativePathCalculator.php',
1249 'PHPUnit\\Runner\\Baseline\\Subscriber' => '/phpunit/Runner/Baseline/Subscriber/Subscriber.php',
1250 'PHPUnit\\Runner\\Baseline\\TestTriggeredDeprecationSubscriber' => '/phpunit/Runner/Baseline/Subscriber/TestTriggeredDeprecationSubscriber.php',
1251 'PHPUnit\\Runner\\Baseline\\TestTriggeredNoticeSubscriber' => '/phpunit/Runner/Baseline/Subscriber/TestTriggeredNoticeSubscriber.php',
1252 'PHPUnit\\Runner\\Baseline\\TestTriggeredPhpDeprecationSubscriber' => '/phpunit/Runner/Baseline/Subscriber/TestTriggeredPhpDeprecationSubscriber.php',
1253 'PHPUnit\\Runner\\Baseline\\TestTriggeredPhpNoticeSubscriber' => '/phpunit/Runner/Baseline/Subscriber/TestTriggeredPhpNoticeSubscriber.php',
1254 'PHPUnit\\Runner\\Baseline\\TestTriggeredPhpWarningSubscriber' => '/phpunit/Runner/Baseline/Subscriber/TestTriggeredPhpWarningSubscriber.php',
1255 'PHPUnit\\Runner\\Baseline\\TestTriggeredWarningSubscriber' => '/phpunit/Runner/Baseline/Subscriber/TestTriggeredWarningSubscriber.php',
1256 'PHPUnit\\Runner\\Baseline\\Writer' => '/phpunit/Runner/Baseline/Writer.php',
1257 'PHPUnit\\Runner\\ClassCannotBeFoundException' => '/phpunit/Runner/Exception/ClassCannotBeFoundException.php',
1258 'PHPUnit\\Runner\\ClassDoesNotExtendTestCaseException' => '/phpunit/Runner/Exception/ClassDoesNotExtendTestCaseException.php',
1259 'PHPUnit\\Runner\\ClassIsAbstractException' => '/phpunit/Runner/Exception/ClassIsAbstractException.php',
1260 'PHPUnit\\Runner\\CodeCoverage' => '/phpunit/Runner/CodeCoverage.php',
1261 'PHPUnit\\Runner\\CodeCoverageFileExistsException' => '/phpunit/Runner/Exception/CodeCoverageFileExistsException.php',
1262 'PHPUnit\\Runner\\DirectoryDoesNotExistException' => '/phpunit/Runner/Exception/DirectoryDoesNotExistException.php',
1263 'PHPUnit\\Runner\\ErrorException' => '/phpunit/Runner/Exception/ErrorException.php',
1264 'PHPUnit\\Runner\\ErrorHandler' => '/phpunit/Runner/ErrorHandler.php',
1265 'PHPUnit\\Runner\\Exception' => '/phpunit/Runner/Exception/Exception.php',
1266 'PHPUnit\\Runner\\Extension\\Extension' => '/phpunit/Runner/Extension/Extension.php',
1267 'PHPUnit\\Runner\\Extension\\ExtensionBootstrapper' => '/phpunit/Runner/Extension/ExtensionBootstrapper.php',
1268 'PHPUnit\\Runner\\Extension\\Facade' => '/phpunit/Runner/Extension/Facade.php',
1269 'PHPUnit\\Runner\\Extension\\ParameterCollection' => '/phpunit/Runner/Extension/ParameterCollection.php',
1270 'PHPUnit\\Runner\\Extension\\PharLoader' => '/phpunit/Runner/Extension/PharLoader.php',
1271 'PHPUnit\\Runner\\FileDoesNotExistException' => '/phpunit/Runner/Exception/FileDoesNotExistException.php',
1272 'PHPUnit\\Runner\\Filter\\ExcludeGroupFilterIterator' => '/phpunit/Runner/Filter/ExcludeGroupFilterIterator.php',
1273 'PHPUnit\\Runner\\Filter\\Factory' => '/phpunit/Runner/Filter/Factory.php',
1274 'PHPUnit\\Runner\\Filter\\GroupFilterIterator' => '/phpunit/Runner/Filter/GroupFilterIterator.php',
1275 'PHPUnit\\Runner\\Filter\\IncludeGroupFilterIterator' => '/phpunit/Runner/Filter/IncludeGroupFilterIterator.php',
1276 'PHPUnit\\Runner\\Filter\\NameFilterIterator' => '/phpunit/Runner/Filter/NameFilterIterator.php',
1277 'PHPUnit\\Runner\\Filter\\TestIdFilterIterator' => '/phpunit/Runner/Filter/TestIdFilterIterator.php',
1278 'PHPUnit\\Runner\\GarbageCollection\\ExecutionFinishedSubscriber' => '/phpunit/Runner/GarbageCollection/Subscriber/ExecutionFinishedSubscriber.php',
1279 'PHPUnit\\Runner\\GarbageCollection\\ExecutionStartedSubscriber' => '/phpunit/Runner/GarbageCollection/Subscriber/ExecutionStartedSubscriber.php',
1280 'PHPUnit\\Runner\\GarbageCollection\\GarbageCollectionHandler' => '/phpunit/Runner/GarbageCollection/GarbageCollectionHandler.php',
1281 'PHPUnit\\Runner\\GarbageCollection\\Subscriber' => '/phpunit/Runner/GarbageCollection/Subscriber/Subscriber.php',
1282 'PHPUnit\\Runner\\GarbageCollection\\TestFinishedSubscriber' => '/phpunit/Runner/GarbageCollection/Subscriber/TestFinishedSubscriber.php',
1283 'PHPUnit\\Runner\\InvalidOrderException' => '/phpunit/Runner/Exception/InvalidOrderException.php',
1284 'PHPUnit\\Runner\\InvalidPhptFileException' => '/phpunit/Runner/Exception/InvalidPhptFileException.php',
1285 'PHPUnit\\Runner\\ParameterDoesNotExistException' => '/phpunit/Runner/Exception/ParameterDoesNotExistException.php',
1286 'PHPUnit\\Runner\\PhptExternalFileCannotBeLoadedException' => '/phpunit/Runner/Exception/PhptExternalFileCannotBeLoadedException.php',
1287 'PHPUnit\\Runner\\PhptTestCase' => '/phpunit/Runner/PhptTestCase.php',
1288 'PHPUnit\\Runner\\ResultCache\\DefaultResultCache' => '/phpunit/Runner/ResultCache/DefaultResultCache.php',
1289 'PHPUnit\\Runner\\ResultCache\\NullResultCache' => '/phpunit/Runner/ResultCache/NullResultCache.php',
1290 'PHPUnit\\Runner\\ResultCache\\ResultCache' => '/phpunit/Runner/ResultCache/ResultCache.php',
1291 'PHPUnit\\Runner\\ResultCache\\ResultCacheHandler' => '/phpunit/Runner/ResultCache/ResultCacheHandler.php',
1292 'PHPUnit\\Runner\\ResultCache\\Subscriber' => '/phpunit/Runner/ResultCache/Subscriber/Subscriber.php',
1293 'PHPUnit\\Runner\\ResultCache\\TestConsideredRiskySubscriber' => '/phpunit/Runner/ResultCache/Subscriber/TestConsideredRiskySubscriber.php',
1294 'PHPUnit\\Runner\\ResultCache\\TestErroredSubscriber' => '/phpunit/Runner/ResultCache/Subscriber/TestErroredSubscriber.php',
1295 'PHPUnit\\Runner\\ResultCache\\TestFailedSubscriber' => '/phpunit/Runner/ResultCache/Subscriber/TestFailedSubscriber.php',
1296 'PHPUnit\\Runner\\ResultCache\\TestFinishedSubscriber' => '/phpunit/Runner/ResultCache/Subscriber/TestFinishedSubscriber.php',
1297 'PHPUnit\\Runner\\ResultCache\\TestMarkedIncompleteSubscriber' => '/phpunit/Runner/ResultCache/Subscriber/TestMarkedIncompleteSubscriber.php',
1298 'PHPUnit\\Runner\\ResultCache\\TestPreparedSubscriber' => '/phpunit/Runner/ResultCache/Subscriber/TestPreparedSubscriber.php',
1299 'PHPUnit\\Runner\\ResultCache\\TestSkippedSubscriber' => '/phpunit/Runner/ResultCache/Subscriber/TestSkippedSubscriber.php',
1300 'PHPUnit\\Runner\\ResultCache\\TestSuiteFinishedSubscriber' => '/phpunit/Runner/ResultCache/Subscriber/TestSuiteFinishedSubscriber.php',
1301 'PHPUnit\\Runner\\ResultCache\\TestSuiteStartedSubscriber' => '/phpunit/Runner/ResultCache/Subscriber/TestSuiteStartedSubscriber.php',
1302 'PHPUnit\\Runner\\TestSuiteLoader' => '/phpunit/Runner/TestSuiteLoader.php',
1303 'PHPUnit\\Runner\\TestSuiteSorter' => '/phpunit/Runner/TestSuiteSorter.php',
1304 'PHPUnit\\Runner\\UnsupportedPhptSectionException' => '/phpunit/Runner/Exception/UnsupportedPhptSectionException.php',
1305 'PHPUnit\\Runner\\Version' => '/phpunit/Runner/Version.php',
1306 'PHPUnit\\TestRunner\\TestResult\\AfterTestClassMethodErroredSubscriber' => '/phpunit/Runner/TestResult/Subscriber/AfterTestClassMethodErroredSubscriber.php',
1307 'PHPUnit\\TestRunner\\TestResult\\BeforeTestClassMethodErroredSubscriber' => '/phpunit/Runner/TestResult/Subscriber/BeforeTestClassMethodErroredSubscriber.php',
1308 'PHPUnit\\TestRunner\\TestResult\\Collector' => '/phpunit/Runner/TestResult/Collector.php',
1309 'PHPUnit\\TestRunner\\TestResult\\ExecutionStartedSubscriber' => '/phpunit/Runner/TestResult/Subscriber/ExecutionStartedSubscriber.php',
1310 'PHPUnit\\TestRunner\\TestResult\\Facade' => '/phpunit/Runner/TestResult/Facade.php',
1311 'PHPUnit\\TestRunner\\TestResult\\Issues\\Issue' => '/phpunit/Runner/TestResult/Issue.php',
1312 'PHPUnit\\TestRunner\\TestResult\\PassedTests' => '/phpunit/Runner/TestResult/PassedTests.php',
1313 'PHPUnit\\TestRunner\\TestResult\\Subscriber' => '/phpunit/Runner/TestResult/Subscriber/Subscriber.php',
1314 'PHPUnit\\TestRunner\\TestResult\\TestConsideredRiskySubscriber' => '/phpunit/Runner/TestResult/Subscriber/TestConsideredRiskySubscriber.php',
1315 'PHPUnit\\TestRunner\\TestResult\\TestErroredSubscriber' => '/phpunit/Runner/TestResult/Subscriber/TestErroredSubscriber.php',
1316 'PHPUnit\\TestRunner\\TestResult\\TestFailedSubscriber' => '/phpunit/Runner/TestResult/Subscriber/TestFailedSubscriber.php',
1317 'PHPUnit\\TestRunner\\TestResult\\TestFinishedSubscriber' => '/phpunit/Runner/TestResult/Subscriber/TestFinishedSubscriber.php',
1318 'PHPUnit\\TestRunner\\TestResult\\TestMarkedIncompleteSubscriber' => '/phpunit/Runner/TestResult/Subscriber/TestMarkedIncompleteSubscriber.php',
1319 'PHPUnit\\TestRunner\\TestResult\\TestPreparedSubscriber' => '/phpunit/Runner/TestResult/Subscriber/TestPreparedSubscriber.php',
1320 'PHPUnit\\TestRunner\\TestResult\\TestResult' => '/phpunit/Runner/TestResult/TestResult.php',
1321 'PHPUnit\\TestRunner\\TestResult\\TestRunnerTriggeredDeprecationSubscriber' => '/phpunit/Runner/TestResult/Subscriber/TestRunnerTriggeredDeprecationSubscriber.php',
1322 'PHPUnit\\TestRunner\\TestResult\\TestRunnerTriggeredWarningSubscriber' => '/phpunit/Runner/TestResult/Subscriber/TestRunnerTriggeredWarningSubscriber.php',
1323 'PHPUnit\\TestRunner\\TestResult\\TestSkippedSubscriber' => '/phpunit/Runner/TestResult/Subscriber/TestSkippedSubscriber.php',
1324 'PHPUnit\\TestRunner\\TestResult\\TestSuiteFinishedSubscriber' => '/phpunit/Runner/TestResult/Subscriber/TestSuiteFinishedSubscriber.php',
1325 'PHPUnit\\TestRunner\\TestResult\\TestSuiteSkippedSubscriber' => '/phpunit/Runner/TestResult/Subscriber/TestSuiteSkippedSubscriber.php',
1326 'PHPUnit\\TestRunner\\TestResult\\TestSuiteStartedSubscriber' => '/phpunit/Runner/TestResult/Subscriber/TestSuiteStartedSubscriber.php',
1327 'PHPUnit\\TestRunner\\TestResult\\TestTriggeredDeprecationSubscriber' => '/phpunit/Runner/TestResult/Subscriber/TestTriggeredDeprecationSubscriber.php',
1328 'PHPUnit\\TestRunner\\TestResult\\TestTriggeredErrorSubscriber' => '/phpunit/Runner/TestResult/Subscriber/TestTriggeredErrorSubscriber.php',
1329 'PHPUnit\\TestRunner\\TestResult\\TestTriggeredNoticeSubscriber' => '/phpunit/Runner/TestResult/Subscriber/TestTriggeredNoticeSubscriber.php',
1330 'PHPUnit\\TestRunner\\TestResult\\TestTriggeredPhpDeprecationSubscriber' => '/phpunit/Runner/TestResult/Subscriber/TestTriggeredPhpDeprecationSubscriber.php',
1331 'PHPUnit\\TestRunner\\TestResult\\TestTriggeredPhpNoticeSubscriber' => '/phpunit/Runner/TestResult/Subscriber/TestTriggeredPhpNoticeSubscriber.php',
1332 'PHPUnit\\TestRunner\\TestResult\\TestTriggeredPhpWarningSubscriber' => '/phpunit/Runner/TestResult/Subscriber/TestTriggeredPhpWarningSubscriber.php',
1333 'PHPUnit\\TestRunner\\TestResult\\TestTriggeredPhpunitDeprecationSubscriber' => '/phpunit/Runner/TestResult/Subscriber/TestTriggeredPhpunitDeprecationSubscriber.php',
1334 'PHPUnit\\TestRunner\\TestResult\\TestTriggeredPhpunitErrorSubscriber' => '/phpunit/Runner/TestResult/Subscriber/TestTriggeredPhpunitErrorSubscriber.php',
1335 'PHPUnit\\TestRunner\\TestResult\\TestTriggeredPhpunitWarningSubscriber' => '/phpunit/Runner/TestResult/Subscriber/TestTriggeredPhpunitWarningSubscriber.php',
1336 'PHPUnit\\TestRunner\\TestResult\\TestTriggeredWarningSubscriber' => '/phpunit/Runner/TestResult/Subscriber/TestTriggeredWarningSubscriber.php',
1337 'PHPUnit\\TextUI\\Application' => '/phpunit/TextUI/Application.php',
1338 'PHPUnit\\TextUI\\CannotOpenSocketException' => '/phpunit/TextUI/Exception/CannotOpenSocketException.php',
1339 'PHPUnit\\TextUI\\CliArguments\\Builder' => '/phpunit/TextUI/Configuration/Cli/Builder.php',
1340 'PHPUnit\\TextUI\\CliArguments\\Configuration' => '/phpunit/TextUI/Configuration/Cli/Configuration.php',
1341 'PHPUnit\\TextUI\\CliArguments\\Exception' => '/phpunit/TextUI/Configuration/Cli/Exception.php',
1342 'PHPUnit\\TextUI\\CliArguments\\XmlConfigurationFileFinder' => '/phpunit/TextUI/Configuration/Cli/XmlConfigurationFileFinder.php',
1343 'PHPUnit\\TextUI\\Command\\AtLeastVersionCommand' => '/phpunit/TextUI/Command/Commands/AtLeastVersionCommand.php',
1344 'PHPUnit\\TextUI\\Command\\CheckPhpConfigurationCommand' => '/phpunit/TextUI/Command/Commands/CheckPhpConfigurationCommand.php',
1345 'PHPUnit\\TextUI\\Command\\Command' => '/phpunit/TextUI/Command/Command.php',
1346 'PHPUnit\\TextUI\\Command\\GenerateConfigurationCommand' => '/phpunit/TextUI/Command/Commands/GenerateConfigurationCommand.php',
1347 'PHPUnit\\TextUI\\Command\\ListGroupsCommand' => '/phpunit/TextUI/Command/Commands/ListGroupsCommand.php',
1348 'PHPUnit\\TextUI\\Command\\ListTestSuitesCommand' => '/phpunit/TextUI/Command/Commands/ListTestSuitesCommand.php',
1349 'PHPUnit\\TextUI\\Command\\ListTestsAsTextCommand' => '/phpunit/TextUI/Command/Commands/ListTestsAsTextCommand.php',
1350 'PHPUnit\\TextUI\\Command\\ListTestsAsXmlCommand' => '/phpunit/TextUI/Command/Commands/ListTestsAsXmlCommand.php',
1351 'PHPUnit\\TextUI\\Command\\MigrateConfigurationCommand' => '/phpunit/TextUI/Command/Commands/MigrateConfigurationCommand.php',
1352 'PHPUnit\\TextUI\\Command\\Result' => '/phpunit/TextUI/Command/Result.php',
1353 'PHPUnit\\TextUI\\Command\\ShowHelpCommand' => '/phpunit/TextUI/Command/Commands/ShowHelpCommand.php',
1354 'PHPUnit\\TextUI\\Command\\ShowVersionCommand' => '/phpunit/TextUI/Command/Commands/ShowVersionCommand.php',
1355 'PHPUnit\\TextUI\\Command\\VersionCheckCommand' => '/phpunit/TextUI/Command/Commands/VersionCheckCommand.php',
1356 'PHPUnit\\TextUI\\Command\\WarmCodeCoverageCacheCommand' => '/phpunit/TextUI/Command/Commands/WarmCodeCoverageCacheCommand.php',
1357 'PHPUnit\\TextUI\\Configuration\\Builder' => '/phpunit/TextUI/Configuration/Builder.php',
1358 'PHPUnit\\TextUI\\Configuration\\CodeCoverageFilterRegistry' => '/phpunit/TextUI/Configuration/CodeCoverageFilterRegistry.php',
1359 'PHPUnit\\TextUI\\Configuration\\CodeCoverageReportNotConfiguredException' => '/phpunit/TextUI/Configuration/Exception/CodeCoverageReportNotConfiguredException.php',
1360 'PHPUnit\\TextUI\\Configuration\\Configuration' => '/phpunit/TextUI/Configuration/Configuration.php',
1361 'PHPUnit\\TextUI\\Configuration\\ConfigurationCannotBeBuiltException' => '/phpunit/TextUI/Configuration/Exception/ConfigurationCannotBeBuiltException.php',
1362 'PHPUnit\\TextUI\\Configuration\\Constant' => '/phpunit/TextUI/Configuration/Value/Constant.php',
1363 'PHPUnit\\TextUI\\Configuration\\ConstantCollection' => '/phpunit/TextUI/Configuration/Value/ConstantCollection.php',
1364 'PHPUnit\\TextUI\\Configuration\\ConstantCollectionIterator' => '/phpunit/TextUI/Configuration/Value/ConstantCollectionIterator.php',
1365 'PHPUnit\\TextUI\\Configuration\\Directory' => '/phpunit/TextUI/Configuration/Value/Directory.php',
1366 'PHPUnit\\TextUI\\Configuration\\DirectoryCollection' => '/phpunit/TextUI/Configuration/Value/DirectoryCollection.php',
1367 'PHPUnit\\TextUI\\Configuration\\DirectoryCollectionIterator' => '/phpunit/TextUI/Configuration/Value/DirectoryCollectionIterator.php',
1368 'PHPUnit\\TextUI\\Configuration\\Exception' => '/phpunit/TextUI/Configuration/Exception/Exception.php',
1369 'PHPUnit\\TextUI\\Configuration\\ExtensionBootstrap' => '/phpunit/TextUI/Configuration/Value/ExtensionBootstrap.php',
1370 'PHPUnit\\TextUI\\Configuration\\ExtensionBootstrapCollection' => '/phpunit/TextUI/Configuration/Value/ExtensionBootstrapCollection.php',
1371 'PHPUnit\\TextUI\\Configuration\\ExtensionBootstrapCollectionIterator' => '/phpunit/TextUI/Configuration/Value/ExtensionBootstrapCollectionIterator.php',
1372 'PHPUnit\\TextUI\\Configuration\\File' => '/phpunit/TextUI/Configuration/Value/File.php',
1373 'PHPUnit\\TextUI\\Configuration\\FileCollection' => '/phpunit/TextUI/Configuration/Value/FileCollection.php',
1374 'PHPUnit\\TextUI\\Configuration\\FileCollectionIterator' => '/phpunit/TextUI/Configuration/Value/FileCollectionIterator.php',
1375 'PHPUnit\\TextUI\\Configuration\\FilterDirectory' => '/phpunit/TextUI/Configuration/Value/FilterDirectory.php',
1376 'PHPUnit\\TextUI\\Configuration\\FilterDirectoryCollection' => '/phpunit/TextUI/Configuration/Value/FilterDirectoryCollection.php',
1377 'PHPUnit\\TextUI\\Configuration\\FilterDirectoryCollectionIterator' => '/phpunit/TextUI/Configuration/Value/FilterDirectoryCollectionIterator.php',
1378 'PHPUnit\\TextUI\\Configuration\\FilterNotConfiguredException' => '/phpunit/TextUI/Configuration/Exception/FilterNotConfiguredException.php',
1379 'PHPUnit\\TextUI\\Configuration\\Group' => '/phpunit/TextUI/Configuration/Value/Group.php',
1380 'PHPUnit\\TextUI\\Configuration\\GroupCollection' => '/phpunit/TextUI/Configuration/Value/GroupCollection.php',
1381 'PHPUnit\\TextUI\\Configuration\\GroupCollectionIterator' => '/phpunit/TextUI/Configuration/Value/GroupCollectionIterator.php',
1382 'PHPUnit\\TextUI\\Configuration\\IniSetting' => '/phpunit/TextUI/Configuration/Value/IniSetting.php',
1383 'PHPUnit\\TextUI\\Configuration\\IniSettingCollection' => '/phpunit/TextUI/Configuration/Value/IniSettingCollection.php',
1384 'PHPUnit\\TextUI\\Configuration\\IniSettingCollectionIterator' => '/phpunit/TextUI/Configuration/Value/IniSettingCollectionIterator.php',
1385 'PHPUnit\\TextUI\\Configuration\\LoggingNotConfiguredException' => '/phpunit/TextUI/Configuration/Exception/LoggingNotConfiguredException.php',
1386 'PHPUnit\\TextUI\\Configuration\\Merger' => '/phpunit/TextUI/Configuration/Merger.php',
1387 'PHPUnit\\TextUI\\Configuration\\NoBaselineException' => '/phpunit/TextUI/Configuration/Exception/NoBaselineException.php',
1388 'PHPUnit\\TextUI\\Configuration\\NoBootstrapException' => '/phpunit/TextUI/Configuration/Exception/NoBootstrapException.php',
1389 'PHPUnit\\TextUI\\Configuration\\NoCacheDirectoryException' => '/phpunit/TextUI/Configuration/Exception/NoCacheDirectoryException.php',
1390 'PHPUnit\\TextUI\\Configuration\\NoCliArgumentException' => '/phpunit/TextUI/Configuration/Exception/NoCliArgumentException.php',
1391 'PHPUnit\\TextUI\\Configuration\\NoConfigurationFileException' => '/phpunit/TextUI/Configuration/Exception/NoConfigurationFileException.php',
1392 'PHPUnit\\TextUI\\Configuration\\NoCoverageCacheDirectoryException' => '/phpunit/TextUI/Configuration/Exception/NoCoverageCacheDirectoryException.php',
1393 'PHPUnit\\TextUI\\Configuration\\NoCustomCssFileException' => '/phpunit/TextUI/Configuration/Exception/NoCustomCssFileException.php',
1394 'PHPUnit\\TextUI\\Configuration\\NoDefaultTestSuiteException' => '/phpunit/TextUI/Configuration/Exception/NoDefaultTestSuiteException.php',
1395 'PHPUnit\\TextUI\\Configuration\\NoPharExtensionDirectoryException' => '/phpunit/TextUI/Configuration/Exception/NoPharExtensionDirectoryException.php',
1396 'PHPUnit\\TextUI\\Configuration\\Php' => '/phpunit/TextUI/Configuration/Value/Php.php',
1397 'PHPUnit\\TextUI\\Configuration\\PhpHandler' => '/phpunit/TextUI/Configuration/PhpHandler.php',
1398 'PHPUnit\\TextUI\\Configuration\\Registry' => '/phpunit/TextUI/Configuration/Registry.php',
1399 'PHPUnit\\TextUI\\Configuration\\Source' => '/phpunit/TextUI/Configuration/Value/Source.php',
1400 'PHPUnit\\TextUI\\Configuration\\SourceFilter' => '/phpunit/TextUI/Configuration/SourceFilter.php',
1401 'PHPUnit\\TextUI\\Configuration\\SourceMapper' => '/phpunit/TextUI/Configuration/SourceMapper.php',
1402 'PHPUnit\\TextUI\\Configuration\\TestDirectory' => '/phpunit/TextUI/Configuration/Value/TestDirectory.php',
1403 'PHPUnit\\TextUI\\Configuration\\TestDirectoryCollection' => '/phpunit/TextUI/Configuration/Value/TestDirectoryCollection.php',
1404 'PHPUnit\\TextUI\\Configuration\\TestDirectoryCollectionIterator' => '/phpunit/TextUI/Configuration/Value/TestDirectoryCollectionIterator.php',
1405 'PHPUnit\\TextUI\\Configuration\\TestFile' => '/phpunit/TextUI/Configuration/Value/TestFile.php',
1406 'PHPUnit\\TextUI\\Configuration\\TestFileCollection' => '/phpunit/TextUI/Configuration/Value/TestFileCollection.php',
1407 'PHPUnit\\TextUI\\Configuration\\TestFileCollectionIterator' => '/phpunit/TextUI/Configuration/Value/TestFileCollectionIterator.php',
1408 'PHPUnit\\TextUI\\Configuration\\TestSuite' => '/phpunit/TextUI/Configuration/Value/TestSuite.php',
1409 'PHPUnit\\TextUI\\Configuration\\TestSuiteBuilder' => '/phpunit/TextUI/Configuration/TestSuiteBuilder.php',
1410 'PHPUnit\\TextUI\\Configuration\\TestSuiteCollection' => '/phpunit/TextUI/Configuration/Value/TestSuiteCollection.php',
1411 'PHPUnit\\TextUI\\Configuration\\TestSuiteCollectionIterator' => '/phpunit/TextUI/Configuration/Value/TestSuiteCollectionIterator.php',
1412 'PHPUnit\\TextUI\\Configuration\\Variable' => '/phpunit/TextUI/Configuration/Value/Variable.php',
1413 'PHPUnit\\TextUI\\Configuration\\VariableCollection' => '/phpunit/TextUI/Configuration/Value/VariableCollection.php',
1414 'PHPUnit\\TextUI\\Configuration\\VariableCollectionIterator' => '/phpunit/TextUI/Configuration/Value/VariableCollectionIterator.php',
1415 'PHPUnit\\TextUI\\Exception' => '/phpunit/TextUI/Exception/Exception.php',
1416 'PHPUnit\\TextUI\\Help' => '/phpunit/TextUI/Help.php',
1417 'PHPUnit\\TextUI\\InvalidSocketException' => '/phpunit/TextUI/Exception/InvalidSocketException.php',
1418 'PHPUnit\\TextUI\\Output\\DefaultPrinter' => '/phpunit/TextUI/Output/Printer/DefaultPrinter.php',
1419 'PHPUnit\\TextUI\\Output\\Default\\ProgressPrinter\\BeforeTestClassMethodErroredSubscriber' => '/phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/BeforeTestClassMethodErroredSubscriber.php',
1420 'PHPUnit\\TextUI\\Output\\Default\\ProgressPrinter\\ProgressPrinter' => '/phpunit/TextUI/Output/Default/ProgressPrinter/ProgressPrinter.php',
1421 'PHPUnit\\TextUI\\Output\\Default\\ProgressPrinter\\Subscriber' => '/phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/Subscriber.php',
1422 'PHPUnit\\TextUI\\Output\\Default\\ProgressPrinter\\TestConsideredRiskySubscriber' => '/phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestConsideredRiskySubscriber.php',
1423 'PHPUnit\\TextUI\\Output\\Default\\ProgressPrinter\\TestErroredSubscriber' => '/phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestErroredSubscriber.php',
1424 'PHPUnit\\TextUI\\Output\\Default\\ProgressPrinter\\TestFailedSubscriber' => '/phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestFailedSubscriber.php',
1425 'PHPUnit\\TextUI\\Output\\Default\\ProgressPrinter\\TestFinishedSubscriber' => '/phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestFinishedSubscriber.php',
1426 'PHPUnit\\TextUI\\Output\\Default\\ProgressPrinter\\TestMarkedIncompleteSubscriber' => '/phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestMarkedIncompleteSubscriber.php',
1427 'PHPUnit\\TextUI\\Output\\Default\\ProgressPrinter\\TestPreparedSubscriber' => '/phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestPreparedSubscriber.php',
1428 'PHPUnit\\TextUI\\Output\\Default\\ProgressPrinter\\TestRunnerExecutionStartedSubscriber' => '/phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestRunnerExecutionStartedSubscriber.php',
1429 'PHPUnit\\TextUI\\Output\\Default\\ProgressPrinter\\TestSkippedSubscriber' => '/phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestSkippedSubscriber.php',
1430 'PHPUnit\\TextUI\\Output\\Default\\ProgressPrinter\\TestTriggeredDeprecationSubscriber' => '/phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestTriggeredDeprecationSubscriber.php',
1431 'PHPUnit\\TextUI\\Output\\Default\\ProgressPrinter\\TestTriggeredErrorSubscriber' => '/phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestTriggeredErrorSubscriber.php',
1432 'PHPUnit\\TextUI\\Output\\Default\\ProgressPrinter\\TestTriggeredNoticeSubscriber' => '/phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestTriggeredNoticeSubscriber.php',
1433 'PHPUnit\\TextUI\\Output\\Default\\ProgressPrinter\\TestTriggeredPhpDeprecationSubscriber' => '/phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestTriggeredPhpDeprecationSubscriber.php',
1434 'PHPUnit\\TextUI\\Output\\Default\\ProgressPrinter\\TestTriggeredPhpNoticeSubscriber' => '/phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestTriggeredPhpNoticeSubscriber.php',
1435 'PHPUnit\\TextUI\\Output\\Default\\ProgressPrinter\\TestTriggeredPhpWarningSubscriber' => '/phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestTriggeredPhpWarningSubscriber.php',
1436 'PHPUnit\\TextUI\\Output\\Default\\ProgressPrinter\\TestTriggeredPhpunitDeprecationSubscriber' => '/phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestTriggeredPhpunitDeprecationSubscriber.php',
1437 'PHPUnit\\TextUI\\Output\\Default\\ProgressPrinter\\TestTriggeredPhpunitWarningSubscriber' => '/phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestTriggeredPhpunitWarningSubscriber.php',
1438 'PHPUnit\\TextUI\\Output\\Default\\ProgressPrinter\\TestTriggeredWarningSubscriber' => '/phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestTriggeredWarningSubscriber.php',
1439 'PHPUnit\\TextUI\\Output\\Default\\ResultPrinter' => '/phpunit/TextUI/Output/Default/ResultPrinter.php',
1440 'PHPUnit\\TextUI\\Output\\Default\\UnexpectedOutputPrinter' => '/phpunit/TextUI/Output/Default/UnexpectedOutputPrinter.php',
1441 'PHPUnit\\TextUI\\Output\\Facade' => '/phpunit/TextUI/Output/Facade.php',
1442 'PHPUnit\\TextUI\\Output\\NullPrinter' => '/phpunit/TextUI/Output/Printer/NullPrinter.php',
1443 'PHPUnit\\TextUI\\Output\\Printer' => '/phpunit/TextUI/Output/Printer/Printer.php',
1444 'PHPUnit\\TextUI\\Output\\SummaryPrinter' => '/phpunit/TextUI/Output/SummaryPrinter.php',
1445 'PHPUnit\\TextUI\\Output\\TestDox\\ResultPrinter' => '/phpunit/TextUI/Output/TestDox/ResultPrinter.php',
1446 'PHPUnit\\TextUI\\RuntimeException' => '/phpunit/TextUI/Exception/RuntimeException.php',
1447 'PHPUnit\\TextUI\\ShellExitCodeCalculator' => '/phpunit/TextUI/ShellExitCodeCalculator.php',
1448 'PHPUnit\\TextUI\\TestDirectoryNotFoundException' => '/phpunit/TextUI/Exception/TestDirectoryNotFoundException.php',
1449 'PHPUnit\\TextUI\\TestFileNotFoundException' => '/phpunit/TextUI/Exception/TestFileNotFoundException.php',
1450 'PHPUnit\\TextUI\\TestRunner' => '/phpunit/TextUI/TestRunner.php',
1451 'PHPUnit\\TextUI\\TestSuiteFilterProcessor' => '/phpunit/TextUI/TestSuiteFilterProcessor.php',
1452 'PHPUnit\\TextUI\\XmlConfiguration\\CannotFindSchemaException' => '/phpunit/TextUI/Configuration/Exception/CannotFindSchemaException.php',
1453 'PHPUnit\\TextUI\\XmlConfiguration\\CodeCoverage\\CodeCoverage' => '/phpunit/TextUI/Configuration/Xml/CodeCoverage/CodeCoverage.php',
1454 'PHPUnit\\TextUI\\XmlConfiguration\\CodeCoverage\\Report\\Clover' => '/phpunit/TextUI/Configuration/Xml/CodeCoverage/Report/Clover.php',
1455 'PHPUnit\\TextUI\\XmlConfiguration\\CodeCoverage\\Report\\Cobertura' => '/phpunit/TextUI/Configuration/Xml/CodeCoverage/Report/Cobertura.php',
1456 'PHPUnit\\TextUI\\XmlConfiguration\\CodeCoverage\\Report\\Crap4j' => '/phpunit/TextUI/Configuration/Xml/CodeCoverage/Report/Crap4j.php',
1457 'PHPUnit\\TextUI\\XmlConfiguration\\CodeCoverage\\Report\\Html' => '/phpunit/TextUI/Configuration/Xml/CodeCoverage/Report/Html.php',
1458 'PHPUnit\\TextUI\\XmlConfiguration\\CodeCoverage\\Report\\Php' => '/phpunit/TextUI/Configuration/Xml/CodeCoverage/Report/Php.php',
1459 'PHPUnit\\TextUI\\XmlConfiguration\\CodeCoverage\\Report\\Text' => '/phpunit/TextUI/Configuration/Xml/CodeCoverage/Report/Text.php',
1460 'PHPUnit\\TextUI\\XmlConfiguration\\CodeCoverage\\Report\\Xml' => '/phpunit/TextUI/Configuration/Xml/CodeCoverage/Report/Xml.php',
1461 'PHPUnit\\TextUI\\XmlConfiguration\\Configuration' => '/phpunit/TextUI/Configuration/Xml/Configuration.php',
1462 'PHPUnit\\TextUI\\XmlConfiguration\\ConvertLogTypes' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/ConvertLogTypes.php',
1463 'PHPUnit\\TextUI\\XmlConfiguration\\CoverageCloverToReport' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/CoverageCloverToReport.php',
1464 'PHPUnit\\TextUI\\XmlConfiguration\\CoverageCrap4jToReport' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/CoverageCrap4jToReport.php',
1465 'PHPUnit\\TextUI\\XmlConfiguration\\CoverageHtmlToReport' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/CoverageHtmlToReport.php',
1466 'PHPUnit\\TextUI\\XmlConfiguration\\CoveragePhpToReport' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/CoveragePhpToReport.php',
1467 'PHPUnit\\TextUI\\XmlConfiguration\\CoverageTextToReport' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/CoverageTextToReport.php',
1468 'PHPUnit\\TextUI\\XmlConfiguration\\CoverageXmlToReport' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/CoverageXmlToReport.php',
1469 'PHPUnit\\TextUI\\XmlConfiguration\\DefaultConfiguration' => '/phpunit/TextUI/Configuration/Xml/DefaultConfiguration.php',
1470 'PHPUnit\\TextUI\\XmlConfiguration\\Exception' => '/phpunit/TextUI/Configuration/Xml/Exception.php',
1471 'PHPUnit\\TextUI\\XmlConfiguration\\FailedSchemaDetectionResult' => '/phpunit/TextUI/Configuration/Xml/SchemaDetector/FailedSchemaDetectionResult.php',
1472 'PHPUnit\\TextUI\\XmlConfiguration\\Generator' => '/phpunit/TextUI/Configuration/Xml/Generator.php',
1473 'PHPUnit\\TextUI\\XmlConfiguration\\Groups' => '/phpunit/TextUI/Configuration/Xml/Groups.php',
1474 'PHPUnit\\TextUI\\XmlConfiguration\\IntroduceCacheDirectoryAttribute' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/IntroduceCacheDirectoryAttribute.php',
1475 'PHPUnit\\TextUI\\XmlConfiguration\\IntroduceCoverageElement' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/IntroduceCoverageElement.php',
1476 'PHPUnit\\TextUI\\XmlConfiguration\\LoadedFromFileConfiguration' => '/phpunit/TextUI/Configuration/Xml/LoadedFromFileConfiguration.php',
1477 'PHPUnit\\TextUI\\XmlConfiguration\\Loader' => '/phpunit/TextUI/Configuration/Xml/Loader.php',
1478 'PHPUnit\\TextUI\\XmlConfiguration\\LogToReportMigration' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/LogToReportMigration.php',
1479 'PHPUnit\\TextUI\\XmlConfiguration\\Logging\\Junit' => '/phpunit/TextUI/Configuration/Xml/Logging/Junit.php',
1480 'PHPUnit\\TextUI\\XmlConfiguration\\Logging\\Logging' => '/phpunit/TextUI/Configuration/Xml/Logging/Logging.php',
1481 'PHPUnit\\TextUI\\XmlConfiguration\\Logging\\TeamCity' => '/phpunit/TextUI/Configuration/Xml/Logging/TeamCity.php',
1482 'PHPUnit\\TextUI\\XmlConfiguration\\Logging\\TestDox\\Html' => '/phpunit/TextUI/Configuration/Xml/Logging/TestDox/Html.php',
1483 'PHPUnit\\TextUI\\XmlConfiguration\\Logging\\TestDox\\Text' => '/phpunit/TextUI/Configuration/Xml/Logging/TestDox/Text.php',
1484 'PHPUnit\\TextUI\\XmlConfiguration\\Migration' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/Migration.php',
1485 'PHPUnit\\TextUI\\XmlConfiguration\\MigrationBuilder' => '/phpunit/TextUI/Configuration/Xml/Migration/MigrationBuilder.php',
1486 'PHPUnit\\TextUI\\XmlConfiguration\\MigrationException' => '/phpunit/TextUI/Configuration/Xml/Migration/MigrationException.php',
1487 'PHPUnit\\TextUI\\XmlConfiguration\\Migrator' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrator.php',
1488 'PHPUnit\\TextUI\\XmlConfiguration\\MoveAttributesFromFilterWhitelistToCoverage' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/MoveAttributesFromFilterWhitelistToCoverage.php',
1489 'PHPUnit\\TextUI\\XmlConfiguration\\MoveAttributesFromRootToCoverage' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/MoveAttributesFromRootToCoverage.php',
1490 'PHPUnit\\TextUI\\XmlConfiguration\\MoveCoverageDirectoriesToSource' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/MoveCoverageDirectoriesToSource.php',
1491 'PHPUnit\\TextUI\\XmlConfiguration\\MoveWhitelistExcludesToCoverage' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/MoveWhitelistExcludesToCoverage.php',
1492 'PHPUnit\\TextUI\\XmlConfiguration\\MoveWhitelistIncludesToCoverage' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/MoveWhitelistIncludesToCoverage.php',
1493 'PHPUnit\\TextUI\\XmlConfiguration\\PHPUnit' => '/phpunit/TextUI/Configuration/Xml/PHPUnit.php',
1494 'PHPUnit\\TextUI\\XmlConfiguration\\RemoveBeStrictAboutResourceUsageDuringSmallTestsAttribute' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveBeStrictAboutResourceUsageDuringSmallTestsAttribute.php',
1495 'PHPUnit\\TextUI\\XmlConfiguration\\RemoveBeStrictAboutTodoAnnotatedTestsAttribute' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveBeStrictAboutTodoAnnotatedTestsAttribute.php',
1496 'PHPUnit\\TextUI\\XmlConfiguration\\RemoveCacheResultFileAttribute' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveCacheResultFileAttribute.php',
1497 'PHPUnit\\TextUI\\XmlConfiguration\\RemoveCacheTokensAttribute' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveCacheTokensAttribute.php',
1498 'PHPUnit\\TextUI\\XmlConfiguration\\RemoveConversionToExceptionsAttributes' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveConversionToExceptionsAttributes.php',
1499 'PHPUnit\\TextUI\\XmlConfiguration\\RemoveCoverageElementCacheDirectoryAttribute' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveCoverageElementCacheDirectoryAttribute.php',
1500 'PHPUnit\\TextUI\\XmlConfiguration\\RemoveCoverageElementProcessUncoveredFilesAttribute' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveCoverageElementProcessUncoveredFilesAttribute.php',
1501 'PHPUnit\\TextUI\\XmlConfiguration\\RemoveEmptyFilter' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveEmptyFilter.php',
1502 'PHPUnit\\TextUI\\XmlConfiguration\\RemoveListeners' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveListeners.php',
1503 'PHPUnit\\TextUI\\XmlConfiguration\\RemoveLogTypes' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveLogTypes.php',
1504 'PHPUnit\\TextUI\\XmlConfiguration\\RemoveLoggingElements' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveLoggingElements.php',
1505 'PHPUnit\\TextUI\\XmlConfiguration\\RemoveNoInteractionAttribute' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveNoInteractionAttribute.php',
1506 'PHPUnit\\TextUI\\XmlConfiguration\\RemovePrinterAttributes' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/RemovePrinterAttributes.php',
1507 'PHPUnit\\TextUI\\XmlConfiguration\\RemoveTestDoxGroupsElement' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveTestDoxGroupsElement.php',
1508 'PHPUnit\\TextUI\\XmlConfiguration\\RemoveTestSuiteLoaderAttributes' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveTestSuiteLoaderAttributes.php',
1509 'PHPUnit\\TextUI\\XmlConfiguration\\RemoveVerboseAttribute' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveVerboseAttribute.php',
1510 'PHPUnit\\TextUI\\XmlConfiguration\\RenameBackupStaticAttributesAttribute' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/RenameBackupStaticAttributesAttribute.php',
1511 'PHPUnit\\TextUI\\XmlConfiguration\\RenameBeStrictAboutCoversAnnotationAttribute' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/RenameBeStrictAboutCoversAnnotationAttribute.php',
1512 'PHPUnit\\TextUI\\XmlConfiguration\\RenameForceCoversAnnotationAttribute' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/RenameForceCoversAnnotationAttribute.php',
1513 'PHPUnit\\TextUI\\XmlConfiguration\\SchemaDetectionResult' => '/phpunit/TextUI/Configuration/Xml/SchemaDetector/SchemaDetectionResult.php',
1514 'PHPUnit\\TextUI\\XmlConfiguration\\SchemaDetector' => '/phpunit/TextUI/Configuration/Xml/SchemaDetector/SchemaDetector.php',
1515 'PHPUnit\\TextUI\\XmlConfiguration\\SchemaFinder' => '/phpunit/TextUI/Configuration/Xml/SchemaFinder.php',
1516 'PHPUnit\\TextUI\\XmlConfiguration\\SnapshotNodeList' => '/phpunit/TextUI/Configuration/Xml/Migration/SnapshotNodeList.php',
1517 'PHPUnit\\TextUI\\XmlConfiguration\\SuccessfulSchemaDetectionResult' => '/phpunit/TextUI/Configuration/Xml/SchemaDetector/SuccessfulSchemaDetectionResult.php',
1518 'PHPUnit\\TextUI\\XmlConfiguration\\TestSuiteMapper' => '/phpunit/TextUI/Configuration/Xml/TestSuiteMapper.php',
1519 'PHPUnit\\TextUI\\XmlConfiguration\\UpdateSchemaLocation' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/UpdateSchemaLocation.php',
1520 'PHPUnit\\TextUI\\XmlConfiguration\\ValidationResult' => '/phpunit/TextUI/Configuration/Xml/Validator/ValidationResult.php',
1521 'PHPUnit\\TextUI\\XmlConfiguration\\Validator' => '/phpunit/TextUI/Configuration/Xml/Validator/Validator.php',
1522 'PHPUnit\\Util\\Cloner' => '/phpunit/Util/Cloner.php',
1523 'PHPUnit\\Util\\Color' => '/phpunit/Util/Color.php',
1524 'PHPUnit\\Util\\Exception' => '/phpunit/Util/Exception/Exception.php',
1525 'PHPUnit\\Util\\ExcludeList' => '/phpunit/Util/ExcludeList.php',
1526 'PHPUnit\\Util\\Exporter' => '/phpunit/Util/Exporter.php',
1527 'PHPUnit\\Util\\Filesystem' => '/phpunit/Util/Filesystem.php',
1528 'PHPUnit\\Util\\Filter' => '/phpunit/Util/Filter.php',
1529 'PHPUnit\\Util\\GlobalState' => '/phpunit/Util/GlobalState.php',
1530 'PHPUnit\\Util\\Http\\Downloader' => '/phpunit/Util/Http/Downloader.php',
1531 'PHPUnit\\Util\\Http\\PhpDownloader' => '/phpunit/Util/Http/PhpDownloader.php',
1532 'PHPUnit\\Util\\InvalidDirectoryException' => '/phpunit/Util/Exception/InvalidDirectoryException.php',
1533 'PHPUnit\\Util\\InvalidJsonException' => '/phpunit/Util/Exception/InvalidJsonException.php',
1534 'PHPUnit\\Util\\InvalidVersionOperatorException' => '/phpunit/Util/Exception/InvalidVersionOperatorException.php',
1535 'PHPUnit\\Util\\Json' => '/phpunit/Util/Json.php',
1536 'PHPUnit\\Util\\PHP\\AbstractPhpProcess' => '/phpunit/Util/PHP/AbstractPhpProcess.php',
1537 'PHPUnit\\Util\\PHP\\DefaultPhpProcess' => '/phpunit/Util/PHP/DefaultPhpProcess.php',
1538 'PHPUnit\\Util\\PHP\\PhpProcessException' => '/phpunit/Util/Exception/PhpProcessException.php',
1539 'PHPUnit\\Util\\Reflection' => '/phpunit/Util/Reflection.php',
1540 'PHPUnit\\Util\\Test' => '/phpunit/Util/Test.php',
1541 'PHPUnit\\Util\\ThrowableToStringMapper' => '/phpunit/Util/ThrowableToStringMapper.php',
1542 'PHPUnit\\Util\\VersionComparisonOperator' => '/phpunit/Util/VersionComparisonOperator.php',
1543 'PHPUnit\\Util\\Xml' => '/phpunit/Util/Xml/Xml.php',
1544 'PHPUnit\\Util\\Xml\\Loader' => '/phpunit/Util/Xml/Loader.php',
1545 'PHPUnit\\Util\\Xml\\XmlException' => '/phpunit/Util/Exception/XmlException.php'];
1546 }
1547
1548 if (isset($classes[$class])) {
1549 require_once 'phar://phpunit-10.5.63.phar' . $classes[$class];
1550 }
1551 },
1552 true,
1553 false
1554 );
1555
1556 foreach (['PHPUnitPHAR\\DeepCopy\\DeepCopy' => '/myclabs-deep-copy/DeepCopy/DeepCopy.php',
1557 'PHPUnitPHAR\\DeepCopy\\Exception\\CloneException' => '/myclabs-deep-copy/DeepCopy/Exception/CloneException.php',
1558 'PHPUnitPHAR\\DeepCopy\\Exception\\PropertyException' => '/myclabs-deep-copy/DeepCopy/Exception/PropertyException.php',
1559 'PHPUnitPHAR\\DeepCopy\\Filter\\ChainableFilter' => '/myclabs-deep-copy/DeepCopy/Filter/ChainableFilter.php',
1560 'PHPUnitPHAR\\DeepCopy\\Filter\\Doctrine\\DoctrineCollectionFilter' => '/myclabs-deep-copy/DeepCopy/Filter/Doctrine/DoctrineCollectionFilter.php',
1561 'PHPUnitPHAR\\DeepCopy\\Filter\\Doctrine\\DoctrineEmptyCollectionFilter' => '/myclabs-deep-copy/DeepCopy/Filter/Doctrine/DoctrineEmptyCollectionFilter.php',
1562 'PHPUnitPHAR\\DeepCopy\\Filter\\Doctrine\\DoctrineProxyFilter' => '/myclabs-deep-copy/DeepCopy/Filter/Doctrine/DoctrineProxyFilter.php',
1563 'PHPUnitPHAR\\DeepCopy\\Filter\\Filter' => '/myclabs-deep-copy/DeepCopy/Filter/Filter.php',
1564 'PHPUnitPHAR\\DeepCopy\\Filter\\KeepFilter' => '/myclabs-deep-copy/DeepCopy/Filter/KeepFilter.php',
1565 'PHPUnitPHAR\\DeepCopy\\Filter\\ReplaceFilter' => '/myclabs-deep-copy/DeepCopy/Filter/ReplaceFilter.php',
1566 'PHPUnitPHAR\\DeepCopy\\Filter\\SetNullFilter' => '/myclabs-deep-copy/DeepCopy/Filter/SetNullFilter.php',
1567 'PHPUnitPHAR\\DeepCopy\\Matcher\\Doctrine\\DoctrineProxyMatcher' => '/myclabs-deep-copy/DeepCopy/Matcher/Doctrine/DoctrineProxyMatcher.php',
1568 'PHPUnitPHAR\\DeepCopy\\Matcher\\Matcher' => '/myclabs-deep-copy/DeepCopy/Matcher/Matcher.php',
1569 'PHPUnitPHAR\\DeepCopy\\Matcher\\PropertyMatcher' => '/myclabs-deep-copy/DeepCopy/Matcher/PropertyMatcher.php',
1570 'PHPUnitPHAR\\DeepCopy\\Matcher\\PropertyNameMatcher' => '/myclabs-deep-copy/DeepCopy/Matcher/PropertyNameMatcher.php',
1571 'PHPUnitPHAR\\DeepCopy\\Matcher\\PropertyTypeMatcher' => '/myclabs-deep-copy/DeepCopy/Matcher/PropertyTypeMatcher.php',
1572 'PHPUnitPHAR\\DeepCopy\\Reflection\\ReflectionHelper' => '/myclabs-deep-copy/DeepCopy/Reflection/ReflectionHelper.php',
1573 'PHPUnitPHAR\\DeepCopy\\TypeFilter\\Date\\DateIntervalFilter' => '/myclabs-deep-copy/DeepCopy/TypeFilter/Date/DateIntervalFilter.php',
1574 'PHPUnitPHAR\\DeepCopy\\TypeFilter\\Date\\DatePeriodFilter' => '/myclabs-deep-copy/DeepCopy/TypeFilter/Date/DatePeriodFilter.php',
1575 'PHPUnitPHAR\\DeepCopy\\TypeFilter\\ReplaceFilter' => '/myclabs-deep-copy/DeepCopy/TypeFilter/ReplaceFilter.php',
1576 'PHPUnitPHAR\\DeepCopy\\TypeFilter\\ShallowCopyFilter' => '/myclabs-deep-copy/DeepCopy/TypeFilter/ShallowCopyFilter.php',
1577 'PHPUnitPHAR\\DeepCopy\\TypeFilter\\Spl\\ArrayObjectFilter' => '/myclabs-deep-copy/DeepCopy/TypeFilter/Spl/ArrayObjectFilter.php',
1578 'PHPUnitPHAR\\DeepCopy\\TypeFilter\\Spl\\SplDoublyLinkedList' => '/myclabs-deep-copy/DeepCopy/TypeFilter/Spl/SplDoublyLinkedList.php',
1579 'PHPUnitPHAR\\DeepCopy\\TypeFilter\\Spl\\SplDoublyLinkedListFilter' => '/myclabs-deep-copy/DeepCopy/TypeFilter/Spl/SplDoublyLinkedListFilter.php',
1580 'PHPUnitPHAR\\DeepCopy\\TypeFilter\\TypeFilter' => '/myclabs-deep-copy/DeepCopy/TypeFilter/TypeFilter.php',
1581 'PHPUnitPHAR\\DeepCopy\\TypeMatcher\\TypeMatcher' => '/myclabs-deep-copy/DeepCopy/TypeMatcher/TypeMatcher.php',
1582 'PHPUnitPHAR\\PharIo\\Manifest\\Application' => '/phar-io-manifest/values/Application.php',
1583 'PHPUnitPHAR\\PharIo\\Manifest\\ApplicationName' => '/phar-io-manifest/values/ApplicationName.php',
1584 'PHPUnitPHAR\\PharIo\\Manifest\\Author' => '/phar-io-manifest/values/Author.php',
1585 'PHPUnitPHAR\\PharIo\\Manifest\\AuthorCollection' => '/phar-io-manifest/values/AuthorCollection.php',
1586 'PHPUnitPHAR\\PharIo\\Manifest\\AuthorCollectionIterator' => '/phar-io-manifest/values/AuthorCollectionIterator.php',
1587 'PHPUnitPHAR\\PharIo\\Manifest\\AuthorElement' => '/phar-io-manifest/xml/AuthorElement.php',
1588 'PHPUnitPHAR\\PharIo\\Manifest\\AuthorElementCollection' => '/phar-io-manifest/xml/AuthorElementCollection.php',
1589 'PHPUnitPHAR\\PharIo\\Manifest\\BundledComponent' => '/phar-io-manifest/values/BundledComponent.php',
1590 'PHPUnitPHAR\\PharIo\\Manifest\\BundledComponentCollection' => '/phar-io-manifest/values/BundledComponentCollection.php',
1591 'PHPUnitPHAR\\PharIo\\Manifest\\BundledComponentCollectionIterator' => '/phar-io-manifest/values/BundledComponentCollectionIterator.php',
1592 'PHPUnitPHAR\\PharIo\\Manifest\\BundlesElement' => '/phar-io-manifest/xml/BundlesElement.php',
1593 'PHPUnitPHAR\\PharIo\\Manifest\\ComponentElement' => '/phar-io-manifest/xml/ComponentElement.php',
1594 'PHPUnitPHAR\\PharIo\\Manifest\\ComponentElementCollection' => '/phar-io-manifest/xml/ComponentElementCollection.php',
1595 'PHPUnitPHAR\\PharIo\\Manifest\\ContainsElement' => '/phar-io-manifest/xml/ContainsElement.php',
1596 'PHPUnitPHAR\\PharIo\\Manifest\\CopyrightElement' => '/phar-io-manifest/xml/CopyrightElement.php',
1597 'PHPUnitPHAR\\PharIo\\Manifest\\CopyrightInformation' => '/phar-io-manifest/values/CopyrightInformation.php',
1598 'PHPUnitPHAR\\PharIo\\Manifest\\ElementCollection' => '/phar-io-manifest/xml/ElementCollection.php',
1599 'PHPUnitPHAR\\PharIo\\Manifest\\ElementCollectionException' => '/phar-io-manifest/exceptions/ElementCollectionException.php',
1600 'PHPUnitPHAR\\PharIo\\Manifest\\Email' => '/phar-io-manifest/values/Email.php',
1601 'PHPUnitPHAR\\PharIo\\Manifest\\Exception' => '/phar-io-manifest/exceptions/Exception.php',
1602 'PHPUnitPHAR\\PharIo\\Manifest\\ExtElement' => '/phar-io-manifest/xml/ExtElement.php',
1603 'PHPUnitPHAR\\PharIo\\Manifest\\ExtElementCollection' => '/phar-io-manifest/xml/ExtElementCollection.php',
1604 'PHPUnitPHAR\\PharIo\\Manifest\\Extension' => '/phar-io-manifest/values/Extension.php',
1605 'PHPUnitPHAR\\PharIo\\Manifest\\ExtensionElement' => '/phar-io-manifest/xml/ExtensionElement.php',
1606 'PHPUnitPHAR\\PharIo\\Manifest\\InvalidApplicationNameException' => '/phar-io-manifest/exceptions/InvalidApplicationNameException.php',
1607 'PHPUnitPHAR\\PharIo\\Manifest\\InvalidEmailException' => '/phar-io-manifest/exceptions/InvalidEmailException.php',
1608 'PHPUnitPHAR\\PharIo\\Manifest\\InvalidUrlException' => '/phar-io-manifest/exceptions/InvalidUrlException.php',
1609 'PHPUnitPHAR\\PharIo\\Manifest\\Library' => '/phar-io-manifest/values/Library.php',
1610 'PHPUnitPHAR\\PharIo\\Manifest\\License' => '/phar-io-manifest/values/License.php',
1611 'PHPUnitPHAR\\PharIo\\Manifest\\LicenseElement' => '/phar-io-manifest/xml/LicenseElement.php',
1612 'PHPUnitPHAR\\PharIo\\Manifest\\Manifest' => '/phar-io-manifest/values/Manifest.php',
1613 'PHPUnitPHAR\\PharIo\\Manifest\\ManifestDocument' => '/phar-io-manifest/xml/ManifestDocument.php',
1614 'PHPUnitPHAR\\PharIo\\Manifest\\ManifestDocumentException' => '/phar-io-manifest/exceptions/ManifestDocumentException.php',
1615 'PHPUnitPHAR\\PharIo\\Manifest\\ManifestDocumentLoadingException' => '/phar-io-manifest/exceptions/ManifestDocumentLoadingException.php',
1616 'PHPUnitPHAR\\PharIo\\Manifest\\ManifestDocumentMapper' => '/phar-io-manifest/ManifestDocumentMapper.php',
1617 'PHPUnitPHAR\\PharIo\\Manifest\\ManifestDocumentMapperException' => '/phar-io-manifest/exceptions/ManifestDocumentMapperException.php',
1618 'PHPUnitPHAR\\PharIo\\Manifest\\ManifestElement' => '/phar-io-manifest/xml/ManifestElement.php',
1619 'PHPUnitPHAR\\PharIo\\Manifest\\ManifestElementException' => '/phar-io-manifest/exceptions/ManifestElementException.php',
1620 'PHPUnitPHAR\\PharIo\\Manifest\\ManifestLoader' => '/phar-io-manifest/ManifestLoader.php',
1621 'PHPUnitPHAR\\PharIo\\Manifest\\ManifestLoaderException' => '/phar-io-manifest/exceptions/ManifestLoaderException.php',
1622 'PHPUnitPHAR\\PharIo\\Manifest\\ManifestSerializer' => '/phar-io-manifest/ManifestSerializer.php',
1623 'PHPUnitPHAR\\PharIo\\Manifest\\NoEmailAddressException' => '/phar-io-manifest/exceptions/NoEmailAddressException.php',
1624 'PHPUnitPHAR\\PharIo\\Manifest\\PhpElement' => '/phar-io-manifest/xml/PhpElement.php',
1625 'PHPUnitPHAR\\PharIo\\Manifest\\PhpExtensionRequirement' => '/phar-io-manifest/values/PhpExtensionRequirement.php',
1626 'PHPUnitPHAR\\PharIo\\Manifest\\PhpVersionRequirement' => '/phar-io-manifest/values/PhpVersionRequirement.php',
1627 'PHPUnitPHAR\\PharIo\\Manifest\\Requirement' => '/phar-io-manifest/values/Requirement.php',
1628 'PHPUnitPHAR\\PharIo\\Manifest\\RequirementCollection' => '/phar-io-manifest/values/RequirementCollection.php',
1629 'PHPUnitPHAR\\PharIo\\Manifest\\RequirementCollectionIterator' => '/phar-io-manifest/values/RequirementCollectionIterator.php',
1630 'PHPUnitPHAR\\PharIo\\Manifest\\RequiresElement' => '/phar-io-manifest/xml/RequiresElement.php',
1631 'PHPUnitPHAR\\PharIo\\Manifest\\Type' => '/phar-io-manifest/values/Type.php',
1632 'PHPUnitPHAR\\PharIo\\Manifest\\Url' => '/phar-io-manifest/values/Url.php',
1633 'PHPUnitPHAR\\PharIo\\Version\\AbstractVersionConstraint' => '/phar-io-version/constraints/AbstractVersionConstraint.php',
1634 'PHPUnitPHAR\\PharIo\\Version\\AndVersionConstraintGroup' => '/phar-io-version/constraints/AndVersionConstraintGroup.php',
1635 'PHPUnitPHAR\\PharIo\\Version\\AnyVersionConstraint' => '/phar-io-version/constraints/AnyVersionConstraint.php',
1636 'PHPUnitPHAR\\PharIo\\Version\\BuildMetaData' => '/phar-io-version/BuildMetaData.php',
1637 'PHPUnitPHAR\\PharIo\\Version\\ExactVersionConstraint' => '/phar-io-version/constraints/ExactVersionConstraint.php',
1638 'PHPUnitPHAR\\PharIo\\Version\\Exception' => '/phar-io-version/exceptions/Exception.php',
1639 'PHPUnitPHAR\\PharIo\\Version\\GreaterThanOrEqualToVersionConstraint' => '/phar-io-version/constraints/GreaterThanOrEqualToVersionConstraint.php',
1640 'PHPUnitPHAR\\PharIo\\Version\\InvalidPreReleaseSuffixException' => '/phar-io-version/exceptions/InvalidPreReleaseSuffixException.php',
1641 'PHPUnitPHAR\\PharIo\\Version\\InvalidVersionException' => '/phar-io-version/exceptions/InvalidVersionException.php',
1642 'PHPUnitPHAR\\PharIo\\Version\\NoBuildMetaDataException' => '/phar-io-version/exceptions/NoBuildMetaDataException.php',
1643 'PHPUnitPHAR\\PharIo\\Version\\NoPreReleaseSuffixException' => '/phar-io-version/exceptions/NoPreReleaseSuffixException.php',
1644 'PHPUnitPHAR\\PharIo\\Version\\OrVersionConstraintGroup' => '/phar-io-version/constraints/OrVersionConstraintGroup.php',
1645 'PHPUnitPHAR\\PharIo\\Version\\PreReleaseSuffix' => '/phar-io-version/PreReleaseSuffix.php',
1646 'PHPUnitPHAR\\PharIo\\Version\\SpecificMajorAndMinorVersionConstraint' => '/phar-io-version/constraints/SpecificMajorAndMinorVersionConstraint.php',
1647 'PHPUnitPHAR\\PharIo\\Version\\SpecificMajorVersionConstraint' => '/phar-io-version/constraints/SpecificMajorVersionConstraint.php',
1648 'PHPUnitPHAR\\PharIo\\Version\\UnsupportedVersionConstraintException' => '/phar-io-version/exceptions/UnsupportedVersionConstraintException.php',
1649 'PHPUnitPHAR\\PharIo\\Version\\Version' => '/phar-io-version/Version.php',
1650 'PHPUnitPHAR\\PharIo\\Version\\VersionConstraint' => '/phar-io-version/constraints/VersionConstraint.php',
1651 'PHPUnitPHAR\\PharIo\\Version\\VersionConstraintParser' => '/phar-io-version/VersionConstraintParser.php',
1652 'PHPUnitPHAR\\PharIo\\Version\\VersionConstraintValue' => '/phar-io-version/VersionConstraintValue.php',
1653 'PHPUnitPHAR\\PharIo\\Version\\VersionNumber' => '/phar-io-version/VersionNumber.php',
1654 'PHPUnitPHAR\\PhpParser\\Builder' => '/nikic-php-parser/PhpParser/Builder.php',
1655 'PHPUnitPHAR\\PhpParser\\BuilderFactory' => '/nikic-php-parser/PhpParser/BuilderFactory.php',
1656 'PHPUnitPHAR\\PhpParser\\BuilderHelpers' => '/nikic-php-parser/PhpParser/BuilderHelpers.php',
1657 'PHPUnitPHAR\\PhpParser\\Builder\\ClassConst' => '/nikic-php-parser/PhpParser/Builder/ClassConst.php',
1658 'PHPUnitPHAR\\PhpParser\\Builder\\Class_' => '/nikic-php-parser/PhpParser/Builder/Class_.php',
1659 'PHPUnitPHAR\\PhpParser\\Builder\\Declaration' => '/nikic-php-parser/PhpParser/Builder/Declaration.php',
1660 'PHPUnitPHAR\\PhpParser\\Builder\\EnumCase' => '/nikic-php-parser/PhpParser/Builder/EnumCase.php',
1661 'PHPUnitPHAR\\PhpParser\\Builder\\Enum_' => '/nikic-php-parser/PhpParser/Builder/Enum_.php',
1662 'PHPUnitPHAR\\PhpParser\\Builder\\FunctionLike' => '/nikic-php-parser/PhpParser/Builder/FunctionLike.php',
1663 'PHPUnitPHAR\\PhpParser\\Builder\\Function_' => '/nikic-php-parser/PhpParser/Builder/Function_.php',
1664 'PHPUnitPHAR\\PhpParser\\Builder\\Interface_' => '/nikic-php-parser/PhpParser/Builder/Interface_.php',
1665 'PHPUnitPHAR\\PhpParser\\Builder\\Method' => '/nikic-php-parser/PhpParser/Builder/Method.php',
1666 'PHPUnitPHAR\\PhpParser\\Builder\\Namespace_' => '/nikic-php-parser/PhpParser/Builder/Namespace_.php',
1667 'PHPUnitPHAR\\PhpParser\\Builder\\Param' => '/nikic-php-parser/PhpParser/Builder/Param.php',
1668 'PHPUnitPHAR\\PhpParser\\Builder\\Property' => '/nikic-php-parser/PhpParser/Builder/Property.php',
1669 'PHPUnitPHAR\\PhpParser\\Builder\\TraitUse' => '/nikic-php-parser/PhpParser/Builder/TraitUse.php',
1670 'PHPUnitPHAR\\PhpParser\\Builder\\TraitUseAdaptation' => '/nikic-php-parser/PhpParser/Builder/TraitUseAdaptation.php',
1671 'PHPUnitPHAR\\PhpParser\\Builder\\Trait_' => '/nikic-php-parser/PhpParser/Builder/Trait_.php',
1672 'PHPUnitPHAR\\PhpParser\\Builder\\Use_' => '/nikic-php-parser/PhpParser/Builder/Use_.php',
1673 'PHPUnitPHAR\\PhpParser\\Comment' => '/nikic-php-parser/PhpParser/Comment.php',
1674 'PHPUnitPHAR\\PhpParser\\Comment\\Doc' => '/nikic-php-parser/PhpParser/Comment/Doc.php',
1675 'PHPUnitPHAR\\PhpParser\\ConstExprEvaluationException' => '/nikic-php-parser/PhpParser/ConstExprEvaluationException.php',
1676 'PHPUnitPHAR\\PhpParser\\ConstExprEvaluator' => '/nikic-php-parser/PhpParser/ConstExprEvaluator.php',
1677 'PHPUnitPHAR\\PhpParser\\Error' => '/nikic-php-parser/PhpParser/Error.php',
1678 'PHPUnitPHAR\\PhpParser\\ErrorHandler' => '/nikic-php-parser/PhpParser/ErrorHandler.php',
1679 'PHPUnitPHAR\\PhpParser\\ErrorHandler\\Collecting' => '/nikic-php-parser/PhpParser/ErrorHandler/Collecting.php',
1680 'PHPUnitPHAR\\PhpParser\\ErrorHandler\\Throwing' => '/nikic-php-parser/PhpParser/ErrorHandler/Throwing.php',
1681 'PHPUnitPHAR\\PhpParser\\Internal\\DiffElem' => '/nikic-php-parser/PhpParser/Internal/DiffElem.php',
1682 'PHPUnitPHAR\\PhpParser\\Internal\\Differ' => '/nikic-php-parser/PhpParser/Internal/Differ.php',
1683 'PHPUnitPHAR\\PhpParser\\Internal\\PrintableNewAnonClassNode' => '/nikic-php-parser/PhpParser/Internal/PrintableNewAnonClassNode.php',
1684 'PHPUnitPHAR\\PhpParser\\Internal\\TokenPolyfill' => '/nikic-php-parser/PhpParser/Internal/TokenPolyfill.php',
1685 'PHPUnitPHAR\\PhpParser\\Internal\\TokenStream' => '/nikic-php-parser/PhpParser/Internal/TokenStream.php',
1686 'PHPUnitPHAR\\PhpParser\\JsonDecoder' => '/nikic-php-parser/PhpParser/JsonDecoder.php',
1687 'PHPUnitPHAR\\PhpParser\\Lexer' => '/nikic-php-parser/PhpParser/Lexer.php',
1688 'PHPUnitPHAR\\PhpParser\\Lexer\\Emulative' => '/nikic-php-parser/PhpParser/Lexer/Emulative.php',
1689 'PHPUnitPHAR\\PhpParser\\Lexer\\TokenEmulator\\AsymmetricVisibilityTokenEmulator' => '/nikic-php-parser/PhpParser/Lexer/TokenEmulator/AsymmetricVisibilityTokenEmulator.php',
1690 'PHPUnitPHAR\\PhpParser\\Lexer\\TokenEmulator\\AttributeEmulator' => '/nikic-php-parser/PhpParser/Lexer/TokenEmulator/AttributeEmulator.php',
1691 'PHPUnitPHAR\\PhpParser\\Lexer\\TokenEmulator\\EnumTokenEmulator' => '/nikic-php-parser/PhpParser/Lexer/TokenEmulator/EnumTokenEmulator.php',
1692 'PHPUnitPHAR\\PhpParser\\Lexer\\TokenEmulator\\ExplicitOctalEmulator' => '/nikic-php-parser/PhpParser/Lexer/TokenEmulator/ExplicitOctalEmulator.php',
1693 'PHPUnitPHAR\\PhpParser\\Lexer\\TokenEmulator\\KeywordEmulator' => '/nikic-php-parser/PhpParser/Lexer/TokenEmulator/KeywordEmulator.php',
1694 'PHPUnitPHAR\\PhpParser\\Lexer\\TokenEmulator\\MatchTokenEmulator' => '/nikic-php-parser/PhpParser/Lexer/TokenEmulator/MatchTokenEmulator.php',
1695 'PHPUnitPHAR\\PhpParser\\Lexer\\TokenEmulator\\NullsafeTokenEmulator' => '/nikic-php-parser/PhpParser/Lexer/TokenEmulator/NullsafeTokenEmulator.php',
1696 'PHPUnitPHAR\\PhpParser\\Lexer\\TokenEmulator\\PipeOperatorEmulator' => '/nikic-php-parser/PhpParser/Lexer/TokenEmulator/PipeOperatorEmulator.php',
1697 'PHPUnitPHAR\\PhpParser\\Lexer\\TokenEmulator\\PropertyTokenEmulator' => '/nikic-php-parser/PhpParser/Lexer/TokenEmulator/PropertyTokenEmulator.php',
1698 'PHPUnitPHAR\\PhpParser\\Lexer\\TokenEmulator\\ReadonlyFunctionTokenEmulator' => '/nikic-php-parser/PhpParser/Lexer/TokenEmulator/ReadonlyFunctionTokenEmulator.php',
1699 'PHPUnitPHAR\\PhpParser\\Lexer\\TokenEmulator\\ReadonlyTokenEmulator' => '/nikic-php-parser/PhpParser/Lexer/TokenEmulator/ReadonlyTokenEmulator.php',
1700 'PHPUnitPHAR\\PhpParser\\Lexer\\TokenEmulator\\ReverseEmulator' => '/nikic-php-parser/PhpParser/Lexer/TokenEmulator/ReverseEmulator.php',
1701 'PHPUnitPHAR\\PhpParser\\Lexer\\TokenEmulator\\TokenEmulator' => '/nikic-php-parser/PhpParser/Lexer/TokenEmulator/TokenEmulator.php',
1702 'PHPUnitPHAR\\PhpParser\\Lexer\\TokenEmulator\\VoidCastEmulator' => '/nikic-php-parser/PhpParser/Lexer/TokenEmulator/VoidCastEmulator.php',
1703 'PHPUnitPHAR\\PhpParser\\Modifiers' => '/nikic-php-parser/PhpParser/Modifiers.php',
1704 'PHPUnitPHAR\\PhpParser\\NameContext' => '/nikic-php-parser/PhpParser/NameContext.php',
1705 'PHPUnitPHAR\\PhpParser\\Node' => '/nikic-php-parser/PhpParser/Node.php',
1706 'PHPUnitPHAR\\PhpParser\\NodeAbstract' => '/nikic-php-parser/PhpParser/NodeAbstract.php',
1707 'PHPUnitPHAR\\PhpParser\\NodeDumper' => '/nikic-php-parser/PhpParser/NodeDumper.php',
1708 'PHPUnitPHAR\\PhpParser\\NodeFinder' => '/nikic-php-parser/PhpParser/NodeFinder.php',
1709 'PHPUnitPHAR\\PhpParser\\NodeTraverser' => '/nikic-php-parser/PhpParser/NodeTraverser.php',
1710 'PHPUnitPHAR\\PhpParser\\NodeTraverserInterface' => '/nikic-php-parser/PhpParser/NodeTraverserInterface.php',
1711 'PHPUnitPHAR\\PhpParser\\NodeVisitor' => '/nikic-php-parser/PhpParser/NodeVisitor.php',
1712 'PHPUnitPHAR\\PhpParser\\NodeVisitorAbstract' => '/nikic-php-parser/PhpParser/NodeVisitorAbstract.php',
1713 'PHPUnitPHAR\\PhpParser\\NodeVisitor\\CloningVisitor' => '/nikic-php-parser/PhpParser/NodeVisitor/CloningVisitor.php',
1714 'PHPUnitPHAR\\PhpParser\\NodeVisitor\\CommentAnnotatingVisitor' => '/nikic-php-parser/PhpParser/NodeVisitor/CommentAnnotatingVisitor.php',
1715 'PHPUnitPHAR\\PhpParser\\NodeVisitor\\FindingVisitor' => '/nikic-php-parser/PhpParser/NodeVisitor/FindingVisitor.php',
1716 'PHPUnitPHAR\\PhpParser\\NodeVisitor\\FirstFindingVisitor' => '/nikic-php-parser/PhpParser/NodeVisitor/FirstFindingVisitor.php',
1717 'PHPUnitPHAR\\PhpParser\\NodeVisitor\\NameResolver' => '/nikic-php-parser/PhpParser/NodeVisitor/NameResolver.php',
1718 'PHPUnitPHAR\\PhpParser\\NodeVisitor\\NodeConnectingVisitor' => '/nikic-php-parser/PhpParser/NodeVisitor/NodeConnectingVisitor.php',
1719 'PHPUnitPHAR\\PhpParser\\NodeVisitor\\ParentConnectingVisitor' => '/nikic-php-parser/PhpParser/NodeVisitor/ParentConnectingVisitor.php',
1720 'PHPUnitPHAR\\PhpParser\\Node\\Arg' => '/nikic-php-parser/PhpParser/Node/Arg.php',
1721 'PHPUnitPHAR\\PhpParser\\Node\\ArrayItem' => '/nikic-php-parser/PhpParser/Node/ArrayItem.php',
1722 'PHPUnitPHAR\\PhpParser\\Node\\Attribute' => '/nikic-php-parser/PhpParser/Node/Attribute.php',
1723 'PHPUnitPHAR\\PhpParser\\Node\\AttributeGroup' => '/nikic-php-parser/PhpParser/Node/AttributeGroup.php',
1724 'PHPUnitPHAR\\PhpParser\\Node\\ClosureUse' => '/nikic-php-parser/PhpParser/Node/ClosureUse.php',
1725 'PHPUnitPHAR\\PhpParser\\Node\\ComplexType' => '/nikic-php-parser/PhpParser/Node/ComplexType.php',
1726 'PHPUnitPHAR\\PhpParser\\Node\\Const_' => '/nikic-php-parser/PhpParser/Node/Const_.php',
1727 'PHPUnitPHAR\\PhpParser\\Node\\DeclareItem' => '/nikic-php-parser/PhpParser/Node/DeclareItem.php',
1728 'PHPUnitPHAR\\PhpParser\\Node\\Expr' => '/nikic-php-parser/PhpParser/Node/Expr.php',
1729 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\ArrayDimFetch' => '/nikic-php-parser/PhpParser/Node/Expr/ArrayDimFetch.php',
1730 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\Array_' => '/nikic-php-parser/PhpParser/Node/Expr/Array_.php',
1731 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\ArrowFunction' => '/nikic-php-parser/PhpParser/Node/Expr/ArrowFunction.php',
1732 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\Assign' => '/nikic-php-parser/PhpParser/Node/Expr/Assign.php',
1733 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\AssignOp' => '/nikic-php-parser/PhpParser/Node/Expr/AssignOp.php',
1734 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\AssignOp\\BitwiseAnd' => '/nikic-php-parser/PhpParser/Node/Expr/AssignOp/BitwiseAnd.php',
1735 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\AssignOp\\BitwiseOr' => '/nikic-php-parser/PhpParser/Node/Expr/AssignOp/BitwiseOr.php',
1736 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\AssignOp\\BitwiseXor' => '/nikic-php-parser/PhpParser/Node/Expr/AssignOp/BitwiseXor.php',
1737 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\AssignOp\\Coalesce' => '/nikic-php-parser/PhpParser/Node/Expr/AssignOp/Coalesce.php',
1738 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\AssignOp\\Concat' => '/nikic-php-parser/PhpParser/Node/Expr/AssignOp/Concat.php',
1739 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\AssignOp\\Div' => '/nikic-php-parser/PhpParser/Node/Expr/AssignOp/Div.php',
1740 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\AssignOp\\Minus' => '/nikic-php-parser/PhpParser/Node/Expr/AssignOp/Minus.php',
1741 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\AssignOp\\Mod' => '/nikic-php-parser/PhpParser/Node/Expr/AssignOp/Mod.php',
1742 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\AssignOp\\Mul' => '/nikic-php-parser/PhpParser/Node/Expr/AssignOp/Mul.php',
1743 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\AssignOp\\Plus' => '/nikic-php-parser/PhpParser/Node/Expr/AssignOp/Plus.php',
1744 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\AssignOp\\Pow' => '/nikic-php-parser/PhpParser/Node/Expr/AssignOp/Pow.php',
1745 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\AssignOp\\ShiftLeft' => '/nikic-php-parser/PhpParser/Node/Expr/AssignOp/ShiftLeft.php',
1746 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\AssignOp\\ShiftRight' => '/nikic-php-parser/PhpParser/Node/Expr/AssignOp/ShiftRight.php',
1747 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\AssignRef' => '/nikic-php-parser/PhpParser/Node/Expr/AssignRef.php',
1748 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BinaryOp' => '/nikic-php-parser/PhpParser/Node/Expr/BinaryOp.php',
1749 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BinaryOp\\BitwiseAnd' => '/nikic-php-parser/PhpParser/Node/Expr/BinaryOp/BitwiseAnd.php',
1750 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BinaryOp\\BitwiseOr' => '/nikic-php-parser/PhpParser/Node/Expr/BinaryOp/BitwiseOr.php',
1751 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BinaryOp\\BitwiseXor' => '/nikic-php-parser/PhpParser/Node/Expr/BinaryOp/BitwiseXor.php',
1752 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BinaryOp\\BooleanAnd' => '/nikic-php-parser/PhpParser/Node/Expr/BinaryOp/BooleanAnd.php',
1753 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BinaryOp\\BooleanOr' => '/nikic-php-parser/PhpParser/Node/Expr/BinaryOp/BooleanOr.php',
1754 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BinaryOp\\Coalesce' => '/nikic-php-parser/PhpParser/Node/Expr/BinaryOp/Coalesce.php',
1755 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BinaryOp\\Concat' => '/nikic-php-parser/PhpParser/Node/Expr/BinaryOp/Concat.php',
1756 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BinaryOp\\Div' => '/nikic-php-parser/PhpParser/Node/Expr/BinaryOp/Div.php',
1757 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BinaryOp\\Equal' => '/nikic-php-parser/PhpParser/Node/Expr/BinaryOp/Equal.php',
1758 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BinaryOp\\Greater' => '/nikic-php-parser/PhpParser/Node/Expr/BinaryOp/Greater.php',
1759 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BinaryOp\\GreaterOrEqual' => '/nikic-php-parser/PhpParser/Node/Expr/BinaryOp/GreaterOrEqual.php',
1760 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BinaryOp\\Identical' => '/nikic-php-parser/PhpParser/Node/Expr/BinaryOp/Identical.php',
1761 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BinaryOp\\LogicalAnd' => '/nikic-php-parser/PhpParser/Node/Expr/BinaryOp/LogicalAnd.php',
1762 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BinaryOp\\LogicalOr' => '/nikic-php-parser/PhpParser/Node/Expr/BinaryOp/LogicalOr.php',
1763 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BinaryOp\\LogicalXor' => '/nikic-php-parser/PhpParser/Node/Expr/BinaryOp/LogicalXor.php',
1764 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BinaryOp\\Minus' => '/nikic-php-parser/PhpParser/Node/Expr/BinaryOp/Minus.php',
1765 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BinaryOp\\Mod' => '/nikic-php-parser/PhpParser/Node/Expr/BinaryOp/Mod.php',
1766 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BinaryOp\\Mul' => '/nikic-php-parser/PhpParser/Node/Expr/BinaryOp/Mul.php',
1767 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BinaryOp\\NotEqual' => '/nikic-php-parser/PhpParser/Node/Expr/BinaryOp/NotEqual.php',
1768 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BinaryOp\\NotIdentical' => '/nikic-php-parser/PhpParser/Node/Expr/BinaryOp/NotIdentical.php',
1769 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BinaryOp\\Pipe' => '/nikic-php-parser/PhpParser/Node/Expr/BinaryOp/Pipe.php',
1770 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BinaryOp\\Plus' => '/nikic-php-parser/PhpParser/Node/Expr/BinaryOp/Plus.php',
1771 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BinaryOp\\Pow' => '/nikic-php-parser/PhpParser/Node/Expr/BinaryOp/Pow.php',
1772 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BinaryOp\\ShiftLeft' => '/nikic-php-parser/PhpParser/Node/Expr/BinaryOp/ShiftLeft.php',
1773 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BinaryOp\\ShiftRight' => '/nikic-php-parser/PhpParser/Node/Expr/BinaryOp/ShiftRight.php',
1774 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BinaryOp\\Smaller' => '/nikic-php-parser/PhpParser/Node/Expr/BinaryOp/Smaller.php',
1775 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BinaryOp\\SmallerOrEqual' => '/nikic-php-parser/PhpParser/Node/Expr/BinaryOp/SmallerOrEqual.php',
1776 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BinaryOp\\Spaceship' => '/nikic-php-parser/PhpParser/Node/Expr/BinaryOp/Spaceship.php',
1777 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BitwiseNot' => '/nikic-php-parser/PhpParser/Node/Expr/BitwiseNot.php',
1778 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\BooleanNot' => '/nikic-php-parser/PhpParser/Node/Expr/BooleanNot.php',
1779 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\CallLike' => '/nikic-php-parser/PhpParser/Node/Expr/CallLike.php',
1780 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\Cast' => '/nikic-php-parser/PhpParser/Node/Expr/Cast.php',
1781 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\Cast\\Array_' => '/nikic-php-parser/PhpParser/Node/Expr/Cast/Array_.php',
1782 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\Cast\\Bool_' => '/nikic-php-parser/PhpParser/Node/Expr/Cast/Bool_.php',
1783 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\Cast\\Double' => '/nikic-php-parser/PhpParser/Node/Expr/Cast/Double.php',
1784 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\Cast\\Int_' => '/nikic-php-parser/PhpParser/Node/Expr/Cast/Int_.php',
1785 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\Cast\\Object_' => '/nikic-php-parser/PhpParser/Node/Expr/Cast/Object_.php',
1786 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\Cast\\String_' => '/nikic-php-parser/PhpParser/Node/Expr/Cast/String_.php',
1787 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\Cast\\Unset_' => '/nikic-php-parser/PhpParser/Node/Expr/Cast/Unset_.php',
1788 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\Cast\\Void_' => '/nikic-php-parser/PhpParser/Node/Expr/Cast/Void_.php',
1789 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\ClassConstFetch' => '/nikic-php-parser/PhpParser/Node/Expr/ClassConstFetch.php',
1790 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\Clone_' => '/nikic-php-parser/PhpParser/Node/Expr/Clone_.php',
1791 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\Closure' => '/nikic-php-parser/PhpParser/Node/Expr/Closure.php',
1792 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\ConstFetch' => '/nikic-php-parser/PhpParser/Node/Expr/ConstFetch.php',
1793 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\Empty_' => '/nikic-php-parser/PhpParser/Node/Expr/Empty_.php',
1794 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\Error' => '/nikic-php-parser/PhpParser/Node/Expr/Error.php',
1795 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\ErrorSuppress' => '/nikic-php-parser/PhpParser/Node/Expr/ErrorSuppress.php',
1796 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\Eval_' => '/nikic-php-parser/PhpParser/Node/Expr/Eval_.php',
1797 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\Exit_' => '/nikic-php-parser/PhpParser/Node/Expr/Exit_.php',
1798 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\FuncCall' => '/nikic-php-parser/PhpParser/Node/Expr/FuncCall.php',
1799 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\Include_' => '/nikic-php-parser/PhpParser/Node/Expr/Include_.php',
1800 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\Instanceof_' => '/nikic-php-parser/PhpParser/Node/Expr/Instanceof_.php',
1801 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\Isset_' => '/nikic-php-parser/PhpParser/Node/Expr/Isset_.php',
1802 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\List_' => '/nikic-php-parser/PhpParser/Node/Expr/List_.php',
1803 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\Match_' => '/nikic-php-parser/PhpParser/Node/Expr/Match_.php',
1804 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\MethodCall' => '/nikic-php-parser/PhpParser/Node/Expr/MethodCall.php',
1805 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\New_' => '/nikic-php-parser/PhpParser/Node/Expr/New_.php',
1806 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\NullsafeMethodCall' => '/nikic-php-parser/PhpParser/Node/Expr/NullsafeMethodCall.php',
1807 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\NullsafePropertyFetch' => '/nikic-php-parser/PhpParser/Node/Expr/NullsafePropertyFetch.php',
1808 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\PostDec' => '/nikic-php-parser/PhpParser/Node/Expr/PostDec.php',
1809 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\PostInc' => '/nikic-php-parser/PhpParser/Node/Expr/PostInc.php',
1810 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\PreDec' => '/nikic-php-parser/PhpParser/Node/Expr/PreDec.php',
1811 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\PreInc' => '/nikic-php-parser/PhpParser/Node/Expr/PreInc.php',
1812 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\Print_' => '/nikic-php-parser/PhpParser/Node/Expr/Print_.php',
1813 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\PropertyFetch' => '/nikic-php-parser/PhpParser/Node/Expr/PropertyFetch.php',
1814 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\ShellExec' => '/nikic-php-parser/PhpParser/Node/Expr/ShellExec.php',
1815 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\StaticCall' => '/nikic-php-parser/PhpParser/Node/Expr/StaticCall.php',
1816 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\StaticPropertyFetch' => '/nikic-php-parser/PhpParser/Node/Expr/StaticPropertyFetch.php',
1817 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\Ternary' => '/nikic-php-parser/PhpParser/Node/Expr/Ternary.php',
1818 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\Throw_' => '/nikic-php-parser/PhpParser/Node/Expr/Throw_.php',
1819 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\UnaryMinus' => '/nikic-php-parser/PhpParser/Node/Expr/UnaryMinus.php',
1820 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\UnaryPlus' => '/nikic-php-parser/PhpParser/Node/Expr/UnaryPlus.php',
1821 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\Variable' => '/nikic-php-parser/PhpParser/Node/Expr/Variable.php',
1822 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\YieldFrom' => '/nikic-php-parser/PhpParser/Node/Expr/YieldFrom.php',
1823 'PHPUnitPHAR\\PhpParser\\Node\\Expr\\Yield_' => '/nikic-php-parser/PhpParser/Node/Expr/Yield_.php',
1824 'PHPUnitPHAR\\PhpParser\\Node\\FunctionLike' => '/nikic-php-parser/PhpParser/Node/FunctionLike.php',
1825 'PHPUnitPHAR\\PhpParser\\Node\\Identifier' => '/nikic-php-parser/PhpParser/Node/Identifier.php',
1826 'PHPUnitPHAR\\PhpParser\\Node\\InterpolatedStringPart' => '/nikic-php-parser/PhpParser/Node/InterpolatedStringPart.php',
1827 'PHPUnitPHAR\\PhpParser\\Node\\IntersectionType' => '/nikic-php-parser/PhpParser/Node/IntersectionType.php',
1828 'PHPUnitPHAR\\PhpParser\\Node\\MatchArm' => '/nikic-php-parser/PhpParser/Node/MatchArm.php',
1829 'PHPUnitPHAR\\PhpParser\\Node\\Name' => '/nikic-php-parser/PhpParser/Node/Name.php',
1830 'PHPUnitPHAR\\PhpParser\\Node\\Name\\FullyQualified' => '/nikic-php-parser/PhpParser/Node/Name/FullyQualified.php',
1831 'PHPUnitPHAR\\PhpParser\\Node\\Name\\Relative' => '/nikic-php-parser/PhpParser/Node/Name/Relative.php',
1832 'PHPUnitPHAR\\PhpParser\\Node\\NullableType' => '/nikic-php-parser/PhpParser/Node/NullableType.php',
1833 'PHPUnitPHAR\\PhpParser\\Node\\Param' => '/nikic-php-parser/PhpParser/Node/Param.php',
1834 'PHPUnitPHAR\\PhpParser\\Node\\PropertyHook' => '/nikic-php-parser/PhpParser/Node/PropertyHook.php',
1835 'PHPUnitPHAR\\PhpParser\\Node\\PropertyItem' => '/nikic-php-parser/PhpParser/Node/PropertyItem.php',
1836 'PHPUnitPHAR\\PhpParser\\Node\\Scalar' => '/nikic-php-parser/PhpParser/Node/Scalar.php',
1837 'PHPUnitPHAR\\PhpParser\\Node\\Scalar\\Float_' => '/nikic-php-parser/PhpParser/Node/Scalar/Float_.php',
1838 'PHPUnitPHAR\\PhpParser\\Node\\Scalar\\Int_' => '/nikic-php-parser/PhpParser/Node/Scalar/Int_.php',
1839 'PHPUnitPHAR\\PhpParser\\Node\\Scalar\\InterpolatedString' => '/nikic-php-parser/PhpParser/Node/Scalar/InterpolatedString.php',
1840 'PHPUnitPHAR\\PhpParser\\Node\\Scalar\\MagicConst' => '/nikic-php-parser/PhpParser/Node/Scalar/MagicConst.php',
1841 'PHPUnitPHAR\\PhpParser\\Node\\Scalar\\MagicConst\\Class_' => '/nikic-php-parser/PhpParser/Node/Scalar/MagicConst/Class_.php',
1842 'PHPUnitPHAR\\PhpParser\\Node\\Scalar\\MagicConst\\Dir' => '/nikic-php-parser/PhpParser/Node/Scalar/MagicConst/Dir.php',
1843 'PHPUnitPHAR\\PhpParser\\Node\\Scalar\\MagicConst\\File' => '/nikic-php-parser/PhpParser/Node/Scalar/MagicConst/File.php',
1844 'PHPUnitPHAR\\PhpParser\\Node\\Scalar\\MagicConst\\Function_' => '/nikic-php-parser/PhpParser/Node/Scalar/MagicConst/Function_.php',
1845 'PHPUnitPHAR\\PhpParser\\Node\\Scalar\\MagicConst\\Line' => '/nikic-php-parser/PhpParser/Node/Scalar/MagicConst/Line.php',
1846 'PHPUnitPHAR\\PhpParser\\Node\\Scalar\\MagicConst\\Method' => '/nikic-php-parser/PhpParser/Node/Scalar/MagicConst/Method.php',
1847 'PHPUnitPHAR\\PhpParser\\Node\\Scalar\\MagicConst\\Namespace_' => '/nikic-php-parser/PhpParser/Node/Scalar/MagicConst/Namespace_.php',
1848 'PHPUnitPHAR\\PhpParser\\Node\\Scalar\\MagicConst\\Property' => '/nikic-php-parser/PhpParser/Node/Scalar/MagicConst/Property.php',
1849 'PHPUnitPHAR\\PhpParser\\Node\\Scalar\\MagicConst\\Trait_' => '/nikic-php-parser/PhpParser/Node/Scalar/MagicConst/Trait_.php',
1850 'PHPUnitPHAR\\PhpParser\\Node\\Scalar\\String_' => '/nikic-php-parser/PhpParser/Node/Scalar/String_.php',
1851 'PHPUnitPHAR\\PhpParser\\Node\\StaticVar' => '/nikic-php-parser/PhpParser/Node/StaticVar.php',
1852 'PHPUnitPHAR\\PhpParser\\Node\\Stmt' => '/nikic-php-parser/PhpParser/Node/Stmt.php',
1853 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\Block' => '/nikic-php-parser/PhpParser/Node/Stmt/Block.php',
1854 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\Break_' => '/nikic-php-parser/PhpParser/Node/Stmt/Break_.php',
1855 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\Case_' => '/nikic-php-parser/PhpParser/Node/Stmt/Case_.php',
1856 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\Catch_' => '/nikic-php-parser/PhpParser/Node/Stmt/Catch_.php',
1857 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\ClassConst' => '/nikic-php-parser/PhpParser/Node/Stmt/ClassConst.php',
1858 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\ClassLike' => '/nikic-php-parser/PhpParser/Node/Stmt/ClassLike.php',
1859 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\ClassMethod' => '/nikic-php-parser/PhpParser/Node/Stmt/ClassMethod.php',
1860 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\Class_' => '/nikic-php-parser/PhpParser/Node/Stmt/Class_.php',
1861 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\Const_' => '/nikic-php-parser/PhpParser/Node/Stmt/Const_.php',
1862 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\Continue_' => '/nikic-php-parser/PhpParser/Node/Stmt/Continue_.php',
1863 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\Declare_' => '/nikic-php-parser/PhpParser/Node/Stmt/Declare_.php',
1864 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\Do_' => '/nikic-php-parser/PhpParser/Node/Stmt/Do_.php',
1865 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\Echo_' => '/nikic-php-parser/PhpParser/Node/Stmt/Echo_.php',
1866 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\ElseIf_' => '/nikic-php-parser/PhpParser/Node/Stmt/ElseIf_.php',
1867 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\Else_' => '/nikic-php-parser/PhpParser/Node/Stmt/Else_.php',
1868 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\EnumCase' => '/nikic-php-parser/PhpParser/Node/Stmt/EnumCase.php',
1869 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\Enum_' => '/nikic-php-parser/PhpParser/Node/Stmt/Enum_.php',
1870 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\Expression' => '/nikic-php-parser/PhpParser/Node/Stmt/Expression.php',
1871 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\Finally_' => '/nikic-php-parser/PhpParser/Node/Stmt/Finally_.php',
1872 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\For_' => '/nikic-php-parser/PhpParser/Node/Stmt/For_.php',
1873 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\Foreach_' => '/nikic-php-parser/PhpParser/Node/Stmt/Foreach_.php',
1874 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\Function_' => '/nikic-php-parser/PhpParser/Node/Stmt/Function_.php',
1875 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\Global_' => '/nikic-php-parser/PhpParser/Node/Stmt/Global_.php',
1876 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\Goto_' => '/nikic-php-parser/PhpParser/Node/Stmt/Goto_.php',
1877 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\GroupUse' => '/nikic-php-parser/PhpParser/Node/Stmt/GroupUse.php',
1878 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\HaltCompiler' => '/nikic-php-parser/PhpParser/Node/Stmt/HaltCompiler.php',
1879 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\If_' => '/nikic-php-parser/PhpParser/Node/Stmt/If_.php',
1880 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\InlineHTML' => '/nikic-php-parser/PhpParser/Node/Stmt/InlineHTML.php',
1881 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\Interface_' => '/nikic-php-parser/PhpParser/Node/Stmt/Interface_.php',
1882 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\Label' => '/nikic-php-parser/PhpParser/Node/Stmt/Label.php',
1883 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\Namespace_' => '/nikic-php-parser/PhpParser/Node/Stmt/Namespace_.php',
1884 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\Nop' => '/nikic-php-parser/PhpParser/Node/Stmt/Nop.php',
1885 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\Property' => '/nikic-php-parser/PhpParser/Node/Stmt/Property.php',
1886 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\Return_' => '/nikic-php-parser/PhpParser/Node/Stmt/Return_.php',
1887 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\Static_' => '/nikic-php-parser/PhpParser/Node/Stmt/Static_.php',
1888 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\Switch_' => '/nikic-php-parser/PhpParser/Node/Stmt/Switch_.php',
1889 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\TraitUse' => '/nikic-php-parser/PhpParser/Node/Stmt/TraitUse.php',
1890 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\TraitUseAdaptation' => '/nikic-php-parser/PhpParser/Node/Stmt/TraitUseAdaptation.php',
1891 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\TraitUseAdaptation\\Alias' => '/nikic-php-parser/PhpParser/Node/Stmt/TraitUseAdaptation/Alias.php',
1892 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\TraitUseAdaptation\\Precedence' => '/nikic-php-parser/PhpParser/Node/Stmt/TraitUseAdaptation/Precedence.php',
1893 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\Trait_' => '/nikic-php-parser/PhpParser/Node/Stmt/Trait_.php',
1894 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\TryCatch' => '/nikic-php-parser/PhpParser/Node/Stmt/TryCatch.php',
1895 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\Unset_' => '/nikic-php-parser/PhpParser/Node/Stmt/Unset_.php',
1896 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\Use_' => '/nikic-php-parser/PhpParser/Node/Stmt/Use_.php',
1897 'PHPUnitPHAR\\PhpParser\\Node\\Stmt\\While_' => '/nikic-php-parser/PhpParser/Node/Stmt/While_.php',
1898 'PHPUnitPHAR\\PhpParser\\Node\\UnionType' => '/nikic-php-parser/PhpParser/Node/UnionType.php',
1899 'PHPUnitPHAR\\PhpParser\\Node\\UseItem' => '/nikic-php-parser/PhpParser/Node/UseItem.php',
1900 'PHPUnitPHAR\\PhpParser\\Node\\VarLikeIdentifier' => '/nikic-php-parser/PhpParser/Node/VarLikeIdentifier.php',
1901 'PHPUnitPHAR\\PhpParser\\Node\\VariadicPlaceholder' => '/nikic-php-parser/PhpParser/Node/VariadicPlaceholder.php',
1902 'PHPUnitPHAR\\PhpParser\\Parser' => '/nikic-php-parser/PhpParser/Parser.php',
1903 'PHPUnitPHAR\\PhpParser\\ParserAbstract' => '/nikic-php-parser/PhpParser/ParserAbstract.php',
1904 'PHPUnitPHAR\\PhpParser\\ParserFactory' => '/nikic-php-parser/PhpParser/ParserFactory.php',
1905 'PHPUnitPHAR\\PhpParser\\Parser\\Php7' => '/nikic-php-parser/PhpParser/Parser/Php7.php',
1906 'PHPUnitPHAR\\PhpParser\\Parser\\Php8' => '/nikic-php-parser/PhpParser/Parser/Php8.php',
1907 'PHPUnitPHAR\\PhpParser\\PhpVersion' => '/nikic-php-parser/PhpParser/PhpVersion.php',
1908 'PHPUnitPHAR\\PhpParser\\PrettyPrinter' => '/nikic-php-parser/PhpParser/PrettyPrinter.php',
1909 'PHPUnitPHAR\\PhpParser\\PrettyPrinterAbstract' => '/nikic-php-parser/PhpParser/PrettyPrinterAbstract.php',
1910 'PHPUnitPHAR\\PhpParser\\PrettyPrinter\\Standard' => '/nikic-php-parser/PhpParser/PrettyPrinter/Standard.php',
1911 'PHPUnitPHAR\\PhpParser\\Token' => '/nikic-php-parser/PhpParser/Token.php',
1912 'PHPUnitPHAR\\SebastianBergmann\\CliParser\\AmbiguousOptionException' => '/sebastian-cli-parser/exceptions/AmbiguousOptionException.php',
1913 'PHPUnitPHAR\\SebastianBergmann\\CliParser\\Exception' => '/sebastian-cli-parser/exceptions/Exception.php',
1914 'PHPUnitPHAR\\SebastianBergmann\\CliParser\\OptionDoesNotAllowArgumentException' => '/sebastian-cli-parser/exceptions/OptionDoesNotAllowArgumentException.php',
1915 'PHPUnitPHAR\\SebastianBergmann\\CliParser\\Parser' => '/sebastian-cli-parser/Parser.php',
1916 'PHPUnitPHAR\\SebastianBergmann\\CliParser\\RequiredOptionArgumentMissingException' => '/sebastian-cli-parser/exceptions/RequiredOptionArgumentMissingException.php',
1917 'PHPUnitPHAR\\SebastianBergmann\\CliParser\\UnknownOptionException' => '/sebastian-cli-parser/exceptions/UnknownOptionException.php',
1918 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\BranchAndPathCoverageNotSupportedException' => '/php-code-coverage/Exception/BranchAndPathCoverageNotSupportedException.php',
1919 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\CodeCoverage' => '/php-code-coverage/CodeCoverage.php',
1920 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Data\\ProcessedCodeCoverageData' => '/php-code-coverage/Data/ProcessedCodeCoverageData.php',
1921 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Data\\RawCodeCoverageData' => '/php-code-coverage/Data/RawCodeCoverageData.php',
1922 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\DeadCodeDetectionNotSupportedException' => '/php-code-coverage/Exception/DeadCodeDetectionNotSupportedException.php',
1923 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Driver\\Driver' => '/php-code-coverage/Driver/Driver.php',
1924 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Driver\\PathExistsButIsNotDirectoryException' => '/php-code-coverage/Exception/PathExistsButIsNotDirectoryException.php',
1925 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Driver\\PcovDriver' => '/php-code-coverage/Driver/PcovDriver.php',
1926 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Driver\\PcovNotAvailableException' => '/php-code-coverage/Exception/PcovNotAvailableException.php',
1927 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Driver\\Selector' => '/php-code-coverage/Driver/Selector.php',
1928 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Driver\\WriteOperationFailedException' => '/php-code-coverage/Exception/WriteOperationFailedException.php',
1929 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Driver\\XdebugDriver' => '/php-code-coverage/Driver/XdebugDriver.php',
1930 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Driver\\XdebugNotAvailableException' => '/php-code-coverage/Exception/XdebugNotAvailableException.php',
1931 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Driver\\XdebugNotEnabledException' => '/php-code-coverage/Exception/XdebugNotEnabledException.php',
1932 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Exception' => '/php-code-coverage/Exception/Exception.php',
1933 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\FileCouldNotBeWrittenException' => '/php-code-coverage/Exception/FileCouldNotBeWrittenException.php',
1934 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Filter' => '/php-code-coverage/Filter.php',
1935 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\InvalidArgumentException' => '/php-code-coverage/Exception/InvalidArgumentException.php',
1936 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\NoCodeCoverageDriverAvailableException' => '/php-code-coverage/Exception/NoCodeCoverageDriverAvailableException.php',
1937 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\NoCodeCoverageDriverWithPathCoverageSupportAvailableException' => '/php-code-coverage/Exception/NoCodeCoverageDriverWithPathCoverageSupportAvailableException.php',
1938 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Node\\AbstractNode' => '/php-code-coverage/Node/AbstractNode.php',
1939 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Node\\Builder' => '/php-code-coverage/Node/Builder.php',
1940 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Node\\CrapIndex' => '/php-code-coverage/Node/CrapIndex.php',
1941 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Node\\Directory' => '/php-code-coverage/Node/Directory.php',
1942 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Node\\File' => '/php-code-coverage/Node/File.php',
1943 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Node\\Iterator' => '/php-code-coverage/Node/Iterator.php',
1944 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\ParserException' => '/php-code-coverage/Exception/ParserException.php',
1945 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\ReflectionException' => '/php-code-coverage/Exception/ReflectionException.php',
1946 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\ReportAlreadyFinalizedException' => '/php-code-coverage/Exception/ReportAlreadyFinalizedException.php',
1947 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Report\\Clover' => '/php-code-coverage/Report/Clover.php',
1948 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Report\\Cobertura' => '/php-code-coverage/Report/Cobertura.php',
1949 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Report\\Crap4j' => '/php-code-coverage/Report/Crap4j.php',
1950 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Report\\Html\\Colors' => '/php-code-coverage/Report/Html/Colors.php',
1951 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Report\\Html\\CustomCssFile' => '/php-code-coverage/Report/Html/CustomCssFile.php',
1952 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Report\\Html\\Dashboard' => '/php-code-coverage/Report/Html/Renderer/Dashboard.php',
1953 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Report\\Html\\Directory' => '/php-code-coverage/Report/Html/Renderer/Directory.php',
1954 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Report\\Html\\Facade' => '/php-code-coverage/Report/Html/Facade.php',
1955 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Report\\Html\\File' => '/php-code-coverage/Report/Html/Renderer/File.php',
1956 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Report\\Html\\Renderer' => '/php-code-coverage/Report/Html/Renderer.php',
1957 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Report\\PHP' => '/php-code-coverage/Report/PHP.php',
1958 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Report\\Text' => '/php-code-coverage/Report/Text.php',
1959 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Report\\Thresholds' => '/php-code-coverage/Report/Thresholds.php',
1960 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Report\\Xml\\BuildInformation' => '/php-code-coverage/Report/Xml/BuildInformation.php',
1961 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Report\\Xml\\Coverage' => '/php-code-coverage/Report/Xml/Coverage.php',
1962 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Report\\Xml\\Directory' => '/php-code-coverage/Report/Xml/Directory.php',
1963 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Report\\Xml\\Facade' => '/php-code-coverage/Report/Xml/Facade.php',
1964 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Report\\Xml\\File' => '/php-code-coverage/Report/Xml/File.php',
1965 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Report\\Xml\\Method' => '/php-code-coverage/Report/Xml/Method.php',
1966 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Report\\Xml\\Node' => '/php-code-coverage/Report/Xml/Node.php',
1967 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Report\\Xml\\Project' => '/php-code-coverage/Report/Xml/Project.php',
1968 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Report\\Xml\\Report' => '/php-code-coverage/Report/Xml/Report.php',
1969 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Report\\Xml\\Source' => '/php-code-coverage/Report/Xml/Source.php',
1970 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Report\\Xml\\Tests' => '/php-code-coverage/Report/Xml/Tests.php',
1971 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Report\\Xml\\Totals' => '/php-code-coverage/Report/Xml/Totals.php',
1972 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Report\\Xml\\Unit' => '/php-code-coverage/Report/Xml/Unit.php',
1973 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\StaticAnalysisCacheNotConfiguredException' => '/php-code-coverage/Exception/StaticAnalysisCacheNotConfiguredException.php',
1974 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\StaticAnalysis\\CacheWarmer' => '/php-code-coverage/StaticAnalysis/CacheWarmer.php',
1975 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\StaticAnalysis\\CachingFileAnalyser' => '/php-code-coverage/StaticAnalysis/CachingFileAnalyser.php',
1976 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\StaticAnalysis\\CodeUnitFindingVisitor' => '/php-code-coverage/StaticAnalysis/CodeUnitFindingVisitor.php',
1977 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\StaticAnalysis\\ExecutableLinesFindingVisitor' => '/php-code-coverage/StaticAnalysis/ExecutableLinesFindingVisitor.php',
1978 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\StaticAnalysis\\FileAnalyser' => '/php-code-coverage/StaticAnalysis/FileAnalyser.php',
1979 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\StaticAnalysis\\IgnoredLinesFindingVisitor' => '/php-code-coverage/StaticAnalysis/IgnoredLinesFindingVisitor.php',
1980 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\StaticAnalysis\\ParsingFileAnalyser' => '/php-code-coverage/StaticAnalysis/ParsingFileAnalyser.php',
1981 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\TestIdMissingException' => '/php-code-coverage/Exception/TestIdMissingException.php',
1982 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Test\\TestSize\\Known' => '/php-code-coverage/TestSize/Known.php',
1983 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Test\\TestSize\\Large' => '/php-code-coverage/TestSize/Large.php',
1984 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Test\\TestSize\\Medium' => '/php-code-coverage/TestSize/Medium.php',
1985 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Test\\TestSize\\Small' => '/php-code-coverage/TestSize/Small.php',
1986 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Test\\TestSize\\TestSize' => '/php-code-coverage/TestSize/TestSize.php',
1987 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Test\\TestSize\\Unknown' => '/php-code-coverage/TestSize/Unknown.php',
1988 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Test\\TestStatus\\Failure' => '/php-code-coverage/TestStatus/Failure.php',
1989 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Test\\TestStatus\\Known' => '/php-code-coverage/TestStatus/Known.php',
1990 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Test\\TestStatus\\Success' => '/php-code-coverage/TestStatus/Success.php',
1991 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Test\\TestStatus\\TestStatus' => '/php-code-coverage/TestStatus/TestStatus.php',
1992 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Test\\TestStatus\\Unknown' => '/php-code-coverage/TestStatus/Unknown.php',
1993 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\UnintentionallyCoveredCodeException' => '/php-code-coverage/Exception/UnintentionallyCoveredCodeException.php',
1994 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Util\\DirectoryCouldNotBeCreatedException' => '/php-code-coverage/Exception/DirectoryCouldNotBeCreatedException.php',
1995 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Util\\Filesystem' => '/php-code-coverage/Util/Filesystem.php',
1996 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Util\\Percentage' => '/php-code-coverage/Util/Percentage.php',
1997 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\Version' => '/php-code-coverage/Version.php',
1998 'PHPUnitPHAR\\SebastianBergmann\\CodeCoverage\\XmlException' => '/php-code-coverage/Exception/XmlException.php',
1999 'PHPUnitPHAR\\SebastianBergmann\\CodeUnitReverseLookup\\Wizard' => '/sebastian-code-unit-reverse-lookup/Wizard.php',
2000 'PHPUnitPHAR\\SebastianBergmann\\CodeUnit\\ClassMethodUnit' => '/sebastian-code-unit/ClassMethodUnit.php',
2001 'PHPUnitPHAR\\SebastianBergmann\\CodeUnit\\ClassUnit' => '/sebastian-code-unit/ClassUnit.php',
2002 'PHPUnitPHAR\\SebastianBergmann\\CodeUnit\\CodeUnit' => '/sebastian-code-unit/CodeUnit.php',
2003 'PHPUnitPHAR\\SebastianBergmann\\CodeUnit\\CodeUnitCollection' => '/sebastian-code-unit/CodeUnitCollection.php',
2004 'PHPUnitPHAR\\SebastianBergmann\\CodeUnit\\CodeUnitCollectionIterator' => '/sebastian-code-unit/CodeUnitCollectionIterator.php',
2005 'PHPUnitPHAR\\SebastianBergmann\\CodeUnit\\Exception' => '/sebastian-code-unit/exceptions/Exception.php',
2006 'PHPUnitPHAR\\SebastianBergmann\\CodeUnit\\FileUnit' => '/sebastian-code-unit/FileUnit.php',
2007 'PHPUnitPHAR\\SebastianBergmann\\CodeUnit\\FunctionUnit' => '/sebastian-code-unit/FunctionUnit.php',
2008 'PHPUnitPHAR\\SebastianBergmann\\CodeUnit\\InterfaceMethodUnit' => '/sebastian-code-unit/InterfaceMethodUnit.php',
2009 'PHPUnitPHAR\\SebastianBergmann\\CodeUnit\\InterfaceUnit' => '/sebastian-code-unit/InterfaceUnit.php',
2010 'PHPUnitPHAR\\SebastianBergmann\\CodeUnit\\InvalidCodeUnitException' => '/sebastian-code-unit/exceptions/InvalidCodeUnitException.php',
2011 'PHPUnitPHAR\\SebastianBergmann\\CodeUnit\\Mapper' => '/sebastian-code-unit/Mapper.php',
2012 'PHPUnitPHAR\\SebastianBergmann\\CodeUnit\\NoTraitException' => '/sebastian-code-unit/exceptions/NoTraitException.php',
2013 'PHPUnitPHAR\\SebastianBergmann\\CodeUnit\\ReflectionException' => '/sebastian-code-unit/exceptions/ReflectionException.php',
2014 'PHPUnitPHAR\\SebastianBergmann\\CodeUnit\\TraitMethodUnit' => '/sebastian-code-unit/TraitMethodUnit.php',
2015 'PHPUnitPHAR\\SebastianBergmann\\CodeUnit\\TraitUnit' => '/sebastian-code-unit/TraitUnit.php',
2016 'PHPUnitPHAR\\SebastianBergmann\\Comparator\\ArrayComparator' => '/sebastian-comparator/ArrayComparator.php',
2017 'PHPUnitPHAR\\SebastianBergmann\\Comparator\\Comparator' => '/sebastian-comparator/Comparator.php',
2018 'PHPUnitPHAR\\SebastianBergmann\\Comparator\\ComparisonFailure' => '/sebastian-comparator/ComparisonFailure.php',
2019 'PHPUnitPHAR\\SebastianBergmann\\Comparator\\DOMNodeComparator' => '/sebastian-comparator/DOMNodeComparator.php',
2020 'PHPUnitPHAR\\SebastianBergmann\\Comparator\\DateTimeComparator' => '/sebastian-comparator/DateTimeComparator.php',
2021 'PHPUnitPHAR\\SebastianBergmann\\Comparator\\Exception' => '/sebastian-comparator/exceptions/Exception.php',
2022 'PHPUnitPHAR\\SebastianBergmann\\Comparator\\ExceptionComparator' => '/sebastian-comparator/ExceptionComparator.php',
2023 'PHPUnitPHAR\\SebastianBergmann\\Comparator\\Factory' => '/sebastian-comparator/Factory.php',
2024 'PHPUnitPHAR\\SebastianBergmann\\Comparator\\MockObjectComparator' => '/sebastian-comparator/MockObjectComparator.php',
2025 'PHPUnitPHAR\\SebastianBergmann\\Comparator\\NumericComparator' => '/sebastian-comparator/NumericComparator.php',
2026 'PHPUnitPHAR\\SebastianBergmann\\Comparator\\ObjectComparator' => '/sebastian-comparator/ObjectComparator.php',
2027 'PHPUnitPHAR\\SebastianBergmann\\Comparator\\ResourceComparator' => '/sebastian-comparator/ResourceComparator.php',
2028 'PHPUnitPHAR\\SebastianBergmann\\Comparator\\RuntimeException' => '/sebastian-comparator/exceptions/RuntimeException.php',
2029 'PHPUnitPHAR\\SebastianBergmann\\Comparator\\ScalarComparator' => '/sebastian-comparator/ScalarComparator.php',
2030 'PHPUnitPHAR\\SebastianBergmann\\Comparator\\SplObjectStorageComparator' => '/sebastian-comparator/SplObjectStorageComparator.php',
2031 'PHPUnitPHAR\\SebastianBergmann\\Comparator\\TypeComparator' => '/sebastian-comparator/TypeComparator.php',
2032 'PHPUnitPHAR\\SebastianBergmann\\Complexity\\Calculator' => '/sebastian-complexity/Calculator.php',
2033 'PHPUnitPHAR\\SebastianBergmann\\Complexity\\Complexity' => '/sebastian-complexity/Complexity/Complexity.php',
2034 'PHPUnitPHAR\\SebastianBergmann\\Complexity\\ComplexityCalculatingVisitor' => '/sebastian-complexity/Visitor/ComplexityCalculatingVisitor.php',
2035 'PHPUnitPHAR\\SebastianBergmann\\Complexity\\ComplexityCollection' => '/sebastian-complexity/Complexity/ComplexityCollection.php',
2036 'PHPUnitPHAR\\SebastianBergmann\\Complexity\\ComplexityCollectionIterator' => '/sebastian-complexity/Complexity/ComplexityCollectionIterator.php',
2037 'PHPUnitPHAR\\SebastianBergmann\\Complexity\\CyclomaticComplexityCalculatingVisitor' => '/sebastian-complexity/Visitor/CyclomaticComplexityCalculatingVisitor.php',
2038 'PHPUnitPHAR\\SebastianBergmann\\Complexity\\Exception' => '/sebastian-complexity/Exception/Exception.php',
2039 'PHPUnitPHAR\\SebastianBergmann\\Complexity\\RuntimeException' => '/sebastian-complexity/Exception/RuntimeException.php',
2040 'PHPUnitPHAR\\SebastianBergmann\\Diff\\Chunk' => '/sebastian-diff/Chunk.php',
2041 'PHPUnitPHAR\\SebastianBergmann\\Diff\\ConfigurationException' => '/sebastian-diff/Exception/ConfigurationException.php',
2042 'PHPUnitPHAR\\SebastianBergmann\\Diff\\Diff' => '/sebastian-diff/Diff.php',
2043 'PHPUnitPHAR\\SebastianBergmann\\Diff\\Differ' => '/sebastian-diff/Differ.php',
2044 'PHPUnitPHAR\\SebastianBergmann\\Diff\\Exception' => '/sebastian-diff/Exception/Exception.php',
2045 'PHPUnitPHAR\\SebastianBergmann\\Diff\\InvalidArgumentException' => '/sebastian-diff/Exception/InvalidArgumentException.php',
2046 'PHPUnitPHAR\\SebastianBergmann\\Diff\\Line' => '/sebastian-diff/Line.php',
2047 'PHPUnitPHAR\\SebastianBergmann\\Diff\\LongestCommonSubsequenceCalculator' => '/sebastian-diff/LongestCommonSubsequenceCalculator.php',
2048 'PHPUnitPHAR\\SebastianBergmann\\Diff\\MemoryEfficientLongestCommonSubsequenceCalculator' => '/sebastian-diff/MemoryEfficientLongestCommonSubsequenceCalculator.php',
2049 'PHPUnitPHAR\\SebastianBergmann\\Diff\\Output\\AbstractChunkOutputBuilder' => '/sebastian-diff/Output/AbstractChunkOutputBuilder.php',
2050 'PHPUnitPHAR\\SebastianBergmann\\Diff\\Output\\DiffOnlyOutputBuilder' => '/sebastian-diff/Output/DiffOnlyOutputBuilder.php',
2051 'PHPUnitPHAR\\SebastianBergmann\\Diff\\Output\\DiffOutputBuilderInterface' => '/sebastian-diff/Output/DiffOutputBuilderInterface.php',
2052 'PHPUnitPHAR\\SebastianBergmann\\Diff\\Output\\StrictUnifiedDiffOutputBuilder' => '/sebastian-diff/Output/StrictUnifiedDiffOutputBuilder.php',
2053 'PHPUnitPHAR\\SebastianBergmann\\Diff\\Output\\UnifiedDiffOutputBuilder' => '/sebastian-diff/Output/UnifiedDiffOutputBuilder.php',
2054 'PHPUnitPHAR\\SebastianBergmann\\Diff\\Parser' => '/sebastian-diff/Parser.php',
2055 'PHPUnitPHAR\\SebastianBergmann\\Diff\\TimeEfficientLongestCommonSubsequenceCalculator' => '/sebastian-diff/TimeEfficientLongestCommonSubsequenceCalculator.php',
2056 'PHPUnitPHAR\\SebastianBergmann\\Environment\\Console' => '/sebastian-environment/Console.php',
2057 'PHPUnitPHAR\\SebastianBergmann\\Environment\\Runtime' => '/sebastian-environment/Runtime.php',
2058 'PHPUnitPHAR\\SebastianBergmann\\Exporter\\Exporter' => '/sebastian-exporter/Exporter.php',
2059 'PHPUnitPHAR\\SebastianBergmann\\FileIterator\\ExcludeIterator' => '/php-file-iterator/ExcludeIterator.php',
2060 'PHPUnitPHAR\\SebastianBergmann\\FileIterator\\Facade' => '/php-file-iterator/Facade.php',
2061 'PHPUnitPHAR\\SebastianBergmann\\FileIterator\\Factory' => '/php-file-iterator/Factory.php',
2062 'PHPUnitPHAR\\SebastianBergmann\\FileIterator\\Iterator' => '/php-file-iterator/Iterator.php',
2063 'PHPUnitPHAR\\SebastianBergmann\\GlobalState\\CodeExporter' => '/sebastian-global-state/CodeExporter.php',
2064 'PHPUnitPHAR\\SebastianBergmann\\GlobalState\\Exception' => '/sebastian-global-state/exceptions/Exception.php',
2065 'PHPUnitPHAR\\SebastianBergmann\\GlobalState\\ExcludeList' => '/sebastian-global-state/ExcludeList.php',
2066 'PHPUnitPHAR\\SebastianBergmann\\GlobalState\\Restorer' => '/sebastian-global-state/Restorer.php',
2067 'PHPUnitPHAR\\SebastianBergmann\\GlobalState\\RuntimeException' => '/sebastian-global-state/exceptions/RuntimeException.php',
2068 'PHPUnitPHAR\\SebastianBergmann\\GlobalState\\Snapshot' => '/sebastian-global-state/Snapshot.php',
2069 'PHPUnitPHAR\\SebastianBergmann\\Invoker\\Exception' => '/php-invoker/exceptions/Exception.php',
2070 'PHPUnitPHAR\\SebastianBergmann\\Invoker\\Invoker' => '/php-invoker/Invoker.php',
2071 'PHPUnitPHAR\\SebastianBergmann\\Invoker\\ProcessControlExtensionNotLoadedException' => '/php-invoker/exceptions/ProcessControlExtensionNotLoadedException.php',
2072 'PHPUnitPHAR\\SebastianBergmann\\Invoker\\TimeoutException' => '/php-invoker/exceptions/TimeoutException.php',
2073 'PHPUnitPHAR\\SebastianBergmann\\LinesOfCode\\Counter' => '/sebastian-lines-of-code/Counter.php',
2074 'PHPUnitPHAR\\SebastianBergmann\\LinesOfCode\\Exception' => '/sebastian-lines-of-code/Exception/Exception.php',
2075 'PHPUnitPHAR\\SebastianBergmann\\LinesOfCode\\IllogicalValuesException' => '/sebastian-lines-of-code/Exception/IllogicalValuesException.php',
2076 'PHPUnitPHAR\\SebastianBergmann\\LinesOfCode\\LineCountingVisitor' => '/sebastian-lines-of-code/LineCountingVisitor.php',
2077 'PHPUnitPHAR\\SebastianBergmann\\LinesOfCode\\LinesOfCode' => '/sebastian-lines-of-code/LinesOfCode.php',
2078 'PHPUnitPHAR\\SebastianBergmann\\LinesOfCode\\NegativeValueException' => '/sebastian-lines-of-code/Exception/NegativeValueException.php',
2079 'PHPUnitPHAR\\SebastianBergmann\\LinesOfCode\\RuntimeException' => '/sebastian-lines-of-code/Exception/RuntimeException.php',
2080 'PHPUnitPHAR\\SebastianBergmann\\ObjectEnumerator\\Enumerator' => '/sebastian-object-enumerator/Enumerator.php',
2081 'PHPUnitPHAR\\SebastianBergmann\\ObjectReflector\\ObjectReflector' => '/sebastian-object-reflector/ObjectReflector.php',
2082 'PHPUnitPHAR\\SebastianBergmann\\RecursionContext\\Context' => '/sebastian-recursion-context/Context.php',
2083 'PHPUnitPHAR\\SebastianBergmann\\Template\\Exception' => '/php-text-template/exceptions/Exception.php',
2084 'PHPUnitPHAR\\SebastianBergmann\\Template\\InvalidArgumentException' => '/php-text-template/exceptions/InvalidArgumentException.php',
2085 'PHPUnitPHAR\\SebastianBergmann\\Template\\RuntimeException' => '/php-text-template/exceptions/RuntimeException.php',
2086 'PHPUnitPHAR\\SebastianBergmann\\Template\\Template' => '/php-text-template/Template.php',
2087 'PHPUnitPHAR\\SebastianBergmann\\Timer\\Duration' => '/php-timer/Duration.php',
2088 'PHPUnitPHAR\\SebastianBergmann\\Timer\\Exception' => '/php-timer/exceptions/Exception.php',
2089 'PHPUnitPHAR\\SebastianBergmann\\Timer\\NoActiveTimerException' => '/php-timer/exceptions/NoActiveTimerException.php',
2090 'PHPUnitPHAR\\SebastianBergmann\\Timer\\ResourceUsageFormatter' => '/php-timer/ResourceUsageFormatter.php',
2091 'PHPUnitPHAR\\SebastianBergmann\\Timer\\TimeSinceStartOfRequestNotAvailableException' => '/php-timer/exceptions/TimeSinceStartOfRequestNotAvailableException.php',
2092 'PHPUnitPHAR\\SebastianBergmann\\Timer\\Timer' => '/php-timer/Timer.php',
2093 'PHPUnitPHAR\\SebastianBergmann\\Type\\CallableType' => '/sebastian-type/type/CallableType.php',
2094 'PHPUnitPHAR\\SebastianBergmann\\Type\\Exception' => '/sebastian-type/exception/Exception.php',
2095 'PHPUnitPHAR\\SebastianBergmann\\Type\\FalseType' => '/sebastian-type/type/FalseType.php',
2096 'PHPUnitPHAR\\SebastianBergmann\\Type\\GenericObjectType' => '/sebastian-type/type/GenericObjectType.php',
2097 'PHPUnitPHAR\\SebastianBergmann\\Type\\IntersectionType' => '/sebastian-type/type/IntersectionType.php',
2098 'PHPUnitPHAR\\SebastianBergmann\\Type\\IterableType' => '/sebastian-type/type/IterableType.php',
2099 'PHPUnitPHAR\\SebastianBergmann\\Type\\MixedType' => '/sebastian-type/type/MixedType.php',
2100 'PHPUnitPHAR\\SebastianBergmann\\Type\\NeverType' => '/sebastian-type/type/NeverType.php',
2101 'PHPUnitPHAR\\SebastianBergmann\\Type\\NullType' => '/sebastian-type/type/NullType.php',
2102 'PHPUnitPHAR\\SebastianBergmann\\Type\\ObjectType' => '/sebastian-type/type/ObjectType.php',
2103 'PHPUnitPHAR\\SebastianBergmann\\Type\\Parameter' => '/sebastian-type/Parameter.php',
2104 'PHPUnitPHAR\\SebastianBergmann\\Type\\ReflectionMapper' => '/sebastian-type/ReflectionMapper.php',
2105 'PHPUnitPHAR\\SebastianBergmann\\Type\\RuntimeException' => '/sebastian-type/exception/RuntimeException.php',
2106 'PHPUnitPHAR\\SebastianBergmann\\Type\\SimpleType' => '/sebastian-type/type/SimpleType.php',
2107 'PHPUnitPHAR\\SebastianBergmann\\Type\\StaticType' => '/sebastian-type/type/StaticType.php',
2108 'PHPUnitPHAR\\SebastianBergmann\\Type\\TrueType' => '/sebastian-type/type/TrueType.php',
2109 'PHPUnitPHAR\\SebastianBergmann\\Type\\Type' => '/sebastian-type/type/Type.php',
2110 'PHPUnitPHAR\\SebastianBergmann\\Type\\TypeName' => '/sebastian-type/TypeName.php',
2111 'PHPUnitPHAR\\SebastianBergmann\\Type\\UnionType' => '/sebastian-type/type/UnionType.php',
2112 'PHPUnitPHAR\\SebastianBergmann\\Type\\UnknownType' => '/sebastian-type/type/UnknownType.php',
2113 'PHPUnitPHAR\\SebastianBergmann\\Type\\VoidType' => '/sebastian-type/type/VoidType.php',
2114 'PHPUnitPHAR\\SebastianBergmann\\Version' => '/sebastian-version/Version.php',
2115 'PHPUnitPHAR\\TheSeer\\Tokenizer\\Exception' => '/theseer-tokenizer/Exception.php',
2116 'PHPUnitPHAR\\TheSeer\\Tokenizer\\NamespaceUri' => '/theseer-tokenizer/NamespaceUri.php',
2117 'PHPUnitPHAR\\TheSeer\\Tokenizer\\NamespaceUriException' => '/theseer-tokenizer/NamespaceUriException.php',
2118 'PHPUnitPHAR\\TheSeer\\Tokenizer\\Token' => '/theseer-tokenizer/Token.php',
2119 'PHPUnitPHAR\\TheSeer\\Tokenizer\\TokenCollection' => '/theseer-tokenizer/TokenCollection.php',
2120 'PHPUnitPHAR\\TheSeer\\Tokenizer\\TokenCollectionException' => '/theseer-tokenizer/TokenCollectionException.php',
2121 'PHPUnitPHAR\\TheSeer\\Tokenizer\\Tokenizer' => '/theseer-tokenizer/Tokenizer.php',
2122 'PHPUnitPHAR\\TheSeer\\Tokenizer\\XMLSerializer' => '/theseer-tokenizer/XMLSerializer.php',
2123 'PHPUnit\\Event\\Application\\Finished' => '/phpunit/Event/Events/Application/Finished.php',
2124 'PHPUnit\\Event\\Application\\FinishedSubscriber' => '/phpunit/Event/Events/Application/FinishedSubscriber.php',
2125 'PHPUnit\\Event\\Application\\Started' => '/phpunit/Event/Events/Application/Started.php',
2126 'PHPUnit\\Event\\Application\\StartedSubscriber' => '/phpunit/Event/Events/Application/StartedSubscriber.php',
2127 'PHPUnit\\Event\\Code\\ClassMethod' => '/phpunit/Event/Value/ClassMethod.php',
2128 'PHPUnit\\Event\\Code\\ComparisonFailure' => '/phpunit/Event/Value/ComparisonFailure.php',
2129 'PHPUnit\\Event\\Code\\ComparisonFailureBuilder' => '/phpunit/Event/Value/ComparisonFailureBuilder.php',
2130 'PHPUnit\\Event\\Code\\NoTestCaseObjectOnCallStackException' => '/phpunit/Event/Exception/NoTestCaseObjectOnCallStackException.php',
2131 'PHPUnit\\Event\\Code\\Phpt' => '/phpunit/Event/Value/Test/Phpt.php',
2132 'PHPUnit\\Event\\Code\\Test' => '/phpunit/Event/Value/Test/Test.php',
2133 'PHPUnit\\Event\\Code\\TestCollection' => '/phpunit/Event/Value/Test/TestCollection.php',
2134 'PHPUnit\\Event\\Code\\TestCollectionIterator' => '/phpunit/Event/Value/Test/TestCollectionIterator.php',
2135 'PHPUnit\\Event\\Code\\TestDox' => '/phpunit/Event/Value/Test/TestDox.php',
2136 'PHPUnit\\Event\\Code\\TestDoxBuilder' => '/phpunit/Event/Value/Test/TestDoxBuilder.php',
2137 'PHPUnit\\Event\\Code\\TestMethod' => '/phpunit/Event/Value/Test/TestMethod.php',
2138 'PHPUnit\\Event\\Code\\TestMethodBuilder' => '/phpunit/Event/Value/Test/TestMethodBuilder.php',
2139 'PHPUnit\\Event\\Code\\Throwable' => '/phpunit/Event/Value/Throwable.php',
2140 'PHPUnit\\Event\\Code\\ThrowableBuilder' => '/phpunit/Event/Value/ThrowableBuilder.php',
2141 'PHPUnit\\Event\\CollectingDispatcher' => '/phpunit/Event/Dispatcher/CollectingDispatcher.php',
2142 'PHPUnit\\Event\\DeferringDispatcher' => '/phpunit/Event/Dispatcher/DeferringDispatcher.php',
2143 'PHPUnit\\Event\\DirectDispatcher' => '/phpunit/Event/Dispatcher/DirectDispatcher.php',
2144 'PHPUnit\\Event\\Dispatcher' => '/phpunit/Event/Dispatcher/Dispatcher.php',
2145 'PHPUnit\\Event\\DispatchingEmitter' => '/phpunit/Event/Emitter/DispatchingEmitter.php',
2146 'PHPUnit\\Event\\Emitter' => '/phpunit/Event/Emitter/Emitter.php',
2147 'PHPUnit\\Event\\Event' => '/phpunit/Event/Events/Event.php',
2148 'PHPUnit\\Event\\EventAlreadyAssignedException' => '/phpunit/Event/Exception/EventAlreadyAssignedException.php',
2149 'PHPUnit\\Event\\EventCollection' => '/phpunit/Event/Events/EventCollection.php',
2150 'PHPUnit\\Event\\EventCollectionIterator' => '/phpunit/Event/Events/EventCollectionIterator.php',
2151 'PHPUnit\\Event\\EventFacadeIsSealedException' => '/phpunit/Event/Exception/EventFacadeIsSealedException.php',
2152 'PHPUnit\\Event\\Exception' => '/phpunit/Event/Exception/Exception.php',
2153 'PHPUnit\\Event\\Facade' => '/phpunit/Event/Facade.php',
2154 'PHPUnit\\Event\\InvalidArgumentException' => '/phpunit/Event/Exception/InvalidArgumentException.php',
2155 'PHPUnit\\Event\\InvalidEventException' => '/phpunit/Event/Exception/InvalidEventException.php',
2156 'PHPUnit\\Event\\InvalidSubscriberException' => '/phpunit/Event/Exception/InvalidSubscriberException.php',
2157 'PHPUnit\\Event\\MapError' => '/phpunit/Event/Exception/MapError.php',
2158 'PHPUnit\\Event\\NoPreviousThrowableException' => '/phpunit/Event/Exception/NoPreviousThrowableException.php',
2159 'PHPUnit\\Event\\RuntimeException' => '/phpunit/Event/Exception/RuntimeException.php',
2160 'PHPUnit\\Event\\Runtime\\OperatingSystem' => '/phpunit/Event/Value/Runtime/OperatingSystem.php',
2161 'PHPUnit\\Event\\Runtime\\PHP' => '/phpunit/Event/Value/Runtime/PHP.php',
2162 'PHPUnit\\Event\\Runtime\\PHPUnit' => '/phpunit/Event/Value/Runtime/PHPUnit.php',
2163 'PHPUnit\\Event\\Runtime\\Runtime' => '/phpunit/Event/Value/Runtime/Runtime.php',
2164 'PHPUnit\\Event\\SubscribableDispatcher' => '/phpunit/Event/Dispatcher/SubscribableDispatcher.php',
2165 'PHPUnit\\Event\\Subscriber' => '/phpunit/Event/Subscriber.php',
2166 'PHPUnit\\Event\\SubscriberTypeAlreadyRegisteredException' => '/phpunit/Event/Exception/SubscriberTypeAlreadyRegisteredException.php',
2167 'PHPUnit\\Event\\Telemetry\\Duration' => '/phpunit/Event/Value/Telemetry/Duration.php',
2168 'PHPUnit\\Event\\Telemetry\\GarbageCollectorStatus' => '/phpunit/Event/Value/Telemetry/GarbageCollectorStatus.php',
2169 'PHPUnit\\Event\\Telemetry\\GarbageCollectorStatusProvider' => '/phpunit/Event/Value/Telemetry/GarbageCollectorStatusProvider.php',
2170 'PHPUnit\\Event\\Telemetry\\HRTime' => '/phpunit/Event/Value/Telemetry/HRTime.php',
2171 'PHPUnit\\Event\\Telemetry\\Info' => '/phpunit/Event/Value/Telemetry/Info.php',
2172 'PHPUnit\\Event\\Telemetry\\MemoryMeter' => '/phpunit/Event/Value/Telemetry/MemoryMeter.php',
2173 'PHPUnit\\Event\\Telemetry\\MemoryUsage' => '/phpunit/Event/Value/Telemetry/MemoryUsage.php',
2174 'PHPUnit\\Event\\Telemetry\\Php81GarbageCollectorStatusProvider' => '/phpunit/Event/Value/Telemetry/Php81GarbageCollectorStatusProvider.php',
2175 'PHPUnit\\Event\\Telemetry\\Php83GarbageCollectorStatusProvider' => '/phpunit/Event/Value/Telemetry/Php83GarbageCollectorStatusProvider.php',
2176 'PHPUnit\\Event\\Telemetry\\Snapshot' => '/phpunit/Event/Value/Telemetry/Snapshot.php',
2177 'PHPUnit\\Event\\Telemetry\\StopWatch' => '/phpunit/Event/Value/Telemetry/StopWatch.php',
2178 'PHPUnit\\Event\\Telemetry\\System' => '/phpunit/Event/Value/Telemetry/System.php',
2179 'PHPUnit\\Event\\Telemetry\\SystemMemoryMeter' => '/phpunit/Event/Value/Telemetry/SystemMemoryMeter.php',
2180 'PHPUnit\\Event\\Telemetry\\SystemStopWatch' => '/phpunit/Event/Value/Telemetry/SystemStopWatch.php',
2181 'PHPUnit\\Event\\Telemetry\\SystemStopWatchWithOffset' => '/phpunit/Event/Value/Telemetry/SystemStopWatchWithOffset.php',
2182 'PHPUnit\\Event\\TestData\\DataFromDataProvider' => '/phpunit/Event/Value/Test/TestData/DataFromDataProvider.php',
2183 'PHPUnit\\Event\\TestData\\DataFromTestDependency' => '/phpunit/Event/Value/Test/TestData/DataFromTestDependency.php',
2184 'PHPUnit\\Event\\TestData\\MoreThanOneDataSetFromDataProviderException' => '/phpunit/Event/Exception/MoreThanOneDataSetFromDataProviderException.php',
2185 'PHPUnit\\Event\\TestData\\NoDataSetFromDataProviderException' => '/phpunit/Event/Exception/NoDataSetFromDataProviderException.php',
2186 'PHPUnit\\Event\\TestData\\TestData' => '/phpunit/Event/Value/Test/TestData/TestData.php',
2187 'PHPUnit\\Event\\TestData\\TestDataCollection' => '/phpunit/Event/Value/Test/TestData/TestDataCollection.php',
2188 'PHPUnit\\Event\\TestData\\TestDataCollectionIterator' => '/phpunit/Event/Value/Test/TestData/TestDataCollectionIterator.php',
2189 'PHPUnit\\Event\\TestRunner\\BootstrapFinished' => '/phpunit/Event/Events/TestRunner/BootstrapFinished.php',
2190 'PHPUnit\\Event\\TestRunner\\BootstrapFinishedSubscriber' => '/phpunit/Event/Events/TestRunner/BootstrapFinishedSubscriber.php',
2191 'PHPUnit\\Event\\TestRunner\\Configured' => '/phpunit/Event/Events/TestRunner/Configured.php',
2192 'PHPUnit\\Event\\TestRunner\\ConfiguredSubscriber' => '/phpunit/Event/Events/TestRunner/ConfiguredSubscriber.php',
2193 'PHPUnit\\Event\\TestRunner\\DeprecationTriggered' => '/phpunit/Event/Events/TestRunner/DeprecationTriggered.php',
2194 'PHPUnit\\Event\\TestRunner\\DeprecationTriggeredSubscriber' => '/phpunit/Event/Events/TestRunner/DeprecationTriggeredSubscriber.php',
2195 'PHPUnit\\Event\\TestRunner\\EventFacadeSealed' => '/phpunit/Event/Events/TestRunner/EventFacadeSealed.php',
2196 'PHPUnit\\Event\\TestRunner\\EventFacadeSealedSubscriber' => '/phpunit/Event/Events/TestRunner/EventFacadeSealedSubscriber.php',
2197 'PHPUnit\\Event\\TestRunner\\ExecutionAborted' => '/phpunit/Event/Events/TestRunner/ExecutionAborted.php',
2198 'PHPUnit\\Event\\TestRunner\\ExecutionAbortedSubscriber' => '/phpunit/Event/Events/TestRunner/ExecutionAbortedSubscriber.php',
2199 'PHPUnit\\Event\\TestRunner\\ExecutionFinished' => '/phpunit/Event/Events/TestRunner/ExecutionFinished.php',
2200 'PHPUnit\\Event\\TestRunner\\ExecutionFinishedSubscriber' => '/phpunit/Event/Events/TestRunner/ExecutionFinishedSubscriber.php',
2201 'PHPUnit\\Event\\TestRunner\\ExecutionStarted' => '/phpunit/Event/Events/TestRunner/ExecutionStarted.php',
2202 'PHPUnit\\Event\\TestRunner\\ExecutionStartedSubscriber' => '/phpunit/Event/Events/TestRunner/ExecutionStartedSubscriber.php',
2203 'PHPUnit\\Event\\TestRunner\\ExtensionBootstrapped' => '/phpunit/Event/Events/TestRunner/ExtensionBootstrapped.php',
2204 'PHPUnit\\Event\\TestRunner\\ExtensionBootstrappedSubscriber' => '/phpunit/Event/Events/TestRunner/ExtensionBootstrappedSubscriber.php',
2205 'PHPUnit\\Event\\TestRunner\\ExtensionLoadedFromPhar' => '/phpunit/Event/Events/TestRunner/ExtensionLoadedFromPhar.php',
2206 'PHPUnit\\Event\\TestRunner\\ExtensionLoadedFromPharSubscriber' => '/phpunit/Event/Events/TestRunner/ExtensionLoadedFromPharSubscriber.php',
2207 'PHPUnit\\Event\\TestRunner\\Finished' => '/phpunit/Event/Events/TestRunner/Finished.php',
2208 'PHPUnit\\Event\\TestRunner\\FinishedSubscriber' => '/phpunit/Event/Events/TestRunner/FinishedSubscriber.php',
2209 'PHPUnit\\Event\\TestRunner\\GarbageCollectionDisabled' => '/phpunit/Event/Events/TestRunner/GarbageCollectionDisabled.php',
2210 'PHPUnit\\Event\\TestRunner\\GarbageCollectionDisabledSubscriber' => '/phpunit/Event/Events/TestRunner/GarbageCollectionDisabledSubscriber.php',
2211 'PHPUnit\\Event\\TestRunner\\GarbageCollectionEnabled' => '/phpunit/Event/Events/TestRunner/GarbageCollectionEnabled.php',
2212 'PHPUnit\\Event\\TestRunner\\GarbageCollectionEnabledSubscriber' => '/phpunit/Event/Events/TestRunner/GarbageCollectionEnabledSubscriber.php',
2213 'PHPUnit\\Event\\TestRunner\\GarbageCollectionTriggered' => '/phpunit/Event/Events/TestRunner/GarbageCollectionTriggered.php',
2214 'PHPUnit\\Event\\TestRunner\\GarbageCollectionTriggeredSubscriber' => '/phpunit/Event/Events/TestRunner/GarbageCollectionTriggeredSubscriber.php',
2215 'PHPUnit\\Event\\TestRunner\\Started' => '/phpunit/Event/Events/TestRunner/Started.php',
2216 'PHPUnit\\Event\\TestRunner\\StartedSubscriber' => '/phpunit/Event/Events/TestRunner/StartedSubscriber.php',
2217 'PHPUnit\\Event\\TestRunner\\WarningTriggered' => '/phpunit/Event/Events/TestRunner/WarningTriggered.php',
2218 'PHPUnit\\Event\\TestRunner\\WarningTriggeredSubscriber' => '/phpunit/Event/Events/TestRunner/WarningTriggeredSubscriber.php',
2219 'PHPUnit\\Event\\TestSuite\\Filtered' => '/phpunit/Event/Events/TestSuite/Filtered.php',
2220 'PHPUnit\\Event\\TestSuite\\FilteredSubscriber' => '/phpunit/Event/Events/TestSuite/FilteredSubscriber.php',
2221 'PHPUnit\\Event\\TestSuite\\Finished' => '/phpunit/Event/Events/TestSuite/Finished.php',
2222 'PHPUnit\\Event\\TestSuite\\FinishedSubscriber' => '/phpunit/Event/Events/TestSuite/FinishedSubscriber.php',
2223 'PHPUnit\\Event\\TestSuite\\Loaded' => '/phpunit/Event/Events/TestSuite/Loaded.php',
2224 'PHPUnit\\Event\\TestSuite\\LoadedSubscriber' => '/phpunit/Event/Events/TestSuite/LoadedSubscriber.php',
2225 'PHPUnit\\Event\\TestSuite\\Skipped' => '/phpunit/Event/Events/TestSuite/Skipped.php',
2226 'PHPUnit\\Event\\TestSuite\\SkippedSubscriber' => '/phpunit/Event/Events/TestSuite/SkippedSubscriber.php',
2227 'PHPUnit\\Event\\TestSuite\\Sorted' => '/phpunit/Event/Events/TestSuite/Sorted.php',
2228 'PHPUnit\\Event\\TestSuite\\SortedSubscriber' => '/phpunit/Event/Events/TestSuite/SortedSubscriber.php',
2229 'PHPUnit\\Event\\TestSuite\\Started' => '/phpunit/Event/Events/TestSuite/Started.php',
2230 'PHPUnit\\Event\\TestSuite\\StartedSubscriber' => '/phpunit/Event/Events/TestSuite/StartedSubscriber.php',
2231 'PHPUnit\\Event\\TestSuite\\TestSuite' => '/phpunit/Event/Value/TestSuite/TestSuite.php',
2232 'PHPUnit\\Event\\TestSuite\\TestSuiteBuilder' => '/phpunit/Event/Value/TestSuite/TestSuiteBuilder.php',
2233 'PHPUnit\\Event\\TestSuite\\TestSuiteForTestClass' => '/phpunit/Event/Value/TestSuite/TestSuiteForTestClass.php',
2234 'PHPUnit\\Event\\TestSuite\\TestSuiteForTestMethodWithDataProvider' => '/phpunit/Event/Value/TestSuite/TestSuiteForTestMethodWithDataProvider.php',
2235 'PHPUnit\\Event\\TestSuite\\TestSuiteWithName' => '/phpunit/Event/Value/TestSuite/TestSuiteWithName.php',
2236 'PHPUnit\\Event\\Test\\AfterLastTestMethodCalled' => '/phpunit/Event/Events/Test/HookMethod/AfterLastTestMethodCalled.php',
2237 'PHPUnit\\Event\\Test\\AfterLastTestMethodCalledSubscriber' => '/phpunit/Event/Events/Test/HookMethod/AfterLastTestMethodCalledSubscriber.php',
2238 'PHPUnit\\Event\\Test\\AfterLastTestMethodErrored' => '/phpunit/Event/Events/Test/HookMethod/AfterLastTestMethodErrored.php',
2239 'PHPUnit\\Event\\Test\\AfterLastTestMethodErroredSubscriber' => '/phpunit/Event/Events/Test/HookMethod/AfterLastTestMethodErroredSubscriber.php',
2240 'PHPUnit\\Event\\Test\\AfterLastTestMethodFinished' => '/phpunit/Event/Events/Test/HookMethod/AfterLastTestMethodFinished.php',
2241 'PHPUnit\\Event\\Test\\AfterLastTestMethodFinishedSubscriber' => '/phpunit/Event/Events/Test/HookMethod/AfterLastTestMethodFinishedSubscriber.php',
2242 'PHPUnit\\Event\\Test\\AfterTestMethodCalled' => '/phpunit/Event/Events/Test/HookMethod/AfterTestMethodCalled.php',
2243 'PHPUnit\\Event\\Test\\AfterTestMethodCalledSubscriber' => '/phpunit/Event/Events/Test/HookMethod/AfterTestMethodCalledSubscriber.php',
2244 'PHPUnit\\Event\\Test\\AfterTestMethodErrored' => '/phpunit/Event/Events/Test/HookMethod/AfterTestMethodErrored.php',
2245 'PHPUnit\\Event\\Test\\AfterTestMethodErroredSubscriber' => '/phpunit/Event/Events/Test/HookMethod/AfterTestMethodErroredSubscriber.php',
2246 'PHPUnit\\Event\\Test\\AfterTestMethodFinished' => '/phpunit/Event/Events/Test/HookMethod/AfterTestMethodFinished.php',
2247 'PHPUnit\\Event\\Test\\AfterTestMethodFinishedSubscriber' => '/phpunit/Event/Events/Test/HookMethod/AfterTestMethodFinishedSubscriber.php',
2248 'PHPUnit\\Event\\Test\\AssertionFailed' => '/phpunit/Event/Events/Test/Assertion/AssertionFailed.php',
2249 'PHPUnit\\Event\\Test\\AssertionFailedSubscriber' => '/phpunit/Event/Events/Test/Assertion/AssertionFailedSubscriber.php',
2250 'PHPUnit\\Event\\Test\\AssertionSucceeded' => '/phpunit/Event/Events/Test/Assertion/AssertionSucceeded.php',
2251 'PHPUnit\\Event\\Test\\AssertionSucceededSubscriber' => '/phpunit/Event/Events/Test/Assertion/AssertionSucceededSubscriber.php',
2252 'PHPUnit\\Event\\Test\\BeforeFirstTestMethodCalled' => '/phpunit/Event/Events/Test/HookMethod/BeforeFirstTestMethodCalled.php',
2253 'PHPUnit\\Event\\Test\\BeforeFirstTestMethodCalledSubscriber' => '/phpunit/Event/Events/Test/HookMethod/BeforeFirstTestMethodCalledSubscriber.php',
2254 'PHPUnit\\Event\\Test\\BeforeFirstTestMethodErrored' => '/phpunit/Event/Events/Test/HookMethod/BeforeFirstTestMethodErrored.php',
2255 'PHPUnit\\Event\\Test\\BeforeFirstTestMethodErroredSubscriber' => '/phpunit/Event/Events/Test/HookMethod/BeforeFirstTestMethodErroredSubscriber.php',
2256 'PHPUnit\\Event\\Test\\BeforeFirstTestMethodFinished' => '/phpunit/Event/Events/Test/HookMethod/BeforeFirstTestMethodFinished.php',
2257 'PHPUnit\\Event\\Test\\BeforeFirstTestMethodFinishedSubscriber' => '/phpunit/Event/Events/Test/HookMethod/BeforeFirstTestMethodFinishedSubscriber.php',
2258 'PHPUnit\\Event\\Test\\BeforeTestMethodCalled' => '/phpunit/Event/Events/Test/HookMethod/BeforeTestMethodCalled.php',
2259 'PHPUnit\\Event\\Test\\BeforeTestMethodCalledSubscriber' => '/phpunit/Event/Events/Test/HookMethod/BeforeTestMethodCalledSubscriber.php',
2260 'PHPUnit\\Event\\Test\\BeforeTestMethodErrored' => '/phpunit/Event/Events/Test/HookMethod/BeforeTestMethodErrored.php',
2261 'PHPUnit\\Event\\Test\\BeforeTestMethodErroredSubscriber' => '/phpunit/Event/Events/Test/HookMethod/BeforeTestMethodErroredSubscriber.php',
2262 'PHPUnit\\Event\\Test\\BeforeTestMethodFinished' => '/phpunit/Event/Events/Test/HookMethod/BeforeTestMethodFinished.php',
2263 'PHPUnit\\Event\\Test\\BeforeTestMethodFinishedSubscriber' => '/phpunit/Event/Events/Test/HookMethod/BeforeTestMethodFinishedSubscriber.php',
2264 'PHPUnit\\Event\\Test\\ComparatorRegistered' => '/phpunit/Event/Events/Test/ComparatorRegistered.php',
2265 'PHPUnit\\Event\\Test\\ComparatorRegisteredSubscriber' => '/phpunit/Event/Events/Test/ComparatorRegisteredSubscriber.php',
2266 'PHPUnit\\Event\\Test\\ConsideredRisky' => '/phpunit/Event/Events/Test/Issue/ConsideredRisky.php',
2267 'PHPUnit\\Event\\Test\\ConsideredRiskySubscriber' => '/phpunit/Event/Events/Test/Issue/ConsideredRiskySubscriber.php',
2268 'PHPUnit\\Event\\Test\\DataProviderMethodCalled' => '/phpunit/Event/Events/Test/Lifecycle/DataProviderMethodCalled.php',
2269 'PHPUnit\\Event\\Test\\DataProviderMethodCalledSubscriber' => '/phpunit/Event/Events/Test/Lifecycle/DataProviderMethodCalledSubscriber.php',
2270 'PHPUnit\\Event\\Test\\DataProviderMethodFinished' => '/phpunit/Event/Events/Test/Lifecycle/DataProviderMethodFinished.php',
2271 'PHPUnit\\Event\\Test\\DataProviderMethodFinishedSubscriber' => '/phpunit/Event/Events/Test/Lifecycle/DataProviderMethodFinishedSubscriber.php',
2272 'PHPUnit\\Event\\Test\\DeprecationTriggered' => '/phpunit/Event/Events/Test/Issue/DeprecationTriggered.php',
2273 'PHPUnit\\Event\\Test\\DeprecationTriggeredSubscriber' => '/phpunit/Event/Events/Test/Issue/DeprecationTriggeredSubscriber.php',
2274 'PHPUnit\\Event\\Test\\ErrorTriggered' => '/phpunit/Event/Events/Test/Issue/ErrorTriggered.php',
2275 'PHPUnit\\Event\\Test\\ErrorTriggeredSubscriber' => '/phpunit/Event/Events/Test/Issue/ErrorTriggeredSubscriber.php',
2276 'PHPUnit\\Event\\Test\\Errored' => '/phpunit/Event/Events/Test/Outcome/Errored.php',
2277 'PHPUnit\\Event\\Test\\ErroredSubscriber' => '/phpunit/Event/Events/Test/Outcome/ErroredSubscriber.php',
2278 'PHPUnit\\Event\\Test\\Failed' => '/phpunit/Event/Events/Test/Outcome/Failed.php',
2279 'PHPUnit\\Event\\Test\\FailedSubscriber' => '/phpunit/Event/Events/Test/Outcome/FailedSubscriber.php',
2280 'PHPUnit\\Event\\Test\\Finished' => '/phpunit/Event/Events/Test/Lifecycle/Finished.php',
2281 'PHPUnit\\Event\\Test\\FinishedSubscriber' => '/phpunit/Event/Events/Test/Lifecycle/FinishedSubscriber.php',
2282 'PHPUnit\\Event\\Test\\MarkedIncomplete' => '/phpunit/Event/Events/Test/Outcome/MarkedIncomplete.php',
2283 'PHPUnit\\Event\\Test\\MarkedIncompleteSubscriber' => '/phpunit/Event/Events/Test/Outcome/MarkedIncompleteSubscriber.php',
2284 'PHPUnit\\Event\\Test\\MockObjectCreated' => '/phpunit/Event/Events/Test/TestDouble/MockObjectCreated.php',
2285 'PHPUnit\\Event\\Test\\MockObjectCreatedSubscriber' => '/phpunit/Event/Events/Test/TestDouble/MockObjectCreatedSubscriber.php',
2286 'PHPUnit\\Event\\Test\\MockObjectForAbstractClassCreated' => '/phpunit/Event/Events/Test/TestDouble/MockObjectForAbstractClassCreated.php',
2287 'PHPUnit\\Event\\Test\\MockObjectForAbstractClassCreatedSubscriber' => '/phpunit/Event/Events/Test/TestDouble/MockObjectForAbstractClassCreatedSubscriber.php',
2288 'PHPUnit\\Event\\Test\\MockObjectForIntersectionOfInterfacesCreated' => '/phpunit/Event/Events/Test/TestDouble/MockObjectForIntersectionOfInterfacesCreated.php',
2289 'PHPUnit\\Event\\Test\\MockObjectForIntersectionOfInterfacesCreatedSubscriber' => '/phpunit/Event/Events/Test/TestDouble/MockObjectForIntersectionOfInterfacesCreatedSubscriber.php',
2290 'PHPUnit\\Event\\Test\\MockObjectForTraitCreated' => '/phpunit/Event/Events/Test/TestDouble/MockObjectForTraitCreated.php',
2291 'PHPUnit\\Event\\Test\\MockObjectForTraitCreatedSubscriber' => '/phpunit/Event/Events/Test/TestDouble/MockObjectForTraitCreatedSubscriber.php',
2292 'PHPUnit\\Event\\Test\\MockObjectFromWsdlCreated' => '/phpunit/Event/Events/Test/TestDouble/MockObjectFromWsdlCreated.php',
2293 'PHPUnit\\Event\\Test\\MockObjectFromWsdlCreatedSubscriber' => '/phpunit/Event/Events/Test/TestDouble/MockObjectFromWsdlCreatedSubscriber.php',
2294 'PHPUnit\\Event\\Test\\NoComparisonFailureException' => '/phpunit/Event/Exception/NoComparisonFailureException.php',
2295 'PHPUnit\\Event\\Test\\NoticeTriggered' => '/phpunit/Event/Events/Test/Issue/NoticeTriggered.php',
2296 'PHPUnit\\Event\\Test\\NoticeTriggeredSubscriber' => '/phpunit/Event/Events/Test/Issue/NoticeTriggeredSubscriber.php',
2297 'PHPUnit\\Event\\Test\\PartialMockObjectCreated' => '/phpunit/Event/Events/Test/TestDouble/PartialMockObjectCreated.php',
2298 'PHPUnit\\Event\\Test\\PartialMockObjectCreatedSubscriber' => '/phpunit/Event/Events/Test/TestDouble/PartialMockObjectCreatedSubscriber.php',
2299 'PHPUnit\\Event\\Test\\Passed' => '/phpunit/Event/Events/Test/Outcome/Passed.php',
2300 'PHPUnit\\Event\\Test\\PassedSubscriber' => '/phpunit/Event/Events/Test/Outcome/PassedSubscriber.php',
2301 'PHPUnit\\Event\\Test\\PhpDeprecationTriggered' => '/phpunit/Event/Events/Test/Issue/PhpDeprecationTriggered.php',
2302 'PHPUnit\\Event\\Test\\PhpDeprecationTriggeredSubscriber' => '/phpunit/Event/Events/Test/Issue/PhpDeprecationTriggeredSubscriber.php',
2303 'PHPUnit\\Event\\Test\\PhpNoticeTriggered' => '/phpunit/Event/Events/Test/Issue/PhpNoticeTriggered.php',
2304 'PHPUnit\\Event\\Test\\PhpNoticeTriggeredSubscriber' => '/phpunit/Event/Events/Test/Issue/PhpNoticeTriggeredSubscriber.php',
2305 'PHPUnit\\Event\\Test\\PhpWarningTriggered' => '/phpunit/Event/Events/Test/Issue/PhpWarningTriggered.php',
2306 'PHPUnit\\Event\\Test\\PhpWarningTriggeredSubscriber' => '/phpunit/Event/Events/Test/Issue/PhpWarningTriggeredSubscriber.php',
2307 'PHPUnit\\Event\\Test\\PhpunitDeprecationTriggered' => '/phpunit/Event/Events/Test/Issue/PhpunitDeprecationTriggered.php',
2308 'PHPUnit\\Event\\Test\\PhpunitDeprecationTriggeredSubscriber' => '/phpunit/Event/Events/Test/Issue/PhpunitDeprecationTriggeredSubscriber.php',
2309 'PHPUnit\\Event\\Test\\PhpunitErrorTriggered' => '/phpunit/Event/Events/Test/Issue/PhpunitErrorTriggered.php',
2310 'PHPUnit\\Event\\Test\\PhpunitErrorTriggeredSubscriber' => '/phpunit/Event/Events/Test/Issue/PhpunitErrorTriggeredSubscriber.php',
2311 'PHPUnit\\Event\\Test\\PhpunitWarningTriggered' => '/phpunit/Event/Events/Test/Issue/PhpunitWarningTriggered.php',
2312 'PHPUnit\\Event\\Test\\PhpunitWarningTriggeredSubscriber' => '/phpunit/Event/Events/Test/Issue/PhpunitWarningTriggeredSubscriber.php',
2313 'PHPUnit\\Event\\Test\\PostConditionCalled' => '/phpunit/Event/Events/Test/HookMethod/PostConditionCalled.php',
2314 'PHPUnit\\Event\\Test\\PostConditionCalledSubscriber' => '/phpunit/Event/Events/Test/HookMethod/PostConditionCalledSubscriber.php',
2315 'PHPUnit\\Event\\Test\\PostConditionErrored' => '/phpunit/Event/Events/Test/HookMethod/PostConditionErrored.php',
2316 'PHPUnit\\Event\\Test\\PostConditionErroredSubscriber' => '/phpunit/Event/Events/Test/HookMethod/PostConditionErroredSubscriber.php',
2317 'PHPUnit\\Event\\Test\\PostConditionFinished' => '/phpunit/Event/Events/Test/HookMethod/PostConditionFinished.php',
2318 'PHPUnit\\Event\\Test\\PostConditionFinishedSubscriber' => '/phpunit/Event/Events/Test/HookMethod/PostConditionFinishedSubscriber.php',
2319 'PHPUnit\\Event\\Test\\PreConditionCalled' => '/phpunit/Event/Events/Test/HookMethod/PreConditionCalled.php',
2320 'PHPUnit\\Event\\Test\\PreConditionCalledSubscriber' => '/phpunit/Event/Events/Test/HookMethod/PreConditionCalledSubscriber.php',
2321 'PHPUnit\\Event\\Test\\PreConditionErrored' => '/phpunit/Event/Events/Test/HookMethod/PreConditionErrored.php',
2322 'PHPUnit\\Event\\Test\\PreConditionErroredSubscriber' => '/phpunit/Event/Events/Test/HookMethod/PreConditionErroredSubscriber.php',
2323 'PHPUnit\\Event\\Test\\PreConditionFinished' => '/phpunit/Event/Events/Test/HookMethod/PreConditionFinished.php',
2324 'PHPUnit\\Event\\Test\\PreConditionFinishedSubscriber' => '/phpunit/Event/Events/Test/HookMethod/PreConditionFinishedSubscriber.php',
2325 'PHPUnit\\Event\\Test\\PreparationFailed' => '/phpunit/Event/Events/Test/Lifecycle/PreparationFailed.php',
2326 'PHPUnit\\Event\\Test\\PreparationFailedSubscriber' => '/phpunit/Event/Events/Test/Lifecycle/PreparationFailedSubscriber.php',
2327 'PHPUnit\\Event\\Test\\PreparationStarted' => '/phpunit/Event/Events/Test/Lifecycle/PreparationStarted.php',
2328 'PHPUnit\\Event\\Test\\PreparationStartedSubscriber' => '/phpunit/Event/Events/Test/Lifecycle/PreparationStartedSubscriber.php',
2329 'PHPUnit\\Event\\Test\\Prepared' => '/phpunit/Event/Events/Test/Lifecycle/Prepared.php',
2330 'PHPUnit\\Event\\Test\\PreparedSubscriber' => '/phpunit/Event/Events/Test/Lifecycle/PreparedSubscriber.php',
2331 'PHPUnit\\Event\\Test\\PrintedUnexpectedOutput' => '/phpunit/Event/Events/Test/PrintedUnexpectedOutput.php',
2332 'PHPUnit\\Event\\Test\\PrintedUnexpectedOutputSubscriber' => '/phpunit/Event/Events/Test/PrintedUnexpectedOutputSubscriber.php',
2333 'PHPUnit\\Event\\Test\\Skipped' => '/phpunit/Event/Events/Test/Outcome/Skipped.php',
2334 'PHPUnit\\Event\\Test\\SkippedSubscriber' => '/phpunit/Event/Events/Test/Outcome/SkippedSubscriber.php',
2335 'PHPUnit\\Event\\Test\\TestProxyCreated' => '/phpunit/Event/Events/Test/TestDouble/TestProxyCreated.php',
2336 'PHPUnit\\Event\\Test\\TestProxyCreatedSubscriber' => '/phpunit/Event/Events/Test/TestDouble/TestProxyCreatedSubscriber.php',
2337 'PHPUnit\\Event\\Test\\TestStubCreated' => '/phpunit/Event/Events/Test/TestDouble/TestStubCreated.php',
2338 'PHPUnit\\Event\\Test\\TestStubCreatedSubscriber' => '/phpunit/Event/Events/Test/TestDouble/TestStubCreatedSubscriber.php',
2339 'PHPUnit\\Event\\Test\\TestStubForIntersectionOfInterfacesCreated' => '/phpunit/Event/Events/Test/TestDouble/TestStubForIntersectionOfInterfacesCreated.php',
2340 'PHPUnit\\Event\\Test\\TestStubForIntersectionOfInterfacesCreatedSubscriber' => '/phpunit/Event/Events/Test/TestDouble/TestStubForIntersectionOfInterfacesCreatedSubscriber.php',
2341 'PHPUnit\\Event\\Test\\WarningTriggered' => '/phpunit/Event/Events/Test/Issue/WarningTriggered.php',
2342 'PHPUnit\\Event\\Test\\WarningTriggeredSubscriber' => '/phpunit/Event/Events/Test/Issue/WarningTriggeredSubscriber.php',
2343 'PHPUnit\\Event\\Tracer\\Tracer' => '/phpunit/Event/Tracer.php',
2344 'PHPUnit\\Event\\TypeMap' => '/phpunit/Event/TypeMap.php',
2345 'PHPUnit\\Event\\UnknownEventException' => '/phpunit/Event/Exception/UnknownEventException.php',
2346 'PHPUnit\\Event\\UnknownEventTypeException' => '/phpunit/Event/Exception/UnknownEventTypeException.php',
2347 'PHPUnit\\Event\\UnknownSubscriberException' => '/phpunit/Event/Exception/UnknownSubscriberException.php',
2348 'PHPUnit\\Event\\UnknownSubscriberTypeException' => '/phpunit/Event/Exception/UnknownSubscriberTypeException.php',
2349 'PHPUnit\\Exception' => '/phpunit/Exception.php',
2350 'PHPUnit\\Framework\\ActualValueIsNotAnObjectException' => '/phpunit/Framework/Exception/ObjectEquals/ActualValueIsNotAnObjectException.php',
2351 'PHPUnit\\Framework\\Assert' => '/phpunit/Framework/Assert.php',
2352 'PHPUnit\\Framework\\AssertionFailedError' => '/phpunit/Framework/Exception/AssertionFailedError.php',
2353 'PHPUnit\\Framework\\Attributes\\After' => '/phpunit/Framework/Attributes/After.php',
2354 'PHPUnit\\Framework\\Attributes\\AfterClass' => '/phpunit/Framework/Attributes/AfterClass.php',
2355 'PHPUnit\\Framework\\Attributes\\BackupGlobals' => '/phpunit/Framework/Attributes/BackupGlobals.php',
2356 'PHPUnit\\Framework\\Attributes\\BackupStaticProperties' => '/phpunit/Framework/Attributes/BackupStaticProperties.php',
2357 'PHPUnit\\Framework\\Attributes\\Before' => '/phpunit/Framework/Attributes/Before.php',
2358 'PHPUnit\\Framework\\Attributes\\BeforeClass' => '/phpunit/Framework/Attributes/BeforeClass.php',
2359 'PHPUnit\\Framework\\Attributes\\CodeCoverageIgnore' => '/phpunit/Framework/Attributes/CodeCoverageIgnore.php',
2360 'PHPUnit\\Framework\\Attributes\\CoversClass' => '/phpunit/Framework/Attributes/CoversClass.php',
2361 'PHPUnit\\Framework\\Attributes\\CoversFunction' => '/phpunit/Framework/Attributes/CoversFunction.php',
2362 'PHPUnit\\Framework\\Attributes\\CoversNothing' => '/phpunit/Framework/Attributes/CoversNothing.php',
2363 'PHPUnit\\Framework\\Attributes\\DataProvider' => '/phpunit/Framework/Attributes/DataProvider.php',
2364 'PHPUnit\\Framework\\Attributes\\DataProviderExternal' => '/phpunit/Framework/Attributes/DataProviderExternal.php',
2365 'PHPUnit\\Framework\\Attributes\\Depends' => '/phpunit/Framework/Attributes/Depends.php',
2366 'PHPUnit\\Framework\\Attributes\\DependsExternal' => '/phpunit/Framework/Attributes/DependsExternal.php',
2367 'PHPUnit\\Framework\\Attributes\\DependsExternalUsingDeepClone' => '/phpunit/Framework/Attributes/DependsExternalUsingDeepClone.php',
2368 'PHPUnit\\Framework\\Attributes\\DependsExternalUsingShallowClone' => '/phpunit/Framework/Attributes/DependsExternalUsingShallowClone.php',
2369 'PHPUnit\\Framework\\Attributes\\DependsOnClass' => '/phpunit/Framework/Attributes/DependsOnClass.php',
2370 'PHPUnit\\Framework\\Attributes\\DependsOnClassUsingDeepClone' => '/phpunit/Framework/Attributes/DependsOnClassUsingDeepClone.php',
2371 'PHPUnit\\Framework\\Attributes\\DependsOnClassUsingShallowClone' => '/phpunit/Framework/Attributes/DependsOnClassUsingShallowClone.php',
2372 'PHPUnit\\Framework\\Attributes\\DependsUsingDeepClone' => '/phpunit/Framework/Attributes/DependsUsingDeepClone.php',
2373 'PHPUnit\\Framework\\Attributes\\DependsUsingShallowClone' => '/phpunit/Framework/Attributes/DependsUsingShallowClone.php',
2374 'PHPUnit\\Framework\\Attributes\\DoesNotPerformAssertions' => '/phpunit/Framework/Attributes/DoesNotPerformAssertions.php',
2375 'PHPUnit\\Framework\\Attributes\\ExcludeGlobalVariableFromBackup' => '/phpunit/Framework/Attributes/ExcludeGlobalVariableFromBackup.php',
2376 'PHPUnit\\Framework\\Attributes\\ExcludeStaticPropertyFromBackup' => '/phpunit/Framework/Attributes/ExcludeStaticPropertyFromBackup.php',
2377 'PHPUnit\\Framework\\Attributes\\Group' => '/phpunit/Framework/Attributes/Group.php',
2378 'PHPUnit\\Framework\\Attributes\\IgnoreClassForCodeCoverage' => '/phpunit/Framework/Attributes/IgnoreClassForCodeCoverage.php',
2379 'PHPUnit\\Framework\\Attributes\\IgnoreDeprecations' => '/phpunit/Framework/Attributes/IgnoreDeprecations.php',
2380 'PHPUnit\\Framework\\Attributes\\IgnoreFunctionForCodeCoverage' => '/phpunit/Framework/Attributes/IgnoreFunctionForCodeCoverage.php',
2381 'PHPUnit\\Framework\\Attributes\\IgnoreMethodForCodeCoverage' => '/phpunit/Framework/Attributes/IgnoreMethodForCodeCoverage.php',
2382 'PHPUnit\\Framework\\Attributes\\Large' => '/phpunit/Framework/Attributes/Large.php',
2383 'PHPUnit\\Framework\\Attributes\\Medium' => '/phpunit/Framework/Attributes/Medium.php',
2384 'PHPUnit\\Framework\\Attributes\\PostCondition' => '/phpunit/Framework/Attributes/PostCondition.php',
2385 'PHPUnit\\Framework\\Attributes\\PreCondition' => '/phpunit/Framework/Attributes/PreCondition.php',
2386 'PHPUnit\\Framework\\Attributes\\PreserveGlobalState' => '/phpunit/Framework/Attributes/PreserveGlobalState.php',
2387 'PHPUnit\\Framework\\Attributes\\RequiresFunction' => '/phpunit/Framework/Attributes/RequiresFunction.php',
2388 'PHPUnit\\Framework\\Attributes\\RequiresMethod' => '/phpunit/Framework/Attributes/RequiresMethod.php',
2389 'PHPUnit\\Framework\\Attributes\\RequiresOperatingSystem' => '/phpunit/Framework/Attributes/RequiresOperatingSystem.php',
2390 'PHPUnit\\Framework\\Attributes\\RequiresOperatingSystemFamily' => '/phpunit/Framework/Attributes/RequiresOperatingSystemFamily.php',
2391 'PHPUnit\\Framework\\Attributes\\RequiresPhp' => '/phpunit/Framework/Attributes/RequiresPhp.php',
2392 'PHPUnit\\Framework\\Attributes\\RequiresPhpExtension' => '/phpunit/Framework/Attributes/RequiresPhpExtension.php',
2393 'PHPUnit\\Framework\\Attributes\\RequiresPhpunit' => '/phpunit/Framework/Attributes/RequiresPhpunit.php',
2394 'PHPUnit\\Framework\\Attributes\\RequiresSetting' => '/phpunit/Framework/Attributes/RequiresSetting.php',
2395 'PHPUnit\\Framework\\Attributes\\RunClassInSeparateProcess' => '/phpunit/Framework/Attributes/RunClassInSeparateProcess.php',
2396 'PHPUnit\\Framework\\Attributes\\RunInSeparateProcess' => '/phpunit/Framework/Attributes/RunInSeparateProcess.php',
2397 'PHPUnit\\Framework\\Attributes\\RunTestsInSeparateProcesses' => '/phpunit/Framework/Attributes/RunTestsInSeparateProcesses.php',
2398 'PHPUnit\\Framework\\Attributes\\Small' => '/phpunit/Framework/Attributes/Small.php',
2399 'PHPUnit\\Framework\\Attributes\\Test' => '/phpunit/Framework/Attributes/Test.php',
2400 'PHPUnit\\Framework\\Attributes\\TestDox' => '/phpunit/Framework/Attributes/TestDox.php',
2401 'PHPUnit\\Framework\\Attributes\\TestWith' => '/phpunit/Framework/Attributes/TestWith.php',
2402 'PHPUnit\\Framework\\Attributes\\TestWithJson' => '/phpunit/Framework/Attributes/TestWithJson.php',
2403 'PHPUnit\\Framework\\Attributes\\Ticket' => '/phpunit/Framework/Attributes/Ticket.php',
2404 'PHPUnit\\Framework\\Attributes\\UsesClass' => '/phpunit/Framework/Attributes/UsesClass.php',
2405 'PHPUnit\\Framework\\Attributes\\UsesFunction' => '/phpunit/Framework/Attributes/UsesFunction.php',
2406 'PHPUnit\\Framework\\Attributes\\WithoutErrorHandler' => '/phpunit/Framework/Attributes/WithoutErrorHandler.php',
2407 'PHPUnit\\Framework\\CodeCoverageException' => '/phpunit/Framework/Exception/CodeCoverageException.php',
2408 'PHPUnit\\Framework\\ComparisonMethodDoesNotAcceptParameterTypeException' => '/phpunit/Framework/Exception/ObjectEquals/ComparisonMethodDoesNotAcceptParameterTypeException.php',
2409 'PHPUnit\\Framework\\ComparisonMethodDoesNotDeclareBoolReturnTypeException' => '/phpunit/Framework/Exception/ObjectEquals/ComparisonMethodDoesNotDeclareBoolReturnTypeException.php',
2410 'PHPUnit\\Framework\\ComparisonMethodDoesNotDeclareExactlyOneParameterException' => '/phpunit/Framework/Exception/ObjectEquals/ComparisonMethodDoesNotDeclareExactlyOneParameterException.php',
2411 'PHPUnit\\Framework\\ComparisonMethodDoesNotDeclareParameterTypeException' => '/phpunit/Framework/Exception/ObjectEquals/ComparisonMethodDoesNotDeclareParameterTypeException.php',
2412 'PHPUnit\\Framework\\ComparisonMethodDoesNotExistException' => '/phpunit/Framework/Exception/ObjectEquals/ComparisonMethodDoesNotExistException.php',
2413 'PHPUnit\\Framework\\Constraint\\ArrayHasKey' => '/phpunit/Framework/Constraint/Traversable/ArrayHasKey.php',
2414 'PHPUnit\\Framework\\Constraint\\BinaryOperator' => '/phpunit/Framework/Constraint/Operator/BinaryOperator.php',
2415 'PHPUnit\\Framework\\Constraint\\Callback' => '/phpunit/Framework/Constraint/Callback.php',
2416 'PHPUnit\\Framework\\Constraint\\Constraint' => '/phpunit/Framework/Constraint/Constraint.php',
2417 'PHPUnit\\Framework\\Constraint\\Count' => '/phpunit/Framework/Constraint/Cardinality/Count.php',
2418 'PHPUnit\\Framework\\Constraint\\DirectoryExists' => '/phpunit/Framework/Constraint/Filesystem/DirectoryExists.php',
2419 'PHPUnit\\Framework\\Constraint\\Exception' => '/phpunit/Framework/Constraint/Exception/Exception.php',
2420 'PHPUnit\\Framework\\Constraint\\ExceptionCode' => '/phpunit/Framework/Constraint/Exception/ExceptionCode.php',
2421 'PHPUnit\\Framework\\Constraint\\ExceptionMessageIsOrContains' => '/phpunit/Framework/Constraint/Exception/ExceptionMessageIsOrContains.php',
2422 'PHPUnit\\Framework\\Constraint\\ExceptionMessageMatchesRegularExpression' => '/phpunit/Framework/Constraint/Exception/ExceptionMessageMatchesRegularExpression.php',
2423 'PHPUnit\\Framework\\Constraint\\FileExists' => '/phpunit/Framework/Constraint/Filesystem/FileExists.php',
2424 'PHPUnit\\Framework\\Constraint\\GreaterThan' => '/phpunit/Framework/Constraint/Cardinality/GreaterThan.php',
2425 'PHPUnit\\Framework\\Constraint\\IsAnything' => '/phpunit/Framework/Constraint/IsAnything.php',
2426 'PHPUnit\\Framework\\Constraint\\IsEmpty' => '/phpunit/Framework/Constraint/Cardinality/IsEmpty.php',
2427 'PHPUnit\\Framework\\Constraint\\IsEqual' => '/phpunit/Framework/Constraint/Equality/IsEqual.php',
2428 'PHPUnit\\Framework\\Constraint\\IsEqualCanonicalizing' => '/phpunit/Framework/Constraint/Equality/IsEqualCanonicalizing.php',
2429 'PHPUnit\\Framework\\Constraint\\IsEqualIgnoringCase' => '/phpunit/Framework/Constraint/Equality/IsEqualIgnoringCase.php',
2430 'PHPUnit\\Framework\\Constraint\\IsEqualWithDelta' => '/phpunit/Framework/Constraint/Equality/IsEqualWithDelta.php',
2431 'PHPUnit\\Framework\\Constraint\\IsFalse' => '/phpunit/Framework/Constraint/Boolean/IsFalse.php',
2432 'PHPUnit\\Framework\\Constraint\\IsFinite' => '/phpunit/Framework/Constraint/Math/IsFinite.php',
2433 'PHPUnit\\Framework\\Constraint\\IsIdentical' => '/phpunit/Framework/Constraint/IsIdentical.php',
2434 'PHPUnit\\Framework\\Constraint\\IsInfinite' => '/phpunit/Framework/Constraint/Math/IsInfinite.php',
2435 'PHPUnit\\Framework\\Constraint\\IsInstanceOf' => '/phpunit/Framework/Constraint/Type/IsInstanceOf.php',
2436 'PHPUnit\\Framework\\Constraint\\IsJson' => '/phpunit/Framework/Constraint/String/IsJson.php',
2437 'PHPUnit\\Framework\\Constraint\\IsList' => '/phpunit/Framework/Constraint/Traversable/IsList.php',
2438 'PHPUnit\\Framework\\Constraint\\IsNan' => '/phpunit/Framework/Constraint/Math/IsNan.php',
2439 'PHPUnit\\Framework\\Constraint\\IsNull' => '/phpunit/Framework/Constraint/Type/IsNull.php',
2440 'PHPUnit\\Framework\\Constraint\\IsReadable' => '/phpunit/Framework/Constraint/Filesystem/IsReadable.php',
2441 'PHPUnit\\Framework\\Constraint\\IsTrue' => '/phpunit/Framework/Constraint/Boolean/IsTrue.php',
2442 'PHPUnit\\Framework\\Constraint\\IsType' => '/phpunit/Framework/Constraint/Type/IsType.php',
2443 'PHPUnit\\Framework\\Constraint\\IsWritable' => '/phpunit/Framework/Constraint/Filesystem/IsWritable.php',
2444 'PHPUnit\\Framework\\Constraint\\JsonMatches' => '/phpunit/Framework/Constraint/JsonMatches.php',
2445 'PHPUnit\\Framework\\Constraint\\LessThan' => '/phpunit/Framework/Constraint/Cardinality/LessThan.php',
2446 'PHPUnit\\Framework\\Constraint\\LogicalAnd' => '/phpunit/Framework/Constraint/Operator/LogicalAnd.php',
2447 'PHPUnit\\Framework\\Constraint\\LogicalNot' => '/phpunit/Framework/Constraint/Operator/LogicalNot.php',
2448 'PHPUnit\\Framework\\Constraint\\LogicalOr' => '/phpunit/Framework/Constraint/Operator/LogicalOr.php',
2449 'PHPUnit\\Framework\\Constraint\\LogicalXor' => '/phpunit/Framework/Constraint/Operator/LogicalXor.php',
2450 'PHPUnit\\Framework\\Constraint\\ObjectEquals' => '/phpunit/Framework/Constraint/Object/ObjectEquals.php',
2451 'PHPUnit\\Framework\\Constraint\\ObjectHasProperty' => '/phpunit/Framework/Constraint/Object/ObjectHasProperty.php',
2452 'PHPUnit\\Framework\\Constraint\\Operator' => '/phpunit/Framework/Constraint/Operator/Operator.php',
2453 'PHPUnit\\Framework\\Constraint\\RegularExpression' => '/phpunit/Framework/Constraint/String/RegularExpression.php',
2454 'PHPUnit\\Framework\\Constraint\\SameSize' => '/phpunit/Framework/Constraint/Cardinality/SameSize.php',
2455 'PHPUnit\\Framework\\Constraint\\StringContains' => '/phpunit/Framework/Constraint/String/StringContains.php',
2456 'PHPUnit\\Framework\\Constraint\\StringEndsWith' => '/phpunit/Framework/Constraint/String/StringEndsWith.php',
2457 'PHPUnit\\Framework\\Constraint\\StringEqualsStringIgnoringLineEndings' => '/phpunit/Framework/Constraint/String/StringEqualsStringIgnoringLineEndings.php',
2458 'PHPUnit\\Framework\\Constraint\\StringMatchesFormatDescription' => '/phpunit/Framework/Constraint/String/StringMatchesFormatDescription.php',
2459 'PHPUnit\\Framework\\Constraint\\StringStartsWith' => '/phpunit/Framework/Constraint/String/StringStartsWith.php',
2460 'PHPUnit\\Framework\\Constraint\\TraversableContains' => '/phpunit/Framework/Constraint/Traversable/TraversableContains.php',
2461 'PHPUnit\\Framework\\Constraint\\TraversableContainsEqual' => '/phpunit/Framework/Constraint/Traversable/TraversableContainsEqual.php',
2462 'PHPUnit\\Framework\\Constraint\\TraversableContainsIdentical' => '/phpunit/Framework/Constraint/Traversable/TraversableContainsIdentical.php',
2463 'PHPUnit\\Framework\\Constraint\\TraversableContainsOnly' => '/phpunit/Framework/Constraint/Traversable/TraversableContainsOnly.php',
2464 'PHPUnit\\Framework\\Constraint\\UnaryOperator' => '/phpunit/Framework/Constraint/Operator/UnaryOperator.php',
2465 'PHPUnit\\Framework\\DataProviderTestSuite' => '/phpunit/Framework/DataProviderTestSuite.php',
2466 'PHPUnit\\Framework\\EmptyStringException' => '/phpunit/Framework/Exception/EmptyStringException.php',
2467 'PHPUnit\\Framework\\Exception' => '/phpunit/Framework/Exception/Exception.php',
2468 'PHPUnit\\Framework\\ExecutionOrderDependency' => '/phpunit/Framework/ExecutionOrderDependency.php',
2469 'PHPUnit\\Framework\\ExpectationFailedException' => '/phpunit/Framework/Exception/ExpectationFailedException.php',
2470 'PHPUnit\\Framework\\GeneratorNotSupportedException' => '/phpunit/Framework/Exception/GeneratorNotSupportedException.php',
2471 'PHPUnit\\Framework\\IncompleteTest' => '/phpunit/Framework/Exception/Incomplete/IncompleteTest.php',
2472 'PHPUnit\\Framework\\IncompleteTestError' => '/phpunit/Framework/Exception/Incomplete/IncompleteTestError.php',
2473 'PHPUnit\\Framework\\InvalidArgumentException' => '/phpunit/Framework/Exception/InvalidArgumentException.php',
2474 'PHPUnit\\Framework\\InvalidCoversTargetException' => '/phpunit/Framework/Exception/InvalidCoversTargetException.php',
2475 'PHPUnit\\Framework\\InvalidDataProviderException' => '/phpunit/Framework/Exception/InvalidDataProviderException.php',
2476 'PHPUnit\\Framework\\InvalidDependencyException' => '/phpunit/Framework/Exception/InvalidDependencyException.php',
2477 'PHPUnit\\Framework\\MockObject\\BadMethodCallException' => '/phpunit/Framework/MockObject/Exception/BadMethodCallException.php',
2478 'PHPUnit\\Framework\\MockObject\\Builder\\Identity' => '/phpunit/Framework/MockObject/Runtime/Builder/Identity.php',
2479 'PHPUnit\\Framework\\MockObject\\Builder\\InvocationMocker' => '/phpunit/Framework/MockObject/Runtime/Builder/InvocationMocker.php',
2480 'PHPUnit\\Framework\\MockObject\\Builder\\InvocationStubber' => '/phpunit/Framework/MockObject/Runtime/Builder/InvocationStubber.php',
2481 'PHPUnit\\Framework\\MockObject\\Builder\\MethodNameMatch' => '/phpunit/Framework/MockObject/Runtime/Builder/MethodNameMatch.php',
2482 'PHPUnit\\Framework\\MockObject\\Builder\\ParametersMatch' => '/phpunit/Framework/MockObject/Runtime/Builder/ParametersMatch.php',
2483 'PHPUnit\\Framework\\MockObject\\Builder\\Stub' => '/phpunit/Framework/MockObject/Runtime/Builder/Stub.php',
2484 'PHPUnit\\Framework\\MockObject\\CannotUseOnlyMethodsException' => '/phpunit/Framework/MockObject/Exception/CannotUseOnlyMethodsException.php',
2485 'PHPUnit\\Framework\\MockObject\\ConfigurableMethod' => '/phpunit/Framework/MockObject/ConfigurableMethod.php',
2486 'PHPUnit\\Framework\\MockObject\\DoubledCloneMethod' => '/phpunit/Framework/MockObject/Runtime/Api/DoubledCloneMethod.php',
2487 'PHPUnit\\Framework\\MockObject\\Exception' => '/phpunit/Framework/MockObject/Exception/Exception.php',
2488 'PHPUnit\\Framework\\MockObject\\Generator\\CannotUseAddMethodsException' => '/phpunit/Framework/MockObject/Generator/Exception/CannotUseAddMethodsException.php',
2489 'PHPUnit\\Framework\\MockObject\\Generator\\ClassIsEnumerationException' => '/phpunit/Framework/MockObject/Generator/Exception/ClassIsEnumerationException.php',
2490 'PHPUnit\\Framework\\MockObject\\Generator\\ClassIsFinalException' => '/phpunit/Framework/MockObject/Generator/Exception/ClassIsFinalException.php',
2491 'PHPUnit\\Framework\\MockObject\\Generator\\ClassIsReadonlyException' => '/phpunit/Framework/MockObject/Generator/Exception/ClassIsReadonlyException.php',
2492 'PHPUnit\\Framework\\MockObject\\Generator\\DuplicateMethodException' => '/phpunit/Framework/MockObject/Generator/Exception/DuplicateMethodException.php',
2493 'PHPUnit\\Framework\\MockObject\\Generator\\Exception' => '/phpunit/Framework/MockObject/Generator/Exception/Exception.php',
2494 'PHPUnit\\Framework\\MockObject\\Generator\\Generator' => '/phpunit/Framework/MockObject/Generator/Generator.php',
2495 'PHPUnit\\Framework\\MockObject\\Generator\\InvalidMethodNameException' => '/phpunit/Framework/MockObject/Generator/Exception/InvalidMethodNameException.php',
2496 'PHPUnit\\Framework\\MockObject\\Generator\\MockClass' => '/phpunit/Framework/MockObject/Generator/MockClass.php',
2497 'PHPUnit\\Framework\\MockObject\\Generator\\MockMethod' => '/phpunit/Framework/MockObject/Generator/MockMethod.php',
2498 'PHPUnit\\Framework\\MockObject\\Generator\\MockMethodSet' => '/phpunit/Framework/MockObject/Generator/MockMethodSet.php',
2499 'PHPUnit\\Framework\\MockObject\\Generator\\MockTrait' => '/phpunit/Framework/MockObject/Generator/MockTrait.php',
2500 'PHPUnit\\Framework\\MockObject\\Generator\\MockType' => '/phpunit/Framework/MockObject/Generator/MockType.php',
2501 'PHPUnit\\Framework\\MockObject\\Generator\\NameAlreadyInUseException' => '/phpunit/Framework/MockObject/Generator/Exception/NameAlreadyInUseException.php',
2502 'PHPUnit\\Framework\\MockObject\\Generator\\OriginalConstructorInvocationRequiredException' => '/phpunit/Framework/MockObject/Generator/Exception/OriginalConstructorInvocationRequiredException.php',
2503 'PHPUnit\\Framework\\MockObject\\Generator\\ReflectionException' => '/phpunit/Framework/MockObject/Generator/Exception/ReflectionException.php',
2504 'PHPUnit\\Framework\\MockObject\\Generator\\RuntimeException' => '/phpunit/Framework/MockObject/Generator/Exception/RuntimeException.php',
2505 'PHPUnit\\Framework\\MockObject\\Generator\\SoapExtensionNotAvailableException' => '/phpunit/Framework/MockObject/Generator/Exception/SoapExtensionNotAvailableException.php',
2506 'PHPUnit\\Framework\\MockObject\\Generator\\TemplateLoader' => '/phpunit/Framework/MockObject/Generator/TemplateLoader.php',
2507 'PHPUnit\\Framework\\MockObject\\Generator\\UnknownClassException' => '/phpunit/Framework/MockObject/Generator/Exception/UnknownClassException.php',
2508 'PHPUnit\\Framework\\MockObject\\Generator\\UnknownTraitException' => '/phpunit/Framework/MockObject/Generator/Exception/UnknownTraitException.php',
2509 'PHPUnit\\Framework\\MockObject\\Generator\\UnknownTypeException' => '/phpunit/Framework/MockObject/Generator/Exception/UnknownTypeException.php',
2510 'PHPUnit\\Framework\\MockObject\\IncompatibleReturnValueException' => '/phpunit/Framework/MockObject/Exception/IncompatibleReturnValueException.php',
2511 'PHPUnit\\Framework\\MockObject\\Invocation' => '/phpunit/Framework/MockObject/Runtime/Invocation.php',
2512 'PHPUnit\\Framework\\MockObject\\InvocationHandler' => '/phpunit/Framework/MockObject/Runtime/InvocationHandler.php',
2513 'PHPUnit\\Framework\\MockObject\\MatchBuilderNotFoundException' => '/phpunit/Framework/MockObject/Exception/MatchBuilderNotFoundException.php',
2514 'PHPUnit\\Framework\\MockObject\\Matcher' => '/phpunit/Framework/MockObject/Runtime/Matcher.php',
2515 'PHPUnit\\Framework\\MockObject\\MatcherAlreadyRegisteredException' => '/phpunit/Framework/MockObject/Exception/MatcherAlreadyRegisteredException.php',
2516 'PHPUnit\\Framework\\MockObject\\Method' => '/phpunit/Framework/MockObject/Runtime/Api/Method.php',
2517 'PHPUnit\\Framework\\MockObject\\MethodCannotBeConfiguredException' => '/phpunit/Framework/MockObject/Exception/MethodCannotBeConfiguredException.php',
2518 'PHPUnit\\Framework\\MockObject\\MethodNameAlreadyConfiguredException' => '/phpunit/Framework/MockObject/Exception/MethodNameAlreadyConfiguredException.php',
2519 'PHPUnit\\Framework\\MockObject\\MethodNameConstraint' => '/phpunit/Framework/MockObject/Runtime/MethodNameConstraint.php',
2520 'PHPUnit\\Framework\\MockObject\\MethodNameNotConfiguredException' => '/phpunit/Framework/MockObject/Exception/MethodNameNotConfiguredException.php',
2521 'PHPUnit\\Framework\\MockObject\\MethodParametersAlreadyConfiguredException' => '/phpunit/Framework/MockObject/Exception/MethodParametersAlreadyConfiguredException.php',
2522 'PHPUnit\\Framework\\MockObject\\MockBuilder' => '/phpunit/Framework/MockObject/MockBuilder.php',
2523 'PHPUnit\\Framework\\MockObject\\MockObject' => '/phpunit/Framework/MockObject/Runtime/Interface/MockObject.php',
2524 'PHPUnit\\Framework\\MockObject\\MockObjectApi' => '/phpunit/Framework/MockObject/Runtime/Api/MockObjectApi.php',
2525 'PHPUnit\\Framework\\MockObject\\MockObjectInternal' => '/phpunit/Framework/MockObject/Runtime/Interface/MockObjectInternal.php',
2526 'PHPUnit\\Framework\\MockObject\\NeverReturningMethodException' => '/phpunit/Framework/MockObject/Exception/NeverReturningMethodException.php',
2527 'PHPUnit\\Framework\\MockObject\\NoMoreReturnValuesConfiguredException' => '/phpunit/Framework/MockObject/Exception/NoMoreReturnValuesConfiguredException.php',
2528 'PHPUnit\\Framework\\MockObject\\ProxiedCloneMethod' => '/phpunit/Framework/MockObject/Runtime/Api/ProxiedCloneMethod.php',
2529 'PHPUnit\\Framework\\MockObject\\ReturnValueGenerator' => '/phpunit/Framework/MockObject/Runtime/ReturnValueGenerator.php',
2530 'PHPUnit\\Framework\\MockObject\\ReturnValueNotConfiguredException' => '/phpunit/Framework/MockObject/Exception/ReturnValueNotConfiguredException.php',
2531 'PHPUnit\\Framework\\MockObject\\Rule\\AnyInvokedCount' => '/phpunit/Framework/MockObject/Runtime/Rule/AnyInvokedCount.php',
2532 'PHPUnit\\Framework\\MockObject\\Rule\\AnyParameters' => '/phpunit/Framework/MockObject/Runtime/Rule/AnyParameters.php',
2533 'PHPUnit\\Framework\\MockObject\\Rule\\InvocationOrder' => '/phpunit/Framework/MockObject/Runtime/Rule/InvocationOrder.php',
2534 'PHPUnit\\Framework\\MockObject\\Rule\\InvokedAtLeastCount' => '/phpunit/Framework/MockObject/Runtime/Rule/InvokedAtLeastCount.php',
2535 'PHPUnit\\Framework\\MockObject\\Rule\\InvokedAtLeastOnce' => '/phpunit/Framework/MockObject/Runtime/Rule/InvokedAtLeastOnce.php',
2536 'PHPUnit\\Framework\\MockObject\\Rule\\InvokedAtMostCount' => '/phpunit/Framework/MockObject/Runtime/Rule/InvokedAtMostCount.php',
2537 'PHPUnit\\Framework\\MockObject\\Rule\\InvokedCount' => '/phpunit/Framework/MockObject/Runtime/Rule/InvokedCount.php',
2538 'PHPUnit\\Framework\\MockObject\\Rule\\MethodName' => '/phpunit/Framework/MockObject/Runtime/Rule/MethodName.php',
2539 'PHPUnit\\Framework\\MockObject\\Rule\\Parameters' => '/phpunit/Framework/MockObject/Runtime/Rule/Parameters.php',
2540 'PHPUnit\\Framework\\MockObject\\Rule\\ParametersRule' => '/phpunit/Framework/MockObject/Runtime/Rule/ParametersRule.php',
2541 'PHPUnit\\Framework\\MockObject\\RuntimeException' => '/phpunit/Framework/MockObject/Exception/RuntimeException.php',
2542 'PHPUnit\\Framework\\MockObject\\Stub' => '/phpunit/Framework/MockObject/Runtime/Interface/Stub.php',
2543 'PHPUnit\\Framework\\MockObject\\StubApi' => '/phpunit/Framework/MockObject/Runtime/Api/StubApi.php',
2544 'PHPUnit\\Framework\\MockObject\\StubInternal' => '/phpunit/Framework/MockObject/Runtime/Interface/StubInternal.php',
2545 'PHPUnit\\Framework\\MockObject\\Stub\\ConsecutiveCalls' => '/phpunit/Framework/MockObject/Runtime/Stub/ConsecutiveCalls.php',
2546 'PHPUnit\\Framework\\MockObject\\Stub\\Exception' => '/phpunit/Framework/MockObject/Runtime/Stub/Exception.php',
2547 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnArgument' => '/phpunit/Framework/MockObject/Runtime/Stub/ReturnArgument.php',
2548 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnCallback' => '/phpunit/Framework/MockObject/Runtime/Stub/ReturnCallback.php',
2549 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnReference' => '/phpunit/Framework/MockObject/Runtime/Stub/ReturnReference.php',
2550 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnSelf' => '/phpunit/Framework/MockObject/Runtime/Stub/ReturnSelf.php',
2551 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnStub' => '/phpunit/Framework/MockObject/Runtime/Stub/ReturnStub.php',
2552 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnValueMap' => '/phpunit/Framework/MockObject/Runtime/Stub/ReturnValueMap.php',
2553 'PHPUnit\\Framework\\MockObject\\Stub\\Stub' => '/phpunit/Framework/MockObject/Runtime/Stub/Stub.php',
2554 'PHPUnit\\Framework\\NoChildTestSuiteException' => '/phpunit/Framework/Exception/NoChildTestSuiteException.php',
2555 'PHPUnit\\Framework\\PhptAssertionFailedError' => '/phpunit/Framework/Exception/PhptAssertionFailedError.php',
2556 'PHPUnit\\Framework\\ProcessIsolationException' => '/phpunit/Framework/Exception/ProcessIsolationException.php',
2557 'PHPUnit\\Framework\\Reorderable' => '/phpunit/Framework/Reorderable.php',
2558 'PHPUnit\\Framework\\SelfDescribing' => '/phpunit/Framework/SelfDescribing.php',
2559 'PHPUnit\\Framework\\SkippedTest' => '/phpunit/Framework/Exception/Skipped/SkippedTest.php',
2560 'PHPUnit\\Framework\\SkippedTestSuiteError' => '/phpunit/Framework/Exception/Skipped/SkippedTestSuiteError.php',
2561 'PHPUnit\\Framework\\SkippedWithMessageException' => '/phpunit/Framework/Exception/Skipped/SkippedWithMessageException.php',
2562 'PHPUnit\\Framework\\Test' => '/phpunit/Framework/Test.php',
2563 'PHPUnit\\Framework\\TestBuilder' => '/phpunit/Framework/TestBuilder.php',
2564 'PHPUnit\\Framework\\TestCase' => '/phpunit/Framework/TestCase.php',
2565 'PHPUnit\\Framework\\TestRunner' => '/phpunit/Framework/TestRunner.php',
2566 'PHPUnit\\Framework\\TestSize\\Known' => '/phpunit/Framework/TestSize/Known.php',
2567 'PHPUnit\\Framework\\TestSize\\Large' => '/phpunit/Framework/TestSize/Large.php',
2568 'PHPUnit\\Framework\\TestSize\\Medium' => '/phpunit/Framework/TestSize/Medium.php',
2569 'PHPUnit\\Framework\\TestSize\\Small' => '/phpunit/Framework/TestSize/Small.php',
2570 'PHPUnit\\Framework\\TestSize\\TestSize' => '/phpunit/Framework/TestSize/TestSize.php',
2571 'PHPUnit\\Framework\\TestSize\\Unknown' => '/phpunit/Framework/TestSize/Unknown.php',
2572 'PHPUnit\\Framework\\TestStatus\\Deprecation' => '/phpunit/Framework/TestStatus/Deprecation.php',
2573 'PHPUnit\\Framework\\TestStatus\\Error' => '/phpunit/Framework/TestStatus/Error.php',
2574 'PHPUnit\\Framework\\TestStatus\\Failure' => '/phpunit/Framework/TestStatus/Failure.php',
2575 'PHPUnit\\Framework\\TestStatus\\Incomplete' => '/phpunit/Framework/TestStatus/Incomplete.php',
2576 'PHPUnit\\Framework\\TestStatus\\Known' => '/phpunit/Framework/TestStatus/Known.php',
2577 'PHPUnit\\Framework\\TestStatus\\Notice' => '/phpunit/Framework/TestStatus/Notice.php',
2578 'PHPUnit\\Framework\\TestStatus\\Risky' => '/phpunit/Framework/TestStatus/Risky.php',
2579 'PHPUnit\\Framework\\TestStatus\\Skipped' => '/phpunit/Framework/TestStatus/Skipped.php',
2580 'PHPUnit\\Framework\\TestStatus\\Success' => '/phpunit/Framework/TestStatus/Success.php',
2581 'PHPUnit\\Framework\\TestStatus\\TestStatus' => '/phpunit/Framework/TestStatus/TestStatus.php',
2582 'PHPUnit\\Framework\\TestStatus\\Unknown' => '/phpunit/Framework/TestStatus/Unknown.php',
2583 'PHPUnit\\Framework\\TestStatus\\Warning' => '/phpunit/Framework/TestStatus/Warning.php',
2584 'PHPUnit\\Framework\\TestSuite' => '/phpunit/Framework/TestSuite.php',
2585 'PHPUnit\\Framework\\TestSuiteIterator' => '/phpunit/Framework/TestSuiteIterator.php',
2586 'PHPUnit\\Framework\\UnknownClassOrInterfaceException' => '/phpunit/Framework/Exception/UnknownClassOrInterfaceException.php',
2587 'PHPUnit\\Framework\\UnknownTypeException' => '/phpunit/Framework/Exception/UnknownTypeException.php',
2588 'PHPUnit\\Logging\\EventLogger' => '/phpunit/Logging/EventLogger.php',
2589 'PHPUnit\\Logging\\JUnit\\JunitXmlLogger' => '/phpunit/Logging/JUnit/JunitXmlLogger.php',
2590 'PHPUnit\\Logging\\JUnit\\Subscriber' => '/phpunit/Logging/JUnit/Subscriber/Subscriber.php',
2591 'PHPUnit\\Logging\\JUnit\\TestErroredSubscriber' => '/phpunit/Logging/JUnit/Subscriber/TestErroredSubscriber.php',
2592 'PHPUnit\\Logging\\JUnit\\TestFailedSubscriber' => '/phpunit/Logging/JUnit/Subscriber/TestFailedSubscriber.php',
2593 'PHPUnit\\Logging\\JUnit\\TestFinishedSubscriber' => '/phpunit/Logging/JUnit/Subscriber/TestFinishedSubscriber.php',
2594 'PHPUnit\\Logging\\JUnit\\TestMarkedIncompleteSubscriber' => '/phpunit/Logging/JUnit/Subscriber/TestMarkedIncompleteSubscriber.php',
2595 'PHPUnit\\Logging\\JUnit\\TestPreparationFailedSubscriber' => '/phpunit/Logging/JUnit/Subscriber/TestPreparationFailedSubscriber.php',
2596 'PHPUnit\\Logging\\JUnit\\TestPreparationStartedSubscriber' => '/phpunit/Logging/JUnit/Subscriber/TestPreparationStartedSubscriber.php',
2597 'PHPUnit\\Logging\\JUnit\\TestPreparedSubscriber' => '/phpunit/Logging/JUnit/Subscriber/TestPreparedSubscriber.php',
2598 'PHPUnit\\Logging\\JUnit\\TestPrintedUnexpectedOutputSubscriber' => '/phpunit/Logging/JUnit/Subscriber/TestPrintedUnexpectedOutputSubscriber.php',
2599 'PHPUnit\\Logging\\JUnit\\TestRunnerExecutionFinishedSubscriber' => '/phpunit/Logging/JUnit/Subscriber/TestRunnerExecutionFinishedSubscriber.php',
2600 'PHPUnit\\Logging\\JUnit\\TestSkippedSubscriber' => '/phpunit/Logging/JUnit/Subscriber/TestSkippedSubscriber.php',
2601 'PHPUnit\\Logging\\JUnit\\TestSuiteFinishedSubscriber' => '/phpunit/Logging/JUnit/Subscriber/TestSuiteFinishedSubscriber.php',
2602 'PHPUnit\\Logging\\JUnit\\TestSuiteStartedSubscriber' => '/phpunit/Logging/JUnit/Subscriber/TestSuiteStartedSubscriber.php',
2603 'PHPUnit\\Logging\\TeamCity\\Subscriber' => '/phpunit/Logging/TeamCity/Subscriber/Subscriber.php',
2604 'PHPUnit\\Logging\\TeamCity\\TeamCityLogger' => '/phpunit/Logging/TeamCity/TeamCityLogger.php',
2605 'PHPUnit\\Logging\\TeamCity\\TestConsideredRiskySubscriber' => '/phpunit/Logging/TeamCity/Subscriber/TestConsideredRiskySubscriber.php',
2606 'PHPUnit\\Logging\\TeamCity\\TestErroredSubscriber' => '/phpunit/Logging/TeamCity/Subscriber/TestErroredSubscriber.php',
2607 'PHPUnit\\Logging\\TeamCity\\TestFailedSubscriber' => '/phpunit/Logging/TeamCity/Subscriber/TestFailedSubscriber.php',
2608 'PHPUnit\\Logging\\TeamCity\\TestFinishedSubscriber' => '/phpunit/Logging/TeamCity/Subscriber/TestFinishedSubscriber.php',
2609 'PHPUnit\\Logging\\TeamCity\\TestMarkedIncompleteSubscriber' => '/phpunit/Logging/TeamCity/Subscriber/TestMarkedIncompleteSubscriber.php',
2610 'PHPUnit\\Logging\\TeamCity\\TestPreparedSubscriber' => '/phpunit/Logging/TeamCity/Subscriber/TestPreparedSubscriber.php',
2611 'PHPUnit\\Logging\\TeamCity\\TestRunnerExecutionFinishedSubscriber' => '/phpunit/Logging/TeamCity/Subscriber/TestRunnerExecutionFinishedSubscriber.php',
2612 'PHPUnit\\Logging\\TeamCity\\TestSkippedSubscriber' => '/phpunit/Logging/TeamCity/Subscriber/TestSkippedSubscriber.php',
2613 'PHPUnit\\Logging\\TeamCity\\TestSuiteBeforeFirstTestMethodErroredSubscriber' => '/phpunit/Logging/TeamCity/Subscriber/TestSuiteBeforeFirstTestMethodErroredSubscriber.php',
2614 'PHPUnit\\Logging\\TeamCity\\TestSuiteFinishedSubscriber' => '/phpunit/Logging/TeamCity/Subscriber/TestSuiteFinishedSubscriber.php',
2615 'PHPUnit\\Logging\\TeamCity\\TestSuiteSkippedSubscriber' => '/phpunit/Logging/TeamCity/Subscriber/TestSuiteSkippedSubscriber.php',
2616 'PHPUnit\\Logging\\TeamCity\\TestSuiteStartedSubscriber' => '/phpunit/Logging/TeamCity/Subscriber/TestSuiteStartedSubscriber.php',
2617 'PHPUnit\\Logging\\TestDox\\HtmlRenderer' => '/phpunit/Logging/TestDox/HtmlRenderer.php',
2618 'PHPUnit\\Logging\\TestDox\\NamePrettifier' => '/phpunit/Logging/TestDox/NamePrettifier.php',
2619 'PHPUnit\\Logging\\TestDox\\PlainTextRenderer' => '/phpunit/Logging/TestDox/PlainTextRenderer.php',
2620 'PHPUnit\\Logging\\TestDox\\Subscriber' => '/phpunit/Logging/TestDox/TestResult/Subscriber/Subscriber.php',
2621 'PHPUnit\\Logging\\TestDox\\TestConsideredRiskySubscriber' => '/phpunit/Logging/TestDox/TestResult/Subscriber/TestConsideredRiskySubscriber.php',
2622 'PHPUnit\\Logging\\TestDox\\TestErroredSubscriber' => '/phpunit/Logging/TestDox/TestResult/Subscriber/TestErroredSubscriber.php',
2623 'PHPUnit\\Logging\\TestDox\\TestFailedSubscriber' => '/phpunit/Logging/TestDox/TestResult/Subscriber/TestFailedSubscriber.php',
2624 'PHPUnit\\Logging\\TestDox\\TestFinishedSubscriber' => '/phpunit/Logging/TestDox/TestResult/Subscriber/TestFinishedSubscriber.php',
2625 'PHPUnit\\Logging\\TestDox\\TestMarkedIncompleteSubscriber' => '/phpunit/Logging/TestDox/TestResult/Subscriber/TestMarkedIncompleteSubscriber.php',
2626 'PHPUnit\\Logging\\TestDox\\TestPassedSubscriber' => '/phpunit/Logging/TestDox/TestResult/Subscriber/TestPassedSubscriber.php',
2627 'PHPUnit\\Logging\\TestDox\\TestPreparedSubscriber' => '/phpunit/Logging/TestDox/TestResult/Subscriber/TestPreparedSubscriber.php',
2628 'PHPUnit\\Logging\\TestDox\\TestResult' => '/phpunit/Logging/TestDox/TestResult/TestResult.php',
2629 'PHPUnit\\Logging\\TestDox\\TestResultCollection' => '/phpunit/Logging/TestDox/TestResult/TestResultCollection.php',
2630 'PHPUnit\\Logging\\TestDox\\TestResultCollectionIterator' => '/phpunit/Logging/TestDox/TestResult/TestResultCollectionIterator.php',
2631 'PHPUnit\\Logging\\TestDox\\TestResultCollector' => '/phpunit/Logging/TestDox/TestResult/TestResultCollector.php',
2632 'PHPUnit\\Logging\\TestDox\\TestSkippedSubscriber' => '/phpunit/Logging/TestDox/TestResult/Subscriber/TestSkippedSubscriber.php',
2633 'PHPUnit\\Logging\\TestDox\\TestTriggeredDeprecationSubscriber' => '/phpunit/Logging/TestDox/TestResult/Subscriber/TestTriggeredDeprecationSubscriber.php',
2634 'PHPUnit\\Logging\\TestDox\\TestTriggeredNoticeSubscriber' => '/phpunit/Logging/TestDox/TestResult/Subscriber/TestTriggeredNoticeSubscriber.php',
2635 'PHPUnit\\Logging\\TestDox\\TestTriggeredPhpDeprecationSubscriber' => '/phpunit/Logging/TestDox/TestResult/Subscriber/TestTriggeredPhpDeprecationSubscriber.php',
2636 'PHPUnit\\Logging\\TestDox\\TestTriggeredPhpNoticeSubscriber' => '/phpunit/Logging/TestDox/TestResult/Subscriber/TestTriggeredPhpNoticeSubscriber.php',
2637 'PHPUnit\\Logging\\TestDox\\TestTriggeredPhpWarningSubscriber' => '/phpunit/Logging/TestDox/TestResult/Subscriber/TestTriggeredPhpWarningSubscriber.php',
2638 'PHPUnit\\Logging\\TestDox\\TestTriggeredPhpunitDeprecationSubscriber' => '/phpunit/Logging/TestDox/TestResult/Subscriber/TestTriggeredPhpunitDeprecationSubscriber.php',
2639 'PHPUnit\\Logging\\TestDox\\TestTriggeredPhpunitErrorSubscriber' => '/phpunit/Logging/TestDox/TestResult/Subscriber/TestTriggeredPhpunitErrorSubscriber.php',
2640 'PHPUnit\\Logging\\TestDox\\TestTriggeredPhpunitWarningSubscriber' => '/phpunit/Logging/TestDox/TestResult/Subscriber/TestTriggeredPhpunitWarningSubscriber.php',
2641 'PHPUnit\\Logging\\TestDox\\TestTriggeredWarningSubscriber' => '/phpunit/Logging/TestDox/TestResult/Subscriber/TestTriggeredWarningSubscriber.php',
2642 'PHPUnit\\Metadata\\After' => '/phpunit/Metadata/After.php',
2643 'PHPUnit\\Metadata\\AfterClass' => '/phpunit/Metadata/AfterClass.php',
2644 'PHPUnit\\Metadata\\Annotation\\Parser\\DocBlock' => '/phpunit/Metadata/Parser/Annotation/DocBlock.php',
2645 'PHPUnit\\Metadata\\Annotation\\Parser\\Registry' => '/phpunit/Metadata/Parser/Annotation/Registry.php',
2646 'PHPUnit\\Metadata\\AnnotationsAreNotSupportedForInternalClassesException' => '/phpunit/Metadata/Exception/AnnotationsAreNotSupportedForInternalClassesException.php',
2647 'PHPUnit\\Metadata\\Api\\CodeCoverage' => '/phpunit/Metadata/Api/CodeCoverage.php',
2648 'PHPUnit\\Metadata\\Api\\DataProvider' => '/phpunit/Metadata/Api/DataProvider.php',
2649 'PHPUnit\\Metadata\\Api\\Dependencies' => '/phpunit/Metadata/Api/Dependencies.php',
2650 'PHPUnit\\Metadata\\Api\\Groups' => '/phpunit/Metadata/Api/Groups.php',
2651 'PHPUnit\\Metadata\\Api\\HookMethods' => '/phpunit/Metadata/Api/HookMethods.php',
2652 'PHPUnit\\Metadata\\Api\\Requirements' => '/phpunit/Metadata/Api/Requirements.php',
2653 'PHPUnit\\Metadata\\BackupGlobals' => '/phpunit/Metadata/BackupGlobals.php',
2654 'PHPUnit\\Metadata\\BackupStaticProperties' => '/phpunit/Metadata/BackupStaticProperties.php',
2655 'PHPUnit\\Metadata\\Before' => '/phpunit/Metadata/Before.php',
2656 'PHPUnit\\Metadata\\BeforeClass' => '/phpunit/Metadata/BeforeClass.php',
2657 'PHPUnit\\Metadata\\Covers' => '/phpunit/Metadata/Covers.php',
2658 'PHPUnit\\Metadata\\CoversClass' => '/phpunit/Metadata/CoversClass.php',
2659 'PHPUnit\\Metadata\\CoversDefaultClass' => '/phpunit/Metadata/CoversDefaultClass.php',
2660 'PHPUnit\\Metadata\\CoversFunction' => '/phpunit/Metadata/CoversFunction.php',
2661 'PHPUnit\\Metadata\\CoversNothing' => '/phpunit/Metadata/CoversNothing.php',
2662 'PHPUnit\\Metadata\\DataProvider' => '/phpunit/Metadata/DataProvider.php',
2663 'PHPUnit\\Metadata\\DependsOnClass' => '/phpunit/Metadata/DependsOnClass.php',
2664 'PHPUnit\\Metadata\\DependsOnMethod' => '/phpunit/Metadata/DependsOnMethod.php',
2665 'PHPUnit\\Metadata\\DoesNotPerformAssertions' => '/phpunit/Metadata/DoesNotPerformAssertions.php',
2666 'PHPUnit\\Metadata\\Exception' => '/phpunit/Metadata/Exception/Exception.php',
2667 'PHPUnit\\Metadata\\ExcludeGlobalVariableFromBackup' => '/phpunit/Metadata/ExcludeGlobalVariableFromBackup.php',
2668 'PHPUnit\\Metadata\\ExcludeStaticPropertyFromBackup' => '/phpunit/Metadata/ExcludeStaticPropertyFromBackup.php',
2669 'PHPUnit\\Metadata\\Group' => '/phpunit/Metadata/Group.php',
2670 'PHPUnit\\Metadata\\IgnoreClassForCodeCoverage' => '/phpunit/Metadata/IgnoreClassForCodeCoverage.php',
2671 'PHPUnit\\Metadata\\IgnoreDeprecations' => '/phpunit/Metadata/IgnoreDeprecations.php',
2672 'PHPUnit\\Metadata\\IgnoreFunctionForCodeCoverage' => '/phpunit/Metadata/IgnoreFunctionForCodeCoverage.php',
2673 'PHPUnit\\Metadata\\IgnoreMethodForCodeCoverage' => '/phpunit/Metadata/IgnoreMethodForCodeCoverage.php',
2674 'PHPUnit\\Metadata\\InvalidAttributeException' => '/phpunit/Metadata/Exception/InvalidAttributeException.php',
2675 'PHPUnit\\Metadata\\InvalidVersionRequirementException' => '/phpunit/Metadata/Exception/InvalidVersionRequirementException.php',
2676 'PHPUnit\\Metadata\\Metadata' => '/phpunit/Metadata/Metadata.php',
2677 'PHPUnit\\Metadata\\MetadataCollection' => '/phpunit/Metadata/MetadataCollection.php',
2678 'PHPUnit\\Metadata\\MetadataCollectionIterator' => '/phpunit/Metadata/MetadataCollectionIterator.php',
2679 'PHPUnit\\Metadata\\NoVersionRequirementException' => '/phpunit/Metadata/Exception/NoVersionRequirementException.php',
2680 'PHPUnit\\Metadata\\Parser\\AnnotationParser' => '/phpunit/Metadata/Parser/AnnotationParser.php',
2681 'PHPUnit\\Metadata\\Parser\\AttributeParser' => '/phpunit/Metadata/Parser/AttributeParser.php',
2682 'PHPUnit\\Metadata\\Parser\\CachingParser' => '/phpunit/Metadata/Parser/CachingParser.php',
2683 'PHPUnit\\Metadata\\Parser\\Parser' => '/phpunit/Metadata/Parser/Parser.php',
2684 'PHPUnit\\Metadata\\Parser\\ParserChain' => '/phpunit/Metadata/Parser/ParserChain.php',
2685 'PHPUnit\\Metadata\\Parser\\Registry' => '/phpunit/Metadata/Parser/Registry.php',
2686 'PHPUnit\\Metadata\\PostCondition' => '/phpunit/Metadata/PostCondition.php',
2687 'PHPUnit\\Metadata\\PreCondition' => '/phpunit/Metadata/PreCondition.php',
2688 'PHPUnit\\Metadata\\PreserveGlobalState' => '/phpunit/Metadata/PreserveGlobalState.php',
2689 'PHPUnit\\Metadata\\ReflectionException' => '/phpunit/Metadata/Exception/ReflectionException.php',
2690 'PHPUnit\\Metadata\\RequiresFunction' => '/phpunit/Metadata/RequiresFunction.php',
2691 'PHPUnit\\Metadata\\RequiresMethod' => '/phpunit/Metadata/RequiresMethod.php',
2692 'PHPUnit\\Metadata\\RequiresOperatingSystem' => '/phpunit/Metadata/RequiresOperatingSystem.php',
2693 'PHPUnit\\Metadata\\RequiresOperatingSystemFamily' => '/phpunit/Metadata/RequiresOperatingSystemFamily.php',
2694 'PHPUnit\\Metadata\\RequiresPhp' => '/phpunit/Metadata/RequiresPhp.php',
2695 'PHPUnit\\Metadata\\RequiresPhpExtension' => '/phpunit/Metadata/RequiresPhpExtension.php',
2696 'PHPUnit\\Metadata\\RequiresPhpunit' => '/phpunit/Metadata/RequiresPhpunit.php',
2697 'PHPUnit\\Metadata\\RequiresSetting' => '/phpunit/Metadata/RequiresSetting.php',
2698 'PHPUnit\\Metadata\\RunClassInSeparateProcess' => '/phpunit/Metadata/RunClassInSeparateProcess.php',
2699 'PHPUnit\\Metadata\\RunInSeparateProcess' => '/phpunit/Metadata/RunInSeparateProcess.php',
2700 'PHPUnit\\Metadata\\RunTestsInSeparateProcesses' => '/phpunit/Metadata/RunTestsInSeparateProcesses.php',
2701 'PHPUnit\\Metadata\\Test' => '/phpunit/Metadata/Test.php',
2702 'PHPUnit\\Metadata\\TestDox' => '/phpunit/Metadata/TestDox.php',
2703 'PHPUnit\\Metadata\\TestWith' => '/phpunit/Metadata/TestWith.php',
2704 'PHPUnit\\Metadata\\Uses' => '/phpunit/Metadata/Uses.php',
2705 'PHPUnit\\Metadata\\UsesClass' => '/phpunit/Metadata/UsesClass.php',
2706 'PHPUnit\\Metadata\\UsesDefaultClass' => '/phpunit/Metadata/UsesDefaultClass.php',
2707 'PHPUnit\\Metadata\\UsesFunction' => '/phpunit/Metadata/UsesFunction.php',
2708 'PHPUnit\\Metadata\\Version\\ComparisonRequirement' => '/phpunit/Metadata/Version/ComparisonRequirement.php',
2709 'PHPUnit\\Metadata\\Version\\ConstraintRequirement' => '/phpunit/Metadata/Version/ConstraintRequirement.php',
2710 'PHPUnit\\Metadata\\Version\\Requirement' => '/phpunit/Metadata/Version/Requirement.php',
2711 'PHPUnit\\Metadata\\WithoutErrorHandler' => '/phpunit/Metadata/WithoutErrorHandler.php',
2712 'PHPUnit\\Runner\\Baseline\\Baseline' => '/phpunit/Runner/Baseline/Baseline.php',
2713 'PHPUnit\\Runner\\Baseline\\CannotLoadBaselineException' => '/phpunit/Runner/Baseline/Exception/CannotLoadBaselineException.php',
2714 'PHPUnit\\Runner\\Baseline\\FileDoesNotHaveLineException' => '/phpunit/Runner/Baseline/Exception/FileDoesNotHaveLineException.php',
2715 'PHPUnit\\Runner\\Baseline\\Generator' => '/phpunit/Runner/Baseline/Generator.php',
2716 'PHPUnit\\Runner\\Baseline\\Issue' => '/phpunit/Runner/Baseline/Issue.php',
2717 'PHPUnit\\Runner\\Baseline\\Reader' => '/phpunit/Runner/Baseline/Reader.php',
2718 'PHPUnit\\Runner\\Baseline\\RelativePathCalculator' => '/phpunit/Runner/Baseline/RelativePathCalculator.php',
2719 'PHPUnit\\Runner\\Baseline\\Subscriber' => '/phpunit/Runner/Baseline/Subscriber/Subscriber.php',
2720 'PHPUnit\\Runner\\Baseline\\TestTriggeredDeprecationSubscriber' => '/phpunit/Runner/Baseline/Subscriber/TestTriggeredDeprecationSubscriber.php',
2721 'PHPUnit\\Runner\\Baseline\\TestTriggeredNoticeSubscriber' => '/phpunit/Runner/Baseline/Subscriber/TestTriggeredNoticeSubscriber.php',
2722 'PHPUnit\\Runner\\Baseline\\TestTriggeredPhpDeprecationSubscriber' => '/phpunit/Runner/Baseline/Subscriber/TestTriggeredPhpDeprecationSubscriber.php',
2723 'PHPUnit\\Runner\\Baseline\\TestTriggeredPhpNoticeSubscriber' => '/phpunit/Runner/Baseline/Subscriber/TestTriggeredPhpNoticeSubscriber.php',
2724 'PHPUnit\\Runner\\Baseline\\TestTriggeredPhpWarningSubscriber' => '/phpunit/Runner/Baseline/Subscriber/TestTriggeredPhpWarningSubscriber.php',
2725 'PHPUnit\\Runner\\Baseline\\TestTriggeredWarningSubscriber' => '/phpunit/Runner/Baseline/Subscriber/TestTriggeredWarningSubscriber.php',
2726 'PHPUnit\\Runner\\Baseline\\Writer' => '/phpunit/Runner/Baseline/Writer.php',
2727 'PHPUnit\\Runner\\ClassCannotBeFoundException' => '/phpunit/Runner/Exception/ClassCannotBeFoundException.php',
2728 'PHPUnit\\Runner\\ClassDoesNotExtendTestCaseException' => '/phpunit/Runner/Exception/ClassDoesNotExtendTestCaseException.php',
2729 'PHPUnit\\Runner\\ClassIsAbstractException' => '/phpunit/Runner/Exception/ClassIsAbstractException.php',
2730 'PHPUnit\\Runner\\CodeCoverage' => '/phpunit/Runner/CodeCoverage.php',
2731 'PHPUnit\\Runner\\CodeCoverageFileExistsException' => '/phpunit/Runner/Exception/CodeCoverageFileExistsException.php',
2732 'PHPUnit\\Runner\\DirectoryDoesNotExistException' => '/phpunit/Runner/Exception/DirectoryDoesNotExistException.php',
2733 'PHPUnit\\Runner\\ErrorException' => '/phpunit/Runner/Exception/ErrorException.php',
2734 'PHPUnit\\Runner\\ErrorHandler' => '/phpunit/Runner/ErrorHandler.php',
2735 'PHPUnit\\Runner\\Exception' => '/phpunit/Runner/Exception/Exception.php',
2736 'PHPUnit\\Runner\\Extension\\Extension' => '/phpunit/Runner/Extension/Extension.php',
2737 'PHPUnit\\Runner\\Extension\\ExtensionBootstrapper' => '/phpunit/Runner/Extension/ExtensionBootstrapper.php',
2738 'PHPUnit\\Runner\\Extension\\Facade' => '/phpunit/Runner/Extension/Facade.php',
2739 'PHPUnit\\Runner\\Extension\\ParameterCollection' => '/phpunit/Runner/Extension/ParameterCollection.php',
2740 'PHPUnit\\Runner\\Extension\\PharLoader' => '/phpunit/Runner/Extension/PharLoader.php',
2741 'PHPUnit\\Runner\\FileDoesNotExistException' => '/phpunit/Runner/Exception/FileDoesNotExistException.php',
2742 'PHPUnit\\Runner\\Filter\\ExcludeGroupFilterIterator' => '/phpunit/Runner/Filter/ExcludeGroupFilterIterator.php',
2743 'PHPUnit\\Runner\\Filter\\Factory' => '/phpunit/Runner/Filter/Factory.php',
2744 'PHPUnit\\Runner\\Filter\\GroupFilterIterator' => '/phpunit/Runner/Filter/GroupFilterIterator.php',
2745 'PHPUnit\\Runner\\Filter\\IncludeGroupFilterIterator' => '/phpunit/Runner/Filter/IncludeGroupFilterIterator.php',
2746 'PHPUnit\\Runner\\Filter\\NameFilterIterator' => '/phpunit/Runner/Filter/NameFilterIterator.php',
2747 'PHPUnit\\Runner\\Filter\\TestIdFilterIterator' => '/phpunit/Runner/Filter/TestIdFilterIterator.php',
2748 'PHPUnit\\Runner\\GarbageCollection\\ExecutionFinishedSubscriber' => '/phpunit/Runner/GarbageCollection/Subscriber/ExecutionFinishedSubscriber.php',
2749 'PHPUnit\\Runner\\GarbageCollection\\ExecutionStartedSubscriber' => '/phpunit/Runner/GarbageCollection/Subscriber/ExecutionStartedSubscriber.php',
2750 'PHPUnit\\Runner\\GarbageCollection\\GarbageCollectionHandler' => '/phpunit/Runner/GarbageCollection/GarbageCollectionHandler.php',
2751 'PHPUnit\\Runner\\GarbageCollection\\Subscriber' => '/phpunit/Runner/GarbageCollection/Subscriber/Subscriber.php',
2752 'PHPUnit\\Runner\\GarbageCollection\\TestFinishedSubscriber' => '/phpunit/Runner/GarbageCollection/Subscriber/TestFinishedSubscriber.php',
2753 'PHPUnit\\Runner\\InvalidOrderException' => '/phpunit/Runner/Exception/InvalidOrderException.php',
2754 'PHPUnit\\Runner\\InvalidPhptFileException' => '/phpunit/Runner/Exception/InvalidPhptFileException.php',
2755 'PHPUnit\\Runner\\ParameterDoesNotExistException' => '/phpunit/Runner/Exception/ParameterDoesNotExistException.php',
2756 'PHPUnit\\Runner\\PhptExternalFileCannotBeLoadedException' => '/phpunit/Runner/Exception/PhptExternalFileCannotBeLoadedException.php',
2757 'PHPUnit\\Runner\\PhptTestCase' => '/phpunit/Runner/PhptTestCase.php',
2758 'PHPUnit\\Runner\\ResultCache\\DefaultResultCache' => '/phpunit/Runner/ResultCache/DefaultResultCache.php',
2759 'PHPUnit\\Runner\\ResultCache\\NullResultCache' => '/phpunit/Runner/ResultCache/NullResultCache.php',
2760 'PHPUnit\\Runner\\ResultCache\\ResultCache' => '/phpunit/Runner/ResultCache/ResultCache.php',
2761 'PHPUnit\\Runner\\ResultCache\\ResultCacheHandler' => '/phpunit/Runner/ResultCache/ResultCacheHandler.php',
2762 'PHPUnit\\Runner\\ResultCache\\Subscriber' => '/phpunit/Runner/ResultCache/Subscriber/Subscriber.php',
2763 'PHPUnit\\Runner\\ResultCache\\TestConsideredRiskySubscriber' => '/phpunit/Runner/ResultCache/Subscriber/TestConsideredRiskySubscriber.php',
2764 'PHPUnit\\Runner\\ResultCache\\TestErroredSubscriber' => '/phpunit/Runner/ResultCache/Subscriber/TestErroredSubscriber.php',
2765 'PHPUnit\\Runner\\ResultCache\\TestFailedSubscriber' => '/phpunit/Runner/ResultCache/Subscriber/TestFailedSubscriber.php',
2766 'PHPUnit\\Runner\\ResultCache\\TestFinishedSubscriber' => '/phpunit/Runner/ResultCache/Subscriber/TestFinishedSubscriber.php',
2767 'PHPUnit\\Runner\\ResultCache\\TestMarkedIncompleteSubscriber' => '/phpunit/Runner/ResultCache/Subscriber/TestMarkedIncompleteSubscriber.php',
2768 'PHPUnit\\Runner\\ResultCache\\TestPreparedSubscriber' => '/phpunit/Runner/ResultCache/Subscriber/TestPreparedSubscriber.php',
2769 'PHPUnit\\Runner\\ResultCache\\TestSkippedSubscriber' => '/phpunit/Runner/ResultCache/Subscriber/TestSkippedSubscriber.php',
2770 'PHPUnit\\Runner\\ResultCache\\TestSuiteFinishedSubscriber' => '/phpunit/Runner/ResultCache/Subscriber/TestSuiteFinishedSubscriber.php',
2771 'PHPUnit\\Runner\\ResultCache\\TestSuiteStartedSubscriber' => '/phpunit/Runner/ResultCache/Subscriber/TestSuiteStartedSubscriber.php',
2772 'PHPUnit\\Runner\\TestSuiteLoader' => '/phpunit/Runner/TestSuiteLoader.php',
2773 'PHPUnit\\Runner\\TestSuiteSorter' => '/phpunit/Runner/TestSuiteSorter.php',
2774 'PHPUnit\\Runner\\UnsupportedPhptSectionException' => '/phpunit/Runner/Exception/UnsupportedPhptSectionException.php',
2775 'PHPUnit\\Runner\\Version' => '/phpunit/Runner/Version.php',
2776 'PHPUnit\\TestRunner\\TestResult\\AfterTestClassMethodErroredSubscriber' => '/phpunit/Runner/TestResult/Subscriber/AfterTestClassMethodErroredSubscriber.php',
2777 'PHPUnit\\TestRunner\\TestResult\\BeforeTestClassMethodErroredSubscriber' => '/phpunit/Runner/TestResult/Subscriber/BeforeTestClassMethodErroredSubscriber.php',
2778 'PHPUnit\\TestRunner\\TestResult\\Collector' => '/phpunit/Runner/TestResult/Collector.php',
2779 'PHPUnit\\TestRunner\\TestResult\\ExecutionStartedSubscriber' => '/phpunit/Runner/TestResult/Subscriber/ExecutionStartedSubscriber.php',
2780 'PHPUnit\\TestRunner\\TestResult\\Facade' => '/phpunit/Runner/TestResult/Facade.php',
2781 'PHPUnit\\TestRunner\\TestResult\\Issues\\Issue' => '/phpunit/Runner/TestResult/Issue.php',
2782 'PHPUnit\\TestRunner\\TestResult\\PassedTests' => '/phpunit/Runner/TestResult/PassedTests.php',
2783 'PHPUnit\\TestRunner\\TestResult\\Subscriber' => '/phpunit/Runner/TestResult/Subscriber/Subscriber.php',
2784 'PHPUnit\\TestRunner\\TestResult\\TestConsideredRiskySubscriber' => '/phpunit/Runner/TestResult/Subscriber/TestConsideredRiskySubscriber.php',
2785 'PHPUnit\\TestRunner\\TestResult\\TestErroredSubscriber' => '/phpunit/Runner/TestResult/Subscriber/TestErroredSubscriber.php',
2786 'PHPUnit\\TestRunner\\TestResult\\TestFailedSubscriber' => '/phpunit/Runner/TestResult/Subscriber/TestFailedSubscriber.php',
2787 'PHPUnit\\TestRunner\\TestResult\\TestFinishedSubscriber' => '/phpunit/Runner/TestResult/Subscriber/TestFinishedSubscriber.php',
2788 'PHPUnit\\TestRunner\\TestResult\\TestMarkedIncompleteSubscriber' => '/phpunit/Runner/TestResult/Subscriber/TestMarkedIncompleteSubscriber.php',
2789 'PHPUnit\\TestRunner\\TestResult\\TestPreparedSubscriber' => '/phpunit/Runner/TestResult/Subscriber/TestPreparedSubscriber.php',
2790 'PHPUnit\\TestRunner\\TestResult\\TestResult' => '/phpunit/Runner/TestResult/TestResult.php',
2791 'PHPUnit\\TestRunner\\TestResult\\TestRunnerTriggeredDeprecationSubscriber' => '/phpunit/Runner/TestResult/Subscriber/TestRunnerTriggeredDeprecationSubscriber.php',
2792 'PHPUnit\\TestRunner\\TestResult\\TestRunnerTriggeredWarningSubscriber' => '/phpunit/Runner/TestResult/Subscriber/TestRunnerTriggeredWarningSubscriber.php',
2793 'PHPUnit\\TestRunner\\TestResult\\TestSkippedSubscriber' => '/phpunit/Runner/TestResult/Subscriber/TestSkippedSubscriber.php',
2794 'PHPUnit\\TestRunner\\TestResult\\TestSuiteFinishedSubscriber' => '/phpunit/Runner/TestResult/Subscriber/TestSuiteFinishedSubscriber.php',
2795 'PHPUnit\\TestRunner\\TestResult\\TestSuiteSkippedSubscriber' => '/phpunit/Runner/TestResult/Subscriber/TestSuiteSkippedSubscriber.php',
2796 'PHPUnit\\TestRunner\\TestResult\\TestSuiteStartedSubscriber' => '/phpunit/Runner/TestResult/Subscriber/TestSuiteStartedSubscriber.php',
2797 'PHPUnit\\TestRunner\\TestResult\\TestTriggeredDeprecationSubscriber' => '/phpunit/Runner/TestResult/Subscriber/TestTriggeredDeprecationSubscriber.php',
2798 'PHPUnit\\TestRunner\\TestResult\\TestTriggeredErrorSubscriber' => '/phpunit/Runner/TestResult/Subscriber/TestTriggeredErrorSubscriber.php',
2799 'PHPUnit\\TestRunner\\TestResult\\TestTriggeredNoticeSubscriber' => '/phpunit/Runner/TestResult/Subscriber/TestTriggeredNoticeSubscriber.php',
2800 'PHPUnit\\TestRunner\\TestResult\\TestTriggeredPhpDeprecationSubscriber' => '/phpunit/Runner/TestResult/Subscriber/TestTriggeredPhpDeprecationSubscriber.php',
2801 'PHPUnit\\TestRunner\\TestResult\\TestTriggeredPhpNoticeSubscriber' => '/phpunit/Runner/TestResult/Subscriber/TestTriggeredPhpNoticeSubscriber.php',
2802 'PHPUnit\\TestRunner\\TestResult\\TestTriggeredPhpWarningSubscriber' => '/phpunit/Runner/TestResult/Subscriber/TestTriggeredPhpWarningSubscriber.php',
2803 'PHPUnit\\TestRunner\\TestResult\\TestTriggeredPhpunitDeprecationSubscriber' => '/phpunit/Runner/TestResult/Subscriber/TestTriggeredPhpunitDeprecationSubscriber.php',
2804 'PHPUnit\\TestRunner\\TestResult\\TestTriggeredPhpunitErrorSubscriber' => '/phpunit/Runner/TestResult/Subscriber/TestTriggeredPhpunitErrorSubscriber.php',
2805 'PHPUnit\\TestRunner\\TestResult\\TestTriggeredPhpunitWarningSubscriber' => '/phpunit/Runner/TestResult/Subscriber/TestTriggeredPhpunitWarningSubscriber.php',
2806 'PHPUnit\\TestRunner\\TestResult\\TestTriggeredWarningSubscriber' => '/phpunit/Runner/TestResult/Subscriber/TestTriggeredWarningSubscriber.php',
2807 'PHPUnit\\TextUI\\Application' => '/phpunit/TextUI/Application.php',
2808 'PHPUnit\\TextUI\\CannotOpenSocketException' => '/phpunit/TextUI/Exception/CannotOpenSocketException.php',
2809 'PHPUnit\\TextUI\\CliArguments\\Builder' => '/phpunit/TextUI/Configuration/Cli/Builder.php',
2810 'PHPUnit\\TextUI\\CliArguments\\Configuration' => '/phpunit/TextUI/Configuration/Cli/Configuration.php',
2811 'PHPUnit\\TextUI\\CliArguments\\Exception' => '/phpunit/TextUI/Configuration/Cli/Exception.php',
2812 'PHPUnit\\TextUI\\CliArguments\\XmlConfigurationFileFinder' => '/phpunit/TextUI/Configuration/Cli/XmlConfigurationFileFinder.php',
2813 'PHPUnit\\TextUI\\Command\\AtLeastVersionCommand' => '/phpunit/TextUI/Command/Commands/AtLeastVersionCommand.php',
2814 'PHPUnit\\TextUI\\Command\\CheckPhpConfigurationCommand' => '/phpunit/TextUI/Command/Commands/CheckPhpConfigurationCommand.php',
2815 'PHPUnit\\TextUI\\Command\\Command' => '/phpunit/TextUI/Command/Command.php',
2816 'PHPUnit\\TextUI\\Command\\GenerateConfigurationCommand' => '/phpunit/TextUI/Command/Commands/GenerateConfigurationCommand.php',
2817 'PHPUnit\\TextUI\\Command\\ListGroupsCommand' => '/phpunit/TextUI/Command/Commands/ListGroupsCommand.php',
2818 'PHPUnit\\TextUI\\Command\\ListTestSuitesCommand' => '/phpunit/TextUI/Command/Commands/ListTestSuitesCommand.php',
2819 'PHPUnit\\TextUI\\Command\\ListTestsAsTextCommand' => '/phpunit/TextUI/Command/Commands/ListTestsAsTextCommand.php',
2820 'PHPUnit\\TextUI\\Command\\ListTestsAsXmlCommand' => '/phpunit/TextUI/Command/Commands/ListTestsAsXmlCommand.php',
2821 'PHPUnit\\TextUI\\Command\\MigrateConfigurationCommand' => '/phpunit/TextUI/Command/Commands/MigrateConfigurationCommand.php',
2822 'PHPUnit\\TextUI\\Command\\Result' => '/phpunit/TextUI/Command/Result.php',
2823 'PHPUnit\\TextUI\\Command\\ShowHelpCommand' => '/phpunit/TextUI/Command/Commands/ShowHelpCommand.php',
2824 'PHPUnit\\TextUI\\Command\\ShowVersionCommand' => '/phpunit/TextUI/Command/Commands/ShowVersionCommand.php',
2825 'PHPUnit\\TextUI\\Command\\VersionCheckCommand' => '/phpunit/TextUI/Command/Commands/VersionCheckCommand.php',
2826 'PHPUnit\\TextUI\\Command\\WarmCodeCoverageCacheCommand' => '/phpunit/TextUI/Command/Commands/WarmCodeCoverageCacheCommand.php',
2827 'PHPUnit\\TextUI\\Configuration\\Builder' => '/phpunit/TextUI/Configuration/Builder.php',
2828 'PHPUnit\\TextUI\\Configuration\\CodeCoverageFilterRegistry' => '/phpunit/TextUI/Configuration/CodeCoverageFilterRegistry.php',
2829 'PHPUnit\\TextUI\\Configuration\\CodeCoverageReportNotConfiguredException' => '/phpunit/TextUI/Configuration/Exception/CodeCoverageReportNotConfiguredException.php',
2830 'PHPUnit\\TextUI\\Configuration\\Configuration' => '/phpunit/TextUI/Configuration/Configuration.php',
2831 'PHPUnit\\TextUI\\Configuration\\ConfigurationCannotBeBuiltException' => '/phpunit/TextUI/Configuration/Exception/ConfigurationCannotBeBuiltException.php',
2832 'PHPUnit\\TextUI\\Configuration\\Constant' => '/phpunit/TextUI/Configuration/Value/Constant.php',
2833 'PHPUnit\\TextUI\\Configuration\\ConstantCollection' => '/phpunit/TextUI/Configuration/Value/ConstantCollection.php',
2834 'PHPUnit\\TextUI\\Configuration\\ConstantCollectionIterator' => '/phpunit/TextUI/Configuration/Value/ConstantCollectionIterator.php',
2835 'PHPUnit\\TextUI\\Configuration\\Directory' => '/phpunit/TextUI/Configuration/Value/Directory.php',
2836 'PHPUnit\\TextUI\\Configuration\\DirectoryCollection' => '/phpunit/TextUI/Configuration/Value/DirectoryCollection.php',
2837 'PHPUnit\\TextUI\\Configuration\\DirectoryCollectionIterator' => '/phpunit/TextUI/Configuration/Value/DirectoryCollectionIterator.php',
2838 'PHPUnit\\TextUI\\Configuration\\Exception' => '/phpunit/TextUI/Configuration/Exception/Exception.php',
2839 'PHPUnit\\TextUI\\Configuration\\ExtensionBootstrap' => '/phpunit/TextUI/Configuration/Value/ExtensionBootstrap.php',
2840 'PHPUnit\\TextUI\\Configuration\\ExtensionBootstrapCollection' => '/phpunit/TextUI/Configuration/Value/ExtensionBootstrapCollection.php',
2841 'PHPUnit\\TextUI\\Configuration\\ExtensionBootstrapCollectionIterator' => '/phpunit/TextUI/Configuration/Value/ExtensionBootstrapCollectionIterator.php',
2842 'PHPUnit\\TextUI\\Configuration\\File' => '/phpunit/TextUI/Configuration/Value/File.php',
2843 'PHPUnit\\TextUI\\Configuration\\FileCollection' => '/phpunit/TextUI/Configuration/Value/FileCollection.php',
2844 'PHPUnit\\TextUI\\Configuration\\FileCollectionIterator' => '/phpunit/TextUI/Configuration/Value/FileCollectionIterator.php',
2845 'PHPUnit\\TextUI\\Configuration\\FilterDirectory' => '/phpunit/TextUI/Configuration/Value/FilterDirectory.php',
2846 'PHPUnit\\TextUI\\Configuration\\FilterDirectoryCollection' => '/phpunit/TextUI/Configuration/Value/FilterDirectoryCollection.php',
2847 'PHPUnit\\TextUI\\Configuration\\FilterDirectoryCollectionIterator' => '/phpunit/TextUI/Configuration/Value/FilterDirectoryCollectionIterator.php',
2848 'PHPUnit\\TextUI\\Configuration\\FilterNotConfiguredException' => '/phpunit/TextUI/Configuration/Exception/FilterNotConfiguredException.php',
2849 'PHPUnit\\TextUI\\Configuration\\Group' => '/phpunit/TextUI/Configuration/Value/Group.php',
2850 'PHPUnit\\TextUI\\Configuration\\GroupCollection' => '/phpunit/TextUI/Configuration/Value/GroupCollection.php',
2851 'PHPUnit\\TextUI\\Configuration\\GroupCollectionIterator' => '/phpunit/TextUI/Configuration/Value/GroupCollectionIterator.php',
2852 'PHPUnit\\TextUI\\Configuration\\IniSetting' => '/phpunit/TextUI/Configuration/Value/IniSetting.php',
2853 'PHPUnit\\TextUI\\Configuration\\IniSettingCollection' => '/phpunit/TextUI/Configuration/Value/IniSettingCollection.php',
2854 'PHPUnit\\TextUI\\Configuration\\IniSettingCollectionIterator' => '/phpunit/TextUI/Configuration/Value/IniSettingCollectionIterator.php',
2855 'PHPUnit\\TextUI\\Configuration\\LoggingNotConfiguredException' => '/phpunit/TextUI/Configuration/Exception/LoggingNotConfiguredException.php',
2856 'PHPUnit\\TextUI\\Configuration\\Merger' => '/phpunit/TextUI/Configuration/Merger.php',
2857 'PHPUnit\\TextUI\\Configuration\\NoBaselineException' => '/phpunit/TextUI/Configuration/Exception/NoBaselineException.php',
2858 'PHPUnit\\TextUI\\Configuration\\NoBootstrapException' => '/phpunit/TextUI/Configuration/Exception/NoBootstrapException.php',
2859 'PHPUnit\\TextUI\\Configuration\\NoCacheDirectoryException' => '/phpunit/TextUI/Configuration/Exception/NoCacheDirectoryException.php',
2860 'PHPUnit\\TextUI\\Configuration\\NoCliArgumentException' => '/phpunit/TextUI/Configuration/Exception/NoCliArgumentException.php',
2861 'PHPUnit\\TextUI\\Configuration\\NoConfigurationFileException' => '/phpunit/TextUI/Configuration/Exception/NoConfigurationFileException.php',
2862 'PHPUnit\\TextUI\\Configuration\\NoCoverageCacheDirectoryException' => '/phpunit/TextUI/Configuration/Exception/NoCoverageCacheDirectoryException.php',
2863 'PHPUnit\\TextUI\\Configuration\\NoCustomCssFileException' => '/phpunit/TextUI/Configuration/Exception/NoCustomCssFileException.php',
2864 'PHPUnit\\TextUI\\Configuration\\NoDefaultTestSuiteException' => '/phpunit/TextUI/Configuration/Exception/NoDefaultTestSuiteException.php',
2865 'PHPUnit\\TextUI\\Configuration\\NoPharExtensionDirectoryException' => '/phpunit/TextUI/Configuration/Exception/NoPharExtensionDirectoryException.php',
2866 'PHPUnit\\TextUI\\Configuration\\Php' => '/phpunit/TextUI/Configuration/Value/Php.php',
2867 'PHPUnit\\TextUI\\Configuration\\PhpHandler' => '/phpunit/TextUI/Configuration/PhpHandler.php',
2868 'PHPUnit\\TextUI\\Configuration\\Registry' => '/phpunit/TextUI/Configuration/Registry.php',
2869 'PHPUnit\\TextUI\\Configuration\\Source' => '/phpunit/TextUI/Configuration/Value/Source.php',
2870 'PHPUnit\\TextUI\\Configuration\\SourceFilter' => '/phpunit/TextUI/Configuration/SourceFilter.php',
2871 'PHPUnit\\TextUI\\Configuration\\SourceMapper' => '/phpunit/TextUI/Configuration/SourceMapper.php',
2872 'PHPUnit\\TextUI\\Configuration\\TestDirectory' => '/phpunit/TextUI/Configuration/Value/TestDirectory.php',
2873 'PHPUnit\\TextUI\\Configuration\\TestDirectoryCollection' => '/phpunit/TextUI/Configuration/Value/TestDirectoryCollection.php',
2874 'PHPUnit\\TextUI\\Configuration\\TestDirectoryCollectionIterator' => '/phpunit/TextUI/Configuration/Value/TestDirectoryCollectionIterator.php',
2875 'PHPUnit\\TextUI\\Configuration\\TestFile' => '/phpunit/TextUI/Configuration/Value/TestFile.php',
2876 'PHPUnit\\TextUI\\Configuration\\TestFileCollection' => '/phpunit/TextUI/Configuration/Value/TestFileCollection.php',
2877 'PHPUnit\\TextUI\\Configuration\\TestFileCollectionIterator' => '/phpunit/TextUI/Configuration/Value/TestFileCollectionIterator.php',
2878 'PHPUnit\\TextUI\\Configuration\\TestSuite' => '/phpunit/TextUI/Configuration/Value/TestSuite.php',
2879 'PHPUnit\\TextUI\\Configuration\\TestSuiteBuilder' => '/phpunit/TextUI/Configuration/TestSuiteBuilder.php',
2880 'PHPUnit\\TextUI\\Configuration\\TestSuiteCollection' => '/phpunit/TextUI/Configuration/Value/TestSuiteCollection.php',
2881 'PHPUnit\\TextUI\\Configuration\\TestSuiteCollectionIterator' => '/phpunit/TextUI/Configuration/Value/TestSuiteCollectionIterator.php',
2882 'PHPUnit\\TextUI\\Configuration\\Variable' => '/phpunit/TextUI/Configuration/Value/Variable.php',
2883 'PHPUnit\\TextUI\\Configuration\\VariableCollection' => '/phpunit/TextUI/Configuration/Value/VariableCollection.php',
2884 'PHPUnit\\TextUI\\Configuration\\VariableCollectionIterator' => '/phpunit/TextUI/Configuration/Value/VariableCollectionIterator.php',
2885 'PHPUnit\\TextUI\\Exception' => '/phpunit/TextUI/Exception/Exception.php',
2886 'PHPUnit\\TextUI\\Help' => '/phpunit/TextUI/Help.php',
2887 'PHPUnit\\TextUI\\InvalidSocketException' => '/phpunit/TextUI/Exception/InvalidSocketException.php',
2888 'PHPUnit\\TextUI\\Output\\DefaultPrinter' => '/phpunit/TextUI/Output/Printer/DefaultPrinter.php',
2889 'PHPUnit\\TextUI\\Output\\Default\\ProgressPrinter\\BeforeTestClassMethodErroredSubscriber' => '/phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/BeforeTestClassMethodErroredSubscriber.php',
2890 'PHPUnit\\TextUI\\Output\\Default\\ProgressPrinter\\ProgressPrinter' => '/phpunit/TextUI/Output/Default/ProgressPrinter/ProgressPrinter.php',
2891 'PHPUnit\\TextUI\\Output\\Default\\ProgressPrinter\\Subscriber' => '/phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/Subscriber.php',
2892 'PHPUnit\\TextUI\\Output\\Default\\ProgressPrinter\\TestConsideredRiskySubscriber' => '/phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestConsideredRiskySubscriber.php',
2893 'PHPUnit\\TextUI\\Output\\Default\\ProgressPrinter\\TestErroredSubscriber' => '/phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestErroredSubscriber.php',
2894 'PHPUnit\\TextUI\\Output\\Default\\ProgressPrinter\\TestFailedSubscriber' => '/phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestFailedSubscriber.php',
2895 'PHPUnit\\TextUI\\Output\\Default\\ProgressPrinter\\TestFinishedSubscriber' => '/phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestFinishedSubscriber.php',
2896 'PHPUnit\\TextUI\\Output\\Default\\ProgressPrinter\\TestMarkedIncompleteSubscriber' => '/phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestMarkedIncompleteSubscriber.php',
2897 'PHPUnit\\TextUI\\Output\\Default\\ProgressPrinter\\TestPreparedSubscriber' => '/phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestPreparedSubscriber.php',
2898 'PHPUnit\\TextUI\\Output\\Default\\ProgressPrinter\\TestRunnerExecutionStartedSubscriber' => '/phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestRunnerExecutionStartedSubscriber.php',
2899 'PHPUnit\\TextUI\\Output\\Default\\ProgressPrinter\\TestSkippedSubscriber' => '/phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestSkippedSubscriber.php',
2900 'PHPUnit\\TextUI\\Output\\Default\\ProgressPrinter\\TestTriggeredDeprecationSubscriber' => '/phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestTriggeredDeprecationSubscriber.php',
2901 'PHPUnit\\TextUI\\Output\\Default\\ProgressPrinter\\TestTriggeredErrorSubscriber' => '/phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestTriggeredErrorSubscriber.php',
2902 'PHPUnit\\TextUI\\Output\\Default\\ProgressPrinter\\TestTriggeredNoticeSubscriber' => '/phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestTriggeredNoticeSubscriber.php',
2903 'PHPUnit\\TextUI\\Output\\Default\\ProgressPrinter\\TestTriggeredPhpDeprecationSubscriber' => '/phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestTriggeredPhpDeprecationSubscriber.php',
2904 'PHPUnit\\TextUI\\Output\\Default\\ProgressPrinter\\TestTriggeredPhpNoticeSubscriber' => '/phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestTriggeredPhpNoticeSubscriber.php',
2905 'PHPUnit\\TextUI\\Output\\Default\\ProgressPrinter\\TestTriggeredPhpWarningSubscriber' => '/phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestTriggeredPhpWarningSubscriber.php',
2906 'PHPUnit\\TextUI\\Output\\Default\\ProgressPrinter\\TestTriggeredPhpunitDeprecationSubscriber' => '/phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestTriggeredPhpunitDeprecationSubscriber.php',
2907 'PHPUnit\\TextUI\\Output\\Default\\ProgressPrinter\\TestTriggeredPhpunitWarningSubscriber' => '/phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestTriggeredPhpunitWarningSubscriber.php',
2908 'PHPUnit\\TextUI\\Output\\Default\\ProgressPrinter\\TestTriggeredWarningSubscriber' => '/phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestTriggeredWarningSubscriber.php',
2909 'PHPUnit\\TextUI\\Output\\Default\\ResultPrinter' => '/phpunit/TextUI/Output/Default/ResultPrinter.php',
2910 'PHPUnit\\TextUI\\Output\\Default\\UnexpectedOutputPrinter' => '/phpunit/TextUI/Output/Default/UnexpectedOutputPrinter.php',
2911 'PHPUnit\\TextUI\\Output\\Facade' => '/phpunit/TextUI/Output/Facade.php',
2912 'PHPUnit\\TextUI\\Output\\NullPrinter' => '/phpunit/TextUI/Output/Printer/NullPrinter.php',
2913 'PHPUnit\\TextUI\\Output\\Printer' => '/phpunit/TextUI/Output/Printer/Printer.php',
2914 'PHPUnit\\TextUI\\Output\\SummaryPrinter' => '/phpunit/TextUI/Output/SummaryPrinter.php',
2915 'PHPUnit\\TextUI\\Output\\TestDox\\ResultPrinter' => '/phpunit/TextUI/Output/TestDox/ResultPrinter.php',
2916 'PHPUnit\\TextUI\\RuntimeException' => '/phpunit/TextUI/Exception/RuntimeException.php',
2917 'PHPUnit\\TextUI\\ShellExitCodeCalculator' => '/phpunit/TextUI/ShellExitCodeCalculator.php',
2918 'PHPUnit\\TextUI\\TestDirectoryNotFoundException' => '/phpunit/TextUI/Exception/TestDirectoryNotFoundException.php',
2919 'PHPUnit\\TextUI\\TestFileNotFoundException' => '/phpunit/TextUI/Exception/TestFileNotFoundException.php',
2920 'PHPUnit\\TextUI\\TestRunner' => '/phpunit/TextUI/TestRunner.php',
2921 'PHPUnit\\TextUI\\TestSuiteFilterProcessor' => '/phpunit/TextUI/TestSuiteFilterProcessor.php',
2922 'PHPUnit\\TextUI\\XmlConfiguration\\CannotFindSchemaException' => '/phpunit/TextUI/Configuration/Exception/CannotFindSchemaException.php',
2923 'PHPUnit\\TextUI\\XmlConfiguration\\CodeCoverage\\CodeCoverage' => '/phpunit/TextUI/Configuration/Xml/CodeCoverage/CodeCoverage.php',
2924 'PHPUnit\\TextUI\\XmlConfiguration\\CodeCoverage\\Report\\Clover' => '/phpunit/TextUI/Configuration/Xml/CodeCoverage/Report/Clover.php',
2925 'PHPUnit\\TextUI\\XmlConfiguration\\CodeCoverage\\Report\\Cobertura' => '/phpunit/TextUI/Configuration/Xml/CodeCoverage/Report/Cobertura.php',
2926 'PHPUnit\\TextUI\\XmlConfiguration\\CodeCoverage\\Report\\Crap4j' => '/phpunit/TextUI/Configuration/Xml/CodeCoverage/Report/Crap4j.php',
2927 'PHPUnit\\TextUI\\XmlConfiguration\\CodeCoverage\\Report\\Html' => '/phpunit/TextUI/Configuration/Xml/CodeCoverage/Report/Html.php',
2928 'PHPUnit\\TextUI\\XmlConfiguration\\CodeCoverage\\Report\\Php' => '/phpunit/TextUI/Configuration/Xml/CodeCoverage/Report/Php.php',
2929 'PHPUnit\\TextUI\\XmlConfiguration\\CodeCoverage\\Report\\Text' => '/phpunit/TextUI/Configuration/Xml/CodeCoverage/Report/Text.php',
2930 'PHPUnit\\TextUI\\XmlConfiguration\\CodeCoverage\\Report\\Xml' => '/phpunit/TextUI/Configuration/Xml/CodeCoverage/Report/Xml.php',
2931 'PHPUnit\\TextUI\\XmlConfiguration\\Configuration' => '/phpunit/TextUI/Configuration/Xml/Configuration.php',
2932 'PHPUnit\\TextUI\\XmlConfiguration\\ConvertLogTypes' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/ConvertLogTypes.php',
2933 'PHPUnit\\TextUI\\XmlConfiguration\\CoverageCloverToReport' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/CoverageCloverToReport.php',
2934 'PHPUnit\\TextUI\\XmlConfiguration\\CoverageCrap4jToReport' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/CoverageCrap4jToReport.php',
2935 'PHPUnit\\TextUI\\XmlConfiguration\\CoverageHtmlToReport' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/CoverageHtmlToReport.php',
2936 'PHPUnit\\TextUI\\XmlConfiguration\\CoveragePhpToReport' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/CoveragePhpToReport.php',
2937 'PHPUnit\\TextUI\\XmlConfiguration\\CoverageTextToReport' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/CoverageTextToReport.php',
2938 'PHPUnit\\TextUI\\XmlConfiguration\\CoverageXmlToReport' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/CoverageXmlToReport.php',
2939 'PHPUnit\\TextUI\\XmlConfiguration\\DefaultConfiguration' => '/phpunit/TextUI/Configuration/Xml/DefaultConfiguration.php',
2940 'PHPUnit\\TextUI\\XmlConfiguration\\Exception' => '/phpunit/TextUI/Configuration/Xml/Exception.php',
2941 'PHPUnit\\TextUI\\XmlConfiguration\\FailedSchemaDetectionResult' => '/phpunit/TextUI/Configuration/Xml/SchemaDetector/FailedSchemaDetectionResult.php',
2942 'PHPUnit\\TextUI\\XmlConfiguration\\Generator' => '/phpunit/TextUI/Configuration/Xml/Generator.php',
2943 'PHPUnit\\TextUI\\XmlConfiguration\\Groups' => '/phpunit/TextUI/Configuration/Xml/Groups.php',
2944 'PHPUnit\\TextUI\\XmlConfiguration\\IntroduceCacheDirectoryAttribute' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/IntroduceCacheDirectoryAttribute.php',
2945 'PHPUnit\\TextUI\\XmlConfiguration\\IntroduceCoverageElement' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/IntroduceCoverageElement.php',
2946 'PHPUnit\\TextUI\\XmlConfiguration\\LoadedFromFileConfiguration' => '/phpunit/TextUI/Configuration/Xml/LoadedFromFileConfiguration.php',
2947 'PHPUnit\\TextUI\\XmlConfiguration\\Loader' => '/phpunit/TextUI/Configuration/Xml/Loader.php',
2948 'PHPUnit\\TextUI\\XmlConfiguration\\LogToReportMigration' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/LogToReportMigration.php',
2949 'PHPUnit\\TextUI\\XmlConfiguration\\Logging\\Junit' => '/phpunit/TextUI/Configuration/Xml/Logging/Junit.php',
2950 'PHPUnit\\TextUI\\XmlConfiguration\\Logging\\Logging' => '/phpunit/TextUI/Configuration/Xml/Logging/Logging.php',
2951 'PHPUnit\\TextUI\\XmlConfiguration\\Logging\\TeamCity' => '/phpunit/TextUI/Configuration/Xml/Logging/TeamCity.php',
2952 'PHPUnit\\TextUI\\XmlConfiguration\\Logging\\TestDox\\Html' => '/phpunit/TextUI/Configuration/Xml/Logging/TestDox/Html.php',
2953 'PHPUnit\\TextUI\\XmlConfiguration\\Logging\\TestDox\\Text' => '/phpunit/TextUI/Configuration/Xml/Logging/TestDox/Text.php',
2954 'PHPUnit\\TextUI\\XmlConfiguration\\Migration' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/Migration.php',
2955 'PHPUnit\\TextUI\\XmlConfiguration\\MigrationBuilder' => '/phpunit/TextUI/Configuration/Xml/Migration/MigrationBuilder.php',
2956 'PHPUnit\\TextUI\\XmlConfiguration\\MigrationException' => '/phpunit/TextUI/Configuration/Xml/Migration/MigrationException.php',
2957 'PHPUnit\\TextUI\\XmlConfiguration\\Migrator' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrator.php',
2958 'PHPUnit\\TextUI\\XmlConfiguration\\MoveAttributesFromFilterWhitelistToCoverage' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/MoveAttributesFromFilterWhitelistToCoverage.php',
2959 'PHPUnit\\TextUI\\XmlConfiguration\\MoveAttributesFromRootToCoverage' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/MoveAttributesFromRootToCoverage.php',
2960 'PHPUnit\\TextUI\\XmlConfiguration\\MoveCoverageDirectoriesToSource' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/MoveCoverageDirectoriesToSource.php',
2961 'PHPUnit\\TextUI\\XmlConfiguration\\MoveWhitelistExcludesToCoverage' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/MoveWhitelistExcludesToCoverage.php',
2962 'PHPUnit\\TextUI\\XmlConfiguration\\MoveWhitelistIncludesToCoverage' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/MoveWhitelistIncludesToCoverage.php',
2963 'PHPUnit\\TextUI\\XmlConfiguration\\PHPUnit' => '/phpunit/TextUI/Configuration/Xml/PHPUnit.php',
2964 'PHPUnit\\TextUI\\XmlConfiguration\\RemoveBeStrictAboutResourceUsageDuringSmallTestsAttribute' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveBeStrictAboutResourceUsageDuringSmallTestsAttribute.php',
2965 'PHPUnit\\TextUI\\XmlConfiguration\\RemoveBeStrictAboutTodoAnnotatedTestsAttribute' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveBeStrictAboutTodoAnnotatedTestsAttribute.php',
2966 'PHPUnit\\TextUI\\XmlConfiguration\\RemoveCacheResultFileAttribute' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveCacheResultFileAttribute.php',
2967 'PHPUnit\\TextUI\\XmlConfiguration\\RemoveCacheTokensAttribute' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveCacheTokensAttribute.php',
2968 'PHPUnit\\TextUI\\XmlConfiguration\\RemoveConversionToExceptionsAttributes' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveConversionToExceptionsAttributes.php',
2969 'PHPUnit\\TextUI\\XmlConfiguration\\RemoveCoverageElementCacheDirectoryAttribute' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveCoverageElementCacheDirectoryAttribute.php',
2970 'PHPUnit\\TextUI\\XmlConfiguration\\RemoveCoverageElementProcessUncoveredFilesAttribute' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveCoverageElementProcessUncoveredFilesAttribute.php',
2971 'PHPUnit\\TextUI\\XmlConfiguration\\RemoveEmptyFilter' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveEmptyFilter.php',
2972 'PHPUnit\\TextUI\\XmlConfiguration\\RemoveListeners' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveListeners.php',
2973 'PHPUnit\\TextUI\\XmlConfiguration\\RemoveLogTypes' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveLogTypes.php',
2974 'PHPUnit\\TextUI\\XmlConfiguration\\RemoveLoggingElements' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveLoggingElements.php',
2975 'PHPUnit\\TextUI\\XmlConfiguration\\RemoveNoInteractionAttribute' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveNoInteractionAttribute.php',
2976 'PHPUnit\\TextUI\\XmlConfiguration\\RemovePrinterAttributes' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/RemovePrinterAttributes.php',
2977 'PHPUnit\\TextUI\\XmlConfiguration\\RemoveTestDoxGroupsElement' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveTestDoxGroupsElement.php',
2978 'PHPUnit\\TextUI\\XmlConfiguration\\RemoveTestSuiteLoaderAttributes' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveTestSuiteLoaderAttributes.php',
2979 'PHPUnit\\TextUI\\XmlConfiguration\\RemoveVerboseAttribute' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveVerboseAttribute.php',
2980 'PHPUnit\\TextUI\\XmlConfiguration\\RenameBackupStaticAttributesAttribute' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/RenameBackupStaticAttributesAttribute.php',
2981 'PHPUnit\\TextUI\\XmlConfiguration\\RenameBeStrictAboutCoversAnnotationAttribute' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/RenameBeStrictAboutCoversAnnotationAttribute.php',
2982 'PHPUnit\\TextUI\\XmlConfiguration\\RenameForceCoversAnnotationAttribute' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/RenameForceCoversAnnotationAttribute.php',
2983 'PHPUnit\\TextUI\\XmlConfiguration\\SchemaDetectionResult' => '/phpunit/TextUI/Configuration/Xml/SchemaDetector/SchemaDetectionResult.php',
2984 'PHPUnit\\TextUI\\XmlConfiguration\\SchemaDetector' => '/phpunit/TextUI/Configuration/Xml/SchemaDetector/SchemaDetector.php',
2985 'PHPUnit\\TextUI\\XmlConfiguration\\SchemaFinder' => '/phpunit/TextUI/Configuration/Xml/SchemaFinder.php',
2986 'PHPUnit\\TextUI\\XmlConfiguration\\SnapshotNodeList' => '/phpunit/TextUI/Configuration/Xml/Migration/SnapshotNodeList.php',
2987 'PHPUnit\\TextUI\\XmlConfiguration\\SuccessfulSchemaDetectionResult' => '/phpunit/TextUI/Configuration/Xml/SchemaDetector/SuccessfulSchemaDetectionResult.php',
2988 'PHPUnit\\TextUI\\XmlConfiguration\\TestSuiteMapper' => '/phpunit/TextUI/Configuration/Xml/TestSuiteMapper.php',
2989 'PHPUnit\\TextUI\\XmlConfiguration\\UpdateSchemaLocation' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/UpdateSchemaLocation.php',
2990 'PHPUnit\\TextUI\\XmlConfiguration\\ValidationResult' => '/phpunit/TextUI/Configuration/Xml/Validator/ValidationResult.php',
2991 'PHPUnit\\TextUI\\XmlConfiguration\\Validator' => '/phpunit/TextUI/Configuration/Xml/Validator/Validator.php',
2992 'PHPUnit\\Util\\Cloner' => '/phpunit/Util/Cloner.php',
2993 'PHPUnit\\Util\\Color' => '/phpunit/Util/Color.php',
2994 'PHPUnit\\Util\\Exception' => '/phpunit/Util/Exception/Exception.php',
2995 'PHPUnit\\Util\\ExcludeList' => '/phpunit/Util/ExcludeList.php',
2996 'PHPUnit\\Util\\Exporter' => '/phpunit/Util/Exporter.php',
2997 'PHPUnit\\Util\\Filesystem' => '/phpunit/Util/Filesystem.php',
2998 'PHPUnit\\Util\\Filter' => '/phpunit/Util/Filter.php',
2999 'PHPUnit\\Util\\GlobalState' => '/phpunit/Util/GlobalState.php',
3000 'PHPUnit\\Util\\Http\\Downloader' => '/phpunit/Util/Http/Downloader.php',
3001 'PHPUnit\\Util\\Http\\PhpDownloader' => '/phpunit/Util/Http/PhpDownloader.php',
3002 'PHPUnit\\Util\\InvalidDirectoryException' => '/phpunit/Util/Exception/InvalidDirectoryException.php',
3003 'PHPUnit\\Util\\InvalidJsonException' => '/phpunit/Util/Exception/InvalidJsonException.php',
3004 'PHPUnit\\Util\\InvalidVersionOperatorException' => '/phpunit/Util/Exception/InvalidVersionOperatorException.php',
3005 'PHPUnit\\Util\\Json' => '/phpunit/Util/Json.php',
3006 'PHPUnit\\Util\\PHP\\AbstractPhpProcess' => '/phpunit/Util/PHP/AbstractPhpProcess.php',
3007 'PHPUnit\\Util\\PHP\\DefaultPhpProcess' => '/phpunit/Util/PHP/DefaultPhpProcess.php',
3008 'PHPUnit\\Util\\PHP\\PhpProcessException' => '/phpunit/Util/Exception/PhpProcessException.php',
3009 'PHPUnit\\Util\\Reflection' => '/phpunit/Util/Reflection.php',
3010 'PHPUnit\\Util\\Test' => '/phpunit/Util/Test.php',
3011 'PHPUnit\\Util\\ThrowableToStringMapper' => '/phpunit/Util/ThrowableToStringMapper.php',
3012 'PHPUnit\\Util\\VersionComparisonOperator' => '/phpunit/Util/VersionComparisonOperator.php',
3013 'PHPUnit\\Util\\Xml' => '/phpunit/Util/Xml/Xml.php',
3014 'PHPUnit\\Util\\Xml\\Loader' => '/phpunit/Util/Xml/Loader.php',
3015 'PHPUnit\\Util\\Xml\\XmlException' => '/phpunit/Util/Exception/XmlException.php'] as $file) {
3016 require_once 'phar://phpunit-10.5.63.phar' . $file;
3017 }
3018
3019 require __PHPUNIT_PHAR_ROOT__ . '/phpunit/Framework/Assert/Functions.php';
3020
3021 if ($execute) {
3022 if (isset($printComposerLock)) {
3023 print file_get_contents(__PHPUNIT_PHAR_ROOT__ . '/composer.lock');
3024
3025 exit;
3026 }
3027
3028 if (isset($printManifest)) {
3029 print file_get_contents(__PHPUNIT_PHAR_ROOT__ . '/manifest.txt');
3030
3031 exit;
3032 }
3033
3034 if (isset($printSbom)) {
3035 print file_get_contents(__PHPUNIT_PHAR_ROOT__ . '/sbom.xml');
3036
3037 exit;
3038 }
3039
3040 unset($execute);
3041
3042 exit((new PHPUnit\TextUI\Application)->run($_SERVER['argv']));
3043 }
3044
3045 __HALT_COMPILER(); ?>
3046 ��
3047 phpunit-10.5.63.phar composer.lock���Qxi���Iw� manifest.txt��Qxi�����'myclabs-deep-copy/DeepCopy/DeepCopy.php@!�Qxi@!n�=�7myclabs-deep-copy/DeepCopy/Exception/CloneException.php��Qxi�JD�Ȥ:myclabs-deep-copy/DeepCopy/Exception/PropertyException.php��Qxi�o��#�5myclabs-deep-copy/DeepCopy/Filter/ChainableFilter.php��Qxi��=(e�Gmyclabs-deep-copy/DeepCopy/Filter/Doctrine/DoctrineCollectionFilter.phpL�QxiL6b]U�Lmyclabs-deep-copy/DeepCopy/Filter/Doctrine/DoctrineEmptyCollectionFilter.php%�Qxi%�d�-�Bmyclabs-deep-copy/DeepCopy/Filter/Doctrine/DoctrineProxyFilter.php��Qxi�fQc_�,myclabs-deep-copy/DeepCopy/Filter/Filter.phph�Qxih�߽�0myclabs-deep-copy/DeepCopy/Filter/KeepFilter.php�Qxi�7#�3myclabs-deep-copy/DeepCopy/Filter/ReplaceFilter.php��Qxi��{�C�3myclabs-deep-copy/DeepCopy/Filter/SetNullFilter.php.�Qxi.~�^�Dmyclabs-deep-copy/DeepCopy/Matcher/Doctrine/DoctrineProxyMatcher.php��Qxi� �3�.myclabs-deep-copy/DeepCopy/Matcher/Matcher.php��Qxi��f�ä6myclabs-deep-copy/DeepCopy/Matcher/PropertyMatcher.php��Qxi��A^�:myclabs-deep-copy/DeepCopy/Matcher/PropertyNameMatcher.php�Qxi��P�:myclabs-deep-copy/DeepCopy/Matcher/PropertyTypeMatcher.phpn�Qxinm$�u�:myclabs-deep-copy/DeepCopy/Reflection/ReflectionHelper.php9�Qxi91����Amyclabs-deep-copy/DeepCopy/TypeFilter/Date/DateIntervalFilter.php��Qxi�[��?myclabs-deep-copy/DeepCopy/TypeFilter/Date/DatePeriodFilter.php`�Qxi`m9���7myclabs-deep-copy/DeepCopy/TypeFilter/ReplaceFilter.php�Qxi�8;�;myclabs-deep-copy/DeepCopy/TypeFilter/ShallowCopyFilter.php��Qxi�F_e��?myclabs-deep-copy/DeepCopy/TypeFilter/Spl/ArrayObjectFilter.php��Qxi��ة�Amyclabs-deep-copy/DeepCopy/TypeFilter/Spl/SplDoublyLinkedList.php��Qxi�K픤Gmyclabs-deep-copy/DeepCopy/TypeFilter/Spl/SplDoublyLinkedListFilter.php*�Qxi*L-� �4myclabs-deep-copy/DeepCopy/TypeFilter/TypeFilter.php��Qxi�Ԋ��6myclabs-deep-copy/DeepCopy/TypeMatcher/TypeMatcher.php��Qxi���$�(myclabs-deep-copy/DeepCopy/deep_copy.php��Qxi��Wȕ�myclabs-deep-copy/LICENSE5�Qxi5ʭ˄�nikic-php-parser/LICENSE��Qxi���*�&nikic-php-parser/PhpParser/Builder.php��Qxi��[ṳ1nikic-php-parser/PhpParser/Builder/ClassConst.php;�Qxi;(k�-nikic-php-parser/PhpParser/Builder/Class_.phpk�QxikӐ�Q�2nikic-php-parser/PhpParser/Builder/Declaration.php��Qxi�`X:�/nikic-php-parser/PhpParser/Builder/EnumCase.php��Qxi�ȸڤ,nikic-php-parser/PhpParser/Builder/Enum_.php� �Qxi� �Uf��3nikic-php-parser/PhpParser/Builder/FunctionLike.php9�Qxi9�B��0nikic-php-parser/PhpParser/Builder/Function_.php��Qxi��33A�1nikic-php-parser/PhpParser/Builder/Interface_.phph
3048 �Qxih
3049 ���|�-nikic-php-parser/PhpParser/Builder/Method.php��Qxi�ڷt��1nikic-php-parser/PhpParser/Builder/Namespace_.phpu�Qxiu ��,nikic-php-parser/PhpParser/Builder/Param.php��Qxi�_먊�/nikic-php-parser/PhpParser/Builder/Property.phpx�QxixV�n�/nikic-php-parser/PhpParser/Builder/TraitUse.php��Qxi�!�rѤ9nikic-php-parser/PhpParser/Builder/TraitUseAdaptation.php��Qxi��0��-nikic-php-parser/PhpParser/Builder/Trait_.php4 �Qxi4 �ѬZ�+nikic-php-parser/PhpParser/Builder/Use_.php,�Qxi,K,g�-nikic-php-parser/PhpParser/BuilderFactory.php)�Qxi) �ҽ�-nikic-php-parser/PhpParser/BuilderHelpers.phpl%�Qxil%�^�[�&nikic-php-parser/PhpParser/Comment.php�QxiVUG�*nikic-php-parser/PhpParser/Comment/Doc.php��Qxi���袤;nikic-php-parser/PhpParser/ConstExprEvaluationException.php}�Qxi}��O�1nikic-php-parser/PhpParser/ConstExprEvaluator.php�&�Qxi�&V7=�$nikic-php-parser/PhpParser/Error.php]�Qxi]�:��+nikic-php-parser/PhpParser/ErrorHandler.php9�Qxi9�yo�6nikic-php-parser/PhpParser/ErrorHandler/Collecting.php��Qxi�H�r(�4nikic-php-parser/PhpParser/ErrorHandler/Throwing.php��Qxi��r���0nikic-php-parser/PhpParser/Internal/DiffElem.php
3050 �Qxi
3051 �_P�.nikic-php-parser/PhpParser/Internal/Differ.php��Qxi�d;v,�Anikic-php-parser/PhpParser/Internal/PrintableNewAnonClassNode.phpe
3052 �Qxie
3053 �G�o�5nikic-php-parser/PhpParser/Internal/TokenPolyfill.php�$�Qxi�$wdz��3nikic-php-parser/PhpParser/Internal/TokenStream.php�#�Qxi�#Gz٤*nikic-php-parser/PhpParser/JsonDecoder.php� �Qxi� 
3054 �n�$nikic-php-parser/PhpParser/Lexer.php(�Qxi(&���.nikic-php-parser/PhpParser/Lexer/Emulative.php� �Qxi� Y�I�Tnikic-php-parser/PhpParser/Lexer/TokenEmulator/AsymmetricVisibilityTokenEmulator.php� �Qxi� ��͝�Dnikic-php-parser/PhpParser/Lexer/TokenEmulator/AttributeEmulator.php��Qxi�� g$�Dnikic-php-parser/PhpParser/Lexer/TokenEmulator/EnumTokenEmulator.php��Qxi�����Hnikic-php-parser/PhpParser/Lexer/TokenEmulator/ExplicitOctalEmulator.php�QxiHU�j�Bnikic-php-parser/PhpParser/Lexer/TokenEmulator/KeywordEmulator.php2�Qxi2$�G��Enikic-php-parser/PhpParser/Lexer/TokenEmulator/MatchTokenEmulator.php��Qxi��9�G�Hnikic-php-parser/PhpParser/Lexer/TokenEmulator/NullsafeTokenEmulator.php-�Qxi-[S��Gnikic-php-parser/PhpParser/Lexer/TokenEmulator/PipeOperatorEmulator.php��Qxi��uMߤHnikic-php-parser/PhpParser/Lexer/TokenEmulator/PropertyTokenEmulator.php��Qxi��4"٤Pnikic-php-parser/PhpParser/Lexer/TokenEmulator/ReadonlyFunctionTokenEmulator.php��Qxi��P�ΤHnikic-php-parser/PhpParser/Lexer/TokenEmulator/ReadonlyTokenEmulator.phpd�Qxid/C�Bnikic-php-parser/PhpParser/Lexer/TokenEmulator/ReverseEmulator.php�Qxi٤@nikic-php-parser/PhpParser/Lexer/TokenEmulator/TokenEmulator.phpW�QxiW3����Cnikic-php-parser/PhpParser/Lexer/TokenEmulator/VoidCastEmulator.php* �Qxi* q �(nikic-php-parser/PhpParser/Modifiers.phpF
3055 �QxiF
3056 `��*nikic-php-parser/PhpParser/NameContext.php &�Qxi &�8�դ#nikic-php-parser/PhpParser/Node.php�Qxi�h�m�'nikic-php-parser/PhpParser/Node/Arg.php �Qxi #E���-nikic-php-parser/PhpParser/Node/ArrayItem.php��Qxi����ݤ-nikic-php-parser/PhpParser/Node/Attribute.php`�Qxi`�v¤2nikic-php-parser/PhpParser/Node/AttributeGroup.php��Qxi�G�iʤ.nikic-php-parser/PhpParser/Node/ClosureUse.php��Qxi�\�jt�/nikic-php-parser/PhpParser/Node/ComplexType.php[�Qxi[�0Us�*nikic-php-parser/PhpParser/Node/Const_.php��Qxi�T�=y�/nikic-php-parser/PhpParser/Node/DeclareItem.php �Qxi �o#�(nikic-php-parser/PhpParser/Node/Expr.php��Qxi�|�)��6nikic-php-parser/PhpParser/Node/Expr/ArrayDimFetch.phpW�QxiWS�!�/nikic-php-parser/PhpParser/Node/Expr/Array_.phpr�Qxir§sG�6nikic-php-parser/PhpParser/Node/Expr/ArrowFunction.php>
3057 �Qxi>
3058 ���M�/nikic-php-parser/PhpParser/Node/Expr/Assign.php'�Qxi'0)�
3059 �1nikic-php-parser/PhpParser/Node/Expr/AssignOp.php��Qxi���b/�<nikic-php-parser/PhpParser/Node/Expr/AssignOp/BitwiseAnd.php�Qxi�?Q�;nikic-php-parser/PhpParser/Node/Expr/AssignOp/BitwiseOr.php�Qxi)��<nikic-php-parser/PhpParser/Node/Expr/AssignOp/BitwiseXor.php�Qxi&�T��:nikic-php-parser/PhpParser/Node/Expr/AssignOp/Coalesce.php�Qxi9����8nikic-php-parser/PhpParser/Node/Expr/AssignOp/Concat.php��Qxi�G�3�5nikic-php-parser/PhpParser/Node/Expr/AssignOp/Div.php��Qxi���/�7nikic-php-parser/PhpParser/Node/Expr/AssignOp/Minus.php��Qxi����c�5nikic-php-parser/PhpParser/Node/Expr/AssignOp/Mod.php��Qxi��j���5nikic-php-parser/PhpParser/Node/Expr/AssignOp/Mul.php��Qxi�Y:�;�6nikic-php-parser/PhpParser/Node/Expr/AssignOp/Plus.php��Qxi�K��]�5nikic-php-parser/PhpParser/Node/Expr/AssignOp/Pow.php��Qxi�ߊ�A�;nikic-php-parser/PhpParser/Node/Expr/AssignOp/ShiftLeft.php�Qxi�(?�<nikic-php-parser/PhpParser/Node/Expr/AssignOp/ShiftRight.php�Qxi����2nikic-php-parser/PhpParser/Node/Expr/AssignRef.phpX�QxiX[���1nikic-php-parser/PhpParser/Node/Expr/BinaryOp.phpd�Qxid�`���<nikic-php-parser/PhpParser/Node/Expr/BinaryOp/BitwiseAnd.phpV�QxiVNVD�;nikic-php-parser/PhpParser/Node/Expr/BinaryOp/BitwiseOr.phpT�QxiT����<nikic-php-parser/PhpParser/Node/Expr/BinaryOp/BitwiseXor.phpV�QxiV�3$��<nikic-php-parser/PhpParser/Node/Expr/BinaryOp/BooleanAnd.phpW�QxiW����;nikic-php-parser/PhpParser/Node/Expr/BinaryOp/BooleanOr.phpU�QxiU��G�:nikic-php-parser/PhpParser/Node/Expr/BinaryOp/Coalesce.phpS�QxiS�/�8nikic-php-parser/PhpParser/Node/Expr/BinaryOp/Concat.phpN�QxiN���5nikic-php-parser/PhpParser/Node/Expr/BinaryOp/Div.phpH�QxiH�A+�7nikic-php-parser/PhpParser/Node/Expr/BinaryOp/Equal.phpM�QxiM�$3�9nikic-php-parser/PhpParser/Node/Expr/BinaryOp/Greater.phpP�QxiPX���@nikic-php-parser/PhpParser/Node/Expr/BinaryOp/GreaterOrEqual.php_�Qxi_��� �;nikic-php-parser/PhpParser/Node/Expr/BinaryOp/Identical.phpV�QxiV���<nikic-php-parser/PhpParser/Node/Expr/BinaryOp/LogicalAnd.phpX�QxiXF��=�;nikic-php-parser/PhpParser/Node/Expr/BinaryOp/LogicalOr.phpU�QxiU-��3�<nikic-php-parser/PhpParser/Node/Expr/BinaryOp/LogicalXor.phpX�QxiX���7nikic-php-parser/PhpParser/Node/Expr/BinaryOp/Minus.phpL�QxiL"7��5nikic-php-parser/PhpParser/Node/Expr/BinaryOp/Mod.phpH�QxiH�
3060
3061 �5nikic-php-parser/PhpParser/Node/Expr/BinaryOp/Mul.phpH�QxiH ��t�:nikic-php-parser/PhpParser/Node/Expr/BinaryOp/NotEqual.phpS�QxiS���ͤ>nikic-php-parser/PhpParser/Node/Expr/BinaryOp/NotIdentical.php\�Qxi\��c_�6nikic-php-parser/PhpParser/Node/Expr/BinaryOp/Pipe.phpK�QxiKu�$�6nikic-php-parser/PhpParser/Node/Expr/BinaryOp/Plus.phpJ�QxiJcm¤5nikic-php-parser/PhpParser/Node/Expr/BinaryOp/Pow.phpI�QxiI��,�;nikic-php-parser/PhpParser/Node/Expr/BinaryOp/ShiftLeft.phpU�QxiUC�Xe�<nikic-php-parser/PhpParser/Node/Expr/BinaryOp/ShiftRight.phpW�QxiW�;��9nikic-php-parser/PhpParser/Node/Expr/BinaryOp/Smaller.phpP�QxiPT��@nikic-php-parser/PhpParser/Node/Expr/BinaryOp/SmallerOrEqual.php_�Qxi_�J��;nikic-php-parser/PhpParser/Node/Expr/BinaryOp/Spaceship.phpV�QxiV�Ex�3nikic-php-parser/PhpParser/Node/Expr/BitwiseNot.php��Qxi�}lMˤ3nikic-php-parser/PhpParser/Node/Expr/BooleanNot.php��Qxi�s�7ޤ1nikic-php-parser/PhpParser/Node/Expr/CallLike.php�Qxi�$�b�-nikic-php-parser/PhpParser/Node/Expr/Cast.phpU�QxiU����4nikic-php-parser/PhpParser/Node/Expr/Cast/Array_.php��Qxi�ȯ���3nikic-php-parser/PhpParser/Node/Expr/Cast/Bool_.php�Qxiux �4nikic-php-parser/PhpParser/Node/Expr/Cast/Double.php��Qxi�S(ۤ2nikic-php-parser/PhpParser/Node/Expr/Cast/Int_.php{�Qxi{��{�5nikic-php-parser/PhpParser/Node/Expr/Cast/Object_.php��Qxi�\����5nikic-php-parser/PhpParser/Node/Expr/Cast/String_.php��Qxi��{Ƥ4nikic-php-parser/PhpParser/Node/Expr/Cast/Unset_.php��Qxi�ɔ�Ԥ3nikic-php-parser/PhpParser/Node/Expr/Cast/Void_.php��Qxi����d�8nikic-php-parser/PhpParser/Node/Expr/ClassConstFetch.php�Qxi�2�/nikic-php-parser/PhpParser/Node/Expr/Clone_.php��Qxi����0nikic-php-parser/PhpParser/Node/Expr/Closure.phpj �Qxij �I��3nikic-php-parser/PhpParser/Node/Expr/ConstFetch.php��Qxi�s�>6�/nikic-php-parser/PhpParser/Node/Expr/Empty_.php��Qxi���ݤ.nikic-php-parser/PhpParser/Node/Expr/Error.php�Qxi$�L��6nikic-php-parser/PhpParser/Node/Expr/ErrorSuppress.php��Qxi�� &�.nikic-php-parser/PhpParser/Node/Expr/Eval_.php��Qxi�A[�.nikic-php-parser/PhpParser/Node/Expr/Exit_.php�Qxig��1nikic-php-parser/PhpParser/Node/Expr/FuncCall.php�Qxi@"]�1nikic-php-parser/PhpParser/Node/Expr/Include_.php��Qxi���� �4nikic-php-parser/PhpParser/Node/Expr/Instanceof_.php��Qxi�.�B��/nikic-php-parser/PhpParser/Node/Expr/Isset_.php��Qxi��>:�.nikic-php-parser/PhpParser/Node/Expr/List_.php��Qxi�2�)�/nikic-php-parser/PhpParser/Node/Expr/Match_.php;�Qxi;h��3nikic-php-parser/PhpParser/Node/Expr/MethodCall.phpQ�QxiQOD��-nikic-php-parser/PhpParser/Node/Expr/New_.php��Qxi�<~h�;nikic-php-parser/PhpParser/Node/Expr/NullsafeMethodCall.phph�Qxihk[�S�>nikic-php-parser/PhpParser/Node/Expr/NullsafePropertyFetch.php�Qxik*��0nikic-php-parser/PhpParser/Node/Expr/PostDec.php��Qxi�Ph@�0nikic-php-parser/PhpParser/Node/Expr/PostInc.php��Qxi�d���/nikic-php-parser/PhpParser/Node/Expr/PreDec.php��Qxi��mB'�/nikic-php-parser/PhpParser/Node/Expr/PreInc.php��Qxi�Է$x�/nikic-php-parser/PhpParser/Node/Expr/Print_.php��Qxi�U���6nikic-php-parser/PhpParser/Node/Expr/PropertyFetch.php��Qxi�:%g�2nikic-php-parser/PhpParser/Node/Expr/ShellExec.phpH�QxiHed��3nikic-php-parser/PhpParser/Node/Expr/StaticCall.php\�Qxi\��P��<nikic-php-parser/PhpParser/Node/Expr/StaticPropertyFetch.php;�Qxi;�.� �0nikic-php-parser/PhpParser/Node/Expr/Ternary.php��Qxi�:X(�/nikic-php-parser/PhpParser/Node/Expr/Throw_.php��Qxi�#�6��3nikic-php-parser/PhpParser/Node/Expr/UnaryMinus.php��Qxi��*C��2nikic-php-parser/PhpParser/Node/Expr/UnaryPlus.php��Qxi�F!Đ�1nikic-php-parser/PhpParser/Node/Expr/Variable.php��Qxi��Ek�2nikic-php-parser/PhpParser/Node/Expr/YieldFrom.php��Qxi��B� �/nikic-php-parser/PhpParser/Node/Expr/Yield_.phpo�Qxio��ƴ�0nikic-php-parser/PhpParser/Node/FunctionLike.php��Qxi��j��.nikic-php-parser/PhpParser/Node/Identifier.phpR�QxiR����:nikic-php-parser/PhpParser/Node/InterpolatedStringPart.phpr�QxirkG�n�4nikic-php-parser/PhpParser/Node/IntersectionType.php��Qxi���u��,nikic-php-parser/PhpParser/Node/MatchArm.php��Qxi��Q\��(nikic-php-parser/PhpParser/Node/Name.php�!�Qxi�!�6Vˤ7nikic-php-parser/PhpParser/Node/Name/FullyQualified.php��Qxi���2��1nikic-php-parser/PhpParser/Node/Name/Relative.php��Qxi��8�V�0nikic-php-parser/PhpParser/Node/NullableType.php��Qxi���)nikic-php-parser/PhpParser/Node/Param.php��Qxi�r
3062 @��0nikic-php-parser/PhpParser/Node/PropertyHook.php� �Qxi� \�BA�0nikic-php-parser/PhpParser/Node/PropertyItem.php\�Qxi\�`��*nikic-php-parser/PhpParser/Node/Scalar.phpo�Qxio���=�1nikic-php-parser/PhpParser/Node/Scalar/Float_.phpW�QxiWj�Ƥ/nikic-php-parser/PhpParser/Node/Scalar/Int_.php� �Qxi� ���=nikic-php-parser/PhpParser/Node/Scalar/InterpolatedString.php��Qxi�?� Z�5nikic-php-parser/PhpParser/Node/Scalar/MagicConst.phpx�Qxix�Ϯ��<nikic-php-parser/PhpParser/Node/Scalar/MagicConst/Class_.phpZ�QxiZ���5�9nikic-php-parser/PhpParser/Node/Scalar/MagicConst/Dir.phpS�QxiSr�fɤ:nikic-php-parser/PhpParser/Node/Scalar/MagicConst/File.phpV�QxiV6�Q�?nikic-php-parser/PhpParser/Node/Scalar/MagicConst/Function_.phpc�Qxic�5��:nikic-php-parser/PhpParser/Node/Scalar/MagicConst/Line.phpV�QxiV�DE��<nikic-php-parser/PhpParser/Node/Scalar/MagicConst/Method.php\�Qxi\�2 N�@nikic-php-parser/PhpParser/Node/Scalar/MagicConst/Namespace_.phpf�Qxif��q�>nikic-php-parser/PhpParser/Node/Scalar/MagicConst/Property.phpb�Qxib0����<nikic-php-parser/PhpParser/Node/Scalar/MagicConst/Trait_.phpZ�QxiZ��ݤ2nikic-php-parser/PhpParser/Node/Scalar/String_.php��Qxi����ˤ-nikic-php-parser/PhpParser/Node/StaticVar.php�Qxi�T>��(nikic-php-parser/PhpParser/Node/Stmt.php��Qxi��y��.nikic-php-parser/PhpParser/Node/Stmt/Block.php��Qxi��j�/nikic-php-parser/PhpParser/Node/Stmt/Break_.php��Qxi�mj��.nikic-php-parser/PhpParser/Node/Stmt/Case_.php��Qxi�ݸO/�/nikic-php-parser/PhpParser/Node/Stmt/Catch_.phpy�Qxiy{�^}�3nikic-php-parser/PhpParser/Node/Stmt/ClassConst.phpS�QxiS/꾬�2nikic-php-parser/PhpParser/Node/Stmt/ClassLike.php �Qxi ��sݤ4nikic-php-parser/PhpParser/Node/Stmt/ClassMethod.php��Qxi� #c�/nikic-php-parser/PhpParser/Node/Stmt/Class_.php� �Qxi� �1�?�/nikic-php-parser/PhpParser/Node/Stmt/Const_.php��Qxi� �2nikic-php-parser/PhpParser/Node/Stmt/Continue_.php��Qxi��򥀤1nikic-php-parser/PhpParser/Node/Stmt/Declare_.php��Qxi�5�`�,nikic-php-parser/PhpParser/Node/Stmt/Do_.phpT�QxiT%�0��.nikic-php-parser/PhpParser/Node/Stmt/Echo_.php��Qxi���`)�0nikic-php-parser/PhpParser/Node/Stmt/ElseIf_.php[�Qxi[bE�Ѥ.nikic-php-parser/PhpParser/Node/Stmt/Else_.php��Qxi�&�1nikic-php-parser/PhpParser/Node/Stmt/EnumCase.php��Qxi�w4m�.nikic-php-parser/PhpParser/Node/Stmt/Enum_.phpJ�QxiJ���?�3nikic-php-parser/PhpParser/Node/Stmt/Expression.php��Qxi� ��1nikic-php-parser/PhpParser/Node/Stmt/Finally_.php��Qxi�8���-nikic-php-parser/PhpParser/Node/Stmt/For_.php��Qxi����+�1nikic-php-parser/PhpParser/Node/Stmt/Foreach_.php��Qxi��0�פ2nikic-php-parser/PhpParser/Node/Stmt/Function_.php�
3063 �Qxi�
3064 f*키0nikic-php-parser/PhpParser/Node/Stmt/Global_.php��Qxi�Po6�.nikic-php-parser/PhpParser/Node/Stmt/Goto_.php"�Qxi"�X ��1nikic-php-parser/PhpParser/Node/Stmt/GroupUse.php^�Qxi^��7Ѥ5nikic-php-parser/PhpParser/Node/Stmt/HaltCompiler.php!�Qxi!��y�,nikic-php-parser/PhpParser/Node/Stmt/If_.php��Qxi�4�o�3nikic-php-parser/PhpParser/Node/Stmt/InlineHTML.php��Qxi�o�ȇ�3nikic-php-parser/PhpParser/Node/Stmt/Interface_.phpN�QxiN�y�Ƥ.nikic-php-parser/PhpParser/Node/Stmt/Label.php��Qxi���J�3nikic-php-parser/PhpParser/Node/Stmt/Namespace_.php��Qxi�SvEj�,nikic-php-parser/PhpParser/Node/Stmt/Nop.phpF�QxiF$6�ؤ1nikic-php-parser/PhpParser/Node/Stmt/Property.php� �Qxi� rݦ��0nikic-php-parser/PhpParser/Node/Stmt/Return_.php��Qxi�|M�0nikic-php-parser/PhpParser/Node/Stmt/Static_.php��Qxi��ٜޤ0nikic-php-parser/PhpParser/Node/Stmt/Switch_.phpI�QxiIi���1nikic-php-parser/PhpParser/Node/Stmt/TraitUse.php��Qxi�?��\�;nikic-php-parser/PhpParser/Node/Stmt/TraitUseAdaptation.php=�Qxi={:��Anikic-php-parser/PhpParser/Node/Stmt/TraitUseAdaptation/Alias.php1�Qxi1b ֤Fnikic-php-parser/PhpParser/Node/Stmt/TraitUseAdaptation/Precedence.php>�Qxi>�� �/nikic-php-parser/PhpParser/Node/Stmt/Trait_.phpQ�QxiQ�E�Q�1nikic-php-parser/PhpParser/Node/Stmt/TryCatch.php6�Qxi6��2.�/nikic-php-parser/PhpParser/Node/Stmt/Unset_.php��Qxi�:V�ɤ-nikic-php-parser/PhpParser/Node/Stmt/Use_.php��Qxi� �|�/nikic-php-parser/PhpParser/Node/Stmt/While_.phpW�QxiWQ/�פ-nikic-php-parser/PhpParser/Node/UnionType.php��Qxi��H���+nikic-php-parser/PhpParser/Node/UseItem.php��Qxi�73U��5nikic-php-parser/PhpParser/Node/VarLikeIdentifier.php�Qxiy.�7nikic-php-parser/PhpParser/Node/VariadicPlaceholder.php��Qxi�m�W�+nikic-php-parser/PhpParser/NodeAbstract.php7�Qxi7�i��)nikic-php-parser/PhpParser/NodeDumper.php�'�Qxi�'��O��)nikic-php-parser/PhpParser/NodeFinder.phpW
3065 �QxiW
3066 ��^��,nikic-php-parser/PhpParser/NodeTraverser.php�&�Qxi�&�m�5nikic-php-parser/PhpParser/NodeTraverserInterface.phpa�Qxia����*nikic-php-parser/PhpParser/NodeVisitor.phpX�QxiX�p}��9nikic-php-parser/PhpParser/NodeVisitor/CloningVisitor.php�Qxi�"ۤCnikic-php-parser/PhpParser/NodeVisitor/CommentAnnotatingVisitor.php�
3067 �Qxi�
3068 ��^��9nikic-php-parser/PhpParser/NodeVisitor/FindingVisitor.php��Qxi��1A�>nikic-php-parser/PhpParser/NodeVisitor/FirstFindingVisitor.php�Qxi~Ĭ*�7nikic-php-parser/PhpParser/NodeVisitor/NameResolver.phpA(�QxiA(x_� �@nikic-php-parser/PhpParser/NodeVisitor/NodeConnectingVisitor.php$ �Qxi$ V��Bnikic-php-parser/PhpParser/NodeVisitor/ParentConnectingVisitor.phpk�Qxik[>�2nikic-php-parser/PhpParser/NodeVisitorAbstract.php��Qxi����~�%nikic-php-parser/PhpParser/Parser.php �Qxi �0@�*nikic-php-parser/PhpParser/Parser/Php7.php��Qxi��?/}�*nikic-php-parser/PhpParser/Parser/Php8.phpm��Qxim���Dʤ-nikic-php-parser/PhpParser/ParserAbstract.php��Qxi�.�m��,nikic-php-parser/PhpParser/ParserFactory.php��Qxi�(��c�)nikic-php-parser/PhpParser/PhpVersion.php��Qxi����j�,nikic-php-parser/PhpParser/PrettyPrinter.php��Qxi�>����5nikic-php-parser/PhpParser/PrettyPrinter/Standard.php ��Qxi ���'{�4nikic-php-parser/PhpParser/PrettyPrinterAbstract.php�
3069 �Qxi�
3070 8f(��$nikic-php-parser/PhpParser/Token.php��Qxi��� ̤3nikic-php-parser/PhpParser/compatibility_tokens.php1 �Qxi1 ���ɤobject-enumerator/LICENSE��Qxi�f���object-reflector/LICENSE��Qxi�R�6�phar-io-manifest/LICENSE`�Qxi`��p�+phar-io-manifest/ManifestDocumentMapper.php��Qxi�^D��#phar-io-manifest/ManifestLoader.php��Qxi��X�j�'phar-io-manifest/ManifestSerializer.php��Qxi�?j�'�:phar-io-manifest/exceptions/ElementCollectionException.php�QxiIn��)phar-io-manifest/exceptions/Exception.php��Qxi�ֽН�?phar-io-manifest/exceptions/InvalidApplicationNameException.php<�Qxi<���W�5phar-io-manifest/exceptions/InvalidEmailException.php�Qxi)Ϫ}�3phar-io-manifest/exceptions/InvalidUrlException.php �Qxi x᳤9phar-io-manifest/exceptions/ManifestDocumentException.php�Qxi/��"�@phar-io-manifest/exceptions/ManifestDocumentLoadingException.php~�Qxi~H}��?phar-io-manifest/exceptions/ManifestDocumentMapperException.php�QxiJ�R1�8phar-io-manifest/exceptions/ManifestElementException.php�Qxi�̏�7phar-io-manifest/exceptions/ManifestLoaderException.php��Qxi��l
3071 ��7phar-io-manifest/exceptions/NoEmailAddressException.php�Qxi���'phar-io-manifest/values/Application.php �Qxi ;�k�+phar-io-manifest/values/ApplicationName.php��Qxi����"phar-io-manifest/values/Author.php�Qxi�x���,phar-io-manifest/values/AuthorCollection.php-�Qxi-���4phar-io-manifest/values/AuthorCollectionIterator.php��Qxi��Ъe�,phar-io-manifest/values/BundledComponent.phpd�Qxid7���6phar-io-manifest/values/BundledComponentCollection.php��Qxi���ߤ>phar-io-manifest/values/BundledComponentCollectionIterator.php�Qxi _��0phar-io-manifest/values/CopyrightInformation.phpp�Qxip���P�!phar-io-manifest/values/Email.php��Qxi��S��%phar-io-manifest/values/Extension.php��Qxi�F {�#phar-io-manifest/values/Library.php�Qxi���v�#phar-io-manifest/values/License.php�Qxi4��$phar-io-manifest/values/Manifest.php&
3072 �Qxi&
3073 �����3phar-io-manifest/values/PhpExtensionRequirement.php��Qxi��Pη�1phar-io-manifest/values/PhpVersionRequirement.phpA�QxiA��i��'phar-io-manifest/values/Requirement.php��Qxi� ��U�1phar-io-manifest/values/RequirementCollection.phps�Qxis6��M�9phar-io-manifest/values/RequirementCollectionIterator.php��Qxi�U�� phar-io-manifest/values/Type.php��Qxi�ܲ3��phar-io-manifest/values/Url.php��Qxi��O���&phar-io-manifest/xml/AuthorElement.php��Qxi����ڤ0phar-io-manifest/xml/AuthorElementCollection.phpM�QxiMj���'phar-io-manifest/xml/BundlesElement.phpt�Qxit]Y���)phar-io-manifest/xml/ComponentElement.php��Qxi��na�3phar-io-manifest/xml/ComponentElementCollection.phpV�QxiV��?�(phar-io-manifest/xml/ContainsElement.php��Qxi�l8�)phar-io-manifest/xml/CopyrightElement.php��Qxi��hDp�*phar-io-manifest/xml/ElementCollection.php��Qxi�<^�ޤ#phar-io-manifest/xml/ExtElement.php*�Qxi*^�פ-phar-io-manifest/xml/ExtElementCollection.phpD�QxiDβS�)phar-io-manifest/xml/ExtensionElement.php��Qxi�� J��'phar-io-manifest/xml/LicenseElement.php��Qxi�v�/!�)phar-io-manifest/xml/ManifestDocument.php� �Qxi� ��i_�(phar-io-manifest/xml/ManifestElement.php��Qxi�#�=�#phar-io-manifest/xml/PhpElement.php�QxiY��(phar-io-manifest/xml/RequiresElement.phpE�QxiEdwʤ!phar-io-version/BuildMetaData.php��Qxi�3A(*�phar-io-version/LICENSE&�Qxi&Ҫ �$phar-io-version/PreReleaseSuffix.php�Qxi8^��phar-io-version/Version.php��Qxi����+phar-io-version/VersionConstraintParser.phpN �QxiN n�%ˤ*phar-io-version/VersionConstraintValue.phpA
3074 �QxiA
3075 �fi��!phar-io-version/VersionNumber.php��Qxi�Kp�_�9phar-io-version/constraints/AbstractVersionConstraint.php��Qxi�42�o�9phar-io-version/constraints/AndVersionConstraintGroup.php��Qxi�kO��4phar-io-version/constraints/AnyVersionConstraint.phpT�QxiT�v�6phar-io-version/constraints/ExactVersionConstraint.php��Qxi�g��q�Ephar-io-version/constraints/GreaterThanOrEqualToVersionConstraint.php��Qxi����_�8phar-io-version/constraints/OrVersionConstraintGroup.php�Qxi���6�Fphar-io-version/constraints/SpecificMajorAndMinorVersionConstraint.php��Qxi�B��,�>phar-io-version/constraints/SpecificMajorVersionConstraint.php �Qxi ����1phar-io-version/constraints/VersionConstraint.php��Qxi��d�(phar-io-version/exceptions/Exception.php��Qxi���<��?phar-io-version/exceptions/InvalidPreReleaseSuffixException.php��Qxi��[��6phar-io-version/exceptions/InvalidVersionException.php��Qxi���y�7phar-io-version/exceptions/NoBuildMetaDataException.php��Qxi�+${��:phar-io-version/exceptions/NoPreReleaseSuffixException.php��Qxi��"��Dphar-io-version/exceptions/UnsupportedVersionConstraintException.php��Qxi���樤"php-code-coverage/CodeCoverage.php%A�Qxi%AY��9�4php-code-coverage/Data/ProcessedCodeCoverageData.phpX'�QxiX'�b�ܤ.php-code-coverage/Data/RawCodeCoverageData.php�#�Qxi�#��I�#php-code-coverage/Driver/Driver.php� �Qxi� ��Y֤'php-code-coverage/Driver/PcovDriver.php��Qxi��=� �%php-code-coverage/Driver/Selector.phpC�QxiC��;I�)php-code-coverage/Driver/XdebugDriver.php�Qxi��d�Jphp-code-coverage/Exception/BranchAndPathCoverageNotSupportedException.php��Qxi�z�Fphp-code-coverage/Exception/DeadCodeDetectionNotSupportedException.php��Qxi��o�I�Cphp-code-coverage/Exception/DirectoryCouldNotBeCreatedException.php��Qxi�<�6'�)php-code-coverage/Exception/Exception.php��Qxi�+��Q�>php-code-coverage/Exception/FileCouldNotBeWrittenException.php��Qxi����8php-code-coverage/Exception/InvalidArgumentException.php��Qxi�l�~ФFphp-code-coverage/Exception/NoCodeCoverageDriverAvailableException.php3�Qxi35oYC�]php-code-coverage/Exception/NoCodeCoverageDriverWithPathCoverageSupportAvailableException.phpe�Qxie�X3��/php-code-coverage/Exception/ParserException.php��Qxi�p��ڤDphp-code-coverage/Exception/PathExistsButIsNotDirectoryException.php��Qxi�i�kd�9php-code-coverage/Exception/PcovNotAvailableException.phpi�Qxii�q�3php-code-coverage/Exception/ReflectionException.php��Qxi��`��?php-code-coverage/Exception/ReportAlreadyFinalizedException.php>�Qxi>�mU=�Iphp-code-coverage/Exception/StaticAnalysisCacheNotConfiguredException.php��Qxi��p�6php-code-coverage/Exception/TestIdMissingException.php�Qxi3�O�Cphp-code-coverage/Exception/UnintentionallyCoveredCodeException.php��Qxi�{:��=php-code-coverage/Exception/WriteOperationFailedException.php��Qxi�u�䶤;php-code-coverage/Exception/XdebugNotAvailableException.phpm�Qxim�{F�9php-code-coverage/Exception/XdebugNotEnabledException.php��Qxi�J]0�,php-code-coverage/Exception/XmlException.php��Qxi�0)�R�php-code-coverage/Filter.phpb �Qxib �7�b�php-code-coverage/LICENSE��Qxi�>�R�'php-code-coverage/Node/AbstractNode.php�Qxi1*3�"php-code-coverage/Node/Builder.php[�Qxi[\:��$php-code-coverage/Node/CrapIndex.php��Qxi���$php-code-coverage/Node/Directory.php1$�Qxi1$ua�php-code-coverage/Node/File.phpDW�QxiDWv� �#php-code-coverage/Node/Iterator.phpu�QxiuB�0��#php-code-coverage/Report/Clover.phpJ(�QxiJ(�<z�&php-code-coverage/Report/Cobertura.phpS1�QxiS1=���#php-code-coverage/Report/Crap4j.php;�Qxi;7�¤(php-code-coverage/Report/Html/Colors.php��Qxi�g�c�/php-code-coverage/Report/Html/CustomCssFile.php;�Qxi;yJ��(php-code-coverage/Report/Html/Facade.php��Qxi���ڤ*php-code-coverage/Report/Html/Renderer.php� �Qxi� ��Ҥ4php-code-coverage/Report/Html/Renderer/Dashboard.php�!�Qxi�!���ܤ4php-code-coverage/Report/Html/Renderer/Directory.phpK�QxiK�88a�/php-code-coverage/Report/Html/Renderer/File.php��Qxi�����Bphp-code-coverage/Report/Html/Renderer/Template/branches.html.dist��Qxi�h2+�Fphp-code-coverage/Report/Html/Renderer/Template/coverage_bar.html.dist'�Qxi'�O}�Mphp-code-coverage/Report/Html/Renderer/Template/coverage_bar_branch.html.dist'�Qxi'�O}�Ephp-code-coverage/Report/Html/Renderer/Template/css/bootstrap.min.css�y�Qxi�y��Ĥ>php-code-coverage/Report/Html/Renderer/Template/css/custom.css�Qxi�Aphp-code-coverage/Report/Html/Renderer/Template/css/nv.d3.min.cssX%�QxiX%�0,�@php-code-coverage/Report/Html/Renderer/Template/css/octicons.cssX�QxiX'#��=php-code-coverage/Report/Html/Renderer/Template/css/style.cssH
3076 �QxiH
3077 �BѺ�Cphp-code-coverage/Report/Html/Renderer/Template/dashboard.html.dist��Qxi���D�Jphp-code-coverage/Report/Html/Renderer/Template/dashboard_branch.html.dist��Qxi���D�Cphp-code-coverage/Report/Html/Renderer/Template/directory.html.dist��Qxi��Ն�Jphp-code-coverage/Report/Html/Renderer/Template/directory_branch.html.dist��Qxi�n2]�Hphp-code-coverage/Report/Html/Renderer/Template/directory_item.html.distA�QxiAds�Ophp-code-coverage/Report/Html/Renderer/Template/directory_item_branch.html.dist;�Qxi;�m�ۤ>php-code-coverage/Report/Html/Renderer/Template/file.html.distP �QxiP j��*�Ephp-code-coverage/Report/Html/Renderer/Template/file_branch.html.dist� �Qxi� �㉞�Cphp-code-coverage/Report/Html/Renderer/Template/file_item.html.distr�Qxir��/y�Jphp-code-coverage/Report/Html/Renderer/Template/file_item_branch.html.distl�Qxil�-���Cphp-code-coverage/Report/Html/Renderer/Template/icons/file-code.svg0�Qxi0�QUU�Hphp-code-coverage/Report/Html/Renderer/Template/icons/file-directory.svg��Qxi���Z��Cphp-code-coverage/Report/Html/Renderer/Template/js/bootstrap.min.jsc��Qxic��"#�<php-code-coverage/Report/Html/Renderer/Template/js/d3.min.js�P�Qxi�P�h�b�:php-code-coverage/Report/Html/Renderer/Template/js/file.js��Qxi�b�䆤@php-code-coverage/Report/Html/Renderer/Template/js/jquery.min.js@^�Qxi@^ ���?php-code-coverage/Report/Html/Renderer/Template/js/nv.d3.min.js�R�Qxi�R<Ms�@php-code-coverage/Report/Html/Renderer/Template/js/popper.min.js�R�Qxi�RQ�d��>php-code-coverage/Report/Html/Renderer/Template/line.html.dist��Qxi���{�?php-code-coverage/Report/Html/Renderer/Template/lines.html.diste�Qxiedf �Ephp-code-coverage/Report/Html/Renderer/Template/method_item.html.dist��Qxi��jפLphp-code-coverage/Report/Html/Renderer/Template/method_item_branch.html.dist��Qxi�yĎk�?php-code-coverage/Report/Html/Renderer/Template/paths.html.dist��Qxi��*'ݤ php-code-coverage/Report/PHP.php'�Qxi';��!php-code-coverage/Report/Text.php�&�Qxi�&�+�Ҥ'php-code-coverage/Report/Thresholds.phpW�QxiW&�a�1php-code-coverage/Report/Xml/BuildInformation.php��Qxi�X5��)php-code-coverage/Report/Xml/Coverage.php��Qxi�5 �,�*php-code-coverage/Report/Xml/Directory.php��Qxi� �Fn�'php-code-coverage/Report/Xml/Facade.php�!�Qxi�!��X��%php-code-coverage/Report/Xml/File.php�Qxi��c�'php-code-coverage/Report/Xml/Method.phpC�QxiCG�V��%php-code-coverage/Report/Xml/Node.php��Qxi� f!>�(php-code-coverage/Report/Xml/Project.phpd�Qxid�����'php-code-coverage/Report/Xml/Report.php �Qxi �d���'php-code-coverage/Report/Xml/Source.php��Qxi��;���&php-code-coverage/Report/Xml/Tests.php��Qxi�zH)פ'php-code-coverage/Report/Xml/Totals.php��Qxi��쭤%php-code-coverage/Report/Xml/Unit.php��Qxi�` p��0php-code-coverage/StaticAnalysis/CacheWarmer.phpg�Qxig�][7�8php-code-coverage/StaticAnalysis/CachingFileAnalyser.php�Qxi`D�{�;php-code-coverage/StaticAnalysis/CodeUnitFindingVisitor.php�%�Qxi�%$�Bphp-code-coverage/StaticAnalysis/ExecutableLinesFindingVisitor.phpe-�Qxie- �B�1php-code-coverage/StaticAnalysis/FileAnalyser.php�Qxi?��4�?php-code-coverage/StaticAnalysis/IgnoredLinesFindingVisitor.php9�Qxi9I� 6�8php-code-coverage/StaticAnalysis/ParsingFileAnalyser.php��Qxi����$php-code-coverage/TestSize/Known.phpZ�QxiZ��G�$php-code-coverage/TestSize/Large.php��Qxi�mr��%php-code-coverage/TestSize/Medium.php��Qxi�8��$php-code-coverage/TestSize/Small.php��Qxi�/�H�'php-code-coverage/TestSize/TestSize.php��Qxi��87Ť&php-code-coverage/TestSize/Unknown.phpk�Qxik?�!ޤ(php-code-coverage/TestStatus/Failure.phpj�QxijZ��&php-code-coverage/TestStatus/Known.php�Qxi���>�(php-code-coverage/TestStatus/Success.phpj�QxijՑ+�+php-code-coverage/TestStatus/TestStatus.php��Qxi�NxQ��(php-code-coverage/TestStatus/Unknown.phpo�Qxio��g��%php-code-coverage/Util/Filesystem.php��Qxi�(У|�%php-code-coverage/Util/Percentage.php^�Qxi^�&�B�php-code-coverage/Version.php��Qxi�d}�%php-file-iterator/ExcludeIterator.php.�Qxi.���php-file-iterator/Facade.php��Qxi�'h�php-file-iterator/Factory.php�
3078 �Qxi�
3079 �uw�php-file-iterator/Iterator.php� �Qxi� $"�v�php-file-iterator/LICENSE��Qxi�-~y֤php-invoker/Invoker.php��Qxi�����$php-invoker/exceptions/Exception.phpv�Qxiv'P=�Dphp-invoker/exceptions/ProcessControlExtensionNotLoadedException.php��Qxi��Ӥ+php-invoker/exceptions/TimeoutException.php��Qxi��tJ�php-text-template/LICENSE��Qxi�-~y֤php-text-template/Template.phpV �QxiV � %X�*php-text-template/exceptions/Exception.php}�Qxi}��`"�9php-text-template/exceptions/InvalidArgumentException.php��Qxi��¤1php-text-template/exceptions/RuntimeException.php��Qxi��]Mp�php-timer/Duration.php� �Qxi� ��ߤphp-timer/LICENSE��Qxi����$php-timer/ResourceUsageFormatter.php��Qxi�65�Ĥphp-timer/Timer.php��Qxi������"php-timer/exceptions/Exception.phpr�Qxir��<�/php-timer/exceptions/NoActiveTimerException.php��Qxi�*���Ephp-timer/exceptions/TimeSinceStartOfRequestNotAvailableException.php��Qxi��.�� phpunit.xsd�G�Qxi�G�a�I�1phpunit/Event/Dispatcher/CollectingDispatcher.php��Qxi�\�Ae�0phpunit/Event/Dispatcher/DeferringDispatcher.php��Qxi�MW���-phpunit/Event/Dispatcher/DirectDispatcher.php� �Qxi� �*0!�'phpunit/Event/Dispatcher/Dispatcher.php}�Qxi};G`��3phpunit/Event/Dispatcher/SubscribableDispatcher.php�Qxi�>�L�,phpunit/Event/Emitter/DispatchingEmitter.php{�Qxi{���
3080 �!phpunit/Event/Emitter/Emitter.php�-�Qxi�-J'�I�-phpunit/Event/Events/Application/Finished.php��Qxi��
3081 ���7phpunit/Event/Events/Application/FinishedSubscriber.php6�Qxi6�)��,phpunit/Event/Events/Application/Started.php��Qxi���i�6phpunit/Event/Events/Application/StartedSubscriber.php4�Qxi4J�'�phpunit/Event/Events/Event.php
3082 �Qxi
3083 �췠�(phpunit/Event/Events/EventCollection.phpI�QxiI
3084 �Ȥ0phpunit/Event/Events/EventCollectionIterator.php��Qxi��x��7phpunit/Event/Events/Test/Assertion/AssertionFailed.php��Qxi���5�Aphpunit/Event/Events/Test/Assertion/AssertionFailedSubscriber.phpH�QxiH�V�<�:phpunit/Event/Events/Test/Assertion/AssertionSucceeded.php��Qxi�̓�ФDphpunit/Event/Events/Test/Assertion/AssertionSucceededSubscriber.phpN�QxiN��c�2phpunit/Event/Events/Test/ComparatorRegistered.php
3085 �Qxi
3086 ��Za�<phpunit/Event/Events/Test/ComparatorRegisteredSubscriber.php@�Qxi@ڭ�Bphpunit/Event/Events/Test/HookMethod/AfterLastTestMethodCalled.phpi�Qxii�d��Lphpunit/Event/Events/Test/HookMethod/AfterLastTestMethodCalledSubscriber.phpJ�QxiJ����Cphpunit/Event/Events/Test/HookMethod/AfterLastTestMethodErrored.php��Qxi�o����Mphpunit/Event/Events/Test/HookMethod/AfterLastTestMethodErroredSubscriber.phpL�QxiL���Dphpunit/Event/Events/Test/HookMethod/AfterLastTestMethodFinished.php`�Qxi`��@��Nphpunit/Event/Events/Test/HookMethod/AfterLastTestMethodFinishedSubscriber.phpN�QxiNw��K�>phpunit/Event/Events/Test/HookMethod/AfterTestMethodCalled.php`�Qxi`��7�Hphpunit/Event/Events/Test/HookMethod/AfterTestMethodCalledSubscriber.phpB�QxiB�R���?phpunit/Event/Events/Test/HookMethod/AfterTestMethodErrored.php��Qxi� u]`�Iphpunit/Event/Events/Test/HookMethod/AfterTestMethodErroredSubscriber.phpD�QxiD%?��@phpunit/Event/Events/Test/HookMethod/AfterTestMethodFinished.phpW�QxiW�S��Jphpunit/Event/Events/Test/HookMethod/AfterTestMethodFinishedSubscriber.phpF�QxiF�^�_�Dphpunit/Event/Events/Test/HookMethod/BeforeFirstTestMethodCalled.phpm�Qxim\��Nphpunit/Event/Events/Test/HookMethod/BeforeFirstTestMethodCalledSubscriber.phpN�QxiNe��u�Ephpunit/Event/Events/Test/HookMethod/BeforeFirstTestMethodErrored.php��Qxi��z�c�Ophpunit/Event/Events/Test/HookMethod/BeforeFirstTestMethodErroredSubscriber.phpP�QxiP񨥲�Fphpunit/Event/Events/Test/HookMethod/BeforeFirstTestMethodFinished.phpd�QxidX'�ŤPphpunit/Event/Events/Test/HookMethod/BeforeFirstTestMethodFinishedSubscriber.phpR�QxiR���\�?phpunit/Event/Events/Test/HookMethod/BeforeTestMethodCalled.phpb�Qxib~��Iphpunit/Event/Events/Test/HookMethod/BeforeTestMethodCalledSubscriber.phpD�QxiD��ƾ�@phpunit/Event/Events/Test/HookMethod/BeforeTestMethodErrored.php��Qxi�Y:��Jphpunit/Event/Events/Test/HookMethod/BeforeTestMethodErroredSubscriber.phpF�QxiF��0�Aphpunit/Event/Events/Test/HookMethod/BeforeTestMethodFinished.phpY�QxiY%�'�Kphpunit/Event/Events/Test/HookMethod/BeforeTestMethodFinishedSubscriber.phpH�QxiHx��S�<phpunit/Event/Events/Test/HookMethod/PostConditionCalled.phpb�Qxib�<�Fphpunit/Event/Events/Test/HookMethod/PostConditionCalledSubscriber.php>�Qxi>b*�=phpunit/Event/Events/Test/HookMethod/PostConditionErrored.php��Qxi�&��Gphpunit/Event/Events/Test/HookMethod/PostConditionErroredSubscriber.php@�Qxi@qh���>phpunit/Event/Events/Test/HookMethod/PostConditionFinished.phpY�QxiY�w�:�Hphpunit/Event/Events/Test/HookMethod/PostConditionFinishedSubscriber.phpB�QxiBWXF��;phpunit/Event/Events/Test/HookMethod/PreConditionCalled.php`�Qxi`�� F�Ephpunit/Event/Events/Test/HookMethod/PreConditionCalledSubscriber.php<�Qxi<u8O&�<phpunit/Event/Events/Test/HookMethod/PreConditionErrored.php��Qxi�n�t�Fphpunit/Event/Events/Test/HookMethod/PreConditionErroredSubscriber.php>�Qxi>����=phpunit/Event/Events/Test/HookMethod/PreConditionFinished.phpW�QxiW)/Iy�Gphpunit/Event/Events/Test/HookMethod/PreConditionFinishedSubscriber.php@�Qxi@��X�3phpunit/Event/Events/Test/Issue/ConsideredRisky.php��Qxi�"���=phpunit/Event/Events/Test/Issue/ConsideredRiskySubscriber.php6�Qxi6S%LT�8phpunit/Event/Events/Test/Issue/DeprecationTriggered.php< �Qxi< T8GP�Bphpunit/Event/Events/Test/Issue/DeprecationTriggeredSubscriber.php@�Qxi@����2phpunit/Event/Events/Test/Issue/ErrorTriggered.php� �Qxi� �o���<phpunit/Event/Events/Test/Issue/ErrorTriggeredSubscriber.php4�Qxi4R��5�3phpunit/Event/Events/Test/Issue/NoticeTriggered.php �Qxi @��~�=phpunit/Event/Events/Test/Issue/NoticeTriggeredSubscriber.php6�Qxi6'T$��;phpunit/Event/Events/Test/Issue/PhpDeprecationTriggered.phpC �QxiC �&��Ephpunit/Event/Events/Test/Issue/PhpDeprecationTriggeredSubscriber.phpF�QxiF�s��6phpunit/Event/Events/Test/Issue/PhpNoticeTriggered.php �Qxi ��=��@phpunit/Event/Events/Test/Issue/PhpNoticeTriggeredSubscriber.php<�Qxi<M�s�7phpunit/Event/Events/Test/Issue/PhpWarningTriggered.php! �Qxi! �m�q�Aphpunit/Event/Events/Test/Issue/PhpWarningTriggeredSubscriber.php>�Qxi>�
3087 d�?phpunit/Event/Events/Test/Issue/PhpunitDeprecationTriggered.phpd�Qxid���n�Iphpunit/Event/Events/Test/Issue/PhpunitDeprecationTriggeredSubscriber.phpN�QxiNlp��9phpunit/Event/Events/Test/Issue/PhpunitErrorTriggered.phpq�Qxiq'0c�Cphpunit/Event/Events/Test/Issue/PhpunitErrorTriggeredSubscriber.phpB�QxiB���;�;phpunit/Event/Events/Test/Issue/PhpunitWarningTriggered.php\�Qxi\�g�.�Ephpunit/Event/Events/Test/Issue/PhpunitWarningTriggeredSubscriber.phpF�QxiF����4phpunit/Event/Events/Test/Issue/WarningTriggered.php �Qxi � �2�>phpunit/Event/Events/Test/Issue/WarningTriggeredSubscriber.php8�Qxi8��Z{�@phpunit/Event/Events/Test/Lifecycle/DataProviderMethodCalled.php.�Qxi.bj}Z�Jphpunit/Event/Events/Test/Lifecycle/DataProviderMethodCalledSubscriber.phpH�QxiH�~-r�Bphpunit/Event/Events/Test/Lifecycle/DataProviderMethodFinished.php �Qxi ���K�Lphpunit/Event/Events/Test/Lifecycle/DataProviderMethodFinishedSubscriber.phpL�QxiL �?��0phpunit/Event/Events/Test/Lifecycle/Finished.phpw�Qxiwu=6y�:phpunit/Event/Events/Test/Lifecycle/FinishedSubscriber.php(�Qxi(.͵P�9phpunit/Event/Events/Test/Lifecycle/PreparationFailed.phpp�Qxip�3&-�Cphpunit/Event/Events/Test/Lifecycle/PreparationFailedSubscriber.php:�Qxi:��"��:phpunit/Event/Events/Test/Lifecycle/PreparationStarted.phpr�Qxir_��Dphpunit/Event/Events/Test/Lifecycle/PreparationStartedSubscriber.php<�Qxi<&Uep�0phpunit/Event/Events/Test/Lifecycle/Prepared.php]�Qxi]q��}�:phpunit/Event/Events/Test/Lifecycle/PreparedSubscriber.php(�Qxi(ħK��-phpunit/Event/Events/Test/Outcome/Errored.php��Qxi��@ޤ7phpunit/Event/Events/Test/Outcome/ErroredSubscriber.php&�Qxi&�d3�,phpunit/Event/Events/Test/Outcome/Failed.php��Qxi�Ef�ɤ6phpunit/Event/Events/Test/Outcome/FailedSubscriber.php$�Qxi$�\*�6phpunit/Event/Events/Test/Outcome/MarkedIncomplete.php �Qxi �GEϤ@phpunit/Event/Events/Test/Outcome/MarkedIncompleteSubscriber.php8�Qxi8
3088 6��,phpunit/Event/Events/Test/Outcome/Passed.phpY�QxiY��^�6phpunit/Event/Events/Test/Outcome/PassedSubscriber.php$�Qxi$��:y�-phpunit/Event/Events/Test/Outcome/Skipped.php��Qxi�W��7phpunit/Event/Events/Test/Outcome/SkippedSubscriber.php&�Qxi&{�dz�5phpunit/Event/Events/Test/PrintedUnexpectedOutput.php%�Qxi%=P���?phpunit/Event/Events/Test/PrintedUnexpectedOutputSubscriber.phpF�QxiF�4���:phpunit/Event/Events/Test/TestDouble/MockObjectCreated.php�Qxi*�~�Dphpunit/Event/Events/Test/TestDouble/MockObjectCreatedSubscriber.php:�Qxi:E�'�Jphpunit/Event/Events/Test/TestDouble/MockObjectForAbstractClassCreated.php�Qxi/bL�Tphpunit/Event/Events/Test/TestDouble/MockObjectForAbstractClassCreatedSubscriber.phpZ�QxiZ�*�Uphpunit/Event/Events/Test/TestDouble/MockObjectForIntersectionOfInterfacesCreated.phpU�QxiU��d�_phpunit/Event/Events/Test/TestDouble/MockObjectForIntersectionOfInterfacesCreatedSubscriber.phpp�Qxip-�Bphpunit/Event/Events/Test/TestDouble/MockObjectForTraitCreated.php �Qxi ��[��Lphpunit/Event/Events/Test/TestDouble/MockObjectForTraitCreatedSubscriber.phpJ�QxiJ~�H �Bphpunit/Event/Events/Test/TestDouble/MockObjectFromWsdlCreated.php
3089 �Qxi
3090 ��P��Lphpunit/Event/Events/Test/TestDouble/MockObjectFromWsdlCreatedSubscriber.phpJ�QxiJ���ͤAphpunit/Event/Events/Test/TestDouble/PartialMockObjectCreated.php9�Qxi9�RgäKphpunit/Event/Events/Test/TestDouble/PartialMockObjectCreatedSubscriber.phpH�QxiH�����9phpunit/Event/Events/Test/TestDouble/TestProxyCreated.php��Qxi��ϤCphpunit/Event/Events/Test/TestDouble/TestProxyCreatedSubscriber.php8�Qxi84���8phpunit/Event/Events/Test/TestDouble/TestStubCreated.php��Qxi�� 0��Bphpunit/Event/Events/Test/TestDouble/TestStubCreatedSubscriber.php6�Qxi6�� �Sphpunit/Event/Events/Test/TestDouble/TestStubForIntersectionOfInterfacesCreated.phpQ�QxiQ#��]phpunit/Event/Events/Test/TestDouble/TestStubForIntersectionOfInterfacesCreatedSubscriber.phpl�Qxil��R�5phpunit/Event/Events/TestRunner/BootstrapFinished.phpf�QxifJ���?phpunit/Event/Events/TestRunner/BootstrapFinishedSubscriber.phpF�QxiF�2�=�.phpunit/Event/Events/TestRunner/Configured.phpz�Qxizr�w8�8phpunit/Event/Events/TestRunner/ConfiguredSubscriber.php8�Qxi8�L�Ϥ8phpunit/Event/Events/TestRunner/DeprecationTriggered.phpq�Qxiq� o~�Bphpunit/Event/Events/TestRunner/DeprecationTriggeredSubscriber.phpL�QxiL��`2�5phpunit/Event/Events/TestRunner/EventFacadeSealed.php��Qxi��j�Z�?phpunit/Event/Events/TestRunner/EventFacadeSealedSubscriber.phpF�QxiF$�v^�4phpunit/Event/Events/TestRunner/ExecutionAborted.php��Qxi��p���>phpunit/Event/Events/TestRunner/ExecutionAbortedSubscriber.phpD�QxiD�sl|�5phpunit/Event/Events/TestRunner/ExecutionFinished.php��Qxi�J�lM�?phpunit/Event/Events/TestRunner/ExecutionFinishedSubscriber.phpF�QxiF�Ӿ�4phpunit/Event/Events/TestRunner/ExecutionStarted.php��Qxi���fn�>phpunit/Event/Events/TestRunner/ExecutionStartedSubscriber.phpD�QxiD�.�9phpunit/Event/Events/TestRunner/ExtensionBootstrapped.phpu�Qxiu@*��Cphpunit/Event/Events/TestRunner/ExtensionBootstrappedSubscriber.phpN�QxiNå��;phpunit/Event/Events/TestRunner/ExtensionLoadedFromPhar.php��Qxi���&O�Ephpunit/Event/Events/TestRunner/ExtensionLoadedFromPharSubscriber.phpR�QxiRA�ƾ�,phpunit/Event/Events/TestRunner/Finished.phpy�Qxiy��6phpunit/Event/Events/TestRunner/FinishedSubscriber.php4�Qxi4[Ix�=phpunit/Event/Events/TestRunner/GarbageCollectionDisabled.php��Qxi�w���Gphpunit/Event/Events/TestRunner/GarbageCollectionDisabledSubscriber.phpV�QxiVy �W�<phpunit/Event/Events/TestRunner/GarbageCollectionEnabled.php��Qxi�a�'֤Fphpunit/Event/Events/TestRunner/GarbageCollectionEnabledSubscriber.phpT�QxiTy�
3091 �>phpunit/Event/Events/TestRunner/GarbageCollectionTriggered.php��Qxi��jq�Hphpunit/Event/Events/TestRunner/GarbageCollectionTriggeredSubscriber.phpX�QxiX�Jz�+phpunit/Event/Events/TestRunner/Started.phpw�Qxiw0�t�5phpunit/Event/Events/TestRunner/StartedSubscriber.php2�Qxi2}�Rp�4phpunit/Event/Events/TestRunner/WarningTriggered.phpi�Qxiib���>phpunit/Event/Events/TestRunner/WarningTriggeredSubscriber.phpD�QxiDʉ���+phpunit/Event/Events/TestSuite/Filtered.php��Qxi�8�T�5phpunit/Event/Events/TestSuite/FilteredSubscriber.php2�Qxi2�?�ˤ+phpunit/Event/Events/TestSuite/Finished.php�Qxi~�H�5phpunit/Event/Events/TestSuite/FinishedSubscriber.php2�Qxi2JV�8�)phpunit/Event/Events/TestSuite/Loaded.php��Qxi���U�3phpunit/Event/Events/TestSuite/LoadedSubscriber.php.�Qxi.��)�*phpunit/Event/Events/TestSuite/Skipped.php}�Qxi}�[}�4phpunit/Event/Events/TestSuite/SkippedSubscriber.php0�Qxi0���)phpunit/Event/Events/TestSuite/Sorted.php"�Qxi":�^��3phpunit/Event/Events/TestSuite/SortedSubscriber.php.�Qxi.�IN"�*phpunit/Event/Events/TestSuite/Started.php�Qxi�`�}�4phpunit/Event/Events/TestSuite/StartedSubscriber.php0�Qxi0��.�9phpunit/Event/Exception/EventAlreadyAssignedException.php �Qxi 0�ɤ8phpunit/Event/Exception/EventFacadeIsSealedException.php
3092 �Qxi
3093 J� ؤ%phpunit/Event/Exception/Exception.phpL�QxiLgx��4phpunit/Event/Exception/InvalidArgumentException.php��Qxi��䀤1phpunit/Event/Exception/InvalidEventException.php�QxiE>��6phpunit/Event/Exception/InvalidSubscriberException.php�QxiS�g�$phpunit/Event/Exception/MapError.php��Qxi���R�Gphpunit/Event/Exception/MoreThanOneDataSetFromDataProviderException.php0�Qxi0R=�8phpunit/Event/Exception/NoComparisonFailureException.php�Qxi�{k��>phpunit/Event/Exception/NoDataSetFromDataProviderException.php'�Qxi'@~�8phpunit/Event/Exception/NoPreviousThrowableException.php
3094 �Qxi
3095 ��~�@phpunit/Event/Exception/NoTestCaseObjectOnCallStackException.php��Qxi�xs�٤,phpunit/Event/Exception/RuntimeException.php��Qxi�L���Dphpunit/Event/Exception/SubscriberTypeAlreadyRegisteredException.php�Qxiį�K�1phpunit/Event/Exception/UnknownEventException.php�Qxi��}�5phpunit/Event/Exception/UnknownEventTypeException.php�Qxi/<���6phpunit/Event/Exception/UnknownSubscriberException.php�Qxi ��ˤ:phpunit/Event/Exception/UnknownSubscriberTypeException.php �Qxi &'�*�phpunit/Event/Facade.php�"�Qxi�"�D� �phpunit/Event/Subscriber.php��Qxi�dlk��phpunit/Event/Tracer.php��Qxi���m�phpunit/Event/TypeMap.php��Qxi���Ƥ#phpunit/Event/Value/ClassMethod.php��Qxi��@դ)phpunit/Event/Value/ComparisonFailure.php��Qxi����0phpunit/Event/Value/ComparisonFailureBuilder.phpM�QxiM�O�|�/phpunit/Event/Value/Runtime/OperatingSystem.php��Qxi��Sᛤ#phpunit/Event/Value/Runtime/PHP.php �Qxi @�h��'phpunit/Event/Value/Runtime/PHPUnit.phpm�Qxim����'phpunit/Event/Value/Runtime/Runtime.php��Qxi�5l��*phpunit/Event/Value/Telemetry/Duration.php� �Qxi� �8�N�8phpunit/Event/Value/Telemetry/GarbageCollectorStatus.phpJ�QxiJ�}��@phpunit/Event/Value/Telemetry/GarbageCollectorStatusProvider.phpp�Qxipr ٤(phpunit/Event/Value/Telemetry/HRTime.php� �Qxi� l!��&phpunit/Event/Value/Telemetry/Info.php�
3096 �Qxi�
3097 L�Wh�-phpunit/Event/Value/Telemetry/MemoryMeter.php��Qxi�'��}�-phpunit/Event/Value/Telemetry/MemoryUsage.phpd�Qxid����Ephpunit/Event/Value/Telemetry/Php81GarbageCollectorStatusProvider.php��Qxi�<~�Ephpunit/Event/Value/Telemetry/Php83GarbageCollectorStatusProvider.phpH�QxiH�<�*phpunit/Event/Value/Telemetry/Snapshot.php��Qxi�^r��+phpunit/Event/Value/Telemetry/StopWatch.phpL�QxiLQء6�(phpunit/Event/Value/Telemetry/System.php��Qxi� �95�3phpunit/Event/Value/Telemetry/SystemMemoryMeter.php��Qxi�5�t��1phpunit/Event/Value/Telemetry/SystemStopWatch.phpZ�QxiZ@��j�;phpunit/Event/Value/Telemetry/SystemStopWatchWithOffset.php��Qxi��'^L�!phpunit/Event/Value/Test/Phpt.php]�Qxi]2�詤!phpunit/Event/Value/Test/Test.php��Qxi�Υ8��+phpunit/Event/Value/Test/TestCollection.php-�Qxi-��3phpunit/Event/Value/Test/TestCollectionIterator.php��Qxi�q�ˤ:phpunit/Event/Value/Test/TestData/DataFromDataProvider.php�Qxi��}�<phpunit/Event/Value/Test/TestData/DataFromTestDependency.php��Qxi�U�ﻤ.phpunit/Event/Value/Test/TestData/TestData.php��Qxi�#��#�8phpunit/Event/Value/Test/TestData/TestDataCollection.php�
3098 �Qxi�
3099 oA�Ѥ@phpunit/Event/Value/Test/TestData/TestDataCollectionIterator.php��Qxi��-�K�$phpunit/Event/Value/Test/TestDox.php
3100 �Qxi
3101 �%���+phpunit/Event/Value/Test/TestDoxBuilder.phpB�QxiB^���'phpunit/Event/Value/Test/TestMethod.php
3102 �Qxi
3103 �.~�.phpunit/Event/Value/Test/TestMethodBuilder.php �Qxi 7*K#�+phpunit/Event/Value/TestSuite/TestSuite.php��Qxi��G��2phpunit/Event/Value/TestSuite/TestSuiteBuilder.php� �Qxi� Τl�7phpunit/Event/Value/TestSuite/TestSuiteForTestClass.php��Qxi��h~�Hphpunit/Event/Value/TestSuite/TestSuiteForTestMethodWithDataProvider.phpz�QxizqSUy�3phpunit/Event/Value/TestSuite/TestSuiteWithName.php��Qxi�cm�y�!phpunit/Event/Value/Throwable.phpX �QxiX _S[y�(phpunit/Event/Value/ThrowableBuilder.phpx�Qxix��B¤phpunit/Exception.phpL�QxiL��ߊ�phpunit/Framework/Assert.php���Qxi����s�&phpunit/Framework/Assert/Functions.php�Z�Qxi�Z�2)�&phpunit/Framework/Attributes/After.php��Qxi�~jL¤+phpunit/Framework/Attributes/AfterClass.php�Qxi��׎�.phpunit/Framework/Attributes/BackupGlobals.php��Qxi���<ߤ7phpunit/Framework/Attributes/BackupStaticProperties.php��Qxi����'phpunit/Framework/Attributes/Before.php��Qxi���;�,phpunit/Framework/Attributes/BeforeClass.php�Qxi���\�3phpunit/Framework/Attributes/CodeCoverageIgnore.phpn�Qxinp�w��,phpunit/Framework/Attributes/CoversClass.php��Qxi���-ʤ/phpunit/Framework/Attributes/CoversFunction.php��Qxi�u�
3104 ��.phpunit/Framework/Attributes/CoversNothing.php�Qxi&ޏ��-phpunit/Framework/Attributes/DataProvider.php��Qxi�s�\C�5phpunit/Framework/Attributes/DataProviderExternal.php��Qxi��i ��(phpunit/Framework/Attributes/Depends.php��Qxi�4ZR�0phpunit/Framework/Attributes/DependsExternal.php��Qxi��ԭ|�>phpunit/Framework/Attributes/DependsExternalUsingDeepClone.php�Qxiz⪐�Aphpunit/Framework/Attributes/DependsExternalUsingShallowClone.php �Qxi K b �/phpunit/Framework/Attributes/DependsOnClass.php��Qxi�%*�B�=phpunit/Framework/Attributes/DependsOnClassUsingDeepClone.php��Qxi�E2��@phpunit/Framework/Attributes/DependsOnClassUsingShallowClone.php��Qxi���#Y�6phpunit/Framework/Attributes/DependsUsingDeepClone.php��Qxi�$�Bv�9phpunit/Framework/Attributes/DependsUsingShallowClone.php��Qxi�},Fm�9phpunit/Framework/Attributes/DoesNotPerformAssertions.php)�Qxi)�J.~�@phpunit/Framework/Attributes/ExcludeGlobalVariableFromBackup.php�Qxi@�7�@phpunit/Framework/Attributes/ExcludeStaticPropertyFromBackup.php0�Qxi0Hl�p�&phpunit/Framework/Attributes/Group.php��Qxi�Qߤ;phpunit/Framework/Attributes/IgnoreClassForCodeCoverage.php��Qxi�:���3phpunit/Framework/Attributes/IgnoreDeprecations.php#�Qxi#]�e�>phpunit/Framework/Attributes/IgnoreFunctionForCodeCoverage.php�Qxi��1�<phpunit/Framework/Attributes/IgnoreMethodForCodeCoverage.phpN�QxiN��&phpunit/Framework/Attributes/Large.php��Qxi�"m�n�'phpunit/Framework/Attributes/Medium.php��Qxi�'�2��.phpunit/Framework/Attributes/PostCondition.php�QxiK���-phpunit/Framework/Attributes/PreCondition.php�Qxiؕ�@�4phpunit/Framework/Attributes/PreserveGlobalState.php��Qxi���)��1phpunit/Framework/Attributes/RequiresFunction.php��Qxi�42\�/phpunit/Framework/Attributes/RequiresMethod.php�Qxi~�fi�8phpunit/Framework/Attributes/RequiresOperatingSystem.php��Qxi�A�a��>phpunit/Framework/Attributes/RequiresOperatingSystemFamily.php�QxiJ�v5�,phpunit/Framework/Attributes/RequiresPhp.php��Qxi�9g�e�5phpunit/Framework/Attributes/RequiresPhpExtension.phpt�Qxit:hK�0phpunit/Framework/Attributes/RequiresPhpunit.php��Qxi���"�0phpunit/Framework/Attributes/RequiresSetting.php��Qxi����:phpunit/Framework/Attributes/RunClassInSeparateProcess.php�Qxi�:��5phpunit/Framework/Attributes/RunInSeparateProcess.php �Qxi ��<phpunit/Framework/Attributes/RunTestsInSeparateProcesses.php�Qxi�Ī��&phpunit/Framework/Attributes/Small.php��Qxi��w~��%phpunit/Framework/Attributes/Test.php��Qxi��#�(phpunit/Framework/Attributes/TestDox.php��Qxi��2�)phpunit/Framework/Attributes/TestWith.php��Qxi�D��6�-phpunit/Framework/Attributes/TestWithJson.php��Qxi������'phpunit/Framework/Attributes/Ticket.php��Qxi��͙��*phpunit/Framework/Attributes/UsesClass.php��Qxi�� 5�-phpunit/Framework/Attributes/UsesFunction.php��Qxi�����4phpunit/Framework/Attributes/WithoutErrorHandler.php
3105 �Qxi
3106 �����0phpunit/Framework/Constraint/Boolean/IsFalse.php`�Qxi`, ��/phpunit/Framework/Constraint/Boolean/IsTrue.php]�Qxi]?6�ͤ)phpunit/Framework/Constraint/Callback.php�Qxi2��2phpunit/Framework/Constraint/Cardinality/Count.php �Qxi F���8phpunit/Framework/Constraint/Cardinality/GreaterThan.phpT�QxiTFdBI�4phpunit/Framework/Constraint/Cardinality/IsEmpty.phpa�Qxiaq9��5phpunit/Framework/Constraint/Cardinality/LessThan.phpN�QxiNC��5phpunit/Framework/Constraint/Cardinality/SameSize.php��Qxi��Bs�+phpunit/Framework/Constraint/Constraint.php� �Qxi� ��E�1phpunit/Framework/Constraint/Equality/IsEqual.phpe �Qxie ��� �?phpunit/Framework/Constraint/Equality/IsEqualCanonicalizing.php�
3107 �Qxi�
3108 M+:}�=phpunit/Framework/Constraint/Equality/IsEqualIgnoringCase.php�
3109 �Qxi�
3110 �ړ�:phpunit/Framework/Constraint/Equality/IsEqualWithDelta.php� �Qxi� ]D��4phpunit/Framework/Constraint/Exception/Exception.php��Qxi���v{�8phpunit/Framework/Constraint/Exception/ExceptionCode.php>�Qxi>r���Gphpunit/Framework/Constraint/Exception/ExceptionMessageIsOrContains.php$�Qxi$x���Sphpunit/Framework/Constraint/Exception/ExceptionMessageMatchesRegularExpression.php��Qxi�7˫F�;phpunit/Framework/Constraint/Filesystem/DirectoryExists.php��Qxi�-p��6phpunit/Framework/Constraint/Filesystem/FileExists.php��Qxi��+�6phpunit/Framework/Constraint/Filesystem/IsReadable.php��Qxi��A��6phpunit/Framework/Constraint/Filesystem/IsWritable.php��Qxi���B�+phpunit/Framework/Constraint/IsAnything.php��Qxi�\ �s�,phpunit/Framework/Constraint/IsIdentical.php �Qxi ;j�K�,phpunit/Framework/Constraint/JsonMatches.php
3111 �Qxi
3112 ��*Q�.phpunit/Framework/Constraint/Math/IsFinite.phpz�QxizԊ��0phpunit/Framework/Constraint/Math/IsInfinite.php��Qxi��C��+phpunit/Framework/Constraint/Math/IsNan.phpn�Qxin��x�4phpunit/Framework/Constraint/Object/ObjectEquals.phpq�Qxiq�j��9phpunit/Framework/Constraint/Object/ObjectHasProperty.php�Qxi"��Ǥ8phpunit/Framework/Constraint/Operator/BinaryOperator.phpV �QxiV �M
3113 �4phpunit/Framework/Constraint/Operator/LogicalAnd.phpY�QxiY����4phpunit/Framework/Constraint/Operator/LogicalNot.php8 �Qxi8 �/��3phpunit/Framework/Constraint/Operator/LogicalOr.php=�Qxi="iN�4phpunit/Framework/Constraint/Operator/LogicalXor.php��Qxi����ޤ2phpunit/Framework/Constraint/Operator/Operator.php'�Qxi'�J�%�7phpunit/Framework/Constraint/Operator/UnaryOperator.php�Qxi5D �.phpunit/Framework/Constraint/String/IsJson.php� �Qxi� �Q�]�9phpunit/Framework/Constraint/String/RegularExpression.php^�Qxi^�ˬ>�6phpunit/Framework/Constraint/String/StringContains.phpZ�QxiZ9kR�6phpunit/Framework/Constraint/String/StringEndsWith.php��Qxi�@%�-�Mphpunit/Framework/Constraint/String/StringEqualsStringIgnoringLineEndings.php7�Qxi7[�J�Fphpunit/Framework/Constraint/String/StringMatchesFormatDescription.php� �Qxi� �'5a�8phpunit/Framework/Constraint/String/StringStartsWith.php��Qxi��.��8phpunit/Framework/Constraint/Traversable/ArrayHasKey.php~�Qxi~�.���3phpunit/Framework/Constraint/Traversable/IsList.phpW�QxiWm�Fr�@phpunit/Framework/Constraint/Traversable/TraversableContains.php|�Qxi|Gu�z�Ephpunit/Framework/Constraint/Traversable/TraversableContainsEqual.php,�Qxi,6���Iphpunit/Framework/Constraint/Traversable/TraversableContainsIdentical.php��Qxi���#�Dphpunit/Framework/Constraint/Traversable/TraversableContainsOnly.php`�Qxi`��l�2phpunit/Framework/Constraint/Type/IsInstanceOf.php��Qxi��Y�ۤ,phpunit/Framework/Constraint/Type/IsNull.php\�Qxi\a#���,phpunit/Framework/Constraint/Type/IsType.php��Qxi�[�j �+phpunit/Framework/DataProviderTestSuite.php;�Qxi;�gE��4phpunit/Framework/Exception/AssertionFailedError.php��Qxi��5/�5phpunit/Framework/Exception/CodeCoverageException.php/�Qxi/9}��4phpunit/Framework/Exception/EmptyStringException.phpC�QxiC�֚ͤ)phpunit/Framework/Exception/Exception.php� �Qxi� �`�4�:phpunit/Framework/Exception/ExpectationFailedException.php��Qxi��]���>phpunit/Framework/Exception/GeneratorNotSupportedException.php:�Qxi:� j{�9phpunit/Framework/Exception/Incomplete/IncompleteTest.php,�Qxi,_K��>phpunit/Framework/Exception/Incomplete/IncompleteTestError.phpk�Qxik����8phpunit/Framework/Exception/InvalidArgumentException.php;�Qxi;��)�<phpunit/Framework/Exception/InvalidCoversTargetException.phpH�QxiH���n�<phpunit/Framework/Exception/InvalidDataProviderException.php<�Qxi<t�H,�:phpunit/Framework/Exception/InvalidDependencyException.phpo�Qxioi���9phpunit/Framework/Exception/NoChildTestSuiteException.php9�Qxi94�ݤNphpunit/Framework/Exception/ObjectEquals/ActualValueIsNotAnObjectException.php��Qxi���W��`phpunit/Framework/Exception/ObjectEquals/ComparisonMethodDoesNotAcceptParameterTypeException.phpW�QxiW�����bphpunit/Framework/Exception/ObjectEquals/ComparisonMethodDoesNotDeclareBoolReturnTypeException.php>�Qxi>{���gphpunit/Framework/Exception/ObjectEquals/ComparisonMethodDoesNotDeclareExactlyOneParameterException.phpH�QxiH�t���aphpunit/Framework/Exception/ObjectEquals/ComparisonMethodDoesNotDeclareParameterTypeException.phpF�QxiF� �9�Rphpunit/Framework/Exception/ObjectEquals/ComparisonMethodDoesNotExistException.php�Qxi�/]�8phpunit/Framework/Exception/PhptAssertionFailedError.php��Qxi�lj~��9phpunit/Framework/Exception/ProcessIsolationException.php9�Qxi9,�ä3phpunit/Framework/Exception/Skipped/SkippedTest.php)�Qxi)���=phpunit/Framework/Exception/Skipped/SkippedTestSuiteError.phpj�Qxijw܊�Cphpunit/Framework/Exception/Skipped/SkippedWithMessageException.phpp�QxipX&�>�@phpunit/Framework/Exception/UnknownClassOrInterfaceException.php��Qxi�H nw�4phpunit/Framework/Exception/UnknownTypeException.php��Qxi���4�.phpunit/Framework/ExecutionOrderDependency.php�Qxi��[}�3phpunit/Framework/MockObject/ConfigurableMethod.php>�Qxi>gYL�Aphpunit/Framework/MockObject/Exception/BadMethodCallException.phpo�Qxio��!��Hphpunit/Framework/MockObject/Exception/CannotUseOnlyMethodsException.phpt�Qxit��
3114 �4phpunit/Framework/MockObject/Exception/Exception.php,�Qxi,�R�?�Kphpunit/Framework/MockObject/Exception/IncompatibleReturnValueException.php��Qxi�2�K]�Hphpunit/Framework/MockObject/Exception/MatchBuilderNotFoundException.php.�Qxi.���a�Lphpunit/Framework/MockObject/Exception/MatcherAlreadyRegisteredException.php&�Qxi&��Lphpunit/Framework/MockObject/Exception/MethodCannotBeConfiguredException.php��Qxi�7��3�Ophpunit/Framework/MockObject/Exception/MethodNameAlreadyConfiguredException.php��Qxi�<ڬ>�Kphpunit/Framework/MockObject/Exception/MethodNameNotConfiguredException.php��Qxi��Yi�Uphpunit/Framework/MockObject/Exception/MethodParametersAlreadyConfiguredException.php��Qxi��s�Hphpunit/Framework/MockObject/Exception/NeverReturningMethodException.phpm�Qxim+"��Pphpunit/Framework/MockObject/Exception/NoMoreReturnValuesConfiguredException.php��Qxi�H]��Lphpunit/Framework/MockObject/Exception/ReturnValueNotConfiguredException.php��Qxi�2��V�;phpunit/Framework/MockObject/Exception/RuntimeException.phpc�Qxic��= �Qphpunit/Framework/MockObject/Generator/Exception/CannotUseAddMethodsException.php��Qxi�����Pphpunit/Framework/MockObject/Generator/Exception/ClassIsEnumerationException.phpJ�QxiJ `@ �Jphpunit/Framework/MockObject/Generator/Exception/ClassIsFinalException.phpF�QxiFԐ��Mphpunit/Framework/MockObject/Generator/Exception/ClassIsReadonlyException.phpL�QxiL��:u�Mphpunit/Framework/MockObject/Generator/Exception/DuplicateMethodException.phpL�QxiL�����>phpunit/Framework/MockObject/Generator/Exception/Exception.phpn�Qxin�q~��Ophpunit/Framework/MockObject/Generator/Exception/InvalidMethodNameException.php<�Qxi<�Ӫ٤Nphpunit/Framework/MockObject/Generator/Exception/NameAlreadyInUseException.phpo�Qxio���cphpunit/Framework/MockObject/Generator/Exception/OriginalConstructorInvocationRequiredException.php6�Qxi6@Qb֤Hphpunit/Framework/MockObject/Generator/Exception/ReflectionException.php��Qxi�"�Ephpunit/Framework/MockObject/Generator/Exception/RuntimeException.php��Qxi����Wphpunit/Framework/MockObject/Generator/Exception/SoapExtensionNotAvailableException.php%�Qxi%NM�Jphpunit/Framework/MockObject/Generator/Exception/UnknownClassException.php+�Qxi+�򻓤Jphpunit/Framework/MockObject/Generator/Exception/UnknownTraitException.phpv�QxivK�ߤIphpunit/Framework/MockObject/Generator/Exception/UnknownTypeException.php-�Qxi-���V�4phpunit/Framework/MockObject/Generator/Generator.php��Qxi�A�8��4phpunit/Framework/MockObject/Generator/MockClass.php��Qxi��D �5phpunit/Framework/MockObject/Generator/MockMethod.php�*�Qxi�*_SV��8phpunit/Framework/MockObject/Generator/MockMethodSet.php��Qxi�K�Bˤ4phpunit/Framework/MockObject/Generator/MockTrait.php��Qxi�qQ�Y�3phpunit/Framework/MockObject/Generator/MockType.phpt�QxitP0
3115 4�9phpunit/Framework/MockObject/Generator/TemplateLoader.php�Qxi����@phpunit/Framework/MockObject/Generator/templates/deprecation.tpl;�Qxi;O5�s�Cphpunit/Framework/MockObject/Generator/templates/doubled_method.tplV�QxiV��%�Jphpunit/Framework/MockObject/Generator/templates/doubled_static_method.tpl��Qxi� 4�R�Aphpunit/Framework/MockObject/Generator/templates/intersection.tplL�QxiL��-X�Cphpunit/Framework/MockObject/Generator/templates/proxied_method.tpl��Qxi�� ��Fphpunit/Framework/MockObject/Generator/templates/test_double_class.tplf�Qxif'�� �@phpunit/Framework/MockObject/Generator/templates/trait_class.tplQ�QxiQ�<�Ȥ?phpunit/Framework/MockObject/Generator/templates/wsdl_class.tpl��Qxi�����@phpunit/Framework/MockObject/Generator/templates/wsdl_method.tpl<�Qxi<��i��,phpunit/Framework/MockObject/MockBuilder.php�/�Qxi�/�Ww3�?phpunit/Framework/MockObject/Runtime/Api/DoubledCloneMethod.php��Qxi��%n��3phpunit/Framework/MockObject/Runtime/Api/Method.phpx�Qxix2`�Ǥ:phpunit/Framework/MockObject/Runtime/Api/MockObjectApi.php��Qxi���i��?phpunit/Framework/MockObject/Runtime/Api/ProxiedCloneMethod.php��Qxi��c��4phpunit/Framework/MockObject/Runtime/Api/StubApi.php��Qxi�ٙ�9phpunit/Framework/MockObject/Runtime/Builder/Identity.php��Qxi��r���Aphpunit/Framework/MockObject/Runtime/Builder/InvocationMocker.php�"�Qxi�"5����Bphpunit/Framework/MockObject/Runtime/Builder/InvocationStubber.php��Qxi��(�I�@phpunit/Framework/MockObject/Runtime/Builder/MethodNameMatch.phpQ�QxiQ�H݆�@phpunit/Framework/MockObject/Runtime/Builder/ParametersMatch.php��Qxi��䁣�5phpunit/Framework/MockObject/Runtime/Builder/Stub.php��Qxi�t#���=phpunit/Framework/MockObject/Runtime/Interface/MockObject.php��Qxi�m�O�Ephpunit/Framework/MockObject/Runtime/Interface/MockObjectInternal.phpJ�QxiJ 3� �7phpunit/Framework/MockObject/Runtime/Interface/Stub.php�Qxi�liH�?phpunit/Framework/MockObject/Runtime/Interface/StubInternal.php��Qxi��$'�3phpunit/Framework/MockObject/Runtime/Invocation.phpB�QxiB�\��:phpunit/Framework/MockObject/Runtime/InvocationHandler.php�Qxi��4�0phpunit/Framework/MockObject/Runtime/Matcher.php�QxiD>F�=phpunit/Framework/MockObject/Runtime/MethodNameConstraint.php�QxiH� �=phpunit/Framework/MockObject/Runtime/ReturnValueGenerator.php�Qxi��s�=phpunit/Framework/MockObject/Runtime/Rule/AnyInvokedCount.php��Qxi�/d�k�;phpunit/Framework/MockObject/Runtime/Rule/AnyParameters.php �Qxi p��"�=phpunit/Framework/MockObject/Runtime/Rule/InvocationOrder.php=�Qxi=h�Aphpunit/Framework/MockObject/Runtime/Rule/InvokedAtLeastCount.php*�Qxi*䙆��@phpunit/Framework/MockObject/Runtime/Rule/InvokedAtLeastOnce.phpG�QxiG�f�s�@phpunit/Framework/MockObject/Runtime/Rule/InvokedAtMostCount.php�Qxiy�I��:phpunit/Framework/MockObject/Runtime/Rule/InvokedCount.php� �Qxi� �I�8phpunit/Framework/MockObject/Runtime/Rule/MethodName.php{�Qxi{8 ��8phpunit/Framework/MockObject/Runtime/Rule/Parameters.php��Qxi���VJ�<phpunit/Framework/MockObject/Runtime/Rule/ParametersRule.php��Qxi�v�Y�>phpunit/Framework/MockObject/Runtime/Stub/ConsecutiveCalls.php��Qxi���jY�7phpunit/Framework/MockObject/Runtime/Stub/Exception.php��Qxi��fa��<phpunit/Framework/MockObject/Runtime/Stub/ReturnArgument.php��Qxi�^��<phpunit/Framework/MockObject/Runtime/Stub/ReturnCallback.php��Qxi�2�Q�=phpunit/Framework/MockObject/Runtime/Stub/ReturnReference.phpf�Qxif���Ӥ8phpunit/Framework/MockObject/Runtime/Stub/ReturnSelf.phpE�QxiE��DѤ8phpunit/Framework/MockObject/Runtime/Stub/ReturnStub.phpT�QxiT�BO�<phpunit/Framework/MockObject/Runtime/Stub/ReturnValueMap.php�Qxi�W��2phpunit/Framework/MockObject/Runtime/Stub/Stub.php��Qxi��ӱʤ!phpunit/Framework/Reorderable.php�Qxi'Ue��$phpunit/Framework/SelfDescribing.phpy�Qxiy;��;�phpunit/Framework/Test.php��Qxi����9�!phpunit/Framework/TestBuilder.php�'�Qxi�'Jh�e�phpunit/Framework/TestCase.php+�Qxi+��#� phpunit/Framework/TestRunner.php&8�Qxi&8OH#��$phpunit/Framework/TestSize/Known.php�Qxi�~�$phpunit/Framework/TestSize/Large.php��Qxi��٧1�%phpunit/Framework/TestSize/Medium.php��Qxi��2J�$phpunit/Framework/TestSize/Small.php��Qxi�s�%j�'phpunit/Framework/TestSize/TestSize.php��Qxi���q��&phpunit/Framework/TestSize/Unknown.php�Qxi� !��,phpunit/Framework/TestStatus/Deprecation.phpo�Qxio'��K�&phpunit/Framework/TestStatus/Error.phpW�QxiWY�s��(phpunit/Framework/TestStatus/Failure.php_�Qxi_<%�J�+phpunit/Framework/TestStatus/Incomplete.phpk�Qxik�ϝ̤&phpunit/Framework/TestStatus/Known.php��Qxi���Zˤ'phpunit/Framework/TestStatus/Notice.php[�Qxi[��V�&phpunit/Framework/TestStatus/Risky.phpW�QxiW��6��(phpunit/Framework/TestStatus/Skipped.php_�Qxi_L��#�(phpunit/Framework/TestStatus/Success.php_�Qxi_}���+phpunit/Framework/TestStatus/TestStatus.php��Qxi��ɪi�(phpunit/Framework/TestStatus/Unknown.phpe�Qxie�e&�(phpunit/Framework/TestStatus/Warning.php_�Qxi_3�D��phpunit/Framework/TestSuite.php�F�Qxi�F5��'phpunit/Framework/TestSuiteIterator.php��Qxi�4g�[�phpunit/Logging/EventLogger.php�Qxi�C8ؤ(phpunit/Logging/JUnit/JunitXmlLogger.php2�Qxi2 TK��/phpunit/Logging/JUnit/Subscriber/Subscriber.php=�Qxi=_� �:phpunit/Logging/JUnit/Subscriber/TestErroredSubscriber.phpt�Qxit�{�9phpunit/Logging/JUnit/Subscriber/TestFailedSubscriber.phpn�QxinP^��;phpunit/Logging/JUnit/Subscriber/TestFinishedSubscriber.phpz�Qxiz��F��Cphpunit/Logging/JUnit/Subscriber/TestMarkedIncompleteSubscriber.php��Qxi�� [�Dphpunit/Logging/JUnit/Subscriber/TestPreparationFailedSubscriber.php��Qxi��?L��Ephpunit/Logging/JUnit/Subscriber/TestPreparationStartedSubscriber.php��Qxi��x��;phpunit/Logging/JUnit/Subscriber/TestPreparedSubscriber.phpt�Qxith�t:�Jphpunit/Logging/JUnit/Subscriber/TestPrintedUnexpectedOutputSubscriber.phpp�Qxip��ߤJphpunit/Logging/JUnit/Subscriber/TestRunnerExecutionFinishedSubscriber.phpH�QxiHV��:phpunit/Logging/JUnit/Subscriber/TestSkippedSubscriber.phpt�QxitP�V�@phpunit/Logging/JUnit/Subscriber/TestSuiteFinishedSubscriber.php$�Qxi$;�B�?phpunit/Logging/JUnit/Subscriber/TestSuiteStartedSubscriber.php$�Qxi$� *�2phpunit/Logging/TeamCity/Subscriber/Subscriber.phpI�QxiI��KѤEphpunit/Logging/TeamCity/Subscriber/TestConsideredRiskySubscriber.php��Qxi���yݤ=phpunit/Logging/TeamCity/Subscriber/TestErroredSubscriber.phpz�Qxiz�[�<phpunit/Logging/TeamCity/Subscriber/TestFailedSubscriber.phpt�Qxit�۲��>phpunit/Logging/TeamCity/Subscriber/TestFinishedSubscriber.php��Qxi�{���Fphpunit/Logging/TeamCity/Subscriber/TestMarkedIncompleteSubscriber.php��Qxi����]�>phpunit/Logging/TeamCity/Subscriber/TestPreparedSubscriber.php�Qxi�Qz:�Mphpunit/Logging/TeamCity/Subscriber/TestRunnerExecutionFinishedSubscriber.phpN�QxiNDIR�=phpunit/Logging/TeamCity/Subscriber/TestSkippedSubscriber.phpz�Qxiz��Wphpunit/Logging/TeamCity/Subscriber/TestSuiteBeforeFirstTestMethodErroredSubscriber.php��Qxi�}�v��Cphpunit/Logging/TeamCity/Subscriber/TestSuiteFinishedSubscriber.php0�Qxi0_!�ǤBphpunit/Logging/TeamCity/Subscriber/TestSuiteSkippedSubscriber.php��Qxi���r�Bphpunit/Logging/TeamCity/Subscriber/TestSuiteStartedSubscriber.php*�Qxi*��U�+phpunit/Logging/TeamCity/TeamCityLogger.phpt+�Qxit+�;9�(phpunit/Logging/TestDox/HtmlRenderer.php*�Qxi*[��U�*phpunit/Logging/TestDox/NamePrettifier.php�!�Qxi�!QWF�-phpunit/Logging/TestDox/PlainTextRenderer.php��Qxi��*�M�<phpunit/Logging/TestDox/TestResult/Subscriber/Subscriber.phpf�Qxif.=�Ophpunit/Logging/TestDox/TestResult/Subscriber/TestConsideredRiskySubscriber.phpG�QxiG��ӤGphpunit/Logging/TestDox/TestResult/Subscriber/TestErroredSubscriber.php�Qxi�R�Fphpunit/Logging/TestDox/TestResult/Subscriber/TestFailedSubscriber.php�Qxi��pd�Hphpunit/Logging/TestDox/TestResult/Subscriber/TestFinishedSubscriber.php��Qxi�CZhܤPphpunit/Logging/TestDox/TestResult/Subscriber/TestMarkedIncompleteSubscriber.phpM�QxiMEM��Fphpunit/Logging/TestDox/TestResult/Subscriber/TestPassedSubscriber.php�Qxi(+�%�Hphpunit/Logging/TestDox/TestResult/Subscriber/TestPreparedSubscriber.php�Qxi�>W&�Gphpunit/Logging/TestDox/TestResult/Subscriber/TestSkippedSubscriber.php�QxiN85��Tphpunit/Logging/TestDox/TestResult/Subscriber/TestTriggeredDeprecationSubscriber.phpe�Qxie�Z�ۤOphpunit/Logging/TestDox/TestResult/Subscriber/TestTriggeredNoticeSubscriber.phpG�QxiG��`�Wphpunit/Logging/TestDox/TestResult/Subscriber/TestTriggeredPhpDeprecationSubscriber.phpw�Qxiw��v��Rphpunit/Logging/TestDox/TestResult/Subscriber/TestTriggeredPhpNoticeSubscriber.phpY�QxiY�R��Sphpunit/Logging/TestDox/TestResult/Subscriber/TestTriggeredPhpWarningSubscriber.php_�Qxi_�e��[phpunit/Logging/TestDox/TestResult/Subscriber/TestTriggeredPhpunitDeprecationSubscriber.php��Qxi�( פUphpunit/Logging/TestDox/TestResult/Subscriber/TestTriggeredPhpunitErrorSubscriber.phpk�Qxik\��Wphpunit/Logging/TestDox/TestResult/Subscriber/TestTriggeredPhpunitWarningSubscriber.phpw�Qxiw�'[��Pphpunit/Logging/TestDox/TestResult/Subscriber/TestTriggeredWarningSubscriber.phpM�QxiM9^�}�1phpunit/Logging/TestDox/TestResult/TestResult.php|�Qxi|P���;phpunit/Logging/TestDox/TestResult/TestResultCollection.php~�Qxi~ }�Cphpunit/Logging/TestDox/TestResult/TestResultCollectionIterator.phpm�Qxim��y�:phpunit/Logging/TestDox/TestResult/TestResultCollector.php21�Qxi216�>ݤphpunit/Metadata/After.php\�Qxi\ #���phpunit/Metadata/AfterClass.phpk�Qxik�b٤%phpunit/Metadata/Api/CodeCoverage.php&�Qxi&�wq�%phpunit/Metadata/Api/DataProvider.php/#�Qxi/#R�Y�%phpunit/Metadata/Api/Dependencies.php��Qxi�A ���phpunit/Metadata/Api/Groups.php�QxiĘ��$phpunit/Metadata/Api/HookMethods.php� �Qxi� �5�`�%phpunit/Metadata/Api/Requirements.php;�Qxi;�Ր��"phpunit/Metadata/BackupGlobals.php��Qxi�-�5/�+phpunit/Metadata/BackupStaticProperties.php��Qxi��`/r�phpunit/Metadata/Before.php_�Qxi_�dݤ phpunit/Metadata/BeforeClass.phpn�Qxin)M���phpunit/Metadata/Covers.php)�Qxi)l�� phpunit/Metadata/CoversClass.php=�Qxi=�߂�'phpunit/Metadata/CoversDefaultClass.phpV�QxiV0��#phpunit/Metadata/CoversFunction.phpH�QxiH`��&�"phpunit/Metadata/CoversNothing.phpt�Qxit�ΎǤ!phpunit/Metadata/DataProvider.php��Qxi�����#phpunit/Metadata/DependsOnClass.php��Qxi�%���$phpunit/Metadata/DependsOnMethod.php�Qxi�-�-phpunit/Metadata/DoesNotPerformAssertions.php��Qxi���!��Tphpunit/Metadata/Exception/AnnotationsAreNotSupportedForInternalClassesException.php��Qxi�{�ʉ�(phpunit/Metadata/Exception/Exception.phpO�QxiO�w���8phpunit/Metadata/Exception/InvalidAttributeException.phpw�Qxiw�o��Aphpunit/Metadata/Exception/InvalidVersionRequirementException.php��Qxi�P�R��<phpunit/Metadata/Exception/NoVersionRequirementException.php��Qxi�?+睤2phpunit/Metadata/Exception/ReflectionException.phph�Qxih`�c�4phpunit/Metadata/ExcludeGlobalVariableFromBackup.php��Qxi�����4phpunit/Metadata/ExcludeStaticPropertyFromBackup.php��Qxi���0^�phpunit/Metadata/Group.php;�Qxi;�A\��/phpunit/Metadata/IgnoreClassForCodeCoverage.php��Qxi�/Z�g�'phpunit/Metadata/IgnoreDeprecations.php��Qxi�?i�W�2phpunit/Metadata/IgnoreFunctionForCodeCoverage.php��Qxi�*��0phpunit/Metadata/IgnoreMethodForCodeCoverage.php�QxiQ??�phpunit/Metadata/Metadata.php�[�Qxi�[�2��'phpunit/Metadata/MetadataCollection.php.�Qxi.�e���/phpunit/Metadata/MetadataCollectionIterator.php��Qxi����1�/phpunit/Metadata/Parser/Annotation/DocBlock.php�"�Qxi�"��B�/phpunit/Metadata/Parser/Annotation/Registry.php� �Qxi� ����,phpunit/Metadata/Parser/AnnotationParser.phpH�QxiH#��+phpunit/Metadata/Parser/AttributeParser.php\�Qxi\�9��)phpunit/Metadata/Parser/CachingParser.php� �Qxi� �??�"phpunit/Metadata/Parser/Parser.phpI�QxiI�W�'phpunit/Metadata/Parser/ParserChain.php �Qxi 1�V��$phpunit/Metadata/Parser/Registry.php��Qxi�^��w�"phpunit/Metadata/PostCondition.phpt�Qxit�վ.�!phpunit/Metadata/PreCondition.phpq�Qxiq���S�(phpunit/Metadata/PreserveGlobalState.php��Qxi�*od�%phpunit/Metadata/RequiresFunction.phpq�Qxiq���#phpunit/Metadata/RequiresMethod.php��Qxi��9�,phpunit/Metadata/RequiresOperatingSystem.php��Qxi�Z 5��2phpunit/Metadata/RequiresOperatingSystemFamily.php��Qxi�IM-~� phpunit/Metadata/RequiresPhp.php#�Qxi#���c�)phpunit/Metadata/RequiresPhpExtension.php�Qxi�q�$phpunit/Metadata/RequiresPhpunit.php/�Qxi/9D�$phpunit/Metadata/RequiresSetting.php�Qxi��K�.phpunit/Metadata/RunClassInSeparateProcess.php��Qxi��mE�)phpunit/Metadata/RunInSeparateProcess.php��Qxi��3�U�0phpunit/Metadata/RunTestsInSeparateProcesses.php��Qxi��n�a�phpunit/Metadata/Test.phpY�QxiYz7凤phpunit/Metadata/TestDox.php�Qxi��3�phpunit/Metadata/TestWith.php��Qxi�^�2�phpunit/Metadata/Uses.php#�Qxi#N��ܤphpunit/Metadata/UsesClass.php7�Qxi7Ư�%phpunit/Metadata/UsesDefaultClass.phpP�QxiP�IC��!phpunit/Metadata/UsesFunction.phpB�QxiB$3%��2phpunit/Metadata/Version/ComparisonRequirement.phpf�Qxif�Ή��2phpunit/Metadata/Version/ConstraintRequirement.php�Qxi�t�Ҥ(phpunit/Metadata/Version/Requirement.php��Qxi�/�s��(phpunit/Metadata/WithoutErrorHandler.php��Qxi�F=f�$phpunit/Runner/Baseline/Baseline.phpe�Qxie����Aphpunit/Runner/Baseline/Exception/CannotLoadBaselineException.php~�Qxi~=)Sb�Bphpunit/Runner/Baseline/Exception/FileDoesNotHaveLineException.php1�Qxi1�3��%phpunit/Runner/Baseline/Generator.php��Qxi�<����!phpunit/Runner/Baseline/Issue.php� �Qxi� ߈b��"phpunit/Runner/Baseline/Reader.php� �Qxi� ���-�2phpunit/Runner/Baseline/RelativePathCalculator.php �Qxi Gy6�1phpunit/Runner/Baseline/Subscriber/Subscriber.phpH�QxiH���q�Iphpunit/Runner/Baseline/Subscriber/TestTriggeredDeprecationSubscriber.php��Qxi�;��äDphpunit/Runner/Baseline/Subscriber/TestTriggeredNoticeSubscriber.php��Qxi�xO�*�Lphpunit/Runner/Baseline/Subscriber/TestTriggeredPhpDeprecationSubscriber.php�Qxi��XM�Gphpunit/Runner/Baseline/Subscriber/TestTriggeredPhpNoticeSubscriber.php��Qxi��Z�Hphpunit/Runner/Baseline/Subscriber/TestTriggeredPhpWarningSubscriber.php��Qxi����֤Ephpunit/Runner/Baseline/Subscriber/TestTriggeredWarningSubscriber.php��Qxi�$��D�"phpunit/Runner/Baseline/Writer.php��Qxi�R )��phpunit/Runner/CodeCoverage.php�3�Qxi�3И���phpunit/Runner/ErrorHandler.phpB�QxiBL9�8phpunit/Runner/Exception/ClassCannotBeFoundException.php%�Qxi%u�X��@phpunit/Runner/Exception/ClassDoesNotExtendTestCaseException.phpQ�QxiQκY��5phpunit/Runner/Exception/ClassIsAbstractException.php'�Qxi'��T�<phpunit/Runner/Exception/CodeCoverageFileExistsException.phpk�Qxik �ٟ�;phpunit/Runner/Exception/DirectoryDoesNotExistException.php+�Qxi+EH�-�+phpunit/Runner/Exception/ErrorException.phpH�QxiH�Z��&phpunit/Runner/Exception/Exception.php�Qxi�Y�K�6phpunit/Runner/Exception/FileDoesNotExistException.php��Qxi�dfH!�2phpunit/Runner/Exception/InvalidOrderException.phpa�Qxia[�t%�5phpunit/Runner/Exception/InvalidPhptFileException.phpd�QxidN8 Ȥ;phpunit/Runner/Exception/ParameterDoesNotExistException.php�QxiZ��h�Dphpunit/Runner/Exception/PhptExternalFileCannotBeLoadedException.phpC�QxiC��Ur�<phpunit/Runner/Exception/UnsupportedPhptSectionException.php�Qxiġ���&phpunit/Runner/Extension/Extension.php��Qxi�sƲ�2phpunit/Runner/Extension/ExtensionBootstrapper.php� �Qxi� n�T�#phpunit/Runner/Extension/Facade.php�
3116 �Qxi�
3117 �~hؤ0phpunit/Runner/Extension/ParameterCollection.php��Qxi�P�|�'phpunit/Runner/Extension/PharLoader.phpR�QxiRm���4phpunit/Runner/Filter/ExcludeGroupFilterIterator.php��Qxi�n�$�!phpunit/Runner/Filter/Factory.php1�Qxi1���E�-phpunit/Runner/Filter/GroupFilterIterator.php��Qxi�|u�]�4phpunit/Runner/Filter/IncludeGroupFilterIterator.php��Qxi�liФ,phpunit/Runner/Filter/NameFilterIterator.php� �Qxi� �;D+�.phpunit/Runner/Filter/TestIdFilterIterator.php+�Qxi+2�K�=phpunit/Runner/GarbageCollection/GarbageCollectionHandler.php6 �Qxi6 &%�Kphpunit/Runner/GarbageCollection/Subscriber/ExecutionFinishedSubscriber.php3�Qxi39�t�Jphpunit/Runner/GarbageCollection/Subscriber/ExecutionStartedSubscriber.php,�Qxi,�F��:phpunit/Runner/GarbageCollection/Subscriber/Subscriber.php��Qxi��1XK�Fphpunit/Runner/GarbageCollection/Subscriber/TestFinishedSubscriber.php��Qxi������phpunit/Runner/PhptTestCase.php�W�Qxi�W�7�1phpunit/Runner/ResultCache/DefaultResultCache.php��Qxi� hդ.phpunit/Runner/ResultCache/NullResultCache.php�QxiV����*phpunit/Runner/ResultCache/ResultCache.phpg�QxigY6l�1phpunit/Runner/ResultCache/ResultCacheHandler.php�Qxi�0��4phpunit/Runner/ResultCache/Subscriber/Subscriber.phpc�Qxic�h�z�Gphpunit/Runner/ResultCache/Subscriber/TestConsideredRiskySubscriber.phpK�QxiK+��+�?phpunit/Runner/ResultCache/Subscriber/TestErroredSubscriber.php�Qxi���>phpunit/Runner/ResultCache/Subscriber/TestFailedSubscriber.php�Qxi\�Yn�@phpunit/Runner/ResultCache/Subscriber/TestFinishedSubscriber.php��Qxi��F� �Hphpunit/Runner/ResultCache/Subscriber/TestMarkedIncompleteSubscriber.phpQ�QxiQ�:ݢ�@phpunit/Runner/ResultCache/Subscriber/TestPreparedSubscriber.php!�Qxi!��E�?phpunit/Runner/ResultCache/Subscriber/TestSkippedSubscriber.php��Qxi���N�Ephpunit/Runner/ResultCache/Subscriber/TestSuiteFinishedSubscriber.php/�Qxi/��>�Dphpunit/Runner/ResultCache/Subscriber/TestSuiteStartedSubscriber.php)�Qxi)��p�'phpunit/Runner/TestResult/Collector.phpZJ�QxiZJn�9�$phpunit/Runner/TestResult/Facade.php� �Qxi� ����#phpunit/Runner/TestResult/Issue.phpK
3118 �QxiK
3119 If�)phpunit/Runner/TestResult/PassedTests.php� �Qxi� �(�[�Nphpunit/Runner/TestResult/Subscriber/AfterTestClassMethodErroredSubscriber.php��Qxi���Z4�Ophpunit/Runner/TestResult/Subscriber/BeforeTestClassMethodErroredSubscriber.php��Qxi�s�c�Cphpunit/Runner/TestResult/Subscriber/ExecutionStartedSubscriber.php��Qxi�0�R��3phpunit/Runner/TestResult/Subscriber/Subscriber.php`�Qxi`z۩ɤFphpunit/Runner/TestResult/Subscriber/TestConsideredRiskySubscriber.phpS�QxiSpZX"�>phpunit/Runner/TestResult/Subscriber/TestErroredSubscriber.php#�Qxi#���.�=phpunit/Runner/TestResult/Subscriber/TestFailedSubscriber.php�Qxi�1q��?phpunit/Runner/TestResult/Subscriber/TestFinishedSubscriber.php)�Qxi)J�p�Gphpunit/Runner/TestResult/Subscriber/TestMarkedIncompleteSubscriber.phpY�QxiY�cz�?phpunit/Runner/TestResult/Subscriber/TestPreparedSubscriber.php#�Qxi#$��U�Qphpunit/Runner/TestResult/Subscriber/TestRunnerTriggeredDeprecationSubscriber.php��Qxi��,ѤMphpunit/Runner/TestResult/Subscriber/TestRunnerTriggeredWarningSubscriber.phpq�QxiqK����>phpunit/Runner/TestResult/Subscriber/TestSkippedSubscriber.php#�Qxi#�Y��Dphpunit/Runner/TestResult/Subscriber/TestSuiteFinishedSubscriber.php=�Qxi=����Cphpunit/Runner/TestResult/Subscriber/TestSuiteSkippedSubscriber.php7�Qxi7W���Cphpunit/Runner/TestResult/Subscriber/TestSuiteStartedSubscriber.php7�Qxi7')ܤKphpunit/Runner/TestResult/Subscriber/TestTriggeredDeprecationSubscriber.phpq�Qxiq�k�x�Ephpunit/Runner/TestResult/Subscriber/TestTriggeredErrorSubscriber.phpM�QxiM/^�ڤFphpunit/Runner/TestResult/Subscriber/TestTriggeredNoticeSubscriber.phpS�QxiS�`�Nphpunit/Runner/TestResult/Subscriber/TestTriggeredPhpDeprecationSubscriber.php��Qxi�IE&�Iphpunit/Runner/TestResult/Subscriber/TestTriggeredPhpNoticeSubscriber.phpe�Qxie�Z���Jphpunit/Runner/TestResult/Subscriber/TestTriggeredPhpWarningSubscriber.phpk�Qxik�)�e�Rphpunit/Runner/TestResult/Subscriber/TestTriggeredPhpunitDeprecationSubscriber.php��Qxi�TkG�Lphpunit/Runner/TestResult/Subscriber/TestTriggeredPhpunitErrorSubscriber.phpw�Qxiw;N�Q�Nphpunit/Runner/TestResult/Subscriber/TestTriggeredPhpunitWarningSubscriber.php��Qxi�@.W�Gphpunit/Runner/TestResult/Subscriber/TestTriggeredWarningSubscriber.phpY�QxiY����(phpunit/Runner/TestResult/TestResult.phpB@�QxiB@z=Vܤ"phpunit/Runner/TestSuiteLoader.php��Qxi�0�ٗ�"phpunit/Runner/TestSuiteSorter.php� �Qxi� �SS9�phpunit/Runner/Version.phpT�QxiT�����phpunit/TextUI/Application.php�Y�Qxi�Y�?Ƴ�"phpunit/TextUI/Command/Command.phpH�QxiH"F� �9phpunit/TextUI/Command/Commands/AtLeastVersionCommand.php5�Qxi5R~���@phpunit/TextUI/Command/Commands/CheckPhpConfigurationCommand.phpF�QxiFl���@phpunit/TextUI/Command/Commands/GenerateConfigurationCommand.php2
3120 �Qxi2
3121 �D��5phpunit/TextUI/Command/Commands/ListGroupsCommand.php �Qxi 1K�T�9phpunit/TextUI/Command/Commands/ListTestSuitesCommand.php��Qxi�q�M�:phpunit/TextUI/Command/Commands/ListTestsAsTextCommand.phpf �Qxif m��9phpunit/TextUI/Command/Commands/ListTestsAsXmlCommand.php'�Qxi'�^¤?phpunit/TextUI/Command/Commands/MigrateConfigurationCommand.php�Qxi9>Ȟ�3phpunit/TextUI/Command/Commands/ShowHelpCommand.php��Qxi��F@�6phpunit/TextUI/Command/Commands/ShowVersionCommand.php��Qxi���'��7phpunit/TextUI/Command/Commands/VersionCheckCommand.php �Qxi ��0�@phpunit/TextUI/Command/Commands/WarmCodeCoverageCacheCommand.php"
3122 �Qxi"
3123 ��R�!phpunit/TextUI/Command/Result.php��Qxi�SF��(phpunit/TextUI/Configuration/Builder.php��Qxi��^�f�,phpunit/TextUI/Configuration/Cli/Builder.phpkw�Qxikw ��.�2phpunit/TextUI/Configuration/Cli/Configuration.php���Qxi�������.phpunit/TextUI/Configuration/Cli/Exception.php[�Qxi[���'�?phpunit/TextUI/Configuration/Cli/XmlConfigurationFileFinder.phpW�QxiW�&?ؤ;phpunit/TextUI/Configuration/CodeCoverageFilterRegistry.php��Qxi����*�.phpunit/TextUI/Configuration/Configuration.php��Qxi�h=�ѤDphpunit/TextUI/Configuration/Exception/CannotFindSchemaException.php��Qxi����O�Sphpunit/TextUI/Configuration/Exception/CodeCoverageReportNotConfiguredException.php��Qxi���VF�Nphpunit/TextUI/Configuration/Exception/ConfigurationCannotBeBuiltException.php��Qxi�6�դ4phpunit/TextUI/Configuration/Exception/Exception.php3�Qxi3�l�p�Gphpunit/TextUI/Configuration/Exception/FilterNotConfiguredException.php��Qxi��]�9�Hphpunit/TextUI/Configuration/Exception/LoggingNotConfiguredException.php��Qxi�N��>phpunit/TextUI/Configuration/Exception/NoBaselineException.php{�Qxi{%I��?phpunit/TextUI/Configuration/Exception/NoBootstrapException.php|�Qxi|eI��Dphpunit/TextUI/Configuration/Exception/NoCacheDirectoryException.php��Qxi��A��Aphpunit/TextUI/Configuration/Exception/NoCliArgumentException.php~�Qxi~�D�Gphpunit/TextUI/Configuration/Exception/NoConfigurationFileException.php��Qxi���@��Lphpunit/TextUI/Configuration/Exception/NoCoverageCacheDirectoryException.php��Qxi��Gt��Cphpunit/TextUI/Configuration/Exception/NoCustomCssFileException.php��Qxi����ΤFphpunit/TextUI/Configuration/Exception/NoDefaultTestSuiteException.php��Qxi���ÿ�Lphpunit/TextUI/Configuration/Exception/NoPharExtensionDirectoryException.php��Qxi��j� �'phpunit/TextUI/Configuration/Merger.php���Qxi���e꽤+phpunit/TextUI/Configuration/PhpHandler.php��Qxi�D<�)phpunit/TextUI/Configuration/Registry.php)�Qxi)3��Ǥ-phpunit/TextUI/Configuration/SourceFilter.php��Qxi��S��-phpunit/TextUI/Configuration/SourceMapper.php
3124 �Qxi
3125 �:7�1phpunit/TextUI/Configuration/TestSuiteBuilder.phpD�QxiD�Lɤ/phpunit/TextUI/Configuration/Value/Constant.php<�Qxi<S:�9phpunit/TextUI/Configuration/Value/ConstantCollection.php��Qxi�?T�.�Aphpunit/TextUI/Configuration/Value/ConstantCollectionIterator.php��Qxi��J,)�0phpunit/TextUI/Configuration/Value/Directory.php��Qxi�x���:phpunit/TextUI/Configuration/Value/DirectoryCollection.php�Qxi�
3126 ���Bphpunit/TextUI/Configuration/Value/DirectoryCollectionIterator.php��Qxi��c��9phpunit/TextUI/Configuration/Value/ExtensionBootstrap.php��Qxi���P��Cphpunit/TextUI/Configuration/Value/ExtensionBootstrapCollection.php��Qxi�!@T��Kphpunit/TextUI/Configuration/Value/ExtensionBootstrapCollectionIterator.php�Qxi����+phpunit/TextUI/Configuration/Value/File.php.�Qxi.���5phpunit/TextUI/Configuration/Value/FileCollection.php��Qxi��)�;�=phpunit/TextUI/Configuration/Value/FileCollectionIterator.phph�Qxih^��D�6phpunit/TextUI/Configuration/Value/FilterDirectory.php��Qxi��=K�@phpunit/TextUI/Configuration/Value/FilterDirectoryCollection.php?�Qxi?'�m�Hphpunit/TextUI/Configuration/Value/FilterDirectoryCollectionIterator.php��Qxi���4N�,phpunit/TextUI/Configuration/Value/Group.php��Qxi�$���6phpunit/TextUI/Configuration/Value/GroupCollection.php3�Qxi3��K,�>phpunit/TextUI/Configuration/Value/GroupCollectionIterator.phps�Qxis��;�1phpunit/TextUI/Configuration/Value/IniSetting.php/�Qxi/���;phpunit/TextUI/Configuration/Value/IniSettingCollection.php��Qxi�I�C�Cphpunit/TextUI/Configuration/Value/IniSettingCollectionIterator.php��Qxi�2�-�*phpunit/TextUI/Configuration/Value/Php.phpN�QxiN}=���-phpunit/TextUI/Configuration/Value/Source.phpv�Qxiv�}ۤ4phpunit/TextUI/Configuration/Value/TestDirectory.php��Qxi����L�>phpunit/TextUI/Configuration/Value/TestDirectoryCollection.php(�Qxi(�m�J�Fphpunit/TextUI/Configuration/Value/TestDirectoryCollectionIterator.php��Qxi��8Q�/phpunit/TextUI/Configuration/Value/TestFile.php��Qxi����9phpunit/TextUI/Configuration/Value/TestFileCollection.php��Qxi����d�Aphpunit/TextUI/Configuration/Value/TestFileCollectionIterator.php|�Qxi| �N�0phpunit/TextUI/Configuration/Value/TestSuite.php��Qxi���ܤ:phpunit/TextUI/Configuration/Value/TestSuiteCollection.php��Qxi�a��w�Bphpunit/TextUI/Configuration/Value/TestSuiteCollectionIterator.php��Qxi�@>¤/phpunit/TextUI/Configuration/Value/Variable.php��Qxi��,¤9phpunit/TextUI/Configuration/Value/VariableCollection.php��Qxi��Tr0�Aphpunit/TextUI/Configuration/Value/VariableCollectionIterator.php��Qxi�l븤>phpunit/TextUI/Configuration/Xml/CodeCoverage/CodeCoverage.php��Qxi��-�?phpunit/TextUI/Configuration/Xml/CodeCoverage/Report/Clover.php,�Qxi,=?g��Bphpunit/TextUI/Configuration/Xml/CodeCoverage/Report/Cobertura.php/�Qxi/Ԏ)}�?phpunit/TextUI/Configuration/Xml/CodeCoverage/Report/Crap4j.php��Qxi���?�=phpunit/TextUI/Configuration/Xml/CodeCoverage/Report/Html.php^ �Qxi^ � ��<phpunit/TextUI/Configuration/Xml/CodeCoverage/Report/Php.php)�Qxi)k�W��=phpunit/TextUI/Configuration/Xml/CodeCoverage/Report/Text.php��Qxi��V/�<phpunit/TextUI/Configuration/Xml/CodeCoverage/Report/Xml.php=�Qxi=:X7��2phpunit/TextUI/Configuration/Xml/Configuration.phps �Qxis >� ��9phpunit/TextUI/Configuration/Xml/DefaultConfiguration.php� �Qxi� K��S�.phpunit/TextUI/Configuration/Xml/Exception.php_�Qxi_+�g3�.phpunit/TextUI/Configuration/Xml/Generator.php��Qxi�pfL�+phpunit/TextUI/Configuration/Xml/Groups.php��Qxi�a�l��@phpunit/TextUI/Configuration/Xml/LoadedFromFileConfiguration.php��Qxi��N(��+phpunit/TextUI/Configuration/Xml/Loader.php���Qxi���è�2phpunit/TextUI/Configuration/Xml/Logging/Junit.php�Qxi+F�4phpunit/TextUI/Configuration/Xml/Logging/Logging.php$ �Qxi$ ِ ��5phpunit/TextUI/Configuration/Xml/Logging/TeamCity.php"�Qxi"e{w�9phpunit/TextUI/Configuration/Xml/Logging/TestDox/Html.php&�Qxi&C_�9phpunit/TextUI/Configuration/Xml/Logging/TestDox/Text.php&�Qxi&5��Ф?phpunit/TextUI/Configuration/Xml/Migration/MigrationBuilder.php� �Qxi� ,�F_�Aphpunit/TextUI/Configuration/Xml/Migration/MigrationException.phpv�Qxiv�[�r�Iphpunit/TextUI/Configuration/Xml/Migration/Migrations/ConvertLogTypes.php�Qxi��ԤPphpunit/TextUI/Configuration/Xml/Migration/Migrations/CoverageCloverToReport.php��Qxi���O�Pphpunit/TextUI/Configuration/Xml/Migration/Migrations/CoverageCrap4jToReport.php�Qxi[�&Z�Nphpunit/TextUI/Configuration/Xml/Migration/Migrations/CoverageHtmlToReport.php�QxiŰMZ�Mphpunit/TextUI/Configuration/Xml/Migration/Migrations/CoveragePhpToReport.php��Qxi�7� ��Nphpunit/TextUI/Configuration/Xml/Migration/Migrations/CoverageTextToReport.php�Qxi*"��Mphpunit/TextUI/Configuration/Xml/Migration/Migrations/CoverageXmlToReport.php��Qxi�J�~*�Zphpunit/TextUI/Configuration/Xml/Migration/Migrations/IntroduceCacheDirectoryAttribute.php��Qxi�����Rphpunit/TextUI/Configuration/Xml/Migration/Migrations/IntroduceCoverageElement.phpL�QxiL���Nphpunit/TextUI/Configuration/Xml/Migration/Migrations/LogToReportMigration.php��Qxi�%f��Cphpunit/TextUI/Configuration/Xml/Migration/Migrations/Migration.php_�Qxi_*ɟ,�ephpunit/TextUI/Configuration/Xml/Migration/Migrations/MoveAttributesFromFilterWhitelistToCoverage.php�Qxi��[��Zphpunit/TextUI/Configuration/Xml/Migration/Migrations/MoveAttributesFromRootToCoverage.php��Qxi�X.p�Yphpunit/TextUI/Configuration/Xml/Migration/Migrations/MoveCoverageDirectoriesToSource.php��Qxi����:�Yphpunit/TextUI/Configuration/Xml/Migration/Migrations/MoveWhitelistExcludesToCoverage.php- �Qxi- ( �~�Yphpunit/TextUI/Configuration/Xml/Migration/Migrations/MoveWhitelistIncludesToCoverage.php`�Qxi`T�!@�sphpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveBeStrictAboutResourceUsageDuringSmallTestsAttribute.php��Qxi���-�hphpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveBeStrictAboutTodoAnnotatedTestsAttribute.php��Qxi��. �Xphpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveCacheResultFileAttribute.php��Qxi�����Tphpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveCacheTokensAttribute.php��Qxi���5�`phpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveConversionToExceptionsAttributes.phpw�Qxiw��뚤fphpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveCoverageElementCacheDirectoryAttribute.php��Qxi�>_T��mphpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveCoverageElementProcessUncoveredFilesAttribute.php �Qxi �S���Kphpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveEmptyFilter.php��Qxi��H�U�Iphpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveListeners.php��Qxi����Hphpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveLogTypes.php��Qxi���Ophpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveLoggingElements.php��Qxi���k�Vphpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveNoInteractionAttribute.php��Qxi��F;��Qphpunit/TextUI/Configuration/Xml/Migration/Migrations/RemovePrinterAttributes.php
3127 �Qxi
3128 �K;�Tphpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveTestDoxGroupsElement.php��Qxi��6���Yphpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveTestSuiteLoaderAttributes.php2�Qxi2/�Ne�Pphpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveVerboseAttribute.php��Qxi���.�_phpunit/TextUI/Configuration/Xml/Migration/Migrations/RenameBackupStaticAttributesAttribute.php��Qxi�Ifphpunit/TextUI/Configuration/Xml/Migration/Migrations/RenameBeStrictAboutCoversAnnotationAttribute.php��Qxi�Ԫw�^phpunit/TextUI/Configuration/Xml/Migration/Migrations/RenameForceCoversAnnotationAttribute.php��Qxi��_ܤNphpunit/TextUI/Configuration/Xml/Migration/Migrations/UpdateSchemaLocation.php��Qxi�ɷe��7phpunit/TextUI/Configuration/Xml/Migration/Migrator.php}�Qxi}�F$��?phpunit/TextUI/Configuration/Xml/Migration/SnapshotNodeList.php��Qxi��~��,phpunit/TextUI/Configuration/Xml/PHPUnit.phpA�QxiA�H9ĤOphpunit/TextUI/Configuration/Xml/SchemaDetector/FailedSchemaDetectionResult.phpz�Qxiz� ���Iphpunit/TextUI/Configuration/Xml/SchemaDetector/SchemaDetectionResult.php��Qxi��{�A�Bphpunit/TextUI/Configuration/Xml/SchemaDetector/SchemaDetector.phpf�Qxif���I�Sphpunit/TextUI/Configuration/Xml/SchemaDetector/SuccessfulSchemaDetectionResult.php��Qxi���&�1phpunit/TextUI/Configuration/Xml/SchemaFinder.phpw�Qxiw��
3129 Z�4phpunit/TextUI/Configuration/Xml/TestSuiteMapper.php$�Qxi$�&���?phpunit/TextUI/Configuration/Xml/Validator/ValidationResult.php7�Qxi7�F$�8phpunit/TextUI/Configuration/Xml/Validator/Validator.php��Qxi�����6phpunit/TextUI/Exception/CannotOpenSocketException.php�Qxiz���&phpunit/TextUI/Exception/Exception.php$�Qxi$昤3phpunit/TextUI/Exception/InvalidSocketException.php�Qxi�I
3130 �-phpunit/TextUI/Exception/RuntimeException.phpG�QxiG�n V�;phpunit/TextUI/Exception/TestDirectoryNotFoundException.php�QxiH˲P�6phpunit/TextUI/Exception/TestFileNotFoundException.php��Qxi�=�|�phpunit/TextUI/Help.php%>�Qxi%>�u+�Aphpunit/TextUI/Output/Default/ProgressPrinter/ProgressPrinter.php�0�Qxi�0���K�cphpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/BeforeTestClassMethodErroredSubscriber.php��Qxi�I���Gphpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/Subscriber.php��Qxi��+�-�Zphpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestConsideredRiskySubscriber.phpk�Qxik +b|�Rphpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestErroredSubscriber.phpA�QxiA�΁�Qphpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestFailedSubscriber.php5�Qxi5�䟤Sphpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestFinishedSubscriber.phpA�QxiA���ˤ[phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestMarkedIncompleteSubscriber.phpq�QxiqG �}�Sphpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestPreparedSubscriber.phpA�QxiAM�[B�aphpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestRunnerExecutionStartedSubscriber.php��Qxi�l�R �Rphpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestSkippedSubscriber.php;�Qxi;�d�U�_phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestTriggeredDeprecationSubscriber.php��Qxi�� ŤYphpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestTriggeredErrorSubscriber.phpk�Qxik��Zphpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestTriggeredNoticeSubscriber.phpq�Qxiq0\��bphpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestTriggeredPhpDeprecationSubscriber.php��Qxi��"3j�]phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestTriggeredPhpNoticeSubscriber.php��Qxi������^phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestTriggeredPhpWarningSubscriber.php��Qxi�4�zҤfphpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestTriggeredPhpunitDeprecationSubscriber.php��Qxi���+T�bphpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestTriggeredPhpunitWarningSubscriber.php��Qxi��^NL�[phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestTriggeredWarningSubscriber.phpw�Qxiw9���/phpunit/TextUI/Output/Default/ResultPrinter.php�J�Qxi�J('L2�9phpunit/TextUI/Output/Default/UnexpectedOutputPrinter.php3�Qxi3��Og� phpunit/TextUI/Output/Facade.php$#�Qxi$#4aQ�0phpunit/TextUI/Output/Printer/DefaultPrinter.phpO �QxiO g��P�-phpunit/TextUI/Output/Printer/NullPrinter.php��Qxi���&��)phpunit/TextUI/Output/Printer/Printer.php\�Qxi\gD�ߤ(phpunit/TextUI/Output/SummaryPrinter.php6�Qxi6�{G�/phpunit/TextUI/Output/TestDox/ResultPrinter.php�#�Qxi�#�NS��*phpunit/TextUI/ShellExitCodeCalculator.php��Qxi����Ǥphpunit/TextUI/TestRunner.php��Qxi�m/$ؤ+phpunit/TextUI/TestSuiteFilterProcessor.phpT�QxiTn?�T�phpunit/Util/Cloner.phpc�Qxic���phpunit/Util/Color.php��Qxi��|���$phpunit/Util/Exception/Exception.php"�Qxi"�Ҥ4phpunit/Util/Exception/InvalidDirectoryException.php�Qxi ��3�/phpunit/Util/Exception/InvalidJsonException.php\�Qxi\�nt�:phpunit/Util/Exception/InvalidVersionOperatorException.php�Qxip2�٤.phpunit/Util/Exception/PhpProcessException.phpm�QximZ�|�'phpunit/Util/Exception/XmlException.phpf�Qxif�;�Q�phpunit/Util/ExcludeList.php��Qxi�b+"��phpunit/Util/Exporter.phpI�QxiI ��phpunit/Util/Filesystem.phpO�QxiOĆ|�phpunit/Util/Filter.phpV �QxiV �,w|�phpunit/Util/GlobalState.phpj!�Qxij!t�/� phpunit/Util/Http/Downloader.phpt�Qxit.�=ä#phpunit/Util/Http/PhpDownloader.php �Qxi K�>Ƥphpunit/Util/Json.phpC �QxiC �f �'phpunit/Util/PHP/AbstractPhpProcess.php��Qxi�����&phpunit/Util/PHP/DefaultPhpProcess.php� �Qxi� �m�+phpunit/Util/PHP/Template/TestCaseClass.tpld �Qxid f{u �,phpunit/Util/PHP/Template/TestCaseMethod.tplj �Qxij �I�*phpunit/Util/PHP/Template/PhptTestCase.tpl��Qxi�>��u�phpunit/Util/Reflection.phpS �QxiS ;�ؤphpunit/Util/Test.php��Qxi�N ��(phpunit/Util/ThrowableToStringMapper.php��Qxi���*phpunit/Util/VersionComparisonOperator.php1�Qxi1 ̚�phpunit/Util/Xml/Loader.php0 �Qxi0 �W�Фphpunit/Util/Xml/Xml.php*�Qxi*u?Qf�sbom.xml�$�Qxi�$ !�Ȥschema/10.0.xsd=�Qxi=|H�schema/10.1.xsd�B�Qxi�Bܭr��schema/10.2.xsdQE�QxiQE��n�schema/10.3.xsdF�QxiF��3&�schema/10.4.xsdGF�QxiGF?��schema/8.5.xsd�B�Qxi�B2A[��schema/9.0.xsd4B�Qxi4B��7w�schema/9.1.xsd�B�Qxi�B�q'8�schema/9.2.xsd�B�Qxi�Bc��-�schema/9.3.xsd�E�Qxi�E��q�schema/9.4.xsd
3131 F�Qxi
3132 FDOFI�schema/9.5.xsdDF�QxiDF��s|�sebastian-cli-parser/LICENSE��Qxi���k�sebastian-cli-parser/Parser.php��Qxi��B%�<sebastian-cli-parser/exceptions/AmbiguousOptionException.phpJ�QxiJkK*�-sebastian-cli-parser/exceptions/Exception.phpy�Qxiy>���Gsebastian-cli-parser/exceptions/OptionDoesNotAllowArgumentException.phpc�Qxic�RjY�Jsebastian-cli-parser/exceptions/RequiredOptionArgumentMissingException.phpl�QxilzQ��:sebastian-cli-parser/exceptions/UnknownOptionException.phpC�QxiC�*tP�*sebastian-code-unit-reverse-lookup/LICENSE��Qxi�f���-sebastian-code-unit-reverse-lookup/Wizard.php� �Qxi� ��C��'sebastian-code-unit/ClassMethodUnit.php�Qxi�v�!sebastian-code-unit/ClassUnit.php�Qxi�Jk� sebastian-code-unit/CodeUnit.php(�Qxi(�Hפ*sebastian-code-unit/CodeUnitCollection.php��Qxi��j�2sebastian-code-unit/CodeUnitCollectionIterator.php\�Qxi\���Ѥ sebastian-code-unit/FileUnit.php�Qxiow�]�$sebastian-code-unit/FunctionUnit.php�Qxi�􋕤+sebastian-code-unit/InterfaceMethodUnit.php"�Qxi"_!_�%sebastian-code-unit/InterfaceUnit.php�Qxiš%�sebastian-code-unit/LICENSE��Qxi��P@٤sebastian-code-unit/Mapper.php�Qxi"�h8�'sebastian-code-unit/TraitMethodUnit.php�Qxi%E�:�!sebastian-code-unit/TraitUnit.php�Qxiߕ�,sebastian-code-unit/exceptions/Exception.phpw�Qxiw�5�Ǥ;sebastian-code-unit/exceptions/InvalidCodeUnitException.php��Qxi�MvԊ�3sebastian-code-unit/exceptions/NoTraitException.php��Qxi��]�5�6sebastian-code-unit/exceptions/ReflectionException.php��Qxi�c�Q�(sebastian-comparator/ArrayComparator.php �Qxi �-_o�#sebastian-comparator/Comparator.phpR�QxiR��?�*sebastian-comparator/ComparisonFailure.php �Qxi *�*�*sebastian-comparator/DOMNodeComparator.php��Qxi�6�?��+sebastian-comparator/DateTimeComparator.phpY�QxiY�6\�,sebastian-comparator/ExceptionComparator.php��Qxi�K\ � sebastian-comparator/Factory.phpz �Qxiz �|=|�sebastian-comparator/LICENSE��Qxi�^2��-sebastian-comparator/MockObjectComparator.php@�Qxi@ASF �*sebastian-comparator/NumericComparator.php�Qxǐ��)sebastian-comparator/ObjectComparator.php
3133 �Qxi
3134 2� }�+sebastian-comparator/ResourceComparator.phpO�QxiOdn��)sebastian-comparator/ScalarComparator.php� �Qxi� |D`Ф3sebastian-comparator/SplObjectStorageComparator.php(�Qxi(��[��'sebastian-comparator/TypeComparator.php��Qxi�U
3135 h��-sebastian-comparator/exceptions/Exception.phpz�Qxiz��Ϥ4sebastian-comparator/exceptions/RuntimeException.php��Qxi���_�#sebastian-complexity/Calculator.php��Qxi�ߎ�*�.sebastian-complexity/Complexity/Complexity.php2�Qxi2j��;�8sebastian-complexity/Complexity/ComplexityCollection.php
3136
3137 �Qxi
3138
3139 ��u�@sebastian-complexity/Complexity/ComplexityCollectionIterator.php�Qxi�y��,sebastian-complexity/Exception/Exception.phpz�QxizȬ�ˤ3sebastian-complexity/Exception/RuntimeException.php��Qxi����sebastian-complexity/LICENSE��Qxi��P@٤=sebastian-complexity/Visitor/ComplexityCalculatingVisitor.php�Qxi9q2��Gsebastian-complexity/Visitor/CyclomaticComplexityCalculatingVisitor.php8�Qxi8ɮ�sebastian-diff/Chunk.php� �Qxi�  ���sebastian-diff/Diff.phpS�QxiS�:���sebastian-diff/Differ.php��Qxi��J�3sebastian-diff/Exception/ConfigurationException.php&�Qxi&]?���&sebastian-diff/Exception/Exception.phpn�Qxin��/\�5sebastian-diff/Exception/InvalidArgumentException.php��Qxi��$y�sebastian-diff/LICENSE��Qxi��ܡ7�sebastian-diff/Line.php�Qxi��FJ�5sebastian-diff/LongestCommonSubsequenceCalculator.php��Qxi�ep�6�Dsebastian-diff/MemoryEfficientLongestCommonSubsequenceCalculator.php��Qxi��eE�4sebastian-diff/Output/AbstractChunkOutputBuilder.php��Qxi�?&��/sebastian-diff/Output/DiffOnlyOutputBuilder.php��Qxi��|���4sebastian-diff/Output/DiffOutputBuilderInterface.php�Qxipm��8sebastian-diff/Output/StrictUnifiedDiffOutputBuilder.php_(�Qxi_(~I;�2sebastian-diff/Output/UnifiedDiffOutputBuilder.php��Qxi�Y6���sebastian-diff/Parser.php� �Qxi� &pѤBsebastian-diff/TimeEfficientLongestCommonSubsequenceCalculator.php��Qxi�N�h �!sebastian-environment/Console.php��Qxi�*�E2�sebastian-environment/LICENSE��Qxi�'|��!sebastian-environment/Runtime.php��Qxi�R���sebastian-exporter/Exporter.php?"�Qxi?"���sebastian-exporter/LICENSE��Qxi�^2��'sebastian-global-state/CodeExporter.phpg �Qxig ��V�&sebastian-global-state/ExcludeList.php
3140 �Qxi
3141  ��sebastian-global-state/LICENSE��Qxi��ik�#sebastian-global-state/Restorer.php3 �Qxi3 ���#sebastian-global-state/Snapshot.php�&�Qxi�&�N��/sebastian-global-state/exceptions/Exception.php}�Qxi}��ⴤ6sebastian-global-state/exceptions/RuntimeException.php��Qxi�#���#sebastian-lines-of-code/Counter.php��Qxi� Z�~�/sebastian-lines-of-code/Exception/Exception.php~�Qxi~%>���>sebastian-lines-of-code/Exception/IllogicalValuesException.php��Qxi���r��<sebastian-lines-of-code/Exception/NegativeValueException.php��Qxi��&�Ӥ6sebastian-lines-of-code/Exception/RuntimeException.php��Qxi��)Ϲ�sebastian-lines-of-code/LICENSE��Qxi��P@٤/sebastian-lines-of-code/LineCountingVisitor.php �Qxi S���'sebastian-lines-of-code/LinesOfCode.php �Qxi �����*sebastian-object-enumerator/Enumerator.php��Qxi��=��.sebastian-object-reflector/ObjectReflector.php�Qxi�9O�'sebastian-recursion-context/Context.php/�Qxi/�̈�#sebastian-recursion-context/LICENSE��Qxi�^2��sebastian-type/LICENSE��Qxi� ��sebastian-type/Parameter.php�Qxi��E��#sebastian-type/ReflectionMapper.php��Qxi��l ܤsebastian-type/TypeName.php�Qxi�A�֤&sebastian-type/exception/Exception.phpn�Qxin�H3�-sebastian-type/exception/RuntimeException.php��Qxi��;s֤$sebastian-type/type/CallableType.php��Qxi��M{)�!sebastian-type/type/FalseType.phpb�Qxibnޅ^�)sebastian-type/type/GenericObjectType.php �Qxi �IG��(sebastian-type/type/IntersectionType.php�
3142 �Qxi�
3143 �sؤ$sebastian-type/type/IterableType.php��Qxi��~��!sebastian-type/type/MixedType.php&�Qxi&��Ԥ!sebastian-type/type/NeverType.php��Qxi����S� sebastian-type/type/NullType.php!�Qxi!n�6��"sebastian-type/type/ObjectType.php$�Qxi$�a�`�"sebastian-type/type/SimpleType.php*�Qxi*'�hH�"sebastian-type/type/StaticType.php��Qxi�s92� sebastian-type/type/TrueType.php]�Qxi]�z��sebastian-type/type/Type.php��Qxi���!sebastian-type/type/UnionType.php% �Qxi% �E�#sebastian-type/type/UnknownType.php�QxiH��� sebastian-type/type/VoidType.php��Qxi��[��sebastian-version/LICENSE��Qxi��Vo�sebastian-version/Version.php��Qxi��D��theseer-tokenizer/Exception.phpr�Qxir��m��theseer-tokenizer/LICENSE��Qxi��R (�"theseer-tokenizer/NamespaceUri.phpJ�QxiJW�]�+theseer-tokenizer/NamespaceUriException.php}�Qxi}aՓ��theseer-tokenizer/Token.php��Qxi�K�`¤%theseer-tokenizer/TokenCollection.php�Qxi�S]�.theseer-tokenizer/TokenCollectionException.php��Qxi�5�ɤtheseer-tokenizer/Tokenizer.phpU �QxiU �l9$�#theseer-tokenizer/XMLSerializer.php��Qxi��8z��{
3144 "_readme": [
3145 "This file locks the dependencies of your project to a known state",
3146 "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
3147 "This file is @generated automatically"
3148 ],
3149 "content-hash": "8dfe5ace1a29844a4ff8db731eb68f21",
3150 "packages": [
3151 {
3152 "name": "myclabs/deep-copy",
3153 "version": "1.13.4",
3154 "source": {
3155 "type": "git",
3156 "url": "https://github.com/myclabs/DeepCopy.git",
3157 "reference": "07d290f0c47959fd5eed98c95ee5602db07e0b6a"
3158 },
3159 "dist": {
3160 "type": "zip",
3161 "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/07d290f0c47959fd5eed98c95ee5602db07e0b6a",
3162 "reference": "07d290f0c47959fd5eed98c95ee5602db07e0b6a",
3163 "shasum": ""
3164 },
3165 "require": {
3166 "php": "^7.1 || ^8.0"
3167 },
3168 "conflict": {
3169 "doctrine/collections": "<1.6.8",
3170 "doctrine/common": "<2.13.3 || >=3 <3.2.2"
3171 },
3172 "require-dev": {
3173 "doctrine/collections": "^1.6.8",
3174 "doctrine/common": "^2.13.3 || ^3.2.2",
3175 "phpspec/prophecy": "^1.10",
3176 "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13"
3177 },
3178 "type": "library",
3179 "autoload": {
3180 "files": [
3181 "src/DeepCopy/deep_copy.php"
3182 ],
3183 "psr-4": {
3184 "DeepCopy\\": "src/DeepCopy/"
3185 }
3186 },
3187 "notification-url": "https://packagist.org/downloads/",
3188 "license": [
3189 "MIT"
3190 ],
3191 "description": "Create deep copies (clones) of your objects",
3192 "keywords": [
3193 "clone",
3194 "copy",
3195 "duplicate",
3196 "object",
3197 "object graph"
3198 ],
3199 "support": {
3200 "issues": "https://github.com/myclabs/DeepCopy/issues",
3201 "source": "https://github.com/myclabs/DeepCopy/tree/1.13.4"
3202 },
3203 "funding": [
3204 {
3205 "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy",
3206 "type": "tidelift"
3207 }
3208 ],
3209 "time": "2025-08-01T08:46:24+00:00"
3210 },
3211 {
3212 "name": "nikic/php-parser",
3213 "version": "v5.7.0",
3214 "source": {
3215 "type": "git",
3216 "url": "https://github.com/nikic/PHP-Parser.git",
3217 "reference": "dca41cd15c2ac9d055ad70dbfd011130757d1f82"
3218 },
3219 "dist": {
3220 "type": "zip",
3221 "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/dca41cd15c2ac9d055ad70dbfd011130757d1f82",
3222 "reference": "dca41cd15c2ac9d055ad70dbfd011130757d1f82",
3223 "shasum": ""
3224 },
3225 "require": {
3226 "ext-ctype": "*",
3227 "ext-json": "*",
3228 "ext-tokenizer": "*",
3229 "php": ">=7.4"
3230 },
3231 "require-dev": {
3232 "ircmaxell/php-yacc": "^0.0.7",
3233 "phpunit/phpunit": "^9.0"
3234 },
3235 "bin": [
3236 "bin/php-parse"
3237 ],
3238 "type": "library",
3239 "extra": {
3240 "branch-alias": {
3241 "dev-master": "5.x-dev"
3242 }
3243 },
3244 "autoload": {
3245 "psr-4": {
3246 "PhpParser\\": "lib/PhpParser"
3247 }
3248 },
3249 "notification-url": "https://packagist.org/downloads/",
3250 "license": [
3251 "BSD-3-Clause"
3252 ],
3253 "authors": [
3254 {
3255 "name": "Nikita Popov"
3256 }
3257 ],
3258 "description": "A PHP parser written in PHP",
3259 "keywords": [
3260 "parser",
3261 "php"
3262 ],
3263 "support": {
3264 "issues": "https://github.com/nikic/PHP-Parser/issues",
3265 "source": "https://github.com/nikic/PHP-Parser/tree/v5.7.0"
3266 },
3267 "time": "2025-12-06T11:56:16+00:00"
3268 },
3269 {
3270 "name": "phar-io/manifest",
3271 "version": "2.0.4",
3272 "source": {
3273 "type": "git",
3274 "url": "https://github.com/phar-io/manifest.git",
3275 "reference": "54750ef60c58e43759730615a392c31c80e23176"
3276 },
3277 "dist": {
3278 "type": "zip",
3279 "url": "https://api.github.com/repos/phar-io/manifest/zipball/54750ef60c58e43759730615a392c31c80e23176",
3280 "reference": "54750ef60c58e43759730615a392c31c80e23176",
3281 "shasum": ""
3282 },
3283 "require": {
3284 "ext-dom": "*",
3285 "ext-libxml": "*",
3286 "ext-phar": "*",
3287 "ext-xmlwriter": "*",
3288 "phar-io/version": "^3.0.1",
3289 "php": "^7.2 || ^8.0"
3290 },
3291 "type": "library",
3292 "extra": {
3293 "branch-alias": {
3294 "dev-master": "2.0.x-dev"
3295 }
3296 },
3297 "autoload": {
3298 "classmap": [
3299 "src/"
3300 ]
3301 },
3302 "notification-url": "https://packagist.org/downloads/",
3303 "license": [
3304 "BSD-3-Clause"
3305 ],
3306 "authors": [
3307 {
3308 "name": "Arne Blankerts",
3309 "email": "arne@blankerts.de",
3310 "role": "Developer"
3311 },
3312 {
3313 "name": "Sebastian Heuer",
3314 "email": "sebastian@phpeople.de",
3315 "role": "Developer"
3316 },
3317 {
3318 "name": "Sebastian Bergmann",
3319 "email": "sebastian@phpunit.de",
3320 "role": "Developer"
3321 }
3322 ],
3323 "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)",
3324 "support": {
3325 "issues": "https://github.com/phar-io/manifest/issues",
3326 "source": "https://github.com/phar-io/manifest/tree/2.0.4"
3327 },
3328 "funding": [
3329 {
3330 "url": "https://github.com/theseer",
3331 "type": "github"
3332 }
3333 ],
3334 "time": "2024-03-03T12:33:53+00:00"
3335 },
3336 {
3337 "name": "phar-io/version",
3338 "version": "3.2.1",
3339 "source": {
3340 "type": "git",
3341 "url": "https://github.com/phar-io/version.git",
3342 "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74"
3343 },
3344 "dist": {
3345 "type": "zip",
3346 "url": "https://api.github.com/repos/phar-io/version/zipball/4f7fd7836c6f332bb2933569e566a0d6c4cbed74",
3347 "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74",
3348 "shasum": ""
3349 },
3350 "require": {
3351 "php": "^7.2 || ^8.0"
3352 },
3353 "type": "library",
3354 "autoload": {
3355 "classmap": [
3356 "src/"
3357 ]
3358 },
3359 "notification-url": "https://packagist.org/downloads/",
3360 "license": [
3361 "BSD-3-Clause"
3362 ],
3363 "authors": [
3364 {
3365 "name": "Arne Blankerts",
3366 "email": "arne@blankerts.de",
3367 "role": "Developer"
3368 },
3369 {
3370 "name": "Sebastian Heuer",
3371 "email": "sebastian@phpeople.de",
3372 "role": "Developer"
3373 },
3374 {
3375 "name": "Sebastian Bergmann",
3376 "email": "sebastian@phpunit.de",
3377 "role": "Developer"
3378 }
3379 ],
3380 "description": "Library for handling version information and constraints",
3381 "support": {
3382 "issues": "https://github.com/phar-io/version/issues",
3383 "source": "https://github.com/phar-io/version/tree/3.2.1"
3384 },
3385 "time": "2022-02-21T01:04:05+00:00"
3386 },
3387 {
3388 "name": "phpunit/php-code-coverage",
3389 "version": "10.1.16",
3390 "source": {
3391 "type": "git",
3392 "url": "https://github.com/sebastianbergmann/php-code-coverage.git",
3393 "reference": "7e308268858ed6baedc8704a304727d20bc07c77"
3394 },
3395 "dist": {
3396 "type": "zip",
3397 "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/7e308268858ed6baedc8704a304727d20bc07c77",
3398 "reference": "7e308268858ed6baedc8704a304727d20bc07c77",
3399 "shasum": ""
3400 },
3401 "require": {
3402 "ext-dom": "*",
3403 "ext-libxml": "*",
3404 "ext-xmlwriter": "*",
3405 "nikic/php-parser": "^4.19.1 || ^5.1.0",
3406 "php": ">=8.1",
3407 "phpunit/php-file-iterator": "^4.1.0",
3408 "phpunit/php-text-template": "^3.0.1",
3409 "sebastian/code-unit-reverse-lookup": "^3.0.0",
3410 "sebastian/complexity": "^3.2.0",
3411 "sebastian/environment": "^6.1.0",
3412 "sebastian/lines-of-code": "^2.0.2",
3413 "sebastian/version": "^4.0.1",
3414 "theseer/tokenizer": "^1.2.3"
3415 },
3416 "require-dev": {
3417 "phpunit/phpunit": "^10.1"
3418 },
3419 "suggest": {
3420 "ext-pcov": "PHP extension that provides line coverage",
3421 "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage"
3422 },
3423 "type": "library",
3424 "extra": {
3425 "branch-alias": {
3426 "dev-main": "10.1.x-dev"
3427 }
3428 },
3429 "autoload": {
3430 "classmap": [
3431 "src/"
3432 ]
3433 },
3434 "notification-url": "https://packagist.org/downloads/",
3435 "license": [
3436 "BSD-3-Clause"
3437 ],
3438 "authors": [
3439 {
3440 "name": "Sebastian Bergmann",
3441 "email": "sebastian@phpunit.de",
3442 "role": "lead"
3443 }
3444 ],
3445 "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.",
3446 "homepage": "https://github.com/sebastianbergmann/php-code-coverage",
3447 "keywords": [
3448 "coverage",
3449 "testing",
3450 "xunit"
3451 ],
3452 "support": {
3453 "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues",
3454 "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy",
3455 "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/10.1.16"
3456 },
3457 "funding": [
3458 {
3459 "url": "https://github.com/sebastianbergmann",
3460 "type": "github"
3461 }
3462 ],
3463 "time": "2024-08-22T04:31:57+00:00"
3464 },
3465 {
3466 "name": "phpunit/php-file-iterator",
3467 "version": "4.1.0",
3468 "source": {
3469 "type": "git",
3470 "url": "https://github.com/sebastianbergmann/php-file-iterator.git",
3471 "reference": "a95037b6d9e608ba092da1b23931e537cadc3c3c"
3472 },
3473 "dist": {
3474 "type": "zip",
3475 "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/a95037b6d9e608ba092da1b23931e537cadc3c3c",
3476 "reference": "a95037b6d9e608ba092da1b23931e537cadc3c3c",
3477 "shasum": ""
3478 },
3479 "require": {
3480 "php": ">=8.1"
3481 },
3482 "require-dev": {
3483 "phpunit/phpunit": "^10.0"
3484 },
3485 "type": "library",
3486 "extra": {
3487 "branch-alias": {
3488 "dev-main": "4.0-dev"
3489 }
3490 },
3491 "autoload": {
3492 "classmap": [
3493 "src/"
3494 ]
3495 },
3496 "notification-url": "https://packagist.org/downloads/",
3497 "license": [
3498 "BSD-3-Clause"
3499 ],
3500 "authors": [
3501 {
3502 "name": "Sebastian Bergmann",
3503 "email": "sebastian@phpunit.de",
3504 "role": "lead"
3505 }
3506 ],
3507 "description": "FilterIterator implementation that filters files based on a list of suffixes.",
3508 "homepage": "https://github.com/sebastianbergmann/php-file-iterator/",
3509 "keywords": [
3510 "filesystem",
3511 "iterator"
3512 ],
3513 "support": {
3514 "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues",
3515 "security": "https://github.com/sebastianbergmann/php-file-iterator/security/policy",
3516 "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/4.1.0"
3517 },
3518 "funding": [
3519 {
3520 "url": "https://github.com/sebastianbergmann",
3521 "type": "github"
3522 }
3523 ],
3524 "time": "2023-08-31T06:24:48+00:00"
3525 },
3526 {
3527 "name": "phpunit/php-invoker",
3528 "version": "4.0.0",
3529 "source": {
3530 "type": "git",
3531 "url": "https://github.com/sebastianbergmann/php-invoker.git",
3532 "reference": "f5e568ba02fa5ba0ddd0f618391d5a9ea50b06d7"
3533 },
3534 "dist": {
3535 "type": "zip",
3536 "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/f5e568ba02fa5ba0ddd0f618391d5a9ea50b06d7",
3537 "reference": "f5e568ba02fa5ba0ddd0f618391d5a9ea50b06d7",
3538 "shasum": ""
3539 },
3540 "require": {
3541 "php": ">=8.1"
3542 },
3543 "require-dev": {
3544 "ext-pcntl": "*",
3545 "phpunit/phpunit": "^10.0"
3546 },
3547 "suggest": {
3548 "ext-pcntl": "*"
3549 },
3550 "type": "library",
3551 "extra": {
3552 "branch-alias": {
3553 "dev-main": "4.0-dev"
3554 }
3555 },
3556 "autoload": {
3557 "classmap": [
3558 "src/"
3559 ]
3560 },
3561 "notification-url": "https://packagist.org/downloads/",
3562 "license": [
3563 "BSD-3-Clause"
3564 ],
3565 "authors": [
3566 {
3567 "name": "Sebastian Bergmann",
3568 "email": "sebastian@phpunit.de",
3569 "role": "lead"
3570 }
3571 ],
3572 "description": "Invoke callables with a timeout",
3573 "homepage": "https://github.com/sebastianbergmann/php-invoker/",
3574 "keywords": [
3575 "process"
3576 ],
3577 "support": {
3578 "issues": "https://github.com/sebastianbergmann/php-invoker/issues",
3579 "source": "https://github.com/sebastianbergmann/php-invoker/tree/4.0.0"
3580 },
3581 "funding": [
3582 {
3583 "url": "https://github.com/sebastianbergmann",
3584 "type": "github"
3585 }
3586 ],
3587 "time": "2023-02-03T06:56:09+00:00"
3588 },
3589 {
3590 "name": "phpunit/php-text-template",
3591 "version": "3.0.1",
3592 "source": {
3593 "type": "git",
3594 "url": "https://github.com/sebastianbergmann/php-text-template.git",
3595 "reference": "0c7b06ff49e3d5072f057eb1fa59258bf287a748"
3596 },
3597 "dist": {
3598 "type": "zip",
3599 "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/0c7b06ff49e3d5072f057eb1fa59258bf287a748",
3600 "reference": "0c7b06ff49e3d5072f057eb1fa59258bf287a748",
3601 "shasum": ""
3602 },
3603 "require": {
3604 "php": ">=8.1"
3605 },
3606 "require-dev": {
3607 "phpunit/phpunit": "^10.0"
3608 },
3609 "type": "library",
3610 "extra": {
3611 "branch-alias": {
3612 "dev-main": "3.0-dev"
3613 }
3614 },
3615 "autoload": {
3616 "classmap": [
3617 "src/"
3618 ]
3619 },
3620 "notification-url": "https://packagist.org/downloads/",
3621 "license": [
3622 "BSD-3-Clause"
3623 ],
3624 "authors": [
3625 {
3626 "name": "Sebastian Bergmann",
3627 "email": "sebastian@phpunit.de",
3628 "role": "lead"
3629 }
3630 ],
3631 "description": "Simple template engine.",
3632 "homepage": "https://github.com/sebastianbergmann/php-text-template/",
3633 "keywords": [
3634 "template"
3635 ],
3636 "support": {
3637 "issues": "https://github.com/sebastianbergmann/php-text-template/issues",
3638 "security": "https://github.com/sebastianbergmann/php-text-template/security/policy",
3639 "source": "https://github.com/sebastianbergmann/php-text-template/tree/3.0.1"
3640 },
3641 "funding": [
3642 {
3643 "url": "https://github.com/sebastianbergmann",
3644 "type": "github"
3645 }
3646 ],
3647 "time": "2023-08-31T14:07:24+00:00"
3648 },
3649 {
3650 "name": "phpunit/php-timer",
3651 "version": "6.0.0",
3652 "source": {
3653 "type": "git",
3654 "url": "https://github.com/sebastianbergmann/php-timer.git",
3655 "reference": "e2a2d67966e740530f4a3343fe2e030ffdc1161d"
3656 },
3657 "dist": {
3658 "type": "zip",
3659 "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/e2a2d67966e740530f4a3343fe2e030ffdc1161d",
3660 "reference": "e2a2d67966e740530f4a3343fe2e030ffdc1161d",
3661 "shasum": ""
3662 },
3663 "require": {
3664 "php": ">=8.1"
3665 },
3666 "require-dev": {
3667 "phpunit/phpunit": "^10.0"
3668 },
3669 "type": "library",
3670 "extra": {
3671 "branch-alias": {
3672 "dev-main": "6.0-dev"
3673 }
3674 },
3675 "autoload": {
3676 "classmap": [
3677 "src/"
3678 ]
3679 },
3680 "notification-url": "https://packagist.org/downloads/",
3681 "license": [
3682 "BSD-3-Clause"
3683 ],
3684 "authors": [
3685 {
3686 "name": "Sebastian Bergmann",
3687 "email": "sebastian@phpunit.de",
3688 "role": "lead"
3689 }
3690 ],
3691 "description": "Utility class for timing",
3692 "homepage": "https://github.com/sebastianbergmann/php-timer/",
3693 "keywords": [
3694 "timer"
3695 ],
3696 "support": {
3697 "issues": "https://github.com/sebastianbergmann/php-timer/issues",
3698 "source": "https://github.com/sebastianbergmann/php-timer/tree/6.0.0"
3699 },
3700 "funding": [
3701 {
3702 "url": "https://github.com/sebastianbergmann",
3703 "type": "github"
3704 }
3705 ],
3706 "time": "2023-02-03T06:57:52+00:00"
3707 },
3708 {
3709 "name": "sebastian/cli-parser",
3710 "version": "2.0.1",
3711 "source": {
3712 "type": "git",
3713 "url": "https://github.com/sebastianbergmann/cli-parser.git",
3714 "reference": "c34583b87e7b7a8055bf6c450c2c77ce32a24084"
3715 },
3716 "dist": {
3717 "type": "zip",
3718 "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/c34583b87e7b7a8055bf6c450c2c77ce32a24084",
3719 "reference": "c34583b87e7b7a8055bf6c450c2c77ce32a24084",
3720 "shasum": ""
3721 },
3722 "require": {
3723 "php": ">=8.1"
3724 },
3725 "require-dev": {
3726 "phpunit/phpunit": "^10.0"
3727 },
3728 "type": "library",
3729 "extra": {
3730 "branch-alias": {
3731 "dev-main": "2.0-dev"
3732 }
3733 },
3734 "autoload": {
3735 "classmap": [
3736 "src/"
3737 ]
3738 },
3739 "notification-url": "https://packagist.org/downloads/",
3740 "license": [
3741 "BSD-3-Clause"
3742 ],
3743 "authors": [
3744 {
3745 "name": "Sebastian Bergmann",
3746 "email": "sebastian@phpunit.de",
3747 "role": "lead"
3748 }
3749 ],
3750 "description": "Library for parsing CLI options",
3751 "homepage": "https://github.com/sebastianbergmann/cli-parser",
3752 "support": {
3753 "issues": "https://github.com/sebastianbergmann/cli-parser/issues",
3754 "security": "https://github.com/sebastianbergmann/cli-parser/security/policy",
3755 "source": "https://github.com/sebastianbergmann/cli-parser/tree/2.0.1"
3756 },
3757 "funding": [
3758 {
3759 "url": "https://github.com/sebastianbergmann",
3760 "type": "github"
3761 }
3762 ],
3763 "time": "2024-03-02T07:12:49+00:00"
3764 },
3765 {
3766 "name": "sebastian/code-unit",
3767 "version": "2.0.0",
3768 "source": {
3769 "type": "git",
3770 "url": "https://github.com/sebastianbergmann/code-unit.git",
3771 "reference": "a81fee9eef0b7a76af11d121767abc44c104e503"
3772 },
3773 "dist": {
3774 "type": "zip",
3775 "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/a81fee9eef0b7a76af11d121767abc44c104e503",
3776 "reference": "a81fee9eef0b7a76af11d121767abc44c104e503",
3777 "shasum": ""
3778 },
3779 "require": {
3780 "php": ">=8.1"
3781 },
3782 "require-dev": {
3783 "phpunit/phpunit": "^10.0"
3784 },
3785 "type": "library",
3786 "extra": {
3787 "branch-alias": {
3788 "dev-main": "2.0-dev"
3789 }
3790 },
3791 "autoload": {
3792 "classmap": [
3793 "src/"
3794 ]
3795 },
3796 "notification-url": "https://packagist.org/downloads/",
3797 "license": [
3798 "BSD-3-Clause"
3799 ],
3800 "authors": [
3801 {
3802 "name": "Sebastian Bergmann",
3803 "email": "sebastian@phpunit.de",
3804 "role": "lead"
3805 }
3806 ],
3807 "description": "Collection of value objects that represent the PHP code units",
3808 "homepage": "https://github.com/sebastianbergmann/code-unit",
3809 "support": {
3810 "issues": "https://github.com/sebastianbergmann/code-unit/issues",
3811 "source": "https://github.com/sebastianbergmann/code-unit/tree/2.0.0"
3812 },
3813 "funding": [
3814 {
3815 "url": "https://github.com/sebastianbergmann",
3816 "type": "github"
3817 }
3818 ],
3819 "time": "2023-02-03T06:58:43+00:00"
3820 },
3821 {
3822 "name": "sebastian/code-unit-reverse-lookup",
3823 "version": "3.0.0",
3824 "source": {
3825 "type": "git",
3826 "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git",
3827 "reference": "5e3a687f7d8ae33fb362c5c0743794bbb2420a1d"
3828 },
3829 "dist": {
3830 "type": "zip",
3831 "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/5e3a687f7d8ae33fb362c5c0743794bbb2420a1d",
3832 "reference": "5e3a687f7d8ae33fb362c5c0743794bbb2420a1d",
3833 "shasum": ""
3834 },
3835 "require": {
3836 "php": ">=8.1"
3837 },
3838 "require-dev": {
3839 "phpunit/phpunit": "^10.0"
3840 },
3841 "type": "library",
3842 "extra": {
3843 "branch-alias": {
3844 "dev-main": "3.0-dev"
3845 }
3846 },
3847 "autoload": {
3848 "classmap": [
3849 "src/"
3850 ]
3851 },
3852 "notification-url": "https://packagist.org/downloads/",
3853 "license": [
3854 "BSD-3-Clause"
3855 ],
3856 "authors": [
3857 {
3858 "name": "Sebastian Bergmann",
3859 "email": "sebastian@phpunit.de"
3860 }
3861 ],
3862 "description": "Looks up which function or method a line of code belongs to",
3863 "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/",
3864 "support": {
3865 "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues",
3866 "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/3.0.0"
3867 },
3868 "funding": [
3869 {
3870 "url": "https://github.com/sebastianbergmann",
3871 "type": "github"
3872 }
3873 ],
3874 "time": "2023-02-03T06:59:15+00:00"
3875 },
3876 {
3877 "name": "sebastian/comparator",
3878 "version": "5.0.5",
3879 "source": {
3880 "type": "git",
3881 "url": "https://github.com/sebastianbergmann/comparator.git",
3882 "reference": "55dfef806eb7dfeb6e7a6935601fef866f8ca48d"
3883 },
3884 "dist": {
3885 "type": "zip",
3886 "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/55dfef806eb7dfeb6e7a6935601fef866f8ca48d",
3887 "reference": "55dfef806eb7dfeb6e7a6935601fef866f8ca48d",
3888 "shasum": ""
3889 },
3890 "require": {
3891 "ext-dom": "*",
3892 "ext-mbstring": "*",
3893 "php": ">=8.1",
3894 "sebastian/diff": "^5.0",
3895 "sebastian/exporter": "^5.0"
3896 },
3897 "require-dev": {
3898 "phpunit/phpunit": "^10.5"
3899 },
3900 "type": "library",
3901 "extra": {
3902 "branch-alias": {
3903 "dev-main": "5.0-dev"
3904 }
3905 },
3906 "autoload": {
3907 "classmap": [
3908 "src/"
3909 ]
3910 },
3911 "notification-url": "https://packagist.org/downloads/",
3912 "license": [
3913 "BSD-3-Clause"
3914 ],
3915 "authors": [
3916 {
3917 "name": "Sebastian Bergmann",
3918 "email": "sebastian@phpunit.de"
3919 },
3920 {
3921 "name": "Jeff Welch",
3922 "email": "whatthejeff@gmail.com"
3923 },
3924 {
3925 "name": "Volker Dusch",
3926 "email": "github@wallbash.com"
3927 },
3928 {
3929 "name": "Bernhard Schussek",
3930 "email": "bschussek@2bepublished.at"
3931 }
3932 ],
3933 "description": "Provides the functionality to compare PHP values for equality",
3934 "homepage": "https://github.com/sebastianbergmann/comparator",
3935 "keywords": [
3936 "comparator",
3937 "compare",
3938 "equality"
3939 ],
3940 "support": {
3941 "issues": "https://github.com/sebastianbergmann/comparator/issues",
3942 "security": "https://github.com/sebastianbergmann/comparator/security/policy",
3943 "source": "https://github.com/sebastianbergmann/comparator/tree/5.0.5"
3944 },
3945 "funding": [
3946 {
3947 "url": "https://github.com/sebastianbergmann",
3948 "type": "github"
3949 },
3950 {
3951 "url": "https://liberapay.com/sebastianbergmann",
3952 "type": "liberapay"
3953 },
3954 {
3955 "url": "https://thanks.dev/u/gh/sebastianbergmann",
3956 "type": "thanks_dev"
3957 },
3958 {
3959 "url": "https://tidelift.com/funding/github/packagist/sebastian/comparator",
3960 "type": "tidelift"
3961 }
3962 ],
3963 "time": "2026-01-24T09:25:16+00:00"
3964 },
3965 {
3966 "name": "sebastian/complexity",
3967 "version": "3.2.0",
3968 "source": {
3969 "type": "git",
3970 "url": "https://github.com/sebastianbergmann/complexity.git",
3971 "reference": "68ff824baeae169ec9f2137158ee529584553799"
3972 },
3973 "dist": {
3974 "type": "zip",
3975 "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/68ff824baeae169ec9f2137158ee529584553799",
3976 "reference": "68ff824baeae169ec9f2137158ee529584553799",
3977 "shasum": ""
3978 },
3979 "require": {
3980 "nikic/php-parser": "^4.18 || ^5.0",
3981 "php": ">=8.1"
3982 },
3983 "require-dev": {
3984 "phpunit/phpunit": "^10.0"
3985 },
3986 "type": "library",
3987 "extra": {
3988 "branch-alias": {
3989 "dev-main": "3.2-dev"
3990 }
3991 },
3992 "autoload": {
3993 "classmap": [
3994 "src/"
3995 ]
3996 },
3997 "notification-url": "https://packagist.org/downloads/",
3998 "license": [
3999 "BSD-3-Clause"
4000 ],
4001 "authors": [
4002 {
4003 "name": "Sebastian Bergmann",
4004 "email": "sebastian@phpunit.de",
4005 "role": "lead"
4006 }
4007 ],
4008 "description": "Library for calculating the complexity of PHP code units",
4009 "homepage": "https://github.com/sebastianbergmann/complexity",
4010 "support": {
4011 "issues": "https://github.com/sebastianbergmann/complexity/issues",
4012 "security": "https://github.com/sebastianbergmann/complexity/security/policy",
4013 "source": "https://github.com/sebastianbergmann/complexity/tree/3.2.0"
4014 },
4015 "funding": [
4016 {
4017 "url": "https://github.com/sebastianbergmann",
4018 "type": "github"
4019 }
4020 ],
4021 "time": "2023-12-21T08:37:17+00:00"
4022 },
4023 {
4024 "name": "sebastian/diff",
4025 "version": "5.1.1",
4026 "source": {
4027 "type": "git",
4028 "url": "https://github.com/sebastianbergmann/diff.git",
4029 "reference": "c41e007b4b62af48218231d6c2275e4c9b975b2e"
4030 },
4031 "dist": {
4032 "type": "zip",
4033 "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/c41e007b4b62af48218231d6c2275e4c9b975b2e",
4034 "reference": "c41e007b4b62af48218231d6c2275e4c9b975b2e",
4035 "shasum": ""
4036 },
4037 "require": {
4038 "php": ">=8.1"
4039 },
4040 "require-dev": {
4041 "phpunit/phpunit": "^10.0",
4042 "symfony/process": "^6.4"
4043 },
4044 "type": "library",
4045 "extra": {
4046 "branch-alias": {
4047 "dev-main": "5.1-dev"
4048 }
4049 },
4050 "autoload": {
4051 "classmap": [
4052 "src/"
4053 ]
4054 },
4055 "notification-url": "https://packagist.org/downloads/",
4056 "license": [
4057 "BSD-3-Clause"
4058 ],
4059 "authors": [
4060 {
4061 "name": "Sebastian Bergmann",
4062 "email": "sebastian@phpunit.de"
4063 },
4064 {
4065 "name": "Kore Nordmann",
4066 "email": "mail@kore-nordmann.de"
4067 }
4068 ],
4069 "description": "Diff implementation",
4070 "homepage": "https://github.com/sebastianbergmann/diff",
4071 "keywords": [
4072 "diff",
4073 "udiff",
4074 "unidiff",
4075 "unified diff"
4076 ],
4077 "support": {
4078 "issues": "https://github.com/sebastianbergmann/diff/issues",
4079 "security": "https://github.com/sebastianbergmann/diff/security/policy",
4080 "source": "https://github.com/sebastianbergmann/diff/tree/5.1.1"
4081 },
4082 "funding": [
4083 {
4084 "url": "https://github.com/sebastianbergmann",
4085 "type": "github"
4086 }
4087 ],
4088 "time": "2024-03-02T07:15:17+00:00"
4089 },
4090 {
4091 "name": "sebastian/environment",
4092 "version": "6.1.0",
4093 "source": {
4094 "type": "git",
4095 "url": "https://github.com/sebastianbergmann/environment.git",
4096 "reference": "8074dbcd93529b357029f5cc5058fd3e43666984"
4097 },
4098 "dist": {
4099 "type": "zip",
4100 "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/8074dbcd93529b357029f5cc5058fd3e43666984",
4101 "reference": "8074dbcd93529b357029f5cc5058fd3e43666984",
4102 "shasum": ""
4103 },
4104 "require": {
4105 "php": ">=8.1"
4106 },
4107 "require-dev": {
4108 "phpunit/phpunit": "^10.0"
4109 },
4110 "suggest": {
4111 "ext-posix": "*"
4112 },
4113 "type": "library",
4114 "extra": {
4115 "branch-alias": {
4116 "dev-main": "6.1-dev"
4117 }
4118 },
4119 "autoload": {
4120 "classmap": [
4121 "src/"
4122 ]
4123 },
4124 "notification-url": "https://packagist.org/downloads/",
4125 "license": [
4126 "BSD-3-Clause"
4127 ],
4128 "authors": [
4129 {
4130 "name": "Sebastian Bergmann",
4131 "email": "sebastian@phpunit.de"
4132 }
4133 ],
4134 "description": "Provides functionality to handle HHVM/PHP environments",
4135 "homepage": "https://github.com/sebastianbergmann/environment",
4136 "keywords": [
4137 "Xdebug",
4138 "environment",
4139 "hhvm"
4140 ],
4141 "support": {
4142 "issues": "https://github.com/sebastianbergmann/environment/issues",
4143 "security": "https://github.com/sebastianbergmann/environment/security/policy",
4144 "source": "https://github.com/sebastianbergmann/environment/tree/6.1.0"
4145 },
4146 "funding": [
4147 {
4148 "url": "https://github.com/sebastianbergmann",
4149 "type": "github"
4150 }
4151 ],
4152 "time": "2024-03-23T08:47:14+00:00"
4153 },
4154 {
4155 "name": "sebastian/exporter",
4156 "version": "5.1.4",
4157 "source": {
4158 "type": "git",
4159 "url": "https://github.com/sebastianbergmann/exporter.git",
4160 "reference": "0735b90f4da94969541dac1da743446e276defa6"
4161 },
4162 "dist": {
4163 "type": "zip",
4164 "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/0735b90f4da94969541dac1da743446e276defa6",
4165 "reference": "0735b90f4da94969541dac1da743446e276defa6",
4166 "shasum": ""
4167 },
4168 "require": {
4169 "ext-mbstring": "*",
4170 "php": ">=8.1",
4171 "sebastian/recursion-context": "^5.0"
4172 },
4173 "require-dev": {
4174 "phpunit/phpunit": "^10.5"
4175 },
4176 "type": "library",
4177 "extra": {
4178 "branch-alias": {
4179 "dev-main": "5.1-dev"
4180 }
4181 },
4182 "autoload": {
4183 "classmap": [
4184 "src/"
4185 ]
4186 },
4187 "notification-url": "https://packagist.org/downloads/",
4188 "license": [
4189 "BSD-3-Clause"
4190 ],
4191 "authors": [
4192 {
4193 "name": "Sebastian Bergmann",
4194 "email": "sebastian@phpunit.de"
4195 },
4196 {
4197 "name": "Jeff Welch",
4198 "email": "whatthejeff@gmail.com"
4199 },
4200 {
4201 "name": "Volker Dusch",
4202 "email": "github@wallbash.com"
4203 },
4204 {
4205 "name": "Adam Harvey",
4206 "email": "aharvey@php.net"
4207 },
4208 {
4209 "name": "Bernhard Schussek",
4210 "email": "bschussek@gmail.com"
4211 }
4212 ],
4213 "description": "Provides the functionality to export PHP variables for visualization",
4214 "homepage": "https://www.github.com/sebastianbergmann/exporter",
4215 "keywords": [
4216 "export",
4217 "exporter"
4218 ],
4219 "support": {
4220 "issues": "https://github.com/sebastianbergmann/exporter/issues",
4221 "security": "https://github.com/sebastianbergmann/exporter/security/policy",
4222 "source": "https://github.com/sebastianbergmann/exporter/tree/5.1.4"
4223 },
4224 "funding": [
4225 {
4226 "url": "https://github.com/sebastianbergmann",
4227 "type": "github"
4228 },
4229 {
4230 "url": "https://liberapay.com/sebastianbergmann",
4231 "type": "liberapay"
4232 },
4233 {
4234 "url": "https://thanks.dev/u/gh/sebastianbergmann",
4235 "type": "thanks_dev"
4236 },
4237 {
4238 "url": "https://tidelift.com/funding/github/packagist/sebastian/exporter",
4239 "type": "tidelift"
4240 }
4241 ],
4242 "time": "2025-09-24T06:09:11+00:00"
4243 },
4244 {
4245 "name": "sebastian/global-state",
4246 "version": "6.0.2",
4247 "source": {
4248 "type": "git",
4249 "url": "https://github.com/sebastianbergmann/global-state.git",
4250 "reference": "987bafff24ecc4c9ac418cab1145b96dd6e9cbd9"
4251 },
4252 "dist": {
4253 "type": "zip",
4254 "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/987bafff24ecc4c9ac418cab1145b96dd6e9cbd9",
4255 "reference": "987bafff24ecc4c9ac418cab1145b96dd6e9cbd9",
4256 "shasum": ""
4257 },
4258 "require": {
4259 "php": ">=8.1",
4260 "sebastian/object-reflector": "^3.0",
4261 "sebastian/recursion-context": "^5.0"
4262 },
4263 "require-dev": {
4264 "ext-dom": "*",
4265 "phpunit/phpunit": "^10.0"
4266 },
4267 "type": "library",
4268 "extra": {
4269 "branch-alias": {
4270 "dev-main": "6.0-dev"
4271 }
4272 },
4273 "autoload": {
4274 "classmap": [
4275 "src/"
4276 ]
4277 },
4278 "notification-url": "https://packagist.org/downloads/",
4279 "license": [
4280 "BSD-3-Clause"
4281 ],
4282 "authors": [
4283 {
4284 "name": "Sebastian Bergmann",
4285 "email": "sebastian@phpunit.de"
4286 }
4287 ],
4288 "description": "Snapshotting of global state",
4289 "homepage": "https://www.github.com/sebastianbergmann/global-state",
4290 "keywords": [
4291 "global state"
4292 ],
4293 "support": {
4294 "issues": "https://github.com/sebastianbergmann/global-state/issues",
4295 "security": "https://github.com/sebastianbergmann/global-state/security/policy",
4296 "source": "https://github.com/sebastianbergmann/global-state/tree/6.0.2"
4297 },
4298 "funding": [
4299 {
4300 "url": "https://github.com/sebastianbergmann",
4301 "type": "github"
4302 }
4303 ],
4304 "time": "2024-03-02T07:19:19+00:00"
4305 },
4306 {
4307 "name": "sebastian/lines-of-code",
4308 "version": "2.0.2",
4309 "source": {
4310 "type": "git",
4311 "url": "https://github.com/sebastianbergmann/lines-of-code.git",
4312 "reference": "856e7f6a75a84e339195d48c556f23be2ebf75d0"
4313 },
4314 "dist": {
4315 "type": "zip",
4316 "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/856e7f6a75a84e339195d48c556f23be2ebf75d0",
4317 "reference": "856e7f6a75a84e339195d48c556f23be2ebf75d0",
4318 "shasum": ""
4319 },
4320 "require": {
4321 "nikic/php-parser": "^4.18 || ^5.0",
4322 "php": ">=8.1"
4323 },
4324 "require-dev": {
4325 "phpunit/phpunit": "^10.0"
4326 },
4327 "type": "library",
4328 "extra": {
4329 "branch-alias": {
4330 "dev-main": "2.0-dev"
4331 }
4332 },
4333 "autoload": {
4334 "classmap": [
4335 "src/"
4336 ]
4337 },
4338 "notification-url": "https://packagist.org/downloads/",
4339 "license": [
4340 "BSD-3-Clause"
4341 ],
4342 "authors": [
4343 {
4344 "name": "Sebastian Bergmann",
4345 "email": "sebastian@phpunit.de",
4346 "role": "lead"
4347 }
4348 ],
4349 "description": "Library for counting the lines of code in PHP source code",
4350 "homepage": "https://github.com/sebastianbergmann/lines-of-code",
4351 "support": {
4352 "issues": "https://github.com/sebastianbergmann/lines-of-code/issues",
4353 "security": "https://github.com/sebastianbergmann/lines-of-code/security/policy",
4354 "source": "https://github.com/sebastianbergmann/lines-of-code/tree/2.0.2"
4355 },
4356 "funding": [
4357 {
4358 "url": "https://github.com/sebastianbergmann",
4359 "type": "github"
4360 }
4361 ],
4362 "time": "2023-12-21T08:38:20+00:00"
4363 },
4364 {
4365 "name": "sebastian/object-enumerator",
4366 "version": "5.0.0",
4367 "source": {
4368 "type": "git",
4369 "url": "https://github.com/sebastianbergmann/object-enumerator.git",
4370 "reference": "202d0e344a580d7f7d04b3fafce6933e59dae906"
4371 },
4372 "dist": {
4373 "type": "zip",
4374 "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/202d0e344a580d7f7d04b3fafce6933e59dae906",
4375 "reference": "202d0e344a580d7f7d04b3fafce6933e59dae906",
4376 "shasum": ""
4377 },
4378 "require": {
4379 "php": ">=8.1",
4380 "sebastian/object-reflector": "^3.0",
4381 "sebastian/recursion-context": "^5.0"
4382 },
4383 "require-dev": {
4384 "phpunit/phpunit": "^10.0"
4385 },
4386 "type": "library",
4387 "extra": {
4388 "branch-alias": {
4389 "dev-main": "5.0-dev"
4390 }
4391 },
4392 "autoload": {
4393 "classmap": [
4394 "src/"
4395 ]
4396 },
4397 "notification-url": "https://packagist.org/downloads/",
4398 "license": [
4399 "BSD-3-Clause"
4400 ],
4401 "authors": [
4402 {
4403 "name": "Sebastian Bergmann",
4404 "email": "sebastian@phpunit.de"
4405 }
4406 ],
4407 "description": "Traverses array structures and object graphs to enumerate all referenced objects",
4408 "homepage": "https://github.com/sebastianbergmann/object-enumerator/",
4409 "support": {
4410 "issues": "https://github.com/sebastianbergmann/object-enumerator/issues",
4411 "source": "https://github.com/sebastianbergmann/object-enumerator/tree/5.0.0"
4412 },
4413 "funding": [
4414 {
4415 "url": "https://github.com/sebastianbergmann",
4416 "type": "github"
4417 }
4418 ],
4419 "time": "2023-02-03T07:08:32+00:00"
4420 },
4421 {
4422 "name": "sebastian/object-reflector",
4423 "version": "3.0.0",
4424 "source": {
4425 "type": "git",
4426 "url": "https://github.com/sebastianbergmann/object-reflector.git",
4427 "reference": "24ed13d98130f0e7122df55d06c5c4942a577957"
4428 },
4429 "dist": {
4430 "type": "zip",
4431 "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/24ed13d98130f0e7122df55d06c5c4942a577957",
4432 "reference": "24ed13d98130f0e7122df55d06c5c4942a577957",
4433 "shasum": ""
4434 },
4435 "require": {
4436 "php": ">=8.1"
4437 },
4438 "require-dev": {
4439 "phpunit/phpunit": "^10.0"
4440 },
4441 "type": "library",
4442 "extra": {
4443 "branch-alias": {
4444 "dev-main": "3.0-dev"
4445 }
4446 },
4447 "autoload": {
4448 "classmap": [
4449 "src/"
4450 ]
4451 },
4452 "notification-url": "https://packagist.org/downloads/",
4453 "license": [
4454 "BSD-3-Clause"
4455 ],
4456 "authors": [
4457 {
4458 "name": "Sebastian Bergmann",
4459 "email": "sebastian@phpunit.de"
4460 }
4461 ],
4462 "description": "Allows reflection of object attributes, including inherited and non-public ones",
4463 "homepage": "https://github.com/sebastianbergmann/object-reflector/",
4464 "support": {
4465 "issues": "https://github.com/sebastianbergmann/object-reflector/issues",
4466 "source": "https://github.com/sebastianbergmann/object-reflector/tree/3.0.0"
4467 },
4468 "funding": [
4469 {
4470 "url": "https://github.com/sebastianbergmann",
4471 "type": "github"
4472 }
4473 ],
4474 "time": "2023-02-03T07:06:18+00:00"
4475 },
4476 {
4477 "name": "sebastian/recursion-context",
4478 "version": "5.0.1",
4479 "source": {
4480 "type": "git",
4481 "url": "https://github.com/sebastianbergmann/recursion-context.git",
4482 "reference": "47e34210757a2f37a97dcd207d032e1b01e64c7a"
4483 },
4484 "dist": {
4485 "type": "zip",
4486 "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/47e34210757a2f37a97dcd207d032e1b01e64c7a",
4487 "reference": "47e34210757a2f37a97dcd207d032e1b01e64c7a",
4488 "shasum": ""
4489 },
4490 "require": {
4491 "php": ">=8.1"
4492 },
4493 "require-dev": {
4494 "phpunit/phpunit": "^10.5"
4495 },
4496 "type": "library",
4497 "extra": {
4498 "branch-alias": {
4499 "dev-main": "5.0-dev"
4500 }
4501 },
4502 "autoload": {
4503 "classmap": [
4504 "src/"
4505 ]
4506 },
4507 "notification-url": "https://packagist.org/downloads/",
4508 "license": [
4509 "BSD-3-Clause"
4510 ],
4511 "authors": [
4512 {
4513 "name": "Sebastian Bergmann",
4514 "email": "sebastian@phpunit.de"
4515 },
4516 {
4517 "name": "Jeff Welch",
4518 "email": "whatthejeff@gmail.com"
4519 },
4520 {
4521 "name": "Adam Harvey",
4522 "email": "aharvey@php.net"
4523 }
4524 ],
4525 "description": "Provides functionality to recursively process PHP variables",
4526 "homepage": "https://github.com/sebastianbergmann/recursion-context",
4527 "support": {
4528 "issues": "https://github.com/sebastianbergmann/recursion-context/issues",
4529 "security": "https://github.com/sebastianbergmann/recursion-context/security/policy",
4530 "source": "https://github.com/sebastianbergmann/recursion-context/tree/5.0.1"
4531 },
4532 "funding": [
4533 {
4534 "url": "https://github.com/sebastianbergmann",
4535 "type": "github"
4536 },
4537 {
4538 "url": "https://liberapay.com/sebastianbergmann",
4539 "type": "liberapay"
4540 },
4541 {
4542 "url": "https://thanks.dev/u/gh/sebastianbergmann",
4543 "type": "thanks_dev"
4544 },
4545 {
4546 "url": "https://tidelift.com/funding/github/packagist/sebastian/recursion-context",
4547 "type": "tidelift"
4548 }
4549 ],
4550 "time": "2025-08-10T07:50:56+00:00"
4551 },
4552 {
4553 "name": "sebastian/type",
4554 "version": "4.0.0",
4555 "source": {
4556 "type": "git",
4557 "url": "https://github.com/sebastianbergmann/type.git",
4558 "reference": "462699a16464c3944eefc02ebdd77882bd3925bf"
4559 },
4560 "dist": {
4561 "type": "zip",
4562 "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/462699a16464c3944eefc02ebdd77882bd3925bf",
4563 "reference": "462699a16464c3944eefc02ebdd77882bd3925bf",
4564 "shasum": ""
4565 },
4566 "require": {
4567 "php": ">=8.1"
4568 },
4569 "require-dev": {
4570 "phpunit/phpunit": "^10.0"
4571 },
4572 "type": "library",
4573 "extra": {
4574 "branch-alias": {
4575 "dev-main": "4.0-dev"
4576 }
4577 },
4578 "autoload": {
4579 "classmap": [
4580 "src/"
4581 ]
4582 },
4583 "notification-url": "https://packagist.org/downloads/",
4584 "license": [
4585 "BSD-3-Clause"
4586 ],
4587 "authors": [
4588 {
4589 "name": "Sebastian Bergmann",
4590 "email": "sebastian@phpunit.de",
4591 "role": "lead"
4592 }
4593 ],
4594 "description": "Collection of value objects that represent the types of the PHP type system",
4595 "homepage": "https://github.com/sebastianbergmann/type",
4596 "support": {
4597 "issues": "https://github.com/sebastianbergmann/type/issues",
4598 "source": "https://github.com/sebastianbergmann/type/tree/4.0.0"
4599 },
4600 "funding": [
4601 {
4602 "url": "https://github.com/sebastianbergmann",
4603 "type": "github"
4604 }
4605 ],
4606 "time": "2023-02-03T07:10:45+00:00"
4607 },
4608 {
4609 "name": "sebastian/version",
4610 "version": "4.0.1",
4611 "source": {
4612 "type": "git",
4613 "url": "https://github.com/sebastianbergmann/version.git",
4614 "reference": "c51fa83a5d8f43f1402e3f32a005e6262244ef17"
4615 },
4616 "dist": {
4617 "type": "zip",
4618 "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c51fa83a5d8f43f1402e3f32a005e6262244ef17",
4619 "reference": "c51fa83a5d8f43f1402e3f32a005e6262244ef17",
4620 "shasum": ""
4621 },
4622 "require": {
4623 "php": ">=8.1"
4624 },
4625 "type": "library",
4626 "extra": {
4627 "branch-alias": {
4628 "dev-main": "4.0-dev"
4629 }
4630 },
4631 "autoload": {
4632 "classmap": [
4633 "src/"
4634 ]
4635 },
4636 "notification-url": "https://packagist.org/downloads/",
4637 "license": [
4638 "BSD-3-Clause"
4639 ],
4640 "authors": [
4641 {
4642 "name": "Sebastian Bergmann",
4643 "email": "sebastian@phpunit.de",
4644 "role": "lead"
4645 }
4646 ],
4647 "description": "Library that helps with managing the version number of Git-hosted PHP projects",
4648 "homepage": "https://github.com/sebastianbergmann/version",
4649 "support": {
4650 "issues": "https://github.com/sebastianbergmann/version/issues",
4651 "source": "https://github.com/sebastianbergmann/version/tree/4.0.1"
4652 },
4653 "funding": [
4654 {
4655 "url": "https://github.com/sebastianbergmann",
4656 "type": "github"
4657 }
4658 ],
4659 "time": "2023-02-07T11:34:05+00:00"
4660 },
4661 {
4662 "name": "theseer/tokenizer",
4663 "version": "1.3.1",
4664 "source": {
4665 "type": "git",
4666 "url": "https://github.com/theseer/tokenizer.git",
4667 "reference": "b7489ce515e168639d17feec34b8847c326b0b3c"
4668 },
4669 "dist": {
4670 "type": "zip",
4671 "url": "https://api.github.com/repos/theseer/tokenizer/zipball/b7489ce515e168639d17feec34b8847c326b0b3c",
4672 "reference": "b7489ce515e168639d17feec34b8847c326b0b3c",
4673 "shasum": ""
4674 },
4675 "require": {
4676 "ext-dom": "*",
4677 "ext-tokenizer": "*",
4678 "ext-xmlwriter": "*",
4679 "php": "^7.2 || ^8.0"
4680 },
4681 "type": "library",
4682 "autoload": {
4683 "classmap": [
4684 "src/"
4685 ]
4686 },
4687 "notification-url": "https://packagist.org/downloads/",
4688 "license": [
4689 "BSD-3-Clause"
4690 ],
4691 "authors": [
4692 {
4693 "name": "Arne Blankerts",
4694 "email": "arne@blankerts.de",
4695 "role": "Developer"
4696 }
4697 ],
4698 "description": "A small library for converting tokenized PHP source code into XML and potentially other formats",
4699 "support": {
4700 "issues": "https://github.com/theseer/tokenizer/issues",
4701 "source": "https://github.com/theseer/tokenizer/tree/1.3.1"
4702 },
4703 "funding": [
4704 {
4705 "url": "https://github.com/theseer",
4706 "type": "github"
4707 }
4708 ],
4709 "time": "2025-11-17T20:03:58+00:00"
4710 }
4711 ],
4712 "packages-dev": [],
4713 "aliases": [],
4714 "minimum-stability": "stable",
4715 "stability-flags": {},
4716 "prefer-stable": true,
4717 "prefer-lowest": false,
4718 "platform": {
4719 "php": ">=8.1",
4720 "ext-dom": "*",
4721 "ext-json": "*",
4722 "ext-libxml": "*",
4723 "ext-mbstring": "*",
4724 "ext-xml": "*",
4725 "ext-xmlwriter": "*"
4726 },
4727 "platform-dev": {},
4728 "platform-overrides": {
4729 "php": "8.1.0"
4730 },
4731 "plugin-api-version": "2.9.0"
4732 }
4733 phpunit/phpunit: 10.5.63
4734 myclabs/deep-copy: 1.13.4
4735 nikic/php-parser: v5.7.0
4736 phar-io/manifest: 2.0.4
4737 phar-io/version: 3.2.1
4738 phpunit/php-code-coverage: 10.1.16
4739 phpunit/php-file-iterator: 4.1.0
4740 phpunit/php-invoker: 4.0.0
4741 phpunit/php-text-template: 3.0.1
4742 phpunit/php-timer: 6.0.0
4743 sebastian/cli-parser: 2.0.1
4744 sebastian/code-unit: 2.0.0
4745 sebastian/code-unit-reverse-lookup: 3.0.0
4746 sebastian/comparator: 5.0.5
4747 sebastian/complexity: 3.2.0
4748 sebastian/diff: 5.1.1
4749 sebastian/environment: 6.1.0
4750 sebastian/exporter: 5.1.4
4751 sebastian/global-state: 6.0.2
4752 sebastian/lines-of-code: 2.0.2
4753 sebastian/object-enumerator: 5.0.0
4754 sebastian/object-reflector: 3.0.0
4755 sebastian/recursion-context: 5.0.1
4756 sebastian/type: 4.0.0
4757 sebastian/version: 4.0.1
4758 theseer/tokenizer: 1.3.1
4759 <?php
4760
4761 namespace PHPUnitPHAR\DeepCopy;
4762
4763 use ArrayObject;
4764 use DateInterval;
4765 use DatePeriod;
4766 use DateTimeInterface;
4767 use DateTimeZone;
4768 use PHPUnitPHAR\DeepCopy\Exception\CloneException;
4769 use PHPUnitPHAR\DeepCopy\Filter\ChainableFilter;
4770 use PHPUnitPHAR\DeepCopy\Filter\Filter;
4771 use PHPUnitPHAR\DeepCopy\Matcher\Matcher;
4772 use PHPUnitPHAR\DeepCopy\Reflection\ReflectionHelper;
4773 use PHPUnitPHAR\DeepCopy\TypeFilter\Date\DateIntervalFilter;
4774 use PHPUnitPHAR\DeepCopy\TypeFilter\Date\DatePeriodFilter;
4775 use PHPUnitPHAR\DeepCopy\TypeFilter\Spl\ArrayObjectFilter;
4776 use PHPUnitPHAR\DeepCopy\TypeFilter\Spl\SplDoublyLinkedListFilter;
4777 use PHPUnitPHAR\DeepCopy\TypeFilter\TypeFilter;
4778 use PHPUnitPHAR\DeepCopy\TypeMatcher\TypeMatcher;
4779 use ReflectionObject;
4780 use ReflectionProperty;
4781 use SplDoublyLinkedList;
4782 /**
4783 * @final
4784 */
4785 class DeepCopy
4786 {
4787 /**
4788 * @var object[] List of objects copied.
4789 */
4790 private $hashMap = [];
4791 /**
4792 * Filters to apply.
4793 *
4794 * @var array Array of ['filter' => Filter, 'matcher' => Matcher] pairs.
4795 */
4796 private $filters = [];
4797 /**
4798 * Type Filters to apply.
4799 *
4800 * @var array Array of ['filter' => Filter, 'matcher' => Matcher] pairs.
4801 */
4802 private $typeFilters = [];
4803 /**
4804 * @var bool
4805 */
4806 private $skipUncloneable = \false;
4807 /**
4808 * @var bool
4809 */
4810 private $useCloneMethod;
4811 /**
4812 * @param bool $useCloneMethod If set to true, when an object implements the __clone() function, it will be used
4813 * instead of the regular deep cloning.
4814 */
4815 public function __construct($useCloneMethod = \false)
4816 {
4817 $this->useCloneMethod = $useCloneMethod;
4818 $this->addTypeFilter(new ArrayObjectFilter($this), new TypeMatcher(ArrayObject::class));
4819 $this->addTypeFilter(new DateIntervalFilter(), new TypeMatcher(DateInterval::class));
4820 $this->addTypeFilter(new DatePeriodFilter(), new TypeMatcher(DatePeriod::class));
4821 $this->addTypeFilter(new SplDoublyLinkedListFilter($this), new TypeMatcher(SplDoublyLinkedList::class));
4822 }
4823 /**
4824 * If enabled, will not throw an exception when coming across an uncloneable property.
4825 *
4826 * @param $skipUncloneable
4827 *
4828 * @return $this
4829 */
4830 public function skipUncloneable($skipUncloneable = \true)
4831 {
4832 $this->skipUncloneable = $skipUncloneable;
4833 return $this;
4834 }
4835 /**
4836 * Deep copies the given object.
4837 *
4838 * @template TObject
4839 *
4840 * @param TObject $object
4841 *
4842 * @return TObject
4843 */
4844 public function copy($object)
4845 {
4846 $this->hashMap = [];
4847 return $this->recursiveCopy($object);
4848 }
4849 public function addFilter(Filter $filter, Matcher $matcher)
4850 {
4851 $this->filters[] = ['matcher' => $matcher, 'filter' => $filter];
4852 }
4853 public function prependFilter(Filter $filter, Matcher $matcher)
4854 {
4855 array_unshift($this->filters, ['matcher' => $matcher, 'filter' => $filter]);
4856 }
4857 public function addTypeFilter(TypeFilter $filter, TypeMatcher $matcher)
4858 {
4859 $this->typeFilters[] = ['matcher' => $matcher, 'filter' => $filter];
4860 }
4861 public function prependTypeFilter(TypeFilter $filter, TypeMatcher $matcher)
4862 {
4863 array_unshift($this->typeFilters, ['matcher' => $matcher, 'filter' => $filter]);
4864 }
4865 private function recursiveCopy($var)
4866 {
4867 // Matches Type Filter
4868 if ($filter = $this->getFirstMatchedTypeFilter($this->typeFilters, $var)) {
4869 return $filter->apply($var);
4870 }
4871 // Resource
4872 if (is_resource($var)) {
4873 return $var;
4874 }
4875 // Array
4876 if (is_array($var)) {
4877 return $this->copyArray($var);
4878 }
4879 // Scalar
4880 if (!is_object($var)) {
4881 return $var;
4882 }
4883 // Enum
4884 if (\PHP_VERSION_ID >= 80100 && enum_exists(get_class($var))) {
4885 return $var;
4886 }
4887 // Object
4888 return $this->copyObject($var);
4889 }
4890 /**
4891 * Copy an array
4892 * @param array $array
4893 * @return array
4894 */
4895 private function copyArray(array $array)
4896 {
4897 foreach ($array as $key => $value) {
4898 $array[$key] = $this->recursiveCopy($value);
4899 }
4900 return $array;
4901 }
4902 /**
4903 * Copies an object.
4904 *
4905 * @param object $object
4906 *
4907 * @throws CloneException
4908 *
4909 * @return object
4910 */
4911 private function copyObject($object)
4912 {
4913 $objectHash = spl_object_hash($object);
4914 if (isset($this->hashMap[$objectHash])) {
4915 return $this->hashMap[$objectHash];
4916 }
4917 $reflectedObject = new ReflectionObject($object);
4918 $isCloneable = $reflectedObject->isCloneable();
4919 if (\false === $isCloneable) {
4920 if ($this->skipUncloneable) {
4921 $this->hashMap[$objectHash] = $object;
4922 return $object;
4923 }
4924 throw new CloneException(sprintf('The class "%s" is not cloneable.', $reflectedObject->getName()));
4925 }
4926 $newObject = clone $object;
4927 $this->hashMap[$objectHash] = $newObject;
4928 if ($this->useCloneMethod && $reflectedObject->hasMethod('__clone')) {
4929 return $newObject;
4930 }
4931 if ($newObject instanceof DateTimeInterface || $newObject instanceof DateTimeZone) {
4932 return $newObject;
4933 }
4934 foreach (ReflectionHelper::getProperties($reflectedObject) as $property) {
4935 $this->copyObjectProperty($newObject, $property);
4936 }
4937 return $newObject;
4938 }
4939 private function copyObjectProperty($object, ReflectionProperty $property)
4940 {
4941 // Ignore static properties
4942 if ($property->isStatic()) {
4943 return;
4944 }
4945 // Ignore readonly properties
4946 if (method_exists($property, 'isReadOnly') && $property->isReadOnly()) {
4947 return;
4948 }
4949 // Apply the filters
4950 foreach ($this->filters as $item) {
4951 /** @var Matcher $matcher */
4952 $matcher = $item['matcher'];
4953 /** @var Filter $filter */
4954 $filter = $item['filter'];
4955 if ($matcher->matches($object, $property->getName())) {
4956 $filter->apply($object, $property->getName(), function ($object) {
4957 return $this->recursiveCopy($object);
4958 });
4959 if ($filter instanceof ChainableFilter) {
4960 continue;
4961 }
4962 // If a filter matches, we stop processing this property
4963 return;
4964 }
4965 }
4966 if (\PHP_VERSION_ID < 80100) {
4967 $property->setAccessible(\true);
4968 }
4969 // Ignore uninitialized properties (for PHP >7.4)
4970 if (method_exists($property, 'isInitialized') && !$property->isInitialized($object)) {
4971 return;
4972 }
4973 $propertyValue = $property->getValue($object);
4974 // Copy the property
4975 $property->setValue($object, $this->recursiveCopy($propertyValue));
4976 }
4977 /**
4978 * Returns first filter that matches variable, `null` if no such filter found.
4979 *
4980 * @param array $filterRecords Associative array with 2 members: 'filter' with value of type {@see TypeFilter} and
4981 * 'matcher' with value of type {@see TypeMatcher}
4982 * @param mixed $var
4983 *
4984 * @return TypeFilter|null
4985 */
4986 private function getFirstMatchedTypeFilter(array $filterRecords, $var)
4987 {
4988 $matched = $this->first($filterRecords, function (array $record) use ($var) {
4989 /* @var TypeMatcher $matcher */
4990 $matcher = $record['matcher'];
4991 return $matcher->matches($var);
4992 });
4993 return isset($matched) ? $matched['filter'] : null;
4994 }
4995 /**
4996 * Returns first element that matches predicate, `null` if no such element found.
4997 *
4998 * @param array $elements Array of ['filter' => Filter, 'matcher' => Matcher] pairs.
4999 * @param callable $predicate Predicate arguments are: element.
5000 *
5001 * @return array|null Associative array with 2 members: 'filter' with value of type {@see TypeFilter} and 'matcher'
5002 * with value of type {@see TypeMatcher} or `null`.
5003 */
5004 private function first(array $elements, callable $predicate)
5005 {
5006 foreach ($elements as $element) {
5007 if (call_user_func($predicate, $element)) {
5008 return $element;
5009 }
5010 }
5011 return null;
5012 }
5013 }
5014 <?php
5015
5016 namespace PHPUnitPHAR\DeepCopy\Exception;
5017
5018 use UnexpectedValueException;
5019 class CloneException extends UnexpectedValueException
5020 {
5021 }
5022 <?php
5023
5024 namespace PHPUnitPHAR\DeepCopy\Exception;
5025
5026 use ReflectionException;
5027 class PropertyException extends ReflectionException
5028 {
5029 }
5030 <?php
5031
5032 namespace PHPUnitPHAR\DeepCopy\Filter;
5033
5034 /**
5035 * Defines a decorator filter that will not stop the chain of filters.
5036 */
5037 class ChainableFilter implements Filter
5038 {
5039 /**
5040 * @var Filter
5041 */
5042 protected $filter;
5043 public function __construct(Filter $filter)
5044 {
5045 $this->filter = $filter;
5046 }
5047 public function apply($object, $property, $objectCopier)
5048 {
5049 $this->filter->apply($object, $property, $objectCopier);
5050 }
5051 }
5052 <?php
5053
5054 namespace PHPUnitPHAR\DeepCopy\Filter\Doctrine;
5055
5056 use PHPUnitPHAR\DeepCopy\Filter\Filter;
5057 use PHPUnitPHAR\DeepCopy\Reflection\ReflectionHelper;
5058 /**
5059 * @final
5060 */
5061 class DoctrineCollectionFilter implements Filter
5062 {
5063 /**
5064 * Copies the object property doctrine collection.
5065 *
5066 * {@inheritdoc}
5067 */
5068 public function apply($object, $property, $objectCopier)
5069 {
5070 $reflectionProperty = ReflectionHelper::getProperty($object, $property);
5071 if (\PHP_VERSION_ID < 80100) {
5072 $reflectionProperty->setAccessible(\true);
5073 }
5074 $oldCollection = $reflectionProperty->getValue($object);
5075 $newCollection = $oldCollection->map(function ($item) use ($objectCopier) {
5076 return $objectCopier($item);
5077 });
5078 $reflectionProperty->setValue($object, $newCollection);
5079 }
5080 }
5081 <?php
5082
5083 namespace PHPUnitPHAR\DeepCopy\Filter\Doctrine;
5084
5085 use PHPUnitPHAR\DeepCopy\Filter\Filter;
5086 use PHPUnitPHAR\DeepCopy\Reflection\ReflectionHelper;
5087 use PHPUnitPHAR\Doctrine\Common\Collections\ArrayCollection;
5088 /**
5089 * @final
5090 */
5091 class DoctrineEmptyCollectionFilter implements Filter
5092 {
5093 /**
5094 * Sets the object property to an empty doctrine collection.
5095 *
5096 * @param object $object
5097 * @param string $property
5098 * @param callable $objectCopier
5099 */
5100 public function apply($object, $property, $objectCopier)
5101 {
5102 $reflectionProperty = ReflectionHelper::getProperty($object, $property);
5103 if (\PHP_VERSION_ID < 80100) {
5104 $reflectionProperty->setAccessible(\true);
5105 }
5106 $reflectionProperty->setValue($object, new ArrayCollection());
5107 }
5108 }
5109 <?php
5110
5111 namespace PHPUnitPHAR\DeepCopy\Filter\Doctrine;
5112
5113 use PHPUnitPHAR\DeepCopy\Filter\Filter;
5114 /**
5115 * @final
5116 */
5117 class DoctrineProxyFilter implements Filter
5118 {
5119 /**
5120 * Triggers the magic method __load() on a Doctrine Proxy class to load the
5121 * actual entity from the database.
5122 *
5123 * {@inheritdoc}
5124 */
5125 public function apply($object, $property, $objectCopier)
5126 {
5127 $object->__load();
5128 }
5129 }
5130 <?php
5131
5132 namespace PHPUnitPHAR\DeepCopy\Filter;
5133
5134 /**
5135 * Filter to apply to a property while copying an object
5136 */
5137 interface Filter
5138 {
5139 /**
5140 * Applies the filter to the object.
5141 *
5142 * @param object $object
5143 * @param string $property
5144 * @param callable $objectCopier
5145 */
5146 public function apply($object, $property, $objectCopier);
5147 }
5148 <?php
5149
5150 namespace PHPUnitPHAR\DeepCopy\Filter;
5151
5152 class KeepFilter implements Filter
5153 {
5154 /**
5155 * Keeps the value of the object property.
5156 *
5157 * {@inheritdoc}
5158 */
5159 public function apply($object, $property, $objectCopier)
5160 {
5161 // Nothing to do
5162 }
5163 }
5164 <?php
5165
5166 namespace PHPUnitPHAR\DeepCopy\Filter;
5167
5168 use PHPUnitPHAR\DeepCopy\Reflection\ReflectionHelper;
5169 /**
5170 * @final
5171 */
5172 class ReplaceFilter implements Filter
5173 {
5174 /**
5175 * @var callable
5176 */
5177 protected $callback;
5178 /**
5179 * @param callable $callable Will be called to get the new value for each property to replace
5180 */
5181 public function __construct(callable $callable)
5182 {
5183 $this->callback = $callable;
5184 }
5185 /**
5186 * Replaces the object property by the result of the callback called with the object property.
5187 *
5188 * {@inheritdoc}
5189 */
5190 public function apply($object, $property, $objectCopier)
5191 {
5192 $reflectionProperty = ReflectionHelper::getProperty($object, $property);
5193 if (\PHP_VERSION_ID < 80100) {
5194 $reflectionProperty->setAccessible(\true);
5195 }
5196 $value = call_user_func($this->callback, $reflectionProperty->getValue($object));
5197 $reflectionProperty->setValue($object, $value);
5198 }
5199 }
5200 <?php
5201
5202 namespace PHPUnitPHAR\DeepCopy\Filter;
5203
5204 use PHPUnitPHAR\DeepCopy\Reflection\ReflectionHelper;
5205 /**
5206 * @final
5207 */
5208 class SetNullFilter implements Filter
5209 {
5210 /**
5211 * Sets the object property to null.
5212 *
5213 * {@inheritdoc}
5214 */
5215 public function apply($object, $property, $objectCopier)
5216 {
5217 $reflectionProperty = ReflectionHelper::getProperty($object, $property);
5218 if (\PHP_VERSION_ID < 80100) {
5219 $reflectionProperty->setAccessible(\true);
5220 }
5221 $reflectionProperty->setValue($object, null);
5222 }
5223 }
5224 <?php
5225
5226 namespace PHPUnitPHAR\DeepCopy\Matcher\Doctrine;
5227
5228 use PHPUnitPHAR\DeepCopy\Matcher\Matcher;
5229 use PHPUnitPHAR\Doctrine\Persistence\Proxy;
5230 /**
5231 * @final
5232 */
5233 class DoctrineProxyMatcher implements Matcher
5234 {
5235 /**
5236 * Matches a Doctrine Proxy class.
5237 *
5238 * {@inheritdoc}
5239 */
5240 public function matches($object, $property)
5241 {
5242 return $object instanceof Proxy;
5243 }
5244 }
5245 <?php
5246
5247 namespace PHPUnitPHAR\DeepCopy\Matcher;
5248
5249 interface Matcher
5250 {
5251 /**
5252 * @param object $object
5253 * @param string $property
5254 *
5255 * @return boolean
5256 */
5257 public function matches($object, $property);
5258 }
5259 <?php
5260
5261 namespace PHPUnitPHAR\DeepCopy\Matcher;
5262
5263 /**
5264 * @final
5265 */
5266 class PropertyMatcher implements Matcher
5267 {
5268 /**
5269 * @var string
5270 */
5271 private $class;
5272 /**
5273 * @var string
5274 */
5275 private $property;
5276 /**
5277 * @param string $class Class name
5278 * @param string $property Property name
5279 */
5280 public function __construct($class, $property)
5281 {
5282 $this->class = $class;
5283 $this->property = $property;
5284 }
5285 /**
5286 * Matches a specific property of a specific class.
5287 *
5288 * {@inheritdoc}
5289 */
5290 public function matches($object, $property)
5291 {
5292 return $object instanceof $this->class && $property == $this->property;
5293 }
5294 }
5295 <?php
5296
5297 namespace PHPUnitPHAR\DeepCopy\Matcher;
5298
5299 /**
5300 * @final
5301 */
5302 class PropertyNameMatcher implements Matcher
5303 {
5304 /**
5305 * @var string
5306 */
5307 private $property;
5308 /**
5309 * @param string $property Property name
5310 */
5311 public function __construct($property)
5312 {
5313 $this->property = $property;
5314 }
5315 /**
5316 * Matches a property by its name.
5317 *
5318 * {@inheritdoc}
5319 */
5320 public function matches($object, $property)
5321 {
5322 return $property == $this->property;
5323 }
5324 }
5325 <?php
5326
5327 namespace PHPUnitPHAR\DeepCopy\Matcher;
5328
5329 use PHPUnitPHAR\DeepCopy\Reflection\ReflectionHelper;
5330 use ReflectionException;
5331 /**
5332 * Matches a property by its type.
5333 *
5334 * It is recommended to use {@see DeepCopy\TypeFilter\TypeFilter} instead, as it applies on all occurrences
5335 * of given type in copied context (eg. array elements), not just on object properties.
5336 *
5337 * @final
5338 */
5339 class PropertyTypeMatcher implements Matcher
5340 {
5341 /**
5342 * @var string
5343 */
5344 private $propertyType;
5345 /**
5346 * @param string $propertyType Property type
5347 */
5348 public function __construct($propertyType)
5349 {
5350 $this->propertyType = $propertyType;
5351 }
5352 /**
5353 * {@inheritdoc}
5354 */
5355 public function matches($object, $property)
5356 {
5357 try {
5358 $reflectionProperty = ReflectionHelper::getProperty($object, $property);
5359 } catch (ReflectionException $exception) {
5360 return \false;
5361 }
5362 if (\PHP_VERSION_ID < 80100) {
5363 $reflectionProperty->setAccessible(\true);
5364 }
5365 // Uninitialized properties (for PHP >7.4)
5366 if (method_exists($reflectionProperty, 'isInitialized') && !$reflectionProperty->isInitialized($object)) {
5367 // null instanceof $this->propertyType
5368 return \false;
5369 }
5370 return $reflectionProperty->getValue($object) instanceof $this->propertyType;
5371 }
5372 }
5373 <?php
5374
5375 namespace PHPUnitPHAR\DeepCopy\Reflection;
5376
5377 use PHPUnitPHAR\DeepCopy\Exception\PropertyException;
5378 use ReflectionClass;
5379 use ReflectionException;
5380 use ReflectionObject;
5381 use ReflectionProperty;
5382 class ReflectionHelper
5383 {
5384 /**
5385 * Retrieves all properties (including private ones), from object and all its ancestors.
5386 *
5387 * Standard \ReflectionClass->getProperties() does not return private properties from ancestor classes.
5388 *
5389 * @author muratyaman@gmail.com
5390 * @see http://php.net/manual/en/reflectionclass.getproperties.php
5391 *
5392 * @param ReflectionClass $ref
5393 *
5394 * @return ReflectionProperty[]
5395 */
5396 public static function getProperties(ReflectionClass $ref)
5397 {
5398 $props = $ref->getProperties();
5399 $propsArr = array();
5400 foreach ($props as $prop) {
5401 $propertyName = $prop->getName();
5402 $propsArr[$propertyName] = $prop;
5403 }
5404 if ($parentClass = $ref->getParentClass()) {
5405 $parentPropsArr = self::getProperties($parentClass);
5406 foreach ($propsArr as $key => $property) {
5407 $parentPropsArr[$key] = $property;
5408 }
5409 return $parentPropsArr;
5410 }
5411 return $propsArr;
5412 }
5413 /**
5414 * Retrieves property by name from object and all its ancestors.
5415 *
5416 * @param object|string $object
5417 * @param string $name
5418 *
5419 * @throws PropertyException
5420 * @throws ReflectionException
5421 *
5422 * @return ReflectionProperty
5423 */
5424 public static function getProperty($object, $name)
5425 {
5426 $reflection = is_object($object) ? new ReflectionObject($object) : new ReflectionClass($object);
5427 if ($reflection->hasProperty($name)) {
5428 return $reflection->getProperty($name);
5429 }
5430 if ($parentClass = $reflection->getParentClass()) {
5431 return self::getProperty($parentClass->getName(), $name);
5432 }
5433 throw new PropertyException(sprintf('The class "%s" doesn\'t have a property with the given name: "%s".', is_object($object) ? get_class($object) : $object, $name));
5434 }
5435 }
5436 <?php
5437
5438 namespace PHPUnitPHAR\DeepCopy\TypeFilter\Date;
5439
5440 use DateInterval;
5441 use PHPUnitPHAR\DeepCopy\TypeFilter\TypeFilter;
5442 /**
5443 * @final
5444 *
5445 * @deprecated Will be removed in 2.0. This filter will no longer be necessary in PHP 7.1+.
5446 */
5447 class DateIntervalFilter implements TypeFilter
5448 {
5449 /**
5450 * {@inheritdoc}
5451 *
5452 * @param DateInterval $element
5453 *
5454 * @see http://news.php.net/php.bugs/205076
5455 */
5456 public function apply($element)
5457 {
5458 $copy = new DateInterval('P0D');
5459 foreach ($element as $propertyName => $propertyValue) {
5460 $copy->{$propertyName} = $propertyValue;
5461 }
5462 return $copy;
5463 }
5464 }
5465 <?php
5466
5467 namespace PHPUnitPHAR\DeepCopy\TypeFilter\Date;
5468
5469 use DatePeriod;
5470 use PHPUnitPHAR\DeepCopy\TypeFilter\TypeFilter;
5471 /**
5472 * @final
5473 */
5474 class DatePeriodFilter implements TypeFilter
5475 {
5476 /**
5477 * {@inheritdoc}
5478 *
5479 * @param DatePeriod $element
5480 *
5481 * @see http://news.php.net/php.bugs/205076
5482 */
5483 public function apply($element)
5484 {
5485 $options = 0;
5486 if (\PHP_VERSION_ID >= 80200 && $element->include_end_date) {
5487 $options |= DatePeriod::INCLUDE_END_DATE;
5488 }
5489 if (!$element->include_start_date) {
5490 $options |= DatePeriod::EXCLUDE_START_DATE;
5491 }
5492 if ($element->getEndDate()) {
5493 return new DatePeriod($element->getStartDate(), $element->getDateInterval(), $element->getEndDate(), $options);
5494 }
5495 if (\PHP_VERSION_ID >= 70217) {
5496 $recurrences = $element->getRecurrences();
5497 } else {
5498 $recurrences = $element->recurrences - $element->include_start_date;
5499 }
5500 return new DatePeriod($element->getStartDate(), $element->getDateInterval(), $recurrences, $options);
5501 }
5502 }
5503 <?php
5504
5505 namespace PHPUnitPHAR\DeepCopy\TypeFilter;
5506
5507 /**
5508 * @final
5509 */
5510 class ReplaceFilter implements TypeFilter
5511 {
5512 /**
5513 * @var callable
5514 */
5515 protected $callback;
5516 /**
5517 * @param callable $callable Will be called to get the new value for each element to replace
5518 */
5519 public function __construct(callable $callable)
5520 {
5521 $this->callback = $callable;
5522 }
5523 /**
5524 * {@inheritdoc}
5525 */
5526 public function apply($element)
5527 {
5528 return call_user_func($this->callback, $element);
5529 }
5530 }
5531 <?php
5532
5533 namespace PHPUnitPHAR\DeepCopy\TypeFilter;
5534
5535 /**
5536 * @final
5537 */
5538 class ShallowCopyFilter implements TypeFilter
5539 {
5540 /**
5541 * {@inheritdoc}
5542 */
5543 public function apply($element)
5544 {
5545 return clone $element;
5546 }
5547 }
5548 <?php
5549
5550 namespace PHPUnitPHAR\DeepCopy\TypeFilter\Spl;
5551
5552 use PHPUnitPHAR\DeepCopy\DeepCopy;
5553 use PHPUnitPHAR\DeepCopy\TypeFilter\TypeFilter;
5554 /**
5555 * In PHP 7.4 the storage of an ArrayObject isn't returned as
5556 * ReflectionProperty. So we deep copy its array copy.
5557 */
5558 final class ArrayObjectFilter implements TypeFilter
5559 {
5560 /**
5561 * @var DeepCopy
5562 */
5563 private $copier;
5564 public function __construct(DeepCopy $copier)
5565 {
5566 $this->copier = $copier;
5567 }
5568 /**
5569 * {@inheritdoc}
5570 */
5571 public function apply($arrayObject)
5572 {
5573 $clone = clone $arrayObject;
5574 foreach ($arrayObject->getArrayCopy() as $k => $v) {
5575 $clone->offsetSet($k, $this->copier->copy($v));
5576 }
5577 return $clone;
5578 }
5579 }
5580 <?php
5581
5582 namespace PHPUnitPHAR\DeepCopy\TypeFilter\Spl;
5583
5584 /**
5585 * @deprecated Use {@see SplDoublyLinkedListFilter} instead.
5586 */
5587 class SplDoublyLinkedList extends SplDoublyLinkedListFilter
5588 {
5589 }
5590 <?php
5591
5592 namespace PHPUnitPHAR\DeepCopy\TypeFilter\Spl;
5593
5594 use Closure;
5595 use PHPUnitPHAR\DeepCopy\DeepCopy;
5596 use PHPUnitPHAR\DeepCopy\TypeFilter\TypeFilter;
5597 use SplDoublyLinkedList;
5598 /**
5599 * @final
5600 */
5601 class SplDoublyLinkedListFilter implements TypeFilter
5602 {
5603 private $copier;
5604 public function __construct(DeepCopy $copier)
5605 {
5606 $this->copier = $copier;
5607 }
5608 /**
5609 * {@inheritdoc}
5610 */
5611 public function apply($element)
5612 {
5613 $newElement = clone $element;
5614 $copy = $this->createCopyClosure();
5615 return $copy($newElement);
5616 }
5617 private function createCopyClosure()
5618 {
5619 $copier = $this->copier;
5620 $copy = function (SplDoublyLinkedList $list) use ($copier) {
5621 // Replace each element in the list with a deep copy of itself
5622 for ($i = 1; $i <= $list->count(); $i++) {
5623 $copy = $copier->recursiveCopy($list->shift());
5624 $list->push($copy);
5625 }
5626 return $list;
5627 };
5628 return Closure::bind($copy, null, DeepCopy::class);
5629 }
5630 }
5631 <?php
5632
5633 namespace PHPUnitPHAR\DeepCopy\TypeFilter;
5634
5635 interface TypeFilter
5636 {
5637 /**
5638 * Applies the filter to the object.
5639 *
5640 * @param mixed $element
5641 */
5642 public function apply($element);
5643 }
5644 <?php
5645
5646 namespace PHPUnitPHAR\DeepCopy\TypeMatcher;
5647
5648 class TypeMatcher
5649 {
5650 /**
5651 * @var string
5652 */
5653 private $type;
5654 /**
5655 * @param string $type
5656 */
5657 public function __construct($type)
5658 {
5659 $this->type = $type;
5660 }
5661 /**
5662 * @param mixed $element
5663 *
5664 * @return boolean
5665 */
5666 public function matches($element)
5667 {
5668 return is_object($element) ? is_a($element, $this->type) : gettype($element) === $this->type;
5669 }
5670 }
5671 <?php
5672
5673 namespace PHPUnitPHAR\DeepCopy;
5674
5675 use function function_exists;
5676 if (\false === function_exists('PHPUnitPHAR\DeepCopy\deep_copy')) {
5677 /**
5678 * Deep copies the given value.
5679 *
5680 * @param mixed $value
5681 * @param bool $useCloneMethod
5682 *
5683 * @return mixed
5684 */
5685 function deep_copy($value, $useCloneMethod = \false)
5686 {
5687 return (new DeepCopy($useCloneMethod))->copy($value);
5688 }
5689 }
5690 The MIT License (MIT)
5691
5692 Copyright (c) 2013 My C-Sense
5693
5694 Permission is hereby granted, free of charge, to any person obtaining a copy of
5695 this software and associated documentation files (the "Software"), to deal in
5696 the Software without restriction, including without limitation the rights to
5697 use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
5698 the Software, and to permit persons to whom the Software is furnished to do so,
5699 subject to the following conditions:
5700
5701 The above copyright notice and this permission notice shall be included in all
5702 copies or substantial portions of the Software.
5703
5704 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
5705 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
5706 FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
5707 COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
5708 IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
5709 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
5710 BSD 3-Clause License
5711
5712 Copyright (c) 2011, Nikita Popov
5713 All rights reserved.
5714
5715 Redistribution and use in source and binary forms, with or without
5716 modification, are permitted provided that the following conditions are met:
5717
5718 1. Redistributions of source code must retain the above copyright notice, this
5719 list of conditions and the following disclaimer.
5720
5721 2. Redistributions in binary form must reproduce the above copyright notice,
5722 this list of conditions and the following disclaimer in the documentation
5723 and/or other materials provided with the distribution.
5724
5725 3. Neither the name of the copyright holder nor the names of its
5726 contributors may be used to endorse or promote products derived from
5727 this software without specific prior written permission.
5728
5729 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
5730 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
5731 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
5732 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
5733 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
5734 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
5735 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
5736 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
5737 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
5738 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
5739 <?php
5740
5741 declare (strict_types=1);
5742 namespace PHPUnitPHAR\PhpParser;
5743
5744 interface Builder
5745 {
5746 /**
5747 * Returns the built node.
5748 *
5749 * @return Node The built node
5750 */
5751 public function getNode(): Node;
5752 }
5753 <?php
5754
5755 declare (strict_types=1);
5756 namespace PHPUnitPHAR\PhpParser\Builder;
5757
5758 use PHPUnitPHAR\PhpParser;
5759 use PHPUnitPHAR\PhpParser\BuilderHelpers;
5760 use PHPUnitPHAR\PhpParser\Modifiers;
5761 use PHPUnitPHAR\PhpParser\Node;
5762 use PHPUnitPHAR\PhpParser\Node\Const_;
5763 use PHPUnitPHAR\PhpParser\Node\Identifier;
5764 use PHPUnitPHAR\PhpParser\Node\Stmt;
5765 class ClassConst implements PhpParser\Builder
5766 {
5767 protected int $flags = 0;
5768 /** @var array<string, mixed> */
5769 protected array $attributes = [];
5770 /** @var list<Const_> */
5771 protected array $constants = [];
5772 /** @var list<Node\AttributeGroup> */
5773 protected array $attributeGroups = [];
5774 /** @var Identifier|Node\Name|Node\ComplexType|null */
5775 protected ?Node $type = null;
5776 /**
5777 * Creates a class constant builder
5778 *
5779 * @param string|Identifier $name Name
5780 * @param Node\Expr|bool|null|int|float|string|array|\UnitEnum $value Value
5781 */
5782 public function __construct($name, $value)
5783 {
5784 $this->constants = [new Const_($name, BuilderHelpers::normalizeValue($value))];
5785 }
5786 /**
5787 * Add another constant to const group
5788 *
5789 * @param string|Identifier $name Name
5790 * @param Node\Expr|bool|null|int|float|string|array|\UnitEnum $value Value
5791 *
5792 * @return $this The builder instance (for fluid interface)
5793 */
5794 public function addConst($name, $value)
5795 {
5796 $this->constants[] = new Const_($name, BuilderHelpers::normalizeValue($value));
5797 return $this;
5798 }
5799 /**
5800 * Makes the constant public.
5801 *
5802 * @return $this The builder instance (for fluid interface)
5803 */
5804 public function makePublic()
5805 {
5806 $this->flags = BuilderHelpers::addModifier($this->flags, Modifiers::PUBLIC);
5807 return $this;
5808 }
5809 /**
5810 * Makes the constant protected.
5811 *
5812 * @return $this The builder instance (for fluid interface)
5813 */
5814 public function makeProtected()
5815 {
5816 $this->flags = BuilderHelpers::addModifier($this->flags, Modifiers::PROTECTED);
5817 return $this;
5818 }
5819 /**
5820 * Makes the constant private.
5821 *
5822 * @return $this The builder instance (for fluid interface)
5823 */
5824 public function makePrivate()
5825 {
5826 $this->flags = BuilderHelpers::addModifier($this->flags, Modifiers::PRIVATE);
5827 return $this;
5828 }
5829 /**
5830 * Makes the constant final.
5831 *
5832 * @return $this The builder instance (for fluid interface)
5833 */
5834 public function makeFinal()
5835 {
5836 $this->flags = BuilderHelpers::addModifier($this->flags, Modifiers::FINAL);
5837 return $this;
5838 }
5839 /**
5840 * Sets doc comment for the constant.
5841 *
5842 * @param PhpParser\Comment\Doc|string $docComment Doc comment to set
5843 *
5844 * @return $this The builder instance (for fluid interface)
5845 */
5846 public function setDocComment($docComment)
5847 {
5848 $this->attributes = ['comments' => [BuilderHelpers::normalizeDocComment($docComment)]];
5849 return $this;
5850 }
5851 /**
5852 * Adds an attribute group.
5853 *
5854 * @param Node\Attribute|Node\AttributeGroup $attribute
5855 *
5856 * @return $this The builder instance (for fluid interface)
5857 */
5858 public function addAttribute($attribute)
5859 {
5860 $this->attributeGroups[] = BuilderHelpers::normalizeAttribute($attribute);
5861 return $this;
5862 }
5863 /**
5864 * Sets the constant type.
5865 *
5866 * @param string|Node\Name|Identifier|Node\ComplexType $type
5867 *
5868 * @return $this
5869 */
5870 public function setType($type)
5871 {
5872 $this->type = BuilderHelpers::normalizeType($type);
5873 return $this;
5874 }
5875 /**
5876 * Returns the built class node.
5877 *
5878 * @return Stmt\ClassConst The built constant node
5879 */
5880 public function getNode(): PhpParser\Node
5881 {
5882 return new Stmt\ClassConst($this->constants, $this->flags, $this->attributes, $this->attributeGroups, $this->type);
5883 }
5884 }
5885 <?php
5886
5887 declare (strict_types=1);
5888 namespace PHPUnitPHAR\PhpParser\Builder;
5889
5890 use PHPUnitPHAR\PhpParser;
5891 use PHPUnitPHAR\PhpParser\BuilderHelpers;
5892 use PHPUnitPHAR\PhpParser\Modifiers;
5893 use PHPUnitPHAR\PhpParser\Node;
5894 use PHPUnitPHAR\PhpParser\Node\Name;
5895 use PHPUnitPHAR\PhpParser\Node\Stmt;
5896 class Class_ extends Declaration
5897 {
5898 protected string $name;
5899 protected ?Name $extends = null;
5900 /** @var list<Name> */
5901 protected array $implements = [];
5902 protected int $flags = 0;
5903 /** @var list<Stmt\TraitUse> */
5904 protected array $uses = [];
5905 /** @var list<Stmt\ClassConst> */
5906 protected array $constants = [];
5907 /** @var list<Stmt\Property> */
5908 protected array $properties = [];
5909 /** @var list<Stmt\ClassMethod> */
5910 protected array $methods = [];
5911 /** @var list<Node\AttributeGroup> */
5912 protected array $attributeGroups = [];
5913 /**
5914 * Creates a class builder.
5915 *
5916 * @param string $name Name of the class
5917 */
5918 public function __construct(string $name)
5919 {
5920 $this->name = $name;
5921 }
5922 /**
5923 * Extends a class.
5924 *
5925 * @param Name|string $class Name of class to extend
5926 *
5927 * @return $this The builder instance (for fluid interface)
5928 */
5929 public function extend($class)
5930 {
5931 $this->extends = BuilderHelpers::normalizeName($class);
5932 return $this;
5933 }
5934 /**
5935 * Implements one or more interfaces.
5936 *
5937 * @param Name|string ...$interfaces Names of interfaces to implement
5938 *
5939 * @return $this The builder instance (for fluid interface)
5940 */
5941 public function implement(...$interfaces)
5942 {
5943 foreach ($interfaces as $interface) {
5944 $this->implements[] = BuilderHelpers::normalizeName($interface);
5945 }
5946 return $this;
5947 }
5948 /**
5949 * Makes the class abstract.
5950 *
5951 * @return $this The builder instance (for fluid interface)
5952 */
5953 public function makeAbstract()
5954 {
5955 $this->flags = BuilderHelpers::addClassModifier($this->flags, Modifiers::ABSTRACT);
5956 return $this;
5957 }
5958 /**
5959 * Makes the class final.
5960 *
5961 * @return $this The builder instance (for fluid interface)
5962 */
5963 public function makeFinal()
5964 {
5965 $this->flags = BuilderHelpers::addClassModifier($this->flags, Modifiers::FINAL);
5966 return $this;
5967 }
5968 /**
5969 * Makes the class readonly.
5970 *
5971 * @return $this The builder instance (for fluid interface)
5972 */
5973 public function makeReadonly()
5974 {
5975 $this->flags = BuilderHelpers::addClassModifier($this->flags, Modifiers::READONLY);
5976 return $this;
5977 }
5978 /**
5979 * Adds a statement.
5980 *
5981 * @param Stmt|PhpParser\Builder $stmt The statement to add
5982 *
5983 * @return $this The builder instance (for fluid interface)
5984 */
5985 public function addStmt($stmt)
5986 {
5987 $stmt = BuilderHelpers::normalizeNode($stmt);
5988 if ($stmt instanceof Stmt\Property) {
5989 $this->properties[] = $stmt;
5990 } elseif ($stmt instanceof Stmt\ClassMethod) {
5991 $this->methods[] = $stmt;
5992 } elseif ($stmt instanceof Stmt\TraitUse) {
5993 $this->uses[] = $stmt;
5994 } elseif ($stmt instanceof Stmt\ClassConst) {
5995 $this->constants[] = $stmt;
5996 } else {
5997 throw new \LogicException(sprintf('Unexpected node of type "%s"', $stmt->getType()));
5998 }
5999 return $this;
6000 }
6001 /**
6002 * Adds an attribute group.
6003 *
6004 * @param Node\Attribute|Node\AttributeGroup $attribute
6005 *
6006 * @return $this The builder instance (for fluid interface)
6007 */
6008 public function addAttribute($attribute)
6009 {
6010 $this->attributeGroups[] = BuilderHelpers::normalizeAttribute($attribute);
6011 return $this;
6012 }
6013 /**
6014 * Returns the built class node.
6015 *
6016 * @return Stmt\Class_ The built class node
6017 */
6018 public function getNode(): PhpParser\Node
6019 {
6020 return new Stmt\Class_($this->name, ['flags' => $this->flags, 'extends' => $this->extends, 'implements' => $this->implements, 'stmts' => array_merge($this->uses, $this->constants, $this->properties, $this->methods), 'attrGroups' => $this->attributeGroups], $this->attributes);
6021 }
6022 }
6023 <?php
6024
6025 declare (strict_types=1);
6026 namespace PHPUnitPHAR\PhpParser\Builder;
6027
6028 use PHPUnitPHAR\PhpParser;
6029 use PHPUnitPHAR\PhpParser\BuilderHelpers;
6030 abstract class Declaration implements PhpParser\Builder
6031 {
6032 /** @var array<string, mixed> */
6033 protected array $attributes = [];
6034 /**
6035 * Adds a statement.
6036 *
6037 * @param PhpParser\Node\Stmt|PhpParser\Builder $stmt The statement to add
6038 *
6039 * @return $this The builder instance (for fluid interface)
6040 */
6041 abstract public function addStmt($stmt);
6042 /**
6043 * Adds multiple statements.
6044 *
6045 * @param (PhpParser\Node\Stmt|PhpParser\Builder)[] $stmts The statements to add
6046 *
6047 * @return $this The builder instance (for fluid interface)
6048 */
6049 public function addStmts(array $stmts)
6050 {
6051 foreach ($stmts as $stmt) {
6052 $this->addStmt($stmt);
6053 }
6054 return $this;
6055 }
6056 /**
6057 * Sets doc comment for the declaration.
6058 *
6059 * @param PhpParser\Comment\Doc|string $docComment Doc comment to set
6060 *
6061 * @return $this The builder instance (for fluid interface)
6062 */
6063 public function setDocComment($docComment)
6064 {
6065 $this->attributes['comments'] = [BuilderHelpers::normalizeDocComment($docComment)];
6066 return $this;
6067 }
6068 }
6069 <?php
6070
6071 declare (strict_types=1);
6072 namespace PHPUnitPHAR\PhpParser\Builder;
6073
6074 use PHPUnitPHAR\PhpParser;
6075 use PHPUnitPHAR\PhpParser\BuilderHelpers;
6076 use PHPUnitPHAR\PhpParser\Node;
6077 use PHPUnitPHAR\PhpParser\Node\Identifier;
6078 use PHPUnitPHAR\PhpParser\Node\Stmt;
6079 class EnumCase implements PhpParser\Builder
6080 {
6081 /** @var Identifier|string */
6082 protected $name;
6083 protected ?Node\Expr $value = null;
6084 /** @var array<string, mixed> */
6085 protected array $attributes = [];
6086 /** @var list<Node\AttributeGroup> */
6087 protected array $attributeGroups = [];
6088 /**
6089 * Creates an enum case builder.
6090 *
6091 * @param string|Identifier $name Name
6092 */
6093 public function __construct($name)
6094 {
6095 $this->name = $name;
6096 }
6097 /**
6098 * Sets the value.
6099 *
6100 * @param Node\Expr|string|int $value
6101 *
6102 * @return $this
6103 */
6104 public function setValue($value)
6105 {
6106 $this->value = BuilderHelpers::normalizeValue($value);
6107 return $this;
6108 }
6109 /**
6110 * Sets doc comment for the constant.
6111 *
6112 * @param PhpParser\Comment\Doc|string $docComment Doc comment to set
6113 *
6114 * @return $this The builder instance (for fluid interface)
6115 */
6116 public function setDocComment($docComment)
6117 {
6118 $this->attributes = ['comments' => [BuilderHelpers::normalizeDocComment($docComment)]];
6119 return $this;
6120 }
6121 /**
6122 * Adds an attribute group.
6123 *
6124 * @param Node\Attribute|Node\AttributeGroup $attribute
6125 *
6126 * @return $this The builder instance (for fluid interface)
6127 */
6128 public function addAttribute($attribute)
6129 {
6130 $this->attributeGroups[] = BuilderHelpers::normalizeAttribute($attribute);
6131 return $this;
6132 }
6133 /**
6134 * Returns the built enum case node.
6135 *
6136 * @return Stmt\EnumCase The built constant node
6137 */
6138 public function getNode(): PhpParser\Node
6139 {
6140 return new Stmt\EnumCase($this->name, $this->value, $this->attributeGroups, $this->attributes);
6141 }
6142 }
6143 <?php
6144
6145 declare (strict_types=1);
6146 namespace PHPUnitPHAR\PhpParser\Builder;
6147
6148 use PHPUnitPHAR\PhpParser;
6149 use PHPUnitPHAR\PhpParser\BuilderHelpers;
6150 use PHPUnitPHAR\PhpParser\Node;
6151 use PHPUnitPHAR\PhpParser\Node\Identifier;
6152 use PHPUnitPHAR\PhpParser\Node\Name;
6153 use PHPUnitPHAR\PhpParser\Node\Stmt;
6154 class Enum_ extends Declaration
6155 {
6156 protected string $name;
6157 protected ?Identifier $scalarType = null;
6158 /** @var list<Name> */
6159 protected array $implements = [];
6160 /** @var list<Stmt\TraitUse> */
6161 protected array $uses = [];
6162 /** @var list<Stmt\EnumCase> */
6163 protected array $enumCases = [];
6164 /** @var list<Stmt\ClassConst> */
6165 protected array $constants = [];
6166 /** @var list<Stmt\ClassMethod> */
6167 protected array $methods = [];
6168 /** @var list<Node\AttributeGroup> */
6169 protected array $attributeGroups = [];
6170 /**
6171 * Creates an enum builder.
6172 *
6173 * @param string $name Name of the enum
6174 */
6175 public function __construct(string $name)
6176 {
6177 $this->name = $name;
6178 }
6179 /**
6180 * Sets the scalar type.
6181 *
6182 * @param string|Identifier $scalarType
6183 *
6184 * @return $this
6185 */
6186 public function setScalarType($scalarType)
6187 {
6188 $this->scalarType = BuilderHelpers::normalizeType($scalarType);
6189 return $this;
6190 }
6191 /**
6192 * Implements one or more interfaces.
6193 *
6194 * @param Name|string ...$interfaces Names of interfaces to implement
6195 *
6196 * @return $this The builder instance (for fluid interface)
6197 */
6198 public function implement(...$interfaces)
6199 {
6200 foreach ($interfaces as $interface) {
6201 $this->implements[] = BuilderHelpers::normalizeName($interface);
6202 }
6203 return $this;
6204 }
6205 /**
6206 * Adds a statement.
6207 *
6208 * @param Stmt|PhpParser\Builder $stmt The statement to add
6209 *
6210 * @return $this The builder instance (for fluid interface)
6211 */
6212 public function addStmt($stmt)
6213 {
6214 $stmt = BuilderHelpers::normalizeNode($stmt);
6215 if ($stmt instanceof Stmt\EnumCase) {
6216 $this->enumCases[] = $stmt;
6217 } elseif ($stmt instanceof Stmt\ClassMethod) {
6218 $this->methods[] = $stmt;
6219 } elseif ($stmt instanceof Stmt\TraitUse) {
6220 $this->uses[] = $stmt;
6221 } elseif ($stmt instanceof Stmt\ClassConst) {
6222 $this->constants[] = $stmt;
6223 } else {
6224 throw new \LogicException(sprintf('Unexpected node of type "%s"', $stmt->getType()));
6225 }
6226 return $this;
6227 }
6228 /**
6229 * Adds an attribute group.
6230 *
6231 * @param Node\Attribute|Node\AttributeGroup $attribute
6232 *
6233 * @return $this The builder instance (for fluid interface)
6234 */
6235 public function addAttribute($attribute)
6236 {
6237 $this->attributeGroups[] = BuilderHelpers::normalizeAttribute($attribute);
6238 return $this;
6239 }
6240 /**
6241 * Returns the built class node.
6242 *
6243 * @return Stmt\Enum_ The built enum node
6244 */
6245 public function getNode(): PhpParser\Node
6246 {
6247 return new Stmt\Enum_($this->name, ['scalarType' => $this->scalarType, 'implements' => $this->implements, 'stmts' => array_merge($this->uses, $this->enumCases, $this->constants, $this->methods), 'attrGroups' => $this->attributeGroups], $this->attributes);
6248 }
6249 }
6250 <?php
6251
6252 declare (strict_types=1);
6253 namespace PHPUnitPHAR\PhpParser\Builder;
6254
6255 use PHPUnitPHAR\PhpParser\BuilderHelpers;
6256 use PHPUnitPHAR\PhpParser\Node;
6257 abstract class FunctionLike extends Declaration
6258 {
6259 protected bool $returnByRef = \false;
6260 /** @var Node\Param[] */
6261 protected array $params = [];
6262 /** @var Node\Identifier|Node\Name|Node\ComplexType|null */
6263 protected ?Node $returnType = null;
6264 /**
6265 * Make the function return by reference.
6266 *
6267 * @return $this The builder instance (for fluid interface)
6268 */
6269 public function makeReturnByRef()
6270 {
6271 $this->returnByRef = \true;
6272 return $this;
6273 }
6274 /**
6275 * Adds a parameter.
6276 *
6277 * @param Node\Param|Param $param The parameter to add
6278 *
6279 * @return $this The builder instance (for fluid interface)
6280 */
6281 public function addParam($param)
6282 {
6283 $param = BuilderHelpers::normalizeNode($param);
6284 if (!$param instanceof Node\Param) {
6285 throw new \LogicException(sprintf('Expected parameter node, got "%s"', $param->getType()));
6286 }
6287 $this->params[] = $param;
6288 return $this;
6289 }
6290 /**
6291 * Adds multiple parameters.
6292 *
6293 * @param (Node\Param|Param)[] $params The parameters to add
6294 *
6295 * @return $this The builder instance (for fluid interface)
6296 */
6297 public function addParams(array $params)
6298 {
6299 foreach ($params as $param) {
6300 $this->addParam($param);
6301 }
6302 return $this;
6303 }
6304 /**
6305 * Sets the return type for PHP 7.
6306 *
6307 * @param string|Node\Name|Node\Identifier|Node\ComplexType $type
6308 *
6309 * @return $this The builder instance (for fluid interface)
6310 */
6311 public function setReturnType($type)
6312 {
6313 $this->returnType = BuilderHelpers::normalizeType($type);
6314 return $this;
6315 }
6316 }
6317 <?php
6318
6319 declare (strict_types=1);
6320 namespace PHPUnitPHAR\PhpParser\Builder;
6321
6322 use PHPUnitPHAR\PhpParser;
6323 use PHPUnitPHAR\PhpParser\BuilderHelpers;
6324 use PHPUnitPHAR\PhpParser\Node;
6325 use PHPUnitPHAR\PhpParser\Node\Stmt;
6326 class Function_ extends FunctionLike
6327 {
6328 protected string $name;
6329 /** @var list<Stmt> */
6330 protected array $stmts = [];
6331 /** @var list<Node\AttributeGroup> */
6332 protected array $attributeGroups = [];
6333 /**
6334 * Creates a function builder.
6335 *
6336 * @param string $name Name of the function
6337 */
6338 public function __construct(string $name)
6339 {
6340 $this->name = $name;
6341 }
6342 /**
6343 * Adds a statement.
6344 *
6345 * @param Node|PhpParser\Builder $stmt The statement to add
6346 *
6347 * @return $this The builder instance (for fluid interface)
6348 */
6349 public function addStmt($stmt)
6350 {
6351 $this->stmts[] = BuilderHelpers::normalizeStmt($stmt);
6352 return $this;
6353 }
6354 /**
6355 * Adds an attribute group.
6356 *
6357 * @param Node\Attribute|Node\AttributeGroup $attribute
6358 *
6359 * @return $this The builder instance (for fluid interface)
6360 */
6361 public function addAttribute($attribute)
6362 {
6363 $this->attributeGroups[] = BuilderHelpers::normalizeAttribute($attribute);
6364 return $this;
6365 }
6366 /**
6367 * Returns the built function node.
6368 *
6369 * @return Stmt\Function_ The built function node
6370 */
6371 public function getNode(): Node
6372 {
6373 return new Stmt\Function_($this->name, ['byRef' => $this->returnByRef, 'params' => $this->params, 'returnType' => $this->returnType, 'stmts' => $this->stmts, 'attrGroups' => $this->attributeGroups], $this->attributes);
6374 }
6375 }
6376 <?php
6377
6378 declare (strict_types=1);
6379 namespace PHPUnitPHAR\PhpParser\Builder;
6380
6381 use PHPUnitPHAR\PhpParser;
6382 use PHPUnitPHAR\PhpParser\BuilderHelpers;
6383 use PHPUnitPHAR\PhpParser\Node;
6384 use PHPUnitPHAR\PhpParser\Node\Name;
6385 use PHPUnitPHAR\PhpParser\Node\Stmt;
6386 class Interface_ extends Declaration
6387 {
6388 protected string $name;
6389 /** @var list<Name> */
6390 protected array $extends = [];
6391 /** @var list<Stmt\ClassConst> */
6392 protected array $constants = [];
6393 /** @var list<Stmt\ClassMethod> */
6394 protected array $methods = [];
6395 /** @var list<Node\AttributeGroup> */
6396 protected array $attributeGroups = [];
6397 /**
6398 * Creates an interface builder.
6399 *
6400 * @param string $name Name of the interface
6401 */
6402 public function __construct(string $name)
6403 {
6404 $this->name = $name;
6405 }
6406 /**
6407 * Extends one or more interfaces.
6408 *
6409 * @param Name|string ...$interfaces Names of interfaces to extend
6410 *
6411 * @return $this The builder instance (for fluid interface)
6412 */
6413 public function extend(...$interfaces)
6414 {
6415 foreach ($interfaces as $interface) {
6416 $this->extends[] = BuilderHelpers::normalizeName($interface);
6417 }
6418 return $this;
6419 }
6420 /**
6421 * Adds a statement.
6422 *
6423 * @param Stmt|PhpParser\Builder $stmt The statement to add
6424 *
6425 * @return $this The builder instance (for fluid interface)
6426 */
6427 public function addStmt($stmt)
6428 {
6429 $stmt = BuilderHelpers::normalizeNode($stmt);
6430 if ($stmt instanceof Stmt\ClassConst) {
6431 $this->constants[] = $stmt;
6432 } elseif ($stmt instanceof Stmt\ClassMethod) {
6433 // we erase all statements in the body of an interface method
6434 $stmt->stmts = null;
6435 $this->methods[] = $stmt;
6436 } else {
6437 throw new \LogicException(sprintf('Unexpected node of type "%s"', $stmt->getType()));
6438 }
6439 return $this;
6440 }
6441 /**
6442 * Adds an attribute group.
6443 *
6444 * @param Node\Attribute|Node\AttributeGroup $attribute
6445 *
6446 * @return $this The builder instance (for fluid interface)
6447 */
6448 public function addAttribute($attribute)
6449 {
6450 $this->attributeGroups[] = BuilderHelpers::normalizeAttribute($attribute);
6451 return $this;
6452 }
6453 /**
6454 * Returns the built interface node.
6455 *
6456 * @return Stmt\Interface_ The built interface node
6457 */
6458 public function getNode(): PhpParser\Node
6459 {
6460 return new Stmt\Interface_($this->name, ['extends' => $this->extends, 'stmts' => array_merge($this->constants, $this->methods), 'attrGroups' => $this->attributeGroups], $this->attributes);
6461 }
6462 }
6463 <?php
6464
6465 declare (strict_types=1);
6466 namespace PHPUnitPHAR\PhpParser\Builder;
6467
6468 use PHPUnitPHAR\PhpParser;
6469 use PHPUnitPHAR\PhpParser\BuilderHelpers;
6470 use PHPUnitPHAR\PhpParser\Modifiers;
6471 use PHPUnitPHAR\PhpParser\Node;
6472 use PHPUnitPHAR\PhpParser\Node\Stmt;
6473 class Method extends FunctionLike
6474 {
6475 protected string $name;
6476 protected int $flags = 0;
6477 /** @var list<Stmt>|null */
6478 protected ?array $stmts = [];
6479 /** @var list<Node\AttributeGroup> */
6480 protected array $attributeGroups = [];
6481 /**
6482 * Creates a method builder.
6483 *
6484 * @param string $name Name of the method
6485 */
6486 public function __construct(string $name)
6487 {
6488 $this->name = $name;
6489 }
6490 /**
6491 * Makes the method public.
6492 *
6493 * @return $this The builder instance (for fluid interface)
6494 */
6495 public function makePublic()
6496 {
6497 $this->flags = BuilderHelpers::addModifier($this->flags, Modifiers::PUBLIC);
6498 return $this;
6499 }
6500 /**
6501 * Makes the method protected.
6502 *
6503 * @return $this The builder instance (for fluid interface)
6504 */
6505 public function makeProtected()
6506 {
6507 $this->flags = BuilderHelpers::addModifier($this->flags, Modifiers::PROTECTED);
6508 return $this;
6509 }
6510 /**
6511 * Makes the method private.
6512 *
6513 * @return $this The builder instance (for fluid interface)
6514 */
6515 public function makePrivate()
6516 {
6517 $this->flags = BuilderHelpers::addModifier($this->flags, Modifiers::PRIVATE);
6518 return $this;
6519 }
6520 /**
6521 * Makes the method static.
6522 *
6523 * @return $this The builder instance (for fluid interface)
6524 */
6525 public function makeStatic()
6526 {
6527 $this->flags = BuilderHelpers::addModifier($this->flags, Modifiers::STATIC);
6528 return $this;
6529 }
6530 /**
6531 * Makes the method abstract.
6532 *
6533 * @return $this The builder instance (for fluid interface)
6534 */
6535 public function makeAbstract()
6536 {
6537 if (!empty($this->stmts)) {
6538 throw new \LogicException('Cannot make method with statements abstract');
6539 }
6540 $this->flags = BuilderHelpers::addModifier($this->flags, Modifiers::ABSTRACT);
6541 $this->stmts = null;
6542 // abstract methods don't have statements
6543 return $this;
6544 }
6545 /**
6546 * Makes the method final.
6547 *
6548 * @return $this The builder instance (for fluid interface)
6549 */
6550 public function makeFinal()
6551 {
6552 $this->flags = BuilderHelpers::addModifier($this->flags, Modifiers::FINAL);
6553 return $this;
6554 }
6555 /**
6556 * Adds a statement.
6557 *
6558 * @param Node|PhpParser\Builder $stmt The statement to add
6559 *
6560 * @return $this The builder instance (for fluid interface)
6561 */
6562 public function addStmt($stmt)
6563 {
6564 if (null === $this->stmts) {
6565 throw new \LogicException('Cannot add statements to an abstract method');
6566 }
6567 $this->stmts[] = BuilderHelpers::normalizeStmt($stmt);
6568 return $this;
6569 }
6570 /**
6571 * Adds an attribute group.
6572 *
6573 * @param Node\Attribute|Node\AttributeGroup $attribute
6574 *
6575 * @return $this The builder instance (for fluid interface)
6576 */
6577 public function addAttribute($attribute)
6578 {
6579 $this->attributeGroups[] = BuilderHelpers::normalizeAttribute($attribute);
6580 return $this;
6581 }
6582 /**
6583 * Returns the built method node.
6584 *
6585 * @return Stmt\ClassMethod The built method node
6586 */
6587 public function getNode(): Node
6588 {
6589 return new Stmt\ClassMethod($this->name, ['flags' => $this->flags, 'byRef' => $this->returnByRef, 'params' => $this->params, 'returnType' => $this->returnType, 'stmts' => $this->stmts, 'attrGroups' => $this->attributeGroups], $this->attributes);
6590 }
6591 }
6592 <?php
6593
6594 declare (strict_types=1);
6595 namespace PHPUnitPHAR\PhpParser\Builder;
6596
6597 use PHPUnitPHAR\PhpParser;
6598 use PHPUnitPHAR\PhpParser\BuilderHelpers;
6599 use PHPUnitPHAR\PhpParser\Node;
6600 use PHPUnitPHAR\PhpParser\Node\Stmt;
6601 class Namespace_ extends Declaration
6602 {
6603 private ?Node\Name $name;
6604 /** @var Stmt[] */
6605 private array $stmts = [];
6606 /**
6607 * Creates a namespace builder.
6608 *
6609 * @param Node\Name|string|null $name Name of the namespace
6610 */
6611 public function __construct($name)
6612 {
6613 $this->name = null !== $name ? BuilderHelpers::normalizeName($name) : null;
6614 }
6615 /**
6616 * Adds a statement.
6617 *
6618 * @param Node|PhpParser\Builder $stmt The statement to add
6619 *
6620 * @return $this The builder instance (for fluid interface)
6621 */
6622 public function addStmt($stmt)
6623 {
6624 $this->stmts[] = BuilderHelpers::normalizeStmt($stmt);
6625 return $this;
6626 }
6627 /**
6628 * Returns the built node.
6629 *
6630 * @return Stmt\Namespace_ The built node
6631 */
6632 public function getNode(): Node
6633 {
6634 return new Stmt\Namespace_($this->name, $this->stmts, $this->attributes);
6635 }
6636 }
6637 <?php
6638
6639 declare (strict_types=1);
6640 namespace PHPUnitPHAR\PhpParser\Builder;
6641
6642 use PHPUnitPHAR\PhpParser;
6643 use PHPUnitPHAR\PhpParser\BuilderHelpers;
6644 use PHPUnitPHAR\PhpParser\Modifiers;
6645 use PHPUnitPHAR\PhpParser\Node;
6646 class Param implements PhpParser\Builder
6647 {
6648 protected string $name;
6649 protected ?Node\Expr $default = null;
6650 /** @var Node\Identifier|Node\Name|Node\ComplexType|null */
6651 protected ?Node $type = null;
6652 protected bool $byRef = \false;
6653 protected int $flags = 0;
6654 protected bool $variadic = \false;
6655 /** @var list<Node\AttributeGroup> */
6656 protected array $attributeGroups = [];
6657 /**
6658 * Creates a parameter builder.
6659 *
6660 * @param string $name Name of the parameter
6661 */
6662 public function __construct(string $name)
6663 {
6664 $this->name = $name;
6665 }
6666 /**
6667 * Sets default value for the parameter.
6668 *
6669 * @param mixed $value Default value to use
6670 *
6671 * @return $this The builder instance (for fluid interface)
6672 */
6673 public function setDefault($value)
6674 {
6675 $this->default = BuilderHelpers::normalizeValue($value);
6676 return $this;
6677 }
6678 /**
6679 * Sets type for the parameter.
6680 *
6681 * @param string|Node\Name|Node\Identifier|Node\ComplexType $type Parameter type
6682 *
6683 * @return $this The builder instance (for fluid interface)
6684 */
6685 public function setType($type)
6686 {
6687 $this->type = BuilderHelpers::normalizeType($type);
6688 if ($this->type == 'void') {
6689 throw new \LogicException('Parameter type cannot be void');
6690 }
6691 return $this;
6692 }
6693 /**
6694 * Make the parameter accept the value by reference.
6695 *
6696 * @return $this The builder instance (for fluid interface)
6697 */
6698 public function makeByRef()
6699 {
6700 $this->byRef = \true;
6701 return $this;
6702 }
6703 /**
6704 * Make the parameter variadic
6705 *
6706 * @return $this The builder instance (for fluid interface)
6707 */
6708 public function makeVariadic()
6709 {
6710 $this->variadic = \true;
6711 return $this;
6712 }
6713 /**
6714 * Makes the (promoted) parameter public.
6715 *
6716 * @return $this The builder instance (for fluid interface)
6717 */
6718 public function makePublic()
6719 {
6720 $this->flags = BuilderHelpers::addModifier($this->flags, Modifiers::PUBLIC);
6721 return $this;
6722 }
6723 /**
6724 * Makes the (promoted) parameter protected.
6725 *
6726 * @return $this The builder instance (for fluid interface)
6727 */
6728 public function makeProtected()
6729 {
6730 $this->flags = BuilderHelpers::addModifier($this->flags, Modifiers::PROTECTED);
6731 return $this;
6732 }
6733 /**
6734 * Makes the (promoted) parameter private.
6735 *
6736 * @return $this The builder instance (for fluid interface)
6737 */
6738 public function makePrivate()
6739 {
6740 $this->flags = BuilderHelpers::addModifier($this->flags, Modifiers::PRIVATE);
6741 return $this;
6742 }
6743 /**
6744 * Makes the (promoted) parameter readonly.
6745 *
6746 * @return $this The builder instance (for fluid interface)
6747 */
6748 public function makeReadonly()
6749 {
6750 $this->flags = BuilderHelpers::addModifier($this->flags, Modifiers::READONLY);
6751 return $this;
6752 }
6753 /**
6754 * Gives the promoted property private(set) visibility.
6755 *
6756 * @return $this The builder instance (for fluid interface)
6757 */
6758 public function makePrivateSet()
6759 {
6760 $this->flags = BuilderHelpers::addModifier($this->flags, Modifiers::PRIVATE_SET);
6761 return $this;
6762 }
6763 /**
6764 * Gives the promoted property protected(set) visibility.
6765 *
6766 * @return $this The builder instance (for fluid interface)
6767 */
6768 public function makeProtectedSet()
6769 {
6770 $this->flags = BuilderHelpers::addModifier($this->flags, Modifiers::PROTECTED_SET);
6771 return $this;
6772 }
6773 /**
6774 * Adds an attribute group.
6775 *
6776 * @param Node\Attribute|Node\AttributeGroup $attribute
6777 *
6778 * @return $this The builder instance (for fluid interface)
6779 */
6780 public function addAttribute($attribute)
6781 {
6782 $this->attributeGroups[] = BuilderHelpers::normalizeAttribute($attribute);
6783 return $this;
6784 }
6785 /**
6786 * Returns the built parameter node.
6787 *
6788 * @return Node\Param The built parameter node
6789 */
6790 public function getNode(): Node
6791 {
6792 return new Node\Param(new Node\Expr\Variable($this->name), $this->default, $this->type, $this->byRef, $this->variadic, [], $this->flags, $this->attributeGroups);
6793 }
6794 }
6795 <?php
6796
6797 declare (strict_types=1);
6798 namespace PHPUnitPHAR\PhpParser\Builder;
6799
6800 use PHPUnitPHAR\PhpParser;
6801 use PHPUnitPHAR\PhpParser\BuilderHelpers;
6802 use PHPUnitPHAR\PhpParser\Modifiers;
6803 use PHPUnitPHAR\PhpParser\Node;
6804 use PHPUnitPHAR\PhpParser\Node\Identifier;
6805 use PHPUnitPHAR\PhpParser\Node\Name;
6806 use PHPUnitPHAR\PhpParser\Node\Stmt;
6807 use PHPUnitPHAR\PhpParser\Node\ComplexType;
6808 class Property implements PhpParser\Builder
6809 {
6810 protected string $name;
6811 protected int $flags = 0;
6812 protected ?Node\Expr $default = null;
6813 /** @var array<string, mixed> */
6814 protected array $attributes = [];
6815 /** @var null|Identifier|Name|ComplexType */
6816 protected ?Node $type = null;
6817 /** @var list<Node\AttributeGroup> */
6818 protected array $attributeGroups = [];
6819 /** @var list<Node\PropertyHook> */
6820 protected array $hooks = [];
6821 /**
6822 * Creates a property builder.
6823 *
6824 * @param string $name Name of the property
6825 */
6826 public function __construct(string $name)
6827 {
6828 $this->name = $name;
6829 }
6830 /**
6831 * Makes the property public.
6832 *
6833 * @return $this The builder instance (for fluid interface)
6834 */
6835 public function makePublic()
6836 {
6837 $this->flags = BuilderHelpers::addModifier($this->flags, Modifiers::PUBLIC);
6838 return $this;
6839 }
6840 /**
6841 * Makes the property protected.
6842 *
6843 * @return $this The builder instance (for fluid interface)
6844 */
6845 public function makeProtected()
6846 {
6847 $this->flags = BuilderHelpers::addModifier($this->flags, Modifiers::PROTECTED);
6848 return $this;
6849 }
6850 /**
6851 * Makes the property private.
6852 *
6853 * @return $this The builder instance (for fluid interface)
6854 */
6855 public function makePrivate()
6856 {
6857 $this->flags = BuilderHelpers::addModifier($this->flags, Modifiers::PRIVATE);
6858 return $this;
6859 }
6860 /**
6861 * Makes the property static.
6862 *
6863 * @return $this The builder instance (for fluid interface)
6864 */
6865 public function makeStatic()
6866 {
6867 $this->flags = BuilderHelpers::addModifier($this->flags, Modifiers::STATIC);
6868 return $this;
6869 }
6870 /**
6871 * Makes the property readonly.
6872 *
6873 * @return $this The builder instance (for fluid interface)
6874 */
6875 public function makeReadonly()
6876 {
6877 $this->flags = BuilderHelpers::addModifier($this->flags, Modifiers::READONLY);
6878 return $this;
6879 }
6880 /**
6881 * Makes the property abstract. Requires at least one property hook to be specified as well.
6882 *
6883 * @return $this The builder instance (for fluid interface)
6884 */
6885 public function makeAbstract()
6886 {
6887 $this->flags = BuilderHelpers::addModifier($this->flags, Modifiers::ABSTRACT);
6888 return $this;
6889 }
6890 /**
6891 * Makes the property final.
6892 *
6893 * @return $this The builder instance (for fluid interface)
6894 */
6895 public function makeFinal()
6896 {
6897 $this->flags = BuilderHelpers::addModifier($this->flags, Modifiers::FINAL);
6898 return $this;
6899 }
6900 /**
6901 * Gives the property private(set) visibility.
6902 *
6903 * @return $this The builder instance (for fluid interface)
6904 */
6905 public function makePrivateSet()
6906 {
6907 $this->flags = BuilderHelpers::addModifier($this->flags, Modifiers::PRIVATE_SET);
6908 return $this;
6909 }
6910 /**
6911 * Gives the property protected(set) visibility.
6912 *
6913 * @return $this The builder instance (for fluid interface)
6914 */
6915 public function makeProtectedSet()
6916 {
6917 $this->flags = BuilderHelpers::addModifier($this->flags, Modifiers::PROTECTED_SET);
6918 return $this;
6919 }
6920 /**
6921 * Sets default value for the property.
6922 *
6923 * @param mixed $value Default value to use
6924 *
6925 * @return $this The builder instance (for fluid interface)
6926 */
6927 public function setDefault($value)
6928 {
6929 $this->default = BuilderHelpers::normalizeValue($value);
6930 return $this;
6931 }
6932 /**
6933 * Sets doc comment for the property.
6934 *
6935 * @param PhpParser\Comment\Doc|string $docComment Doc comment to set
6936 *
6937 * @return $this The builder instance (for fluid interface)
6938 */
6939 public function setDocComment($docComment)
6940 {
6941 $this->attributes = ['comments' => [BuilderHelpers::normalizeDocComment($docComment)]];
6942 return $this;
6943 }
6944 /**
6945 * Sets the property type for PHP 7.4+.
6946 *
6947 * @param string|Name|Identifier|ComplexType $type
6948 *
6949 * @return $this
6950 */
6951 public function setType($type)
6952 {
6953 $this->type = BuilderHelpers::normalizeType($type);
6954 return $this;
6955 }
6956 /**
6957 * Adds an attribute group.
6958 *
6959 * @param Node\Attribute|Node\AttributeGroup $attribute
6960 *
6961 * @return $this The builder instance (for fluid interface)
6962 */
6963 public function addAttribute($attribute)
6964 {
6965 $this->attributeGroups[] = BuilderHelpers::normalizeAttribute($attribute);
6966 return $this;
6967 }
6968 /**
6969 * Adds a property hook.
6970 *
6971 * @return $this The builder instance (for fluid interface)
6972 */
6973 public function addHook(Node\PropertyHook $hook)
6974 {
6975 $this->hooks[] = $hook;
6976 return $this;
6977 }
6978 /**
6979 * Returns the built class node.
6980 *
6981 * @return Stmt\Property The built property node
6982 */
6983 public function getNode(): PhpParser\Node
6984 {
6985 if ($this->flags & Modifiers::ABSTRACT && !$this->hooks) {
6986 throw new PhpParser\Error('Only hooked properties may be declared abstract');
6987 }
6988 return new Stmt\Property($this->flags !== 0 ? $this->flags : Modifiers::PUBLIC, [new Node\PropertyItem($this->name, $this->default)], $this->attributes, $this->type, $this->attributeGroups, $this->hooks);
6989 }
6990 }
6991 <?php
6992
6993 declare (strict_types=1);
6994 namespace PHPUnitPHAR\PhpParser\Builder;
6995
6996 use PHPUnitPHAR\PhpParser\Builder;
6997 use PHPUnitPHAR\PhpParser\BuilderHelpers;
6998 use PHPUnitPHAR\PhpParser\Node;
6999 use PHPUnitPHAR\PhpParser\Node\Stmt;
7000 class TraitUse implements Builder
7001 {
7002 /** @var Node\Name[] */
7003 protected array $traits = [];
7004 /** @var Stmt\TraitUseAdaptation[] */
7005 protected array $adaptations = [];
7006 /**
7007 * Creates a trait use builder.
7008 *
7009 * @param Node\Name|string ...$traits Names of used traits
7010 */
7011 public function __construct(...$traits)
7012 {
7013 foreach ($traits as $trait) {
7014 $this->and($trait);
7015 }
7016 }
7017 /**
7018 * Adds used trait.
7019 *
7020 * @param Node\Name|string $trait Trait name
7021 *
7022 * @return $this The builder instance (for fluid interface)
7023 */
7024 public function and($trait)
7025 {
7026 $this->traits[] = BuilderHelpers::normalizeName($trait);
7027 return $this;
7028 }
7029 /**
7030 * Adds trait adaptation.
7031 *
7032 * @param Stmt\TraitUseAdaptation|Builder\TraitUseAdaptation $adaptation Trait adaptation
7033 *
7034 * @return $this The builder instance (for fluid interface)
7035 */
7036 public function with($adaptation)
7037 {
7038 $adaptation = BuilderHelpers::normalizeNode($adaptation);
7039 if (!$adaptation instanceof Stmt\TraitUseAdaptation) {
7040 throw new \LogicException('Adaptation must have type TraitUseAdaptation');
7041 }
7042 $this->adaptations[] = $adaptation;
7043 return $this;
7044 }
7045 /**
7046 * Returns the built node.
7047 *
7048 * @return Node The built node
7049 */
7050 public function getNode(): Node
7051 {
7052 return new Stmt\TraitUse($this->traits, $this->adaptations);
7053 }
7054 }
7055 <?php
7056
7057 declare (strict_types=1);
7058 namespace PHPUnitPHAR\PhpParser\Builder;
7059
7060 use PHPUnitPHAR\PhpParser\Builder;
7061 use PHPUnitPHAR\PhpParser\BuilderHelpers;
7062 use PHPUnitPHAR\PhpParser\Modifiers;
7063 use PHPUnitPHAR\PhpParser\Node;
7064 use PHPUnitPHAR\PhpParser\Node\Stmt;
7065 class TraitUseAdaptation implements Builder
7066 {
7067 private const TYPE_UNDEFINED = 0;
7068 private const TYPE_ALIAS = 1;
7069 private const TYPE_PRECEDENCE = 2;
7070 protected int $type;
7071 protected ?Node\Name $trait;
7072 protected Node\Identifier $method;
7073 protected ?int $modifier = null;
7074 protected ?Node\Identifier $alias = null;
7075 /** @var Node\Name[] */
7076 protected array $insteadof = [];
7077 /**
7078 * Creates a trait use adaptation builder.
7079 *
7080 * @param Node\Name|string|null $trait Name of adapted trait
7081 * @param Node\Identifier|string $method Name of adapted method
7082 */
7083 public function __construct($trait, $method)
7084 {
7085 $this->type = self::TYPE_UNDEFINED;
7086 $this->trait = is_null($trait) ? null : BuilderHelpers::normalizeName($trait);
7087 $this->method = BuilderHelpers::normalizeIdentifier($method);
7088 }
7089 /**
7090 * Sets alias of method.
7091 *
7092 * @param Node\Identifier|string $alias Alias for adapted method
7093 *
7094 * @return $this The builder instance (for fluid interface)
7095 */
7096 public function as($alias)
7097 {
7098 if ($this->type === self::TYPE_UNDEFINED) {
7099 $this->type = self::TYPE_ALIAS;
7100 }
7101 if ($this->type !== self::TYPE_ALIAS) {
7102 throw new \LogicException('Cannot set alias for not alias adaptation buider');
7103 }
7104 $this->alias = BuilderHelpers::normalizeIdentifier($alias);
7105 return $this;
7106 }
7107 /**
7108 * Sets adapted method public.
7109 *
7110 * @return $this The builder instance (for fluid interface)
7111 */
7112 public function makePublic()
7113 {
7114 $this->setModifier(Modifiers::PUBLIC);
7115 return $this;
7116 }
7117 /**
7118 * Sets adapted method protected.
7119 *
7120 * @return $this The builder instance (for fluid interface)
7121 */
7122 public function makeProtected()
7123 {
7124 $this->setModifier(Modifiers::PROTECTED);
7125 return $this;
7126 }
7127 /**
7128 * Sets adapted method private.
7129 *
7130 * @return $this The builder instance (for fluid interface)
7131 */
7132 public function makePrivate()
7133 {
7134 $this->setModifier(Modifiers::PRIVATE);
7135 return $this;
7136 }
7137 /**
7138 * Adds overwritten traits.
7139 *
7140 * @param Node\Name|string ...$traits Traits for overwrite
7141 *
7142 * @return $this The builder instance (for fluid interface)
7143 */
7144 public function insteadof(...$traits)
7145 {
7146 if ($this->type === self::TYPE_UNDEFINED) {
7147 if (is_null($this->trait)) {
7148 throw new \LogicException('Precedence adaptation must have trait');
7149 }
7150 $this->type = self::TYPE_PRECEDENCE;
7151 }
7152 if ($this->type !== self::TYPE_PRECEDENCE) {
7153 throw new \LogicException('Cannot add overwritten traits for not precedence adaptation buider');
7154 }
7155 foreach ($traits as $trait) {
7156 $this->insteadof[] = BuilderHelpers::normalizeName($trait);
7157 }
7158 return $this;
7159 }
7160 protected function setModifier(int $modifier): void
7161 {
7162 if ($this->type === self::TYPE_UNDEFINED) {
7163 $this->type = self::TYPE_ALIAS;
7164 }
7165 if ($this->type !== self::TYPE_ALIAS) {
7166 throw new \LogicException('Cannot set access modifier for not alias adaptation buider');
7167 }
7168 if (is_null($this->modifier)) {
7169 $this->modifier = $modifier;
7170 } else {
7171 throw new \LogicException('Multiple access type modifiers are not allowed');
7172 }
7173 }
7174 /**
7175 * Returns the built node.
7176 *
7177 * @return Node The built node
7178 */
7179 public function getNode(): Node
7180 {
7181 switch ($this->type) {
7182 case self::TYPE_ALIAS:
7183 return new Stmt\TraitUseAdaptation\Alias($this->trait, $this->method, $this->modifier, $this->alias);
7184 case self::TYPE_PRECEDENCE:
7185 return new Stmt\TraitUseAdaptation\Precedence($this->trait, $this->method, $this->insteadof);
7186 default:
7187 throw new \LogicException('Type of adaptation is not defined');
7188 }
7189 }
7190 }
7191 <?php
7192
7193 declare (strict_types=1);
7194 namespace PHPUnitPHAR\PhpParser\Builder;
7195
7196 use PHPUnitPHAR\PhpParser;
7197 use PHPUnitPHAR\PhpParser\BuilderHelpers;
7198 use PHPUnitPHAR\PhpParser\Node;
7199 use PHPUnitPHAR\PhpParser\Node\Stmt;
7200 class Trait_ extends Declaration
7201 {
7202 protected string $name;
7203 /** @var list<Stmt\TraitUse> */
7204 protected array $uses = [];
7205 /** @var list<Stmt\ClassConst> */
7206 protected array $constants = [];
7207 /** @var list<Stmt\Property> */
7208 protected array $properties = [];
7209 /** @var list<Stmt\ClassMethod> */
7210 protected array $methods = [];
7211 /** @var list<Node\AttributeGroup> */
7212 protected array $attributeGroups = [];
7213 /**
7214 * Creates an interface builder.
7215 *
7216 * @param string $name Name of the interface
7217 */
7218 public function __construct(string $name)
7219 {
7220 $this->name = $name;
7221 }
7222 /**
7223 * Adds a statement.
7224 *
7225 * @param Stmt|PhpParser\Builder $stmt The statement to add
7226 *
7227 * @return $this The builder instance (for fluid interface)
7228 */
7229 public function addStmt($stmt)
7230 {
7231 $stmt = BuilderHelpers::normalizeNode($stmt);
7232 if ($stmt instanceof Stmt\Property) {
7233 $this->properties[] = $stmt;
7234 } elseif ($stmt instanceof Stmt\ClassMethod) {
7235 $this->methods[] = $stmt;
7236 } elseif ($stmt instanceof Stmt\TraitUse) {
7237 $this->uses[] = $stmt;
7238 } elseif ($stmt instanceof Stmt\ClassConst) {
7239 $this->constants[] = $stmt;
7240 } else {
7241 throw new \LogicException(sprintf('Unexpected node of type "%s"', $stmt->getType()));
7242 }
7243 return $this;
7244 }
7245 /**
7246 * Adds an attribute group.
7247 *
7248 * @param Node\Attribute|Node\AttributeGroup $attribute
7249 *
7250 * @return $this The builder instance (for fluid interface)
7251 */
7252 public function addAttribute($attribute)
7253 {
7254 $this->attributeGroups[] = BuilderHelpers::normalizeAttribute($attribute);
7255 return $this;
7256 }
7257 /**
7258 * Returns the built trait node.
7259 *
7260 * @return Stmt\Trait_ The built interface node
7261 */
7262 public function getNode(): PhpParser\Node
7263 {
7264 return new Stmt\Trait_($this->name, ['stmts' => array_merge($this->uses, $this->constants, $this->properties, $this->methods), 'attrGroups' => $this->attributeGroups], $this->attributes);
7265 }
7266 }
7267 <?php
7268
7269 declare (strict_types=1);
7270 namespace PHPUnitPHAR\PhpParser\Builder;
7271
7272 use PHPUnitPHAR\PhpParser\Builder;
7273 use PHPUnitPHAR\PhpParser\BuilderHelpers;
7274 use PHPUnitPHAR\PhpParser\Node;
7275 use PHPUnitPHAR\PhpParser\Node\Stmt;
7276 class Use_ implements Builder
7277 {
7278 protected Node\Name $name;
7279 /** @var Stmt\Use_::TYPE_* */
7280 protected int $type;
7281 protected ?string $alias = null;
7282 /**
7283 * Creates a name use (alias) builder.
7284 *
7285 * @param Node\Name|string $name Name of the entity (namespace, class, function, constant) to alias
7286 * @param Stmt\Use_::TYPE_* $type One of the Stmt\Use_::TYPE_* constants
7287 */
7288 public function __construct($name, int $type)
7289 {
7290 $this->name = BuilderHelpers::normalizeName($name);
7291 $this->type = $type;
7292 }
7293 /**
7294 * Sets alias for used name.
7295 *
7296 * @param string $alias Alias to use (last component of full name by default)
7297 *
7298 * @return $this The builder instance (for fluid interface)
7299 */
7300 public function as(string $alias)
7301 {
7302 $this->alias = $alias;
7303 return $this;
7304 }
7305 /**
7306 * Returns the built node.
7307 *
7308 * @return Stmt\Use_ The built node
7309 */
7310 public function getNode(): Node
7311 {
7312 return new Stmt\Use_([new Node\UseItem($this->name, $this->alias)], $this->type);
7313 }
7314 }
7315 <?php
7316
7317 declare (strict_types=1);
7318 namespace PHPUnitPHAR\PhpParser;
7319
7320 use PHPUnitPHAR\PhpParser\Node\Arg;
7321 use PHPUnitPHAR\PhpParser\Node\Expr;
7322 use PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp\Concat;
7323 use PHPUnitPHAR\PhpParser\Node\Identifier;
7324 use PHPUnitPHAR\PhpParser\Node\Name;
7325 use PHPUnitPHAR\PhpParser\Node\Scalar\String_;
7326 use PHPUnitPHAR\PhpParser\Node\Stmt\Use_;
7327 class BuilderFactory
7328 {
7329 /**
7330 * Creates an attribute node.
7331 *
7332 * @param string|Name $name Name of the attribute
7333 * @param array $args Attribute named arguments
7334 */
7335 public function attribute($name, array $args = []): Node\Attribute
7336 {
7337 return new Node\Attribute(BuilderHelpers::normalizeName($name), $this->args($args));
7338 }
7339 /**
7340 * Creates a namespace builder.
7341 *
7342 * @param null|string|Node\Name $name Name of the namespace
7343 *
7344 * @return Builder\Namespace_ The created namespace builder
7345 */
7346 public function namespace($name): Builder\Namespace_
7347 {
7348 return new Builder\Namespace_($name);
7349 }
7350 /**
7351 * Creates a class builder.
7352 *
7353 * @param string $name Name of the class
7354 *
7355 * @return Builder\Class_ The created class builder
7356 */
7357 public function class(string $name): Builder\Class_
7358 {
7359 return new Builder\Class_($name);
7360 }
7361 /**
7362 * Creates an interface builder.
7363 *
7364 * @param string $name Name of the interface
7365 *
7366 * @return Builder\Interface_ The created interface builder
7367 */
7368 public function interface(string $name): Builder\Interface_
7369 {
7370 return new Builder\Interface_($name);
7371 }
7372 /**
7373 * Creates a trait builder.
7374 *
7375 * @param string $name Name of the trait
7376 *
7377 * @return Builder\Trait_ The created trait builder
7378 */
7379 public function trait(string $name): Builder\Trait_
7380 {
7381 return new Builder\Trait_($name);
7382 }
7383 /**
7384 * Creates an enum builder.
7385 *
7386 * @param string $name Name of the enum
7387 *
7388 * @return Builder\Enum_ The created enum builder
7389 */
7390 public function enum(string $name): Builder\Enum_
7391 {
7392 return new Builder\Enum_($name);
7393 }
7394 /**
7395 * Creates a trait use builder.
7396 *
7397 * @param Node\Name|string ...$traits Trait names
7398 *
7399 * @return Builder\TraitUse The created trait use builder
7400 */
7401 public function useTrait(...$traits): Builder\TraitUse
7402 {
7403 return new Builder\TraitUse(...$traits);
7404 }
7405 /**
7406 * Creates a trait use adaptation builder.
7407 *
7408 * @param Node\Name|string|null $trait Trait name
7409 * @param Node\Identifier|string $method Method name
7410 *
7411 * @return Builder\TraitUseAdaptation The created trait use adaptation builder
7412 */
7413 public function traitUseAdaptation($trait, $method = null): Builder\TraitUseAdaptation
7414 {
7415 if ($method === null) {
7416 $method = $trait;
7417 $trait = null;
7418 }
7419 return new Builder\TraitUseAdaptation($trait, $method);
7420 }
7421 /**
7422 * Creates a method builder.
7423 *
7424 * @param string $name Name of the method
7425 *
7426 * @return Builder\Method The created method builder
7427 */
7428 public function method(string $name): Builder\Method
7429 {
7430 return new Builder\Method($name);
7431 }
7432 /**
7433 * Creates a parameter builder.
7434 *
7435 * @param string $name Name of the parameter
7436 *
7437 * @return Builder\Param The created parameter builder
7438 */
7439 public function param(string $name): Builder\Param
7440 {
7441 return new Builder\Param($name);
7442 }
7443 /**
7444 * Creates a property builder.
7445 *
7446 * @param string $name Name of the property
7447 *
7448 * @return Builder\Property The created property builder
7449 */
7450 public function property(string $name): Builder\Property
7451 {
7452 return new Builder\Property($name);
7453 }
7454 /**
7455 * Creates a function builder.
7456 *
7457 * @param string $name Name of the function
7458 *
7459 * @return Builder\Function_ The created function builder
7460 */
7461 public function function(string $name): Builder\Function_
7462 {
7463 return new Builder\Function_($name);
7464 }
7465 /**
7466 * Creates a namespace/class use builder.
7467 *
7468 * @param Node\Name|string $name Name of the entity (namespace or class) to alias
7469 *
7470 * @return Builder\Use_ The created use builder
7471 */
7472 public function use($name): Builder\Use_
7473 {
7474 return new Builder\Use_($name, Use_::TYPE_NORMAL);
7475 }
7476 /**
7477 * Creates a function use builder.
7478 *
7479 * @param Node\Name|string $name Name of the function to alias
7480 *
7481 * @return Builder\Use_ The created use function builder
7482 */
7483 public function useFunction($name): Builder\Use_
7484 {
7485 return new Builder\Use_($name, Use_::TYPE_FUNCTION);
7486 }
7487 /**
7488 * Creates a constant use builder.
7489 *
7490 * @param Node\Name|string $name Name of the const to alias
7491 *
7492 * @return Builder\Use_ The created use const builder
7493 */
7494 public function useConst($name): Builder\Use_
7495 {
7496 return new Builder\Use_($name, Use_::TYPE_CONSTANT);
7497 }
7498 /**
7499 * Creates a class constant builder.
7500 *
7501 * @param string|Identifier $name Name
7502 * @param Node\Expr|bool|null|int|float|string|array $value Value
7503 *
7504 * @return Builder\ClassConst The created use const builder
7505 */
7506 public function classConst($name, $value): Builder\ClassConst
7507 {
7508 return new Builder\ClassConst($name, $value);
7509 }
7510 /**
7511 * Creates an enum case builder.
7512 *
7513 * @param string|Identifier $name Name
7514 *
7515 * @return Builder\EnumCase The created use const builder
7516 */
7517 public function enumCase($name): Builder\EnumCase
7518 {
7519 return new Builder\EnumCase($name);
7520 }
7521 /**
7522 * Creates node a for a literal value.
7523 *
7524 * @param Expr|bool|null|int|float|string|array|\UnitEnum $value $value
7525 */
7526 public function val($value): Expr
7527 {
7528 return BuilderHelpers::normalizeValue($value);
7529 }
7530 /**
7531 * Creates variable node.
7532 *
7533 * @param string|Expr $name Name
7534 */
7535 public function var($name): Expr\Variable
7536 {
7537 if (!\is_string($name) && !$name instanceof Expr) {
7538 throw new \LogicException('Variable name must be string or Expr');
7539 }
7540 return new Expr\Variable($name);
7541 }
7542 /**
7543 * Normalizes an argument list.
7544 *
7545 * Creates Arg nodes for all arguments and converts literal values to expressions.
7546 *
7547 * @param array $args List of arguments to normalize
7548 *
7549 * @return list<Arg>
7550 */
7551 public function args(array $args): array
7552 {
7553 $normalizedArgs = [];
7554 foreach ($args as $key => $arg) {
7555 if (!$arg instanceof Arg) {
7556 $arg = new Arg(BuilderHelpers::normalizeValue($arg));
7557 }
7558 if (\is_string($key)) {
7559 $arg->name = BuilderHelpers::normalizeIdentifier($key);
7560 }
7561 $normalizedArgs[] = $arg;
7562 }
7563 return $normalizedArgs;
7564 }
7565 /**
7566 * Creates a function call node.
7567 *
7568 * @param string|Name|Expr $name Function name
7569 * @param array $args Function arguments
7570 */
7571 public function funcCall($name, array $args = []): Expr\FuncCall
7572 {
7573 return new Expr\FuncCall(BuilderHelpers::normalizeNameOrExpr($name), $this->args($args));
7574 }
7575 /**
7576 * Creates a method call node.
7577 *
7578 * @param Expr $var Variable the method is called on
7579 * @param string|Identifier|Expr $name Method name
7580 * @param array $args Method arguments
7581 */
7582 public function methodCall(Expr $var, $name, array $args = []): Expr\MethodCall
7583 {
7584 return new Expr\MethodCall($var, BuilderHelpers::normalizeIdentifierOrExpr($name), $this->args($args));
7585 }
7586 /**
7587 * Creates a static method call node.
7588 *
7589 * @param string|Name|Expr $class Class name
7590 * @param string|Identifier|Expr $name Method name
7591 * @param array $args Method arguments
7592 */
7593 public function staticCall($class, $name, array $args = []): Expr\StaticCall
7594 {
7595 return new Expr\StaticCall(BuilderHelpers::normalizeNameOrExpr($class), BuilderHelpers::normalizeIdentifierOrExpr($name), $this->args($args));
7596 }
7597 /**
7598 * Creates an object creation node.
7599 *
7600 * @param string|Name|Expr $class Class name
7601 * @param array $args Constructor arguments
7602 */
7603 public function new($class, array $args = []): Expr\New_
7604 {
7605 return new Expr\New_(BuilderHelpers::normalizeNameOrExpr($class), $this->args($args));
7606 }
7607 /**
7608 * Creates a constant fetch node.
7609 *
7610 * @param string|Name $name Constant name
7611 */
7612 public function constFetch($name): Expr\ConstFetch
7613 {
7614 return new Expr\ConstFetch(BuilderHelpers::normalizeName($name));
7615 }
7616 /**
7617 * Creates a property fetch node.
7618 *
7619 * @param Expr $var Variable holding object
7620 * @param string|Identifier|Expr $name Property name
7621 */
7622 public function propertyFetch(Expr $var, $name): Expr\PropertyFetch
7623 {
7624 return new Expr\PropertyFetch($var, BuilderHelpers::normalizeIdentifierOrExpr($name));
7625 }
7626 /**
7627 * Creates a class constant fetch node.
7628 *
7629 * @param string|Name|Expr $class Class name
7630 * @param string|Identifier|Expr $name Constant name
7631 */
7632 public function classConstFetch($class, $name): Expr\ClassConstFetch
7633 {
7634 return new Expr\ClassConstFetch(BuilderHelpers::normalizeNameOrExpr($class), BuilderHelpers::normalizeIdentifierOrExpr($name));
7635 }
7636 /**
7637 * Creates nested Concat nodes from a list of expressions.
7638 *
7639 * @param Expr|string ...$exprs Expressions or literal strings
7640 */
7641 public function concat(...$exprs): Concat
7642 {
7643 $numExprs = count($exprs);
7644 if ($numExprs < 2) {
7645 throw new \LogicException('Expected at least two expressions');
7646 }
7647 $lastConcat = $this->normalizeStringExpr($exprs[0]);
7648 for ($i = 1; $i < $numExprs; $i++) {
7649 $lastConcat = new Concat($lastConcat, $this->normalizeStringExpr($exprs[$i]));
7650 }
7651 return $lastConcat;
7652 }
7653 /**
7654 * @param string|Expr $expr
7655 */
7656 private function normalizeStringExpr($expr): Expr
7657 {
7658 if ($expr instanceof Expr) {
7659 return $expr;
7660 }
7661 if (\is_string($expr)) {
7662 return new String_($expr);
7663 }
7664 throw new \LogicException('Expected string or Expr');
7665 }
7666 }
7667 <?php
7668
7669 declare (strict_types=1);
7670 namespace PHPUnitPHAR\PhpParser;
7671
7672 use PHPUnitPHAR\PhpParser\Node\ComplexType;
7673 use PHPUnitPHAR\PhpParser\Node\Expr;
7674 use PHPUnitPHAR\PhpParser\Node\Identifier;
7675 use PHPUnitPHAR\PhpParser\Node\Name;
7676 use PHPUnitPHAR\PhpParser\Node\Name\FullyQualified;
7677 use PHPUnitPHAR\PhpParser\Node\NullableType;
7678 use PHPUnitPHAR\PhpParser\Node\Scalar;
7679 use PHPUnitPHAR\PhpParser\Node\Stmt;
7680 /**
7681 * This class defines helpers used in the implementation of builders. Don't use it directly.
7682 *
7683 * @internal
7684 */
7685 final class BuilderHelpers
7686 {
7687 /**
7688 * Normalizes a node: Converts builder objects to nodes.
7689 *
7690 * @param Node|Builder $node The node to normalize
7691 *
7692 * @return Node The normalized node
7693 */
7694 public static function normalizeNode($node): Node
7695 {
7696 if ($node instanceof Builder) {
7697 return $node->getNode();
7698 }
7699 if ($node instanceof Node) {
7700 return $node;
7701 }
7702 throw new \LogicException('Expected node or builder object');
7703 }
7704 /**
7705 * Normalizes a node to a statement.
7706 *
7707 * Expressions are wrapped in a Stmt\Expression node.
7708 *
7709 * @param Node|Builder $node The node to normalize
7710 *
7711 * @return Stmt The normalized statement node
7712 */
7713 public static function normalizeStmt($node): Stmt
7714 {
7715 $node = self::normalizeNode($node);
7716 if ($node instanceof Stmt) {
7717 return $node;
7718 }
7719 if ($node instanceof Expr) {
7720 return new Stmt\Expression($node);
7721 }
7722 throw new \LogicException('Expected statement or expression node');
7723 }
7724 /**
7725 * Normalizes strings to Identifier.
7726 *
7727 * @param string|Identifier $name The identifier to normalize
7728 *
7729 * @return Identifier The normalized identifier
7730 */
7731 public static function normalizeIdentifier($name): Identifier
7732 {
7733 if ($name instanceof Identifier) {
7734 return $name;
7735 }
7736 if (\is_string($name)) {
7737 return new Identifier($name);
7738 }
7739 throw new \LogicException('Expected string or instance of Node\Identifier');
7740 }
7741 /**
7742 * Normalizes strings to Identifier, also allowing expressions.
7743 *
7744 * @param string|Identifier|Expr $name The identifier to normalize
7745 *
7746 * @return Identifier|Expr The normalized identifier or expression
7747 */
7748 public static function normalizeIdentifierOrExpr($name)
7749 {
7750 if ($name instanceof Identifier || $name instanceof Expr) {
7751 return $name;
7752 }
7753 if (\is_string($name)) {
7754 return new Identifier($name);
7755 }
7756 throw new \LogicException('Expected string or instance of Node\Identifier or Node\Expr');
7757 }
7758 /**
7759 * Normalizes a name: Converts string names to Name nodes.
7760 *
7761 * @param Name|string $name The name to normalize
7762 *
7763 * @return Name The normalized name
7764 */
7765 public static function normalizeName($name): Name
7766 {
7767 if ($name instanceof Name) {
7768 return $name;
7769 }
7770 if (is_string($name)) {
7771 if (!$name) {
7772 throw new \LogicException('Name cannot be empty');
7773 }
7774 if ($name[0] === '\\') {
7775 return new Name\FullyQualified(substr($name, 1));
7776 }
7777 if (0 === strpos($name, 'namespace\\')) {
7778 return new Name\Relative(substr($name, strlen('namespace\\')));
7779 }
7780 return new Name($name);
7781 }
7782 throw new \LogicException('Name must be a string or an instance of Node\Name');
7783 }
7784 /**
7785 * Normalizes a name: Converts string names to Name nodes, while also allowing expressions.
7786 *
7787 * @param Expr|Name|string $name The name to normalize
7788 *
7789 * @return Name|Expr The normalized name or expression
7790 */
7791 public static function normalizeNameOrExpr($name)
7792 {
7793 if ($name instanceof Expr) {
7794 return $name;
7795 }
7796 if (!is_string($name) && !$name instanceof Name) {
7797 throw new \LogicException('Name must be a string or an instance of Node\Name or Node\Expr');
7798 }
7799 return self::normalizeName($name);
7800 }
7801 /**
7802 * Normalizes a type: Converts plain-text type names into proper AST representation.
7803 *
7804 * In particular, builtin types become Identifiers, custom types become Names and nullables
7805 * are wrapped in NullableType nodes.
7806 *
7807 * @param string|Name|Identifier|ComplexType $type The type to normalize
7808 *
7809 * @return Name|Identifier|ComplexType The normalized type
7810 */
7811 public static function normalizeType($type)
7812 {
7813 if (!is_string($type)) {
7814 if (!$type instanceof Name && !$type instanceof Identifier && !$type instanceof ComplexType) {
7815 throw new \LogicException('Type must be a string, or an instance of Name, Identifier or ComplexType');
7816 }
7817 return $type;
7818 }
7819 $nullable = \false;
7820 if (strlen($type) > 0 && $type[0] === '?') {
7821 $nullable = \true;
7822 $type = substr($type, 1);
7823 }
7824 $builtinTypes = ['array', 'callable', 'bool', 'int', 'float', 'string', 'iterable', 'void', 'object', 'null', 'false', 'mixed', 'never', 'true'];
7825 $lowerType = strtolower($type);
7826 if (in_array($lowerType, $builtinTypes)) {
7827 $type = new Identifier($lowerType);
7828 } else {
7829 $type = self::normalizeName($type);
7830 }
7831 $notNullableTypes = ['void', 'mixed', 'never'];
7832 if ($nullable && in_array((string) $type, $notNullableTypes)) {
7833 throw new \LogicException(sprintf('%s type cannot be nullable', $type));
7834 }
7835 return $nullable ? new NullableType($type) : $type;
7836 }
7837 /**
7838 * Normalizes a value: Converts nulls, booleans, integers,
7839 * floats, strings and arrays into their respective nodes
7840 *
7841 * @param Node\Expr|bool|null|int|float|string|array|\UnitEnum $value The value to normalize
7842 *
7843 * @return Expr The normalized value
7844 */
7845 public static function normalizeValue($value): Expr
7846 {
7847 if ($value instanceof Node\Expr) {
7848 return $value;
7849 }
7850 if (is_null($value)) {
7851 return new Expr\ConstFetch(new Name('null'));
7852 }
7853 if (is_bool($value)) {
7854 return new Expr\ConstFetch(new Name($value ? 'true' : 'false'));
7855 }
7856 if (is_int($value)) {
7857 return new Scalar\Int_($value);
7858 }
7859 if (is_float($value)) {
7860 return new Scalar\Float_($value);
7861 }
7862 if (is_string($value)) {
7863 return new Scalar\String_($value);
7864 }
7865 if (is_array($value)) {
7866 $items = [];
7867 $lastKey = -1;
7868 foreach ($value as $itemKey => $itemValue) {
7869 // for consecutive, numeric keys don't generate keys
7870 if (null !== $lastKey && ++$lastKey === $itemKey) {
7871 $items[] = new Node\ArrayItem(self::normalizeValue($itemValue));
7872 } else {
7873 $lastKey = null;
7874 $items[] = new Node\ArrayItem(self::normalizeValue($itemValue), self::normalizeValue($itemKey));
7875 }
7876 }
7877 return new Expr\Array_($items);
7878 }
7879 if ($value instanceof \UnitEnum) {
7880 return new Expr\ClassConstFetch(new FullyQualified(\get_class($value)), new Identifier($value->name));
7881 }
7882 throw new \LogicException('Invalid value');
7883 }
7884 /**
7885 * Normalizes a doc comment: Converts plain strings to PhpParser\Comment\Doc.
7886 *
7887 * @param Comment\Doc|string $docComment The doc comment to normalize
7888 *
7889 * @return Comment\Doc The normalized doc comment
7890 */
7891 public static function normalizeDocComment($docComment): Comment\Doc
7892 {
7893 if ($docComment instanceof Comment\Doc) {
7894 return $docComment;
7895 }
7896 if (is_string($docComment)) {
7897 return new Comment\Doc($docComment);
7898 }
7899 throw new \LogicException('Doc comment must be a string or an instance of PhpParser\Comment\Doc');
7900 }
7901 /**
7902 * Normalizes a attribute: Converts attribute to the Attribute Group if needed.
7903 *
7904 * @param Node\Attribute|Node\AttributeGroup $attribute
7905 *
7906 * @return Node\AttributeGroup The Attribute Group
7907 */
7908 public static function normalizeAttribute($attribute): Node\AttributeGroup
7909 {
7910 if ($attribute instanceof Node\AttributeGroup) {
7911 return $attribute;
7912 }
7913 if (!$attribute instanceof Node\Attribute) {
7914 throw new \LogicException('Attribute must be an instance of PhpParser\Node\Attribute or PhpParser\Node\AttributeGroup');
7915 }
7916 return new Node\AttributeGroup([$attribute]);
7917 }
7918 /**
7919 * Adds a modifier and returns new modifier bitmask.
7920 *
7921 * @param int $modifiers Existing modifiers
7922 * @param int $modifier Modifier to set
7923 *
7924 * @return int New modifiers
7925 */
7926 public static function addModifier(int $modifiers, int $modifier): int
7927 {
7928 Modifiers::verifyModifier($modifiers, $modifier);
7929 return $modifiers | $modifier;
7930 }
7931 /**
7932 * Adds a modifier and returns new modifier bitmask.
7933 * @return int New modifiers
7934 */
7935 public static function addClassModifier(int $existingModifiers, int $modifierToSet): int
7936 {
7937 Modifiers::verifyClassModifier($existingModifiers, $modifierToSet);
7938 return $existingModifiers | $modifierToSet;
7939 }
7940 }
7941 <?php
7942
7943 declare (strict_types=1);
7944 namespace PHPUnitPHAR\PhpParser;
7945
7946 class Comment implements \JsonSerializable
7947 {
7948 protected string $text;
7949 protected int $startLine;
7950 protected int $startFilePos;
7951 protected int $startTokenPos;
7952 protected int $endLine;
7953 protected int $endFilePos;
7954 protected int $endTokenPos;
7955 /**
7956 * Constructs a comment node.
7957 *
7958 * @param string $text Comment text (including comment delimiters like /*)
7959 * @param int $startLine Line number the comment started on
7960 * @param int $startFilePos File offset the comment started on
7961 * @param int $startTokenPos Token offset the comment started on
7962 */
7963 public function __construct(string $text, int $startLine = -1, int $startFilePos = -1, int $startTokenPos = -1, int $endLine = -1, int $endFilePos = -1, int $endTokenPos = -1)
7964 {
7965 $this->text = $text;
7966 $this->startLine = $startLine;
7967 $this->startFilePos = $startFilePos;
7968 $this->startTokenPos = $startTokenPos;
7969 $this->endLine = $endLine;
7970 $this->endFilePos = $endFilePos;
7971 $this->endTokenPos = $endTokenPos;
7972 }
7973 /**
7974 * Gets the comment text.
7975 *
7976 * @return string The comment text (including comment delimiters like /*)
7977 */
7978 public function getText(): string
7979 {
7980 return $this->text;
7981 }
7982 /**
7983 * Gets the line number the comment started on.
7984 *
7985 * @return int Line number (or -1 if not available)
7986 * @phpstan-return -1|positive-int
7987 */
7988 public function getStartLine(): int
7989 {
7990 return $this->startLine;
7991 }
7992 /**
7993 * Gets the file offset the comment started on.
7994 *
7995 * @return int File offset (or -1 if not available)
7996 */
7997 public function getStartFilePos(): int
7998 {
7999 return $this->startFilePos;
8000 }
8001 /**
8002 * Gets the token offset the comment started on.
8003 *
8004 * @return int Token offset (or -1 if not available)
8005 */
8006 public function getStartTokenPos(): int
8007 {
8008 return $this->startTokenPos;
8009 }
8010 /**
8011 * Gets the line number the comment ends on.
8012 *
8013 * @return int Line number (or -1 if not available)
8014 * @phpstan-return -1|positive-int
8015 */
8016 public function getEndLine(): int
8017 {
8018 return $this->endLine;
8019 }
8020 /**
8021 * Gets the file offset the comment ends on.
8022 *
8023 * @return int File offset (or -1 if not available)
8024 */
8025 public function getEndFilePos(): int
8026 {
8027 return $this->endFilePos;
8028 }
8029 /**
8030 * Gets the token offset the comment ends on.
8031 *
8032 * @return int Token offset (or -1 if not available)
8033 */
8034 public function getEndTokenPos(): int
8035 {
8036 return $this->endTokenPos;
8037 }
8038 /**
8039 * Gets the comment text.
8040 *
8041 * @return string The comment text (including comment delimiters like /*)
8042 */
8043 public function __toString(): string
8044 {
8045 return $this->text;
8046 }
8047 /**
8048 * Gets the reformatted comment text.
8049 *
8050 * "Reformatted" here means that we try to clean up the whitespace at the
8051 * starts of the lines. This is necessary because we receive the comments
8052 * without leading whitespace on the first line, but with leading whitespace
8053 * on all subsequent lines.
8054 *
8055 * Additionally, this normalizes CRLF newlines to LF newlines.
8056 */
8057 public function getReformattedText(): string
8058 {
8059 $text = str_replace("\r\n", "\n", $this->text);
8060 $newlinePos = strpos($text, "\n");
8061 if (\false === $newlinePos) {
8062 // Single line comments don't need further processing
8063 return $text;
8064 }
8065 if (preg_match('(^.*(?:\n\s+\*.*)+$)', $text)) {
8066 // Multi line comment of the type
8067 //
8068 // /*
8069 // * Some text.
8070 // * Some more text.
8071 // */
8072 //
8073 // is handled by replacing the whitespace sequences before the * by a single space
8074 return preg_replace('(^\s+\*)m', ' *', $text);
8075 }
8076 if (preg_match('(^/\*\*?\s*\n)', $text) && preg_match('(\n(\s*)\*/$)', $text, $matches)) {
8077 // Multi line comment of the type
8078 //
8079 // /*
8080 // Some text.
8081 // Some more text.
8082 // */
8083 //
8084 // is handled by removing the whitespace sequence on the line before the closing
8085 // */ on all lines. So if the last line is " */", then " " is removed at the
8086 // start of all lines.
8087 return preg_replace('(^' . preg_quote($matches[1]) . ')m', '', $text);
8088 }
8089 if (preg_match('(^/\*\*?\s*(?!\s))', $text, $matches)) {
8090 // Multi line comment of the type
8091 //
8092 // /* Some text.
8093 // Some more text.
8094 // Indented text.
8095 // Even more text. */
8096 //
8097 // is handled by removing the difference between the shortest whitespace prefix on all
8098 // lines and the length of the "/* " opening sequence.
8099 $prefixLen = $this->getShortestWhitespacePrefixLen(substr($text, $newlinePos + 1));
8100 $removeLen = $prefixLen - strlen($matches[0]);
8101 return preg_replace('(^\s{' . $removeLen . '})m', '', $text);
8102 }
8103 // No idea how to format this comment, so simply return as is
8104 return $text;
8105 }
8106 /**
8107 * Get length of shortest whitespace prefix (at the start of a line).
8108 *
8109 * If there is a line with no prefix whitespace, 0 is a valid return value.
8110 *
8111 * @param string $str String to check
8112 * @return int Length in characters. Tabs count as single characters.
8113 */
8114 private function getShortestWhitespacePrefixLen(string $str): int
8115 {
8116 $lines = explode("\n", $str);
8117 $shortestPrefixLen = \PHP_INT_MAX;
8118 foreach ($lines as $line) {
8119 preg_match('(^\s*)', $line, $matches);
8120 $prefixLen = strlen($matches[0]);
8121 if ($prefixLen < $shortestPrefixLen) {
8122 $shortestPrefixLen = $prefixLen;
8123 }
8124 }
8125 return $shortestPrefixLen;
8126 }
8127 /**
8128 * @return array{nodeType:string, text:mixed, line:mixed, filePos:mixed}
8129 */
8130 public function jsonSerialize(): array
8131 {
8132 // Technically not a node, but we make it look like one anyway
8133 $type = $this instanceof Comment\Doc ? 'Comment_Doc' : 'Comment';
8134 return [
8135 'nodeType' => $type,
8136 'text' => $this->text,
8137 // TODO: Rename these to include "start".
8138 'line' => $this->startLine,
8139 'filePos' => $this->startFilePos,
8140 'tokenPos' => $this->startTokenPos,
8141 'endLine' => $this->endLine,
8142 'endFilePos' => $this->endFilePos,
8143 'endTokenPos' => $this->endTokenPos,
8144 ];
8145 }
8146 }
8147 <?php
8148
8149 declare (strict_types=1);
8150 namespace PHPUnitPHAR\PhpParser\Comment;
8151
8152 class Doc extends \PHPUnitPHAR\PhpParser\Comment
8153 {
8154 }
8155 <?php
8156
8157 declare (strict_types=1);
8158 namespace PHPUnitPHAR\PhpParser;
8159
8160 class ConstExprEvaluationException extends \Exception
8161 {
8162 }
8163 <?php
8164
8165 declare (strict_types=1);
8166 namespace PHPUnitPHAR\PhpParser;
8167
8168 use PHPUnitPHAR\PhpParser\Node\Expr;
8169 use PHPUnitPHAR\PhpParser\Node\Scalar;
8170 use function array_merge;
8171 /**
8172 * Evaluates constant expressions.
8173 *
8174 * This evaluator is able to evaluate all constant expressions (as defined by PHP), which can be
8175 * evaluated without further context. If a subexpression is not of this type, a user-provided
8176 * fallback evaluator is invoked. To support all constant expressions that are also supported by
8177 * PHP (and not already handled by this class), the fallback evaluator must be able to handle the
8178 * following node types:
8179 *
8180 * * All Scalar\MagicConst\* nodes.
8181 * * Expr\ConstFetch nodes. Only null/false/true are already handled by this class.
8182 * * Expr\ClassConstFetch nodes.
8183 *
8184 * The fallback evaluator should throw ConstExprEvaluationException for nodes it cannot evaluate.
8185 *
8186 * The evaluation is dependent on runtime configuration in two respects: Firstly, floating
8187 * point to string conversions are affected by the precision ini setting. Secondly, they are also
8188 * affected by the LC_NUMERIC locale.
8189 */
8190 class ConstExprEvaluator
8191 {
8192 /** @var callable|null */
8193 private $fallbackEvaluator;
8194 /**
8195 * Create a constant expression evaluator.
8196 *
8197 * The provided fallback evaluator is invoked whenever a subexpression cannot be evaluated. See
8198 * class doc comment for more information.
8199 *
8200 * @param callable|null $fallbackEvaluator To call if subexpression cannot be evaluated
8201 */
8202 public function __construct(?callable $fallbackEvaluator = null)
8203 {
8204 $this->fallbackEvaluator = $fallbackEvaluator ?? function (Expr $expr) {
8205 throw new ConstExprEvaluationException("Expression of type {$expr->getType()} cannot be evaluated");
8206 };
8207 }
8208 /**
8209 * Silently evaluates a constant expression into a PHP value.
8210 *
8211 * Thrown Errors, warnings or notices will be converted into a ConstExprEvaluationException.
8212 * The original source of the exception is available through getPrevious().
8213 *
8214 * If some part of the expression cannot be evaluated, the fallback evaluator passed to the
8215 * constructor will be invoked. By default, if no fallback is provided, an exception of type
8216 * ConstExprEvaluationException is thrown.
8217 *
8218 * See class doc comment for caveats and limitations.
8219 *
8220 * @param Expr $expr Constant expression to evaluate
8221 * @return mixed Result of evaluation
8222 *
8223 * @throws ConstExprEvaluationException if the expression cannot be evaluated or an error occurred
8224 */
8225 public function evaluateSilently(Expr $expr)
8226 {
8227 set_error_handler(function ($num, $str, $file, $line) {
8228 throw new \ErrorException($str, 0, $num, $file, $line);
8229 });
8230 try {
8231 return $this->evaluate($expr);
8232 } catch (\Throwable $e) {
8233 if (!$e instanceof ConstExprEvaluationException) {
8234 $e = new ConstExprEvaluationException("An error occurred during constant expression evaluation", 0, $e);
8235 }
8236 throw $e;
8237 } finally {
8238 restore_error_handler();
8239 }
8240 }
8241 /**
8242 * Directly evaluates a constant expression into a PHP value.
8243 *
8244 * May generate Error exceptions, warnings or notices. Use evaluateSilently() to convert these
8245 * into a ConstExprEvaluationException.
8246 *
8247 * If some part of the expression cannot be evaluated, the fallback evaluator passed to the
8248 * constructor will be invoked. By default, if no fallback is provided, an exception of type
8249 * ConstExprEvaluationException is thrown.
8250 *
8251 * See class doc comment for caveats and limitations.
8252 *
8253 * @param Expr $expr Constant expression to evaluate
8254 * @return mixed Result of evaluation
8255 *
8256 * @throws ConstExprEvaluationException if the expression cannot be evaluated
8257 */
8258 public function evaluateDirectly(Expr $expr)
8259 {
8260 return $this->evaluate($expr);
8261 }
8262 /** @return mixed */
8263 private function evaluate(Expr $expr)
8264 {
8265 if ($expr instanceof Scalar\Int_ || $expr instanceof Scalar\Float_ || $expr instanceof Scalar\String_) {
8266 return $expr->value;
8267 }
8268 if ($expr instanceof Expr\Array_) {
8269 return $this->evaluateArray($expr);
8270 }
8271 // Unary operators
8272 if ($expr instanceof Expr\UnaryPlus) {
8273 return +$this->evaluate($expr->expr);
8274 }
8275 if ($expr instanceof Expr\UnaryMinus) {
8276 return -$this->evaluate($expr->expr);
8277 }
8278 if ($expr instanceof Expr\BooleanNot) {
8279 return !$this->evaluate($expr->expr);
8280 }
8281 if ($expr instanceof Expr\BitwiseNot) {
8282 return ~$this->evaluate($expr->expr);
8283 }
8284 if ($expr instanceof Expr\BinaryOp) {
8285 return $this->evaluateBinaryOp($expr);
8286 }
8287 if ($expr instanceof Expr\Ternary) {
8288 return $this->evaluateTernary($expr);
8289 }
8290 if ($expr instanceof Expr\ArrayDimFetch && null !== $expr->dim) {
8291 return $this->evaluate($expr->var)[$this->evaluate($expr->dim)];
8292 }
8293 if ($expr instanceof Expr\ConstFetch) {
8294 return $this->evaluateConstFetch($expr);
8295 }
8296 return ($this->fallbackEvaluator)($expr);
8297 }
8298 private function evaluateArray(Expr\Array_ $expr): array
8299 {
8300 $array = [];
8301 foreach ($expr->items as $item) {
8302 if (null !== $item->key) {
8303 $array[$this->evaluate($item->key)] = $this->evaluate($item->value);
8304 } elseif ($item->unpack) {
8305 $array = array_merge($array, $this->evaluate($item->value));
8306 } else {
8307 $array[] = $this->evaluate($item->value);
8308 }
8309 }
8310 return $array;
8311 }
8312 /** @return mixed */
8313 private function evaluateTernary(Expr\Ternary $expr)
8314 {
8315 if (null === $expr->if) {
8316 return $this->evaluate($expr->cond) ?: $this->evaluate($expr->else);
8317 }
8318 return $this->evaluate($expr->cond) ? $this->evaluate($expr->if) : $this->evaluate($expr->else);
8319 }
8320 /** @return mixed */
8321 private function evaluateBinaryOp(Expr\BinaryOp $expr)
8322 {
8323 if ($expr instanceof Expr\BinaryOp\Coalesce && $expr->left instanceof Expr\ArrayDimFetch) {
8324 // This needs to be special cased to respect BP_VAR_IS fetch semantics
8325 return $this->evaluate($expr->left->var)[$this->evaluate($expr->left->dim)] ?? $this->evaluate($expr->right);
8326 }
8327 // The evaluate() calls are repeated in each branch, because some of the operators are
8328 // short-circuiting and evaluating the RHS in advance may be illegal in that case
8329 $l = $expr->left;
8330 $r = $expr->right;
8331 switch ($expr->getOperatorSigil()) {
8332 case '&':
8333 return $this->evaluate($l) & $this->evaluate($r);
8334 case '|':
8335 return $this->evaluate($l) | $this->evaluate($r);
8336 case '^':
8337 return $this->evaluate($l) ^ $this->evaluate($r);
8338 case '&&':
8339 return $this->evaluate($l) && $this->evaluate($r);
8340 case '||':
8341 return $this->evaluate($l) || $this->evaluate($r);
8342 case '??':
8343 return $this->evaluate($l) ?? $this->evaluate($r);
8344 case '.':
8345 return $this->evaluate($l) . $this->evaluate($r);
8346 case '/':
8347 return $this->evaluate($l) / $this->evaluate($r);
8348 case '==':
8349 return $this->evaluate($l) == $this->evaluate($r);
8350 case '>':
8351 return $this->evaluate($l) > $this->evaluate($r);
8352 case '>=':
8353 return $this->evaluate($l) >= $this->evaluate($r);
8354 case '===':
8355 return $this->evaluate($l) === $this->evaluate($r);
8356 case 'and':
8357 return $this->evaluate($l) and $this->evaluate($r);
8358 case 'or':
8359 return $this->evaluate($l) or $this->evaluate($r);
8360 case 'xor':
8361 return $this->evaluate($l) xor $this->evaluate($r);
8362 case '-':
8363 return $this->evaluate($l) - $this->evaluate($r);
8364 case '%':
8365 return $this->evaluate($l) % $this->evaluate($r);
8366 case '*':
8367 return $this->evaluate($l) * $this->evaluate($r);
8368 case '!=':
8369 return $this->evaluate($l) != $this->evaluate($r);
8370 case '!==':
8371 return $this->evaluate($l) !== $this->evaluate($r);
8372 case '+':
8373 return $this->evaluate($l) + $this->evaluate($r);
8374 case '**':
8375 return $this->evaluate($l) ** $this->evaluate($r);
8376 case '<<':
8377 return $this->evaluate($l) << $this->evaluate($r);
8378 case '>>':
8379 return $this->evaluate($l) >> $this->evaluate($r);
8380 case '<':
8381 return $this->evaluate($l) < $this->evaluate($r);
8382 case '<=':
8383 return $this->evaluate($l) <= $this->evaluate($r);
8384 case '<=>':
8385 return $this->evaluate($l) <=> $this->evaluate($r);
8386 case '|>':
8387 $lval = $this->evaluate($l);
8388 return $this->evaluate($r)($lval);
8389 }
8390 throw new \Exception('Should not happen');
8391 }
8392 /** @return mixed */
8393 private function evaluateConstFetch(Expr\ConstFetch $expr)
8394 {
8395 $name = $expr->name->toLowerString();
8396 switch ($name) {
8397 case 'null':
8398 return null;
8399 case 'false':
8400 return \false;
8401 case 'true':
8402 return \true;
8403 }
8404 return ($this->fallbackEvaluator)($expr);
8405 }
8406 }
8407 <?php
8408
8409 declare (strict_types=1);
8410 namespace PHPUnitPHAR\PhpParser;
8411
8412 class Error extends \RuntimeException
8413 {
8414 protected string $rawMessage;
8415 /** @var array<string, mixed> */
8416 protected array $attributes;
8417 /**
8418 * Creates an Exception signifying a parse error.
8419 *
8420 * @param string $message Error message
8421 * @param array<string, mixed> $attributes Attributes of node/token where error occurred
8422 */
8423 public function __construct(string $message, array $attributes = [])
8424 {
8425 $this->rawMessage = $message;
8426 $this->attributes = $attributes;
8427 $this->updateMessage();
8428 }
8429 /**
8430 * Gets the error message
8431 *
8432 * @return string Error message
8433 */
8434 public function getRawMessage(): string
8435 {
8436 return $this->rawMessage;
8437 }
8438 /**
8439 * Gets the line the error starts in.
8440 *
8441 * @return int Error start line
8442 * @phpstan-return -1|positive-int
8443 */
8444 public function getStartLine(): int
8445 {
8446 return $this->attributes['startLine'] ?? -1;
8447 }
8448 /**
8449 * Gets the line the error ends in.
8450 *
8451 * @return int Error end line
8452 * @phpstan-return -1|positive-int
8453 */
8454 public function getEndLine(): int
8455 {
8456 return $this->attributes['endLine'] ?? -1;
8457 }
8458 /**
8459 * Gets the attributes of the node/token the error occurred at.
8460 *
8461 * @return array<string, mixed>
8462 */
8463 public function getAttributes(): array
8464 {
8465 return $this->attributes;
8466 }
8467 /**
8468 * Sets the attributes of the node/token the error occurred at.
8469 *
8470 * @param array<string, mixed> $attributes
8471 */
8472 public function setAttributes(array $attributes): void
8473 {
8474 $this->attributes = $attributes;
8475 $this->updateMessage();
8476 }
8477 /**
8478 * Sets the line of the PHP file the error occurred in.
8479 *
8480 * @param string $message Error message
8481 */
8482 public function setRawMessage(string $message): void
8483 {
8484 $this->rawMessage = $message;
8485 $this->updateMessage();
8486 }
8487 /**
8488 * Sets the line the error starts in.
8489 *
8490 * @param int $line Error start line
8491 */
8492 public function setStartLine(int $line): void
8493 {
8494 $this->attributes['startLine'] = $line;
8495 $this->updateMessage();
8496 }
8497 /**
8498 * Returns whether the error has start and end column information.
8499 *
8500 * For column information enable the startFilePos and endFilePos in the lexer options.
8501 */
8502 public function hasColumnInfo(): bool
8503 {
8504 return isset($this->attributes['startFilePos'], $this->attributes['endFilePos']);
8505 }
8506 /**
8507 * Gets the start column (1-based) into the line where the error started.
8508 *
8509 * @param string $code Source code of the file
8510 */
8511 public function getStartColumn(string $code): int
8512 {
8513 if (!$this->hasColumnInfo()) {
8514 throw new \RuntimeException('Error does not have column information');
8515 }
8516 return $this->toColumn($code, $this->attributes['startFilePos']);
8517 }
8518 /**
8519 * Gets the end column (1-based) into the line where the error ended.
8520 *
8521 * @param string $code Source code of the file
8522 */
8523 public function getEndColumn(string $code): int
8524 {
8525 if (!$this->hasColumnInfo()) {
8526 throw new \RuntimeException('Error does not have column information');
8527 }
8528 return $this->toColumn($code, $this->attributes['endFilePos']);
8529 }
8530 /**
8531 * Formats message including line and column information.
8532 *
8533 * @param string $code Source code associated with the error, for calculation of the columns
8534 *
8535 * @return string Formatted message
8536 */
8537 public function getMessageWithColumnInfo(string $code): string
8538 {
8539 return sprintf('%s from %d:%d to %d:%d', $this->getRawMessage(), $this->getStartLine(), $this->getStartColumn($code), $this->getEndLine(), $this->getEndColumn($code));
8540 }
8541 /**
8542 * Converts a file offset into a column.
8543 *
8544 * @param string $code Source code that $pos indexes into
8545 * @param int $pos 0-based position in $code
8546 *
8547 * @return int 1-based column (relative to start of line)
8548 */
8549 private function toColumn(string $code, int $pos): int
8550 {
8551 if ($pos > strlen($code)) {
8552 throw new \RuntimeException('Invalid position information');
8553 }
8554 $lineStartPos = strrpos($code, "\n", $pos - strlen($code));
8555 if (\false === $lineStartPos) {
8556 $lineStartPos = -1;
8557 }
8558 return $pos - $lineStartPos;
8559 }
8560 /**
8561 * Updates the exception message after a change to rawMessage or rawLine.
8562 */
8563 protected function updateMessage(): void
8564 {
8565 $this->message = $this->rawMessage;
8566 if (-1 === $this->getStartLine()) {
8567 $this->message .= ' on unknown line';
8568 } else {
8569 $this->message .= ' on line ' . $this->getStartLine();
8570 }
8571 }
8572 }
8573 <?php
8574
8575 declare (strict_types=1);
8576 namespace PHPUnitPHAR\PhpParser;
8577
8578 interface ErrorHandler
8579 {
8580 /**
8581 * Handle an error generated during lexing, parsing or some other operation.
8582 *
8583 * @param Error $error The error that needs to be handled
8584 */
8585 public function handleError(Error $error): void;
8586 }
8587 <?php
8588
8589 declare (strict_types=1);
8590 namespace PHPUnitPHAR\PhpParser\ErrorHandler;
8591
8592 use PHPUnitPHAR\PhpParser\Error;
8593 use PHPUnitPHAR\PhpParser\ErrorHandler;
8594 /**
8595 * Error handler that collects all errors into an array.
8596 *
8597 * This allows graceful handling of errors.
8598 */
8599 class Collecting implements ErrorHandler
8600 {
8601 /** @var Error[] Collected errors */
8602 private array $errors = [];
8603 public function handleError(Error $error): void
8604 {
8605 $this->errors[] = $error;
8606 }
8607 /**
8608 * Get collected errors.
8609 *
8610 * @return Error[]
8611 */
8612 public function getErrors(): array
8613 {
8614 return $this->errors;
8615 }
8616 /**
8617 * Check whether there are any errors.
8618 */
8619 public function hasErrors(): bool
8620 {
8621 return !empty($this->errors);
8622 }
8623 /**
8624 * Reset/clear collected errors.
8625 */
8626 public function clearErrors(): void
8627 {
8628 $this->errors = [];
8629 }
8630 }
8631 <?php
8632
8633 declare (strict_types=1);
8634 namespace PHPUnitPHAR\PhpParser\ErrorHandler;
8635
8636 use PHPUnitPHAR\PhpParser\Error;
8637 use PHPUnitPHAR\PhpParser\ErrorHandler;
8638 /**
8639 * Error handler that handles all errors by throwing them.
8640 *
8641 * This is the default strategy used by all components.
8642 */
8643 class Throwing implements ErrorHandler
8644 {
8645 public function handleError(Error $error): void
8646 {
8647 throw $error;
8648 }
8649 }
8650 <?php
8651
8652 declare (strict_types=1);
8653 namespace PHPUnitPHAR\PhpParser\Internal;
8654
8655 /**
8656 * @internal
8657 */
8658 class DiffElem
8659 {
8660 public const TYPE_KEEP = 0;
8661 public const TYPE_REMOVE = 1;
8662 public const TYPE_ADD = 2;
8663 public const TYPE_REPLACE = 3;
8664 /** @var int One of the TYPE_* constants */
8665 public int $type;
8666 /** @var mixed Is null for add operations */
8667 public $old;
8668 /** @var mixed Is null for remove operations */
8669 public $new;
8670 /**
8671 * @param int $type One of the TYPE_* constants
8672 * @param mixed $old Is null for add operations
8673 * @param mixed $new Is null for remove operations
8674 */
8675 public function __construct(int $type, $old, $new)
8676 {
8677 $this->type = $type;
8678 $this->old = $old;
8679 $this->new = $new;
8680 }
8681 }
8682 <?php
8683
8684 declare (strict_types=1);
8685 namespace PHPUnitPHAR\PhpParser\Internal;
8686
8687 /**
8688 * Implements the Myers diff algorithm.
8689 *
8690 * Myers, Eugene W. "An O (ND) difference algorithm and its variations."
8691 * Algorithmica 1.1 (1986): 251-266.
8692 *
8693 * @template T
8694 * @internal
8695 */
8696 class Differ
8697 {
8698 /** @var callable(T, T): bool */
8699 private $isEqual;
8700 /**
8701 * Create differ over the given equality relation.
8702 *
8703 * @param callable(T, T): bool $isEqual Equality relation
8704 */
8705 public function __construct(callable $isEqual)
8706 {
8707 $this->isEqual = $isEqual;
8708 }
8709 /**
8710 * Calculate diff (edit script) from $old to $new.
8711 *
8712 * @param T[] $old Original array
8713 * @param T[] $new New array
8714 *
8715 * @return DiffElem[] Diff (edit script)
8716 */
8717 public function diff(array $old, array $new): array
8718 {
8719 $old = \array_values($old);
8720 $new = \array_values($new);
8721 list($trace, $x, $y) = $this->calculateTrace($old, $new);
8722 return $this->extractDiff($trace, $x, $y, $old, $new);
8723 }
8724 /**
8725 * Calculate diff, including "replace" operations.
8726 *
8727 * If a sequence of remove operations is followed by the same number of add operations, these
8728 * will be coalesced into replace operations.
8729 *
8730 * @param T[] $old Original array
8731 * @param T[] $new New array
8732 *
8733 * @return DiffElem[] Diff (edit script), including replace operations
8734 */
8735 public function diffWithReplacements(array $old, array $new): array
8736 {
8737 return $this->coalesceReplacements($this->diff($old, $new));
8738 }
8739 /**
8740 * @param T[] $old
8741 * @param T[] $new
8742 * @return array{array<int, array<int, int>>, int, int}
8743 */
8744 private function calculateTrace(array $old, array $new): array
8745 {
8746 $n = \count($old);
8747 $m = \count($new);
8748 $max = $n + $m;
8749 $v = [1 => 0];
8750 $trace = [];
8751 for ($d = 0; $d <= $max; $d++) {
8752 $trace[] = $v;
8753 for ($k = -$d; $k <= $d; $k += 2) {
8754 if ($k === -$d || $k !== $d && $v[$k - 1] < $v[$k + 1]) {
8755 $x = $v[$k + 1];
8756 } else {
8757 $x = $v[$k - 1] + 1;
8758 }
8759 $y = $x - $k;
8760 while ($x < $n && $y < $m && ($this->isEqual)($old[$x], $new[$y])) {
8761 $x++;
8762 $y++;
8763 }
8764 $v[$k] = $x;
8765 if ($x >= $n && $y >= $m) {
8766 return [$trace, $x, $y];
8767 }
8768 }
8769 }
8770 throw new \Exception('Should not happen');
8771 }
8772 /**
8773 * @param array<int, array<int, int>> $trace
8774 * @param T[] $old
8775 * @param T[] $new
8776 * @return DiffElem[]
8777 */
8778 private function extractDiff(array $trace, int $x, int $y, array $old, array $new): array
8779 {
8780 $result = [];
8781 for ($d = \count($trace) - 1; $d >= 0; $d--) {
8782 $v = $trace[$d];
8783 $k = $x - $y;
8784 if ($k === -$d || $k !== $d && $v[$k - 1] < $v[$k + 1]) {
8785 $prevK = $k + 1;
8786 } else {
8787 $prevK = $k - 1;
8788 }
8789 $prevX = $v[$prevK];
8790 $prevY = $prevX - $prevK;
8791 while ($x > $prevX && $y > $prevY) {
8792 $result[] = new DiffElem(DiffElem::TYPE_KEEP, $old[$x - 1], $new[$y - 1]);
8793 $x--;
8794 $y--;
8795 }
8796 if ($d === 0) {
8797 break;
8798 }
8799 while ($x > $prevX) {
8800 $result[] = new DiffElem(DiffElem::TYPE_REMOVE, $old[$x - 1], null);
8801 $x--;
8802 }
8803 while ($y > $prevY) {
8804 $result[] = new DiffElem(DiffElem::TYPE_ADD, null, $new[$y - 1]);
8805 $y--;
8806 }
8807 }
8808 return array_reverse($result);
8809 }
8810 /**
8811 * Coalesce equal-length sequences of remove+add into a replace operation.
8812 *
8813 * @param DiffElem[] $diff
8814 * @return DiffElem[]
8815 */
8816 private function coalesceReplacements(array $diff): array
8817 {
8818 $newDiff = [];
8819 $c = \count($diff);
8820 for ($i = 0; $i < $c; $i++) {
8821 $diffType = $diff[$i]->type;
8822 if ($diffType !== DiffElem::TYPE_REMOVE) {
8823 $newDiff[] = $diff[$i];
8824 continue;
8825 }
8826 $j = $i;
8827 while ($j < $c && $diff[$j]->type === DiffElem::TYPE_REMOVE) {
8828 $j++;
8829 }
8830 $k = $j;
8831 while ($k < $c && $diff[$k]->type === DiffElem::TYPE_ADD) {
8832 $k++;
8833 }
8834 if ($j - $i === $k - $j) {
8835 $len = $j - $i;
8836 for ($n = 0; $n < $len; $n++) {
8837 $newDiff[] = new DiffElem(DiffElem::TYPE_REPLACE, $diff[$i + $n]->old, $diff[$j + $n]->new);
8838 }
8839 } else {
8840 for (; $i < $k; $i++) {
8841 $newDiff[] = $diff[$i];
8842 }
8843 }
8844 $i = $k - 1;
8845 }
8846 return $newDiff;
8847 }
8848 }
8849 <?php
8850
8851 declare (strict_types=1);
8852 namespace PHPUnitPHAR\PhpParser\Internal;
8853
8854 use PHPUnitPHAR\PhpParser\Node;
8855 use PHPUnitPHAR\PhpParser\Node\Expr;
8856 /**
8857 * This node is used internally by the format-preserving pretty printer to print anonymous classes.
8858 *
8859 * The normal anonymous class structure violates assumptions about the order of token offsets.
8860 * Namely, the constructor arguments are part of the Expr\New_ node and follow the class node, even
8861 * though they are actually interleaved with them. This special node type is used temporarily to
8862 * restore a sane token offset order.
8863 *
8864 * @internal
8865 */
8866 class PrintableNewAnonClassNode extends Expr
8867 {
8868 /** @var Node\AttributeGroup[] PHP attribute groups */
8869 public array $attrGroups;
8870 /** @var int Modifiers */
8871 public int $flags;
8872 /** @var (Node\Arg|Node\VariadicPlaceholder)[] Arguments */
8873 public array $args;
8874 /** @var null|Node\Name Name of extended class */
8875 public ?Node\Name $extends;
8876 /** @var Node\Name[] Names of implemented interfaces */
8877 public array $implements;
8878 /** @var Node\Stmt[] Statements */
8879 public array $stmts;
8880 /**
8881 * @param Node\AttributeGroup[] $attrGroups PHP attribute groups
8882 * @param (Node\Arg|Node\VariadicPlaceholder)[] $args Arguments
8883 * @param Node\Name|null $extends Name of extended class
8884 * @param Node\Name[] $implements Names of implemented interfaces
8885 * @param Node\Stmt[] $stmts Statements
8886 * @param array<string, mixed> $attributes Attributes
8887 */
8888 public function __construct(array $attrGroups, int $flags, array $args, ?Node\Name $extends, array $implements, array $stmts, array $attributes)
8889 {
8890 parent::__construct($attributes);
8891 $this->attrGroups = $attrGroups;
8892 $this->flags = $flags;
8893 $this->args = $args;
8894 $this->extends = $extends;
8895 $this->implements = $implements;
8896 $this->stmts = $stmts;
8897 }
8898 public static function fromNewNode(Expr\New_ $newNode): self
8899 {
8900 $class = $newNode->class;
8901 assert($class instanceof Node\Stmt\Class_);
8902 // We don't assert that $class->name is null here, to allow consumers to assign unique names
8903 // to anonymous classes for their own purposes. We simplify ignore the name here.
8904 return new self($class->attrGroups, $class->flags, $newNode->args, $class->extends, $class->implements, $class->stmts, $newNode->getAttributes());
8905 }
8906 public function getType(): string
8907 {
8908 return 'Expr_PrintableNewAnonClass';
8909 }
8910 public function getSubNodeNames(): array
8911 {
8912 return ['attrGroups', 'flags', 'args', 'extends', 'implements', 'stmts'];
8913 }
8914 }
8915 <?php
8916
8917 declare (strict_types=1);
8918 namespace PHPUnitPHAR\PhpParser\Internal;
8919
8920 if (\PHP_VERSION_ID >= 80000) {
8921 class TokenPolyfill extends \PhpToken
8922 {
8923 }
8924 return;
8925 }
8926 /**
8927 * This is a polyfill for the PhpToken class introduced in PHP 8.0. We do not actually polyfill
8928 * PhpToken, because composer might end up picking a different polyfill implementation, which does
8929 * not meet our requirements.
8930 *
8931 * @internal
8932 */
8933 class TokenPolyfill
8934 {
8935 /** @var int The ID of the token. Either a T_* constant of a character code < 256. */
8936 public int $id;
8937 /** @var string The textual content of the token. */
8938 public string $text;
8939 /** @var int The 1-based starting line of the token (or -1 if unknown). */
8940 public int $line;
8941 /** @var int The 0-based starting position of the token (or -1 if unknown). */
8942 public int $pos;
8943 /** @var array<int, bool> Tokens ignored by the PHP parser. */
8944 private const IGNORABLE_TOKENS = [\T_WHITESPACE => \true, \T_COMMENT => \true, \T_DOC_COMMENT => \true, \T_OPEN_TAG => \true];
8945 /** @var array<int, bool> Tokens that may be part of a T_NAME_* identifier. */
8946 private static array $identifierTokens;
8947 /**
8948 * Create a Token with the given ID and text, as well optional line and position information.
8949 */
8950 final public function __construct(int $id, string $text, int $line = -1, int $pos = -1)
8951 {
8952 $this->id = $id;
8953 $this->text = $text;
8954 $this->line = $line;
8955 $this->pos = $pos;
8956 }
8957 /**
8958 * Get the name of the token. For single-char tokens this will be the token character.
8959 * Otherwise it will be a T_* style name, or null if the token ID is unknown.
8960 */
8961 public function getTokenName(): ?string
8962 {
8963 if ($this->id < 256) {
8964 return \chr($this->id);
8965 }
8966 $name = token_name($this->id);
8967 return $name === 'UNKNOWN' ? null : $name;
8968 }
8969 /**
8970 * Check whether the token is of the given kind. The kind may be either an integer that matches
8971 * the token ID, a string that matches the token text, or an array of integers/strings. In the
8972 * latter case, the function returns true if any of the kinds in the array match.
8973 *
8974 * @param int|string|(int|string)[] $kind
8975 */
8976 public function is($kind): bool
8977 {
8978 if (\is_int($kind)) {
8979 return $this->id === $kind;
8980 }
8981 if (\is_string($kind)) {
8982 return $this->text === $kind;
8983 }
8984 if (\is_array($kind)) {
8985 foreach ($kind as $entry) {
8986 if (\is_int($entry)) {
8987 if ($this->id === $entry) {
8988 return \true;
8989 }
8990 } elseif (\is_string($entry)) {
8991 if ($this->text === $entry) {
8992 return \true;
8993 }
8994 } else {
8995 throw new \TypeError('Argument #1 ($kind) must only have elements of type string|int, ' . gettype($entry) . ' given');
8996 }
8997 }
8998 return \false;
8999 }
9000 throw new \TypeError('Argument #1 ($kind) must be of type string|int|array, ' . gettype($kind) . ' given');
9001 }
9002 /**
9003 * Check whether this token would be ignored by the PHP parser. Returns true for T_WHITESPACE,
9004 * T_COMMENT, T_DOC_COMMENT and T_OPEN_TAG, and false for everything else.
9005 */
9006 public function isIgnorable(): bool
9007 {
9008 return isset(self::IGNORABLE_TOKENS[$this->id]);
9009 }
9010 /**
9011 * Return the textual content of the token.
9012 */
9013 public function __toString(): string
9014 {
9015 return $this->text;
9016 }
9017 /**
9018 * Tokenize the given source code and return an array of tokens.
9019 *
9020 * This performs certain canonicalizations to match the PHP 8.0 token format:
9021 * * Bad characters are represented using T_BAD_CHARACTER rather than omitted.
9022 * * T_COMMENT does not include trailing newlines, instead the newline is part of a following
9023 * T_WHITESPACE token.
9024 * * Namespaced names are represented using T_NAME_* tokens.
9025 *
9026 * @return static[]
9027 */
9028 public static function tokenize(string $code, int $flags = 0): array
9029 {
9030 self::init();
9031 $tokens = [];
9032 $line = 1;
9033 $pos = 0;
9034 $origTokens = \token_get_all($code, $flags);
9035 $numTokens = \count($origTokens);
9036 for ($i = 0; $i < $numTokens; $i++) {
9037 $token = $origTokens[$i];
9038 if (\is_string($token)) {
9039 if (\strlen($token) === 2) {
9040 // b" and B" are tokenized as single-char tokens, even though they aren't.
9041 $tokens[] = new static(\ord('"'), $token, $line, $pos);
9042 $pos += 2;
9043 } else {
9044 $tokens[] = new static(\ord($token), $token, $line, $pos);
9045 $pos++;
9046 }
9047 } else {
9048 $id = $token[0];
9049 $text = $token[1];
9050 // Emulate PHP 8.0 comment format, which does not include trailing whitespace anymore.
9051 if ($id === \T_COMMENT && \substr($text, 0, 2) !== '/*' && \preg_match('/(\r\n|\n|\r)$/D', $text, $matches)) {
9052 $trailingNewline = $matches[0];
9053 $text = \substr($text, 0, -\strlen($trailingNewline));
9054 $tokens[] = new static($id, $text, $line, $pos);
9055 $pos += \strlen($text);
9056 if ($i + 1 < $numTokens && $origTokens[$i + 1][0] === \T_WHITESPACE) {
9057 // Move trailing newline into following T_WHITESPACE token, if it already exists.
9058 $origTokens[$i + 1][1] = $trailingNewline . $origTokens[$i + 1][1];
9059 $origTokens[$i + 1][2]--;
9060 } else {
9061 // Otherwise, we need to create a new T_WHITESPACE token.
9062 $tokens[] = new static(\T_WHITESPACE, $trailingNewline, $line, $pos);
9063 $line++;
9064 $pos += \strlen($trailingNewline);
9065 }
9066 continue;
9067 }
9068 // Emulate PHP 8.0 T_NAME_* tokens, by combining sequences of T_NS_SEPARATOR and
9069 // T_STRING into a single token.
9070 if ($id === \T_NS_SEPARATOR || isset(self::$identifierTokens[$id])) {
9071 $newText = $text;
9072 $lastWasSeparator = $id === \T_NS_SEPARATOR;
9073 for ($j = $i + 1; $j < $numTokens; $j++) {
9074 if ($lastWasSeparator) {
9075 if (!isset(self::$identifierTokens[$origTokens[$j][0]])) {
9076 break;
9077 }
9078 $lastWasSeparator = \false;
9079 } else {
9080 if ($origTokens[$j][0] !== \T_NS_SEPARATOR) {
9081 break;
9082 }
9083 $lastWasSeparator = \true;
9084 }
9085 $newText .= $origTokens[$j][1];
9086 }
9087 if ($lastWasSeparator) {
9088 // Trailing separator is not part of the name.
9089 $j--;
9090 $newText = \substr($newText, 0, -1);
9091 }
9092 if ($j > $i + 1) {
9093 if ($id === \T_NS_SEPARATOR) {
9094 $id = \T_NAME_FULLY_QUALIFIED;
9095 } elseif ($id === \T_NAMESPACE) {
9096 $id = \T_NAME_RELATIVE;
9097 } else {
9098 $id = \T_NAME_QUALIFIED;
9099 }
9100 $tokens[] = new static($id, $newText, $line, $pos);
9101 $pos += \strlen($newText);
9102 $i = $j - 1;
9103 continue;
9104 }
9105 }
9106 $tokens[] = new static($id, $text, $line, $pos);
9107 $line += \substr_count($text, "\n");
9108 $pos += \strlen($text);
9109 }
9110 }
9111 return $tokens;
9112 }
9113 /** Initialize private static state needed by tokenize(). */
9114 private static function init(): void
9115 {
9116 if (isset(self::$identifierTokens)) {
9117 return;
9118 }
9119 // Based on semi_reserved production.
9120 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);
9121 }
9122 }
9123 <?php
9124
9125 declare (strict_types=1);
9126 namespace PHPUnitPHAR\PhpParser\Internal;
9127
9128 use PHPUnitPHAR\PhpParser\Token;
9129 /**
9130 * Provides operations on token streams, for use by pretty printer.
9131 *
9132 * @internal
9133 */
9134 class TokenStream
9135 {
9136 /** @var Token[] Tokens (in PhpToken::tokenize() format) */
9137 private array $tokens;
9138 /** @var int[] Map from position to indentation */
9139 private array $indentMap;
9140 /**
9141 * Create token stream instance.
9142 *
9143 * @param Token[] $tokens Tokens in PhpToken::tokenize() format
9144 */
9145 public function __construct(array $tokens, int $tabWidth)
9146 {
9147 $this->tokens = $tokens;
9148 $this->indentMap = $this->calcIndentMap($tabWidth);
9149 }
9150 /**
9151 * Whether the given position is immediately surrounded by parenthesis.
9152 *
9153 * @param int $startPos Start position
9154 * @param int $endPos End position
9155 */
9156 public function haveParens(int $startPos, int $endPos): bool
9157 {
9158 return $this->haveTokenImmediatelyBefore($startPos, '(') && $this->haveTokenImmediatelyAfter($endPos, ')');
9159 }
9160 /**
9161 * Whether the given position is immediately surrounded by braces.
9162 *
9163 * @param int $startPos Start position
9164 * @param int $endPos End position
9165 */
9166 public function haveBraces(int $startPos, int $endPos): bool
9167 {
9168 return ($this->haveTokenImmediatelyBefore($startPos, '{') || $this->haveTokenImmediatelyBefore($startPos, \T_CURLY_OPEN)) && $this->haveTokenImmediatelyAfter($endPos, '}');
9169 }
9170 /**
9171 * Check whether the position is directly preceded by a certain token type.
9172 *
9173 * During this check whitespace and comments are skipped.
9174 *
9175 * @param int $pos Position before which the token should occur
9176 * @param int|string $expectedTokenType Token to check for
9177 *
9178 * @return bool Whether the expected token was found
9179 */
9180 public function haveTokenImmediatelyBefore(int $pos, $expectedTokenType): bool
9181 {
9182 $tokens = $this->tokens;
9183 $pos--;
9184 for (; $pos >= 0; $pos--) {
9185 $token = $tokens[$pos];
9186 if ($token->is($expectedTokenType)) {
9187 return \true;
9188 }
9189 if (!$token->isIgnorable()) {
9190 break;
9191 }
9192 }
9193 return \false;
9194 }
9195 /**
9196 * Check whether the position is directly followed by a certain token type.
9197 *
9198 * During this check whitespace and comments are skipped.
9199 *
9200 * @param int $pos Position after which the token should occur
9201 * @param int|string $expectedTokenType Token to check for
9202 *
9203 * @return bool Whether the expected token was found
9204 */
9205 public function haveTokenImmediatelyAfter(int $pos, $expectedTokenType): bool
9206 {
9207 $tokens = $this->tokens;
9208 $pos++;
9209 for ($c = \count($tokens); $pos < $c; $pos++) {
9210 $token = $tokens[$pos];
9211 if ($token->is($expectedTokenType)) {
9212 return \true;
9213 }
9214 if (!$token->isIgnorable()) {
9215 break;
9216 }
9217 }
9218 return \false;
9219 }
9220 /** @param int|string|(int|string)[] $skipTokenType */
9221 public function skipLeft(int $pos, $skipTokenType): int
9222 {
9223 $tokens = $this->tokens;
9224 $pos = $this->skipLeftWhitespace($pos);
9225 if ($skipTokenType === \T_WHITESPACE) {
9226 return $pos;
9227 }
9228 if (!$tokens[$pos]->is($skipTokenType)) {
9229 // Shouldn't happen. The skip token MUST be there
9230 throw new \Exception('Encountered unexpected token');
9231 }
9232 $pos--;
9233 return $this->skipLeftWhitespace($pos);
9234 }
9235 /** @param int|string|(int|string)[] $skipTokenType */
9236 public function skipRight(int $pos, $skipTokenType): int
9237 {
9238 $tokens = $this->tokens;
9239 $pos = $this->skipRightWhitespace($pos);
9240 if ($skipTokenType === \T_WHITESPACE) {
9241 return $pos;
9242 }
9243 if (!$tokens[$pos]->is($skipTokenType)) {
9244 // Shouldn't happen. The skip token MUST be there
9245 throw new \Exception('Encountered unexpected token');
9246 }
9247 $pos++;
9248 return $this->skipRightWhitespace($pos);
9249 }
9250 /**
9251 * Return first non-whitespace token position smaller or equal to passed position.
9252 *
9253 * @param int $pos Token position
9254 * @return int Non-whitespace token position
9255 */
9256 public function skipLeftWhitespace(int $pos): int
9257 {
9258 $tokens = $this->tokens;
9259 for (; $pos >= 0; $pos--) {
9260 if (!$tokens[$pos]->isIgnorable()) {
9261 break;
9262 }
9263 }
9264 return $pos;
9265 }
9266 /**
9267 * Return first non-whitespace position greater or equal to passed position.
9268 *
9269 * @param int $pos Token position
9270 * @return int Non-whitespace token position
9271 */
9272 public function skipRightWhitespace(int $pos): int
9273 {
9274 $tokens = $this->tokens;
9275 for ($count = \count($tokens); $pos < $count; $pos++) {
9276 if (!$tokens[$pos]->isIgnorable()) {
9277 break;
9278 }
9279 }
9280 return $pos;
9281 }
9282 /** @param int|string|(int|string)[] $findTokenType */
9283 public function findRight(int $pos, $findTokenType): int
9284 {
9285 $tokens = $this->tokens;
9286 for ($count = \count($tokens); $pos < $count; $pos++) {
9287 if ($tokens[$pos]->is($findTokenType)) {
9288 return $pos;
9289 }
9290 }
9291 return -1;
9292 }
9293 /**
9294 * Whether the given position range contains a certain token type.
9295 *
9296 * @param int $startPos Starting position (inclusive)
9297 * @param int $endPos Ending position (exclusive)
9298 * @param int|string $tokenType Token type to look for
9299 * @return bool Whether the token occurs in the given range
9300 */
9301 public function haveTokenInRange(int $startPos, int $endPos, $tokenType): bool
9302 {
9303 $tokens = $this->tokens;
9304 for ($pos = $startPos; $pos < $endPos; $pos++) {
9305 if ($tokens[$pos]->is($tokenType)) {
9306 return \true;
9307 }
9308 }
9309 return \false;
9310 }
9311 public function haveTagInRange(int $startPos, int $endPos): bool
9312 {
9313 return $this->haveTokenInRange($startPos, $endPos, \T_OPEN_TAG) || $this->haveTokenInRange($startPos, $endPos, \T_CLOSE_TAG);
9314 }
9315 /**
9316 * Get indentation before token position.
9317 *
9318 * @param int $pos Token position
9319 *
9320 * @return int Indentation depth (in spaces)
9321 */
9322 public function getIndentationBefore(int $pos): int
9323 {
9324 return $this->indentMap[$pos];
9325 }
9326 /**
9327 * Get the code corresponding to a token offset range, optionally adjusted for indentation.
9328 *
9329 * @param int $from Token start position (inclusive)
9330 * @param int $to Token end position (exclusive)
9331 * @param int $indent By how much the code should be indented (can be negative as well)
9332 *
9333 * @return string Code corresponding to token range, adjusted for indentation
9334 */
9335 public function getTokenCode(int $from, int $to, int $indent): string
9336 {
9337 $tokens = $this->tokens;
9338 $result = '';
9339 for ($pos = $from; $pos < $to; $pos++) {
9340 $token = $tokens[$pos];
9341 $id = $token->id;
9342 $text = $token->text;
9343 if ($id === \T_CONSTANT_ENCAPSED_STRING || $id === \T_ENCAPSED_AND_WHITESPACE) {
9344 $result .= $text;
9345 } else if ($indent < 0) {
9346 $result .= str_replace("\n" . str_repeat(" ", -$indent), "\n", $text);
9347 } elseif ($indent > 0) {
9348 $result .= str_replace("\n", "\n" . str_repeat(" ", $indent), $text);
9349 } else {
9350 $result .= $text;
9351 }
9352 }
9353 return $result;
9354 }
9355 /**
9356 * Precalculate the indentation at every token position.
9357 *
9358 * @return int[] Token position to indentation map
9359 */
9360 private function calcIndentMap(int $tabWidth): array
9361 {
9362 $indentMap = [];
9363 $indent = 0;
9364 foreach ($this->tokens as $i => $token) {
9365 $indentMap[] = $indent;
9366 if ($token->id === \T_WHITESPACE) {
9367 $content = $token->text;
9368 $newlinePos = \strrpos($content, "\n");
9369 if (\false !== $newlinePos) {
9370 $indent = $this->getIndent(\substr($content, $newlinePos + 1), $tabWidth);
9371 } elseif ($i === 1 && $this->tokens[0]->id === \T_OPEN_TAG && $this->tokens[0]->text[\strlen($this->tokens[0]->text) - 1] === "\n") {
9372 // Special case: Newline at the end of opening tag followed by whitespace.
9373 $indent = $this->getIndent($content, $tabWidth);
9374 }
9375 }
9376 }
9377 // Add a sentinel for one past end of the file
9378 $indentMap[] = $indent;
9379 return $indentMap;
9380 }
9381 private function getIndent(string $ws, int $tabWidth): int
9382 {
9383 $spaces = \substr_count($ws, " ");
9384 $tabs = \substr_count($ws, "\t");
9385 assert(\strlen($ws) === $spaces + $tabs);
9386 return $spaces + $tabs * $tabWidth;
9387 }
9388 }
9389 <?php
9390
9391 declare (strict_types=1);
9392 namespace PHPUnitPHAR\PhpParser;
9393
9394 class JsonDecoder
9395 {
9396 /** @var \ReflectionClass<Node>[] Node type to reflection class map */
9397 private array $reflectionClassCache;
9398 /** @return mixed */
9399 public function decode(string $json)
9400 {
9401 $value = json_decode($json, \true);
9402 if (json_last_error()) {
9403 throw new \RuntimeException('JSON decoding error: ' . json_last_error_msg());
9404 }
9405 return $this->decodeRecursive($value);
9406 }
9407 /**
9408 * @param mixed $value
9409 * @return mixed
9410 */
9411 private function decodeRecursive($value)
9412 {
9413 if (\is_array($value)) {
9414 if (isset($value['nodeType'])) {
9415 if ($value['nodeType'] === 'Comment' || $value['nodeType'] === 'Comment_Doc') {
9416 return $this->decodeComment($value);
9417 }
9418 return $this->decodeNode($value);
9419 }
9420 return $this->decodeArray($value);
9421 }
9422 return $value;
9423 }
9424 private function decodeArray(array $array): array
9425 {
9426 $decodedArray = [];
9427 foreach ($array as $key => $value) {
9428 $decodedArray[$key] = $this->decodeRecursive($value);
9429 }
9430 return $decodedArray;
9431 }
9432 private function decodeNode(array $value): Node
9433 {
9434 $nodeType = $value['nodeType'];
9435 if (!\is_string($nodeType)) {
9436 throw new \RuntimeException('Node type must be a string');
9437 }
9438 $reflectionClass = $this->reflectionClassFromNodeType($nodeType);
9439 $node = $reflectionClass->newInstanceWithoutConstructor();
9440 if (isset($value['attributes'])) {
9441 if (!\is_array($value['attributes'])) {
9442 throw new \RuntimeException('Attributes must be an array');
9443 }
9444 $node->setAttributes($this->decodeArray($value['attributes']));
9445 }
9446 foreach ($value as $name => $subNode) {
9447 if ($name === 'nodeType' || $name === 'attributes') {
9448 continue;
9449 }
9450 $node->{$name} = $this->decodeRecursive($subNode);
9451 }
9452 return $node;
9453 }
9454 private function decodeComment(array $value): Comment
9455 {
9456 $className = $value['nodeType'] === 'Comment' ? Comment::class : Comment\Doc::class;
9457 if (!isset($value['text'])) {
9458 throw new \RuntimeException('Comment must have text');
9459 }
9460 return new $className($value['text'], $value['line'] ?? -1, $value['filePos'] ?? -1, $value['tokenPos'] ?? -1, $value['endLine'] ?? -1, $value['endFilePos'] ?? -1, $value['endTokenPos'] ?? -1);
9461 }
9462 /** @return \ReflectionClass<Node> */
9463 private function reflectionClassFromNodeType(string $nodeType): \ReflectionClass
9464 {
9465 if (!isset($this->reflectionClassCache[$nodeType])) {
9466 $className = $this->classNameFromNodeType($nodeType);
9467 $this->reflectionClassCache[$nodeType] = new \ReflectionClass($className);
9468 }
9469 return $this->reflectionClassCache[$nodeType];
9470 }
9471 /** @return class-string<Node> */
9472 private function classNameFromNodeType(string $nodeType): string
9473 {
9474 $className = 'PhpParser\Node\\' . strtr($nodeType, '_', '\\');
9475 if (class_exists($className)) {
9476 return $className;
9477 }
9478 $className .= '_';
9479 if (class_exists($className)) {
9480 return $className;
9481 }
9482 throw new \RuntimeException("Unknown node type \"{$nodeType}\"");
9483 }
9484 }
9485 <?php
9486
9487 declare (strict_types=1);
9488 namespace PHPUnitPHAR\PhpParser;
9489
9490 require __DIR__ . '/compatibility_tokens.php';
9491 class Lexer
9492 {
9493 /**
9494 * Tokenize the provided source code.
9495 *
9496 * The token array is in the same format as provided by the PhpToken::tokenize() method in
9497 * PHP 8.0. The tokens are instances of PhpParser\Token, to abstract over a polyfill
9498 * implementation in earlier PHP version.
9499 *
9500 * The token array is terminated by a sentinel token with token ID 0.
9501 * The token array does not discard any tokens (i.e. whitespace and comments are included).
9502 * The token position attributes are against this token array.
9503 *
9504 * @param string $code The source code to tokenize.
9505 * @param ErrorHandler|null $errorHandler Error handler to use for lexing errors. Defaults to
9506 * ErrorHandler\Throwing.
9507 * @return Token[] Tokens
9508 */
9509 public function tokenize(string $code, ?ErrorHandler $errorHandler = null): array
9510 {
9511 if (null === $errorHandler) {
9512 $errorHandler = new ErrorHandler\Throwing();
9513 }
9514 $scream = ini_set('xdebug.scream', '0');
9515 $tokens = @Token::tokenize($code);
9516 $this->postprocessTokens($tokens, $errorHandler);
9517 if (\false !== $scream) {
9518 ini_set('xdebug.scream', $scream);
9519 }
9520 return $tokens;
9521 }
9522 private function handleInvalidCharacter(Token $token, ErrorHandler $errorHandler): void
9523 {
9524 $chr = $token->text;
9525 if ($chr === "\x00") {
9526 // PHP cuts error message after null byte, so need special case
9527 $errorMsg = 'Unexpected null byte';
9528 } else {
9529 $errorMsg = sprintf('Unexpected character "%s" (ASCII %d)', $chr, ord($chr));
9530 }
9531 $errorHandler->handleError(new Error($errorMsg, ['startLine' => $token->line, 'endLine' => $token->line, 'startFilePos' => $token->pos, 'endFilePos' => $token->pos]));
9532 }
9533 private function isUnterminatedComment(Token $token): bool
9534 {
9535 return $token->is([\T_COMMENT, \T_DOC_COMMENT]) && substr($token->text, 0, 2) === '/*' && substr($token->text, -2) !== '*/';
9536 }
9537 /**
9538 * @param list<Token> $tokens
9539 */
9540 protected function postprocessTokens(array &$tokens, ErrorHandler $errorHandler): void
9541 {
9542 // This function reports errors (bad characters and unterminated comments) in the token
9543 // array, and performs certain canonicalizations:
9544 // * Use PHP 8.1 T_AMPERSAND_NOT_FOLLOWED_BY_VAR_OR_VARARG and
9545 // T_AMPERSAND_FOLLOWED_BY_VAR_OR_VARARG tokens used to disambiguate intersection types.
9546 // * Add a sentinel token with ID 0.
9547 $numTokens = \count($tokens);
9548 if ($numTokens === 0) {
9549 // Empty input edge case: Just add the sentinel token.
9550 $tokens[] = new Token(0, "\x00", 1, 0);
9551 return;
9552 }
9553 for ($i = 0; $i < $numTokens; $i++) {
9554 $token = $tokens[$i];
9555 if ($token->id === \T_BAD_CHARACTER) {
9556 $this->handleInvalidCharacter($token, $errorHandler);
9557 }
9558 if ($token->id === \ord('&')) {
9559 $next = $i + 1;
9560 while (isset($tokens[$next]) && $tokens[$next]->id === \T_WHITESPACE) {
9561 $next++;
9562 }
9563 $followedByVarOrVarArg = isset($tokens[$next]) && $tokens[$next]->is([\T_VARIABLE, \T_ELLIPSIS]);
9564 $token->id = $followedByVarOrVarArg ? \T_AMPERSAND_FOLLOWED_BY_VAR_OR_VARARG : \T_AMPERSAND_NOT_FOLLOWED_BY_VAR_OR_VARARG;
9565 }
9566 }
9567 // Check for unterminated comment
9568 $lastToken = $tokens[$numTokens - 1];
9569 if ($this->isUnterminatedComment($lastToken)) {
9570 $errorHandler->handleError(new Error('Unterminated comment', ['startLine' => $lastToken->line, 'endLine' => $lastToken->getEndLine(), 'startFilePos' => $lastToken->pos, 'endFilePos' => $lastToken->getEndPos()]));
9571 }
9572 // Add sentinel token.
9573 $tokens[] = new Token(0, "\x00", $lastToken->getEndLine(), $lastToken->getEndPos());
9574 }
9575 }
9576 <?php
9577
9578 declare (strict_types=1);
9579 namespace PHPUnitPHAR\PhpParser\Lexer;
9580
9581 use PHPUnitPHAR\PhpParser\Error;
9582 use PHPUnitPHAR\PhpParser\ErrorHandler;
9583 use PHPUnitPHAR\PhpParser\Lexer;
9584 use PHPUnitPHAR\PhpParser\Lexer\TokenEmulator\AsymmetricVisibilityTokenEmulator;
9585 use PHPUnitPHAR\PhpParser\Lexer\TokenEmulator\AttributeEmulator;
9586 use PHPUnitPHAR\PhpParser\Lexer\TokenEmulator\EnumTokenEmulator;
9587 use PHPUnitPHAR\PhpParser\Lexer\TokenEmulator\ExplicitOctalEmulator;
9588 use PHPUnitPHAR\PhpParser\Lexer\TokenEmulator\MatchTokenEmulator;
9589 use PHPUnitPHAR\PhpParser\Lexer\TokenEmulator\NullsafeTokenEmulator;
9590 use PHPUnitPHAR\PhpParser\Lexer\TokenEmulator\PipeOperatorEmulator;
9591 use PHPUnitPHAR\PhpParser\Lexer\TokenEmulator\PropertyTokenEmulator;
9592 use PHPUnitPHAR\PhpParser\Lexer\TokenEmulator\ReadonlyFunctionTokenEmulator;
9593 use PHPUnitPHAR\PhpParser\Lexer\TokenEmulator\ReadonlyTokenEmulator;
9594 use PHPUnitPHAR\PhpParser\Lexer\TokenEmulator\ReverseEmulator;
9595 use PHPUnitPHAR\PhpParser\Lexer\TokenEmulator\TokenEmulator;
9596 use PHPUnitPHAR\PhpParser\Lexer\TokenEmulator\VoidCastEmulator;
9597 use PHPUnitPHAR\PhpParser\PhpVersion;
9598 use PHPUnitPHAR\PhpParser\Token;
9599 class Emulative extends Lexer
9600 {
9601 /** @var array{int, string, string}[] Patches used to reverse changes introduced in the code */
9602 private array $patches = [];
9603 /** @var list<TokenEmulator> */
9604 private array $emulators = [];
9605 private PhpVersion $targetPhpVersion;
9606 private PhpVersion $hostPhpVersion;
9607 /**
9608 * @param PhpVersion|null $phpVersion PHP version to emulate. Defaults to newest supported.
9609 */
9610 public function __construct(?PhpVersion $phpVersion = null)
9611 {
9612 $this->targetPhpVersion = $phpVersion ?? PhpVersion::getNewestSupported();
9613 $this->hostPhpVersion = PhpVersion::getHostVersion();
9614 $emulators = [new MatchTokenEmulator(), new NullsafeTokenEmulator(), new AttributeEmulator(), new EnumTokenEmulator(), new ReadonlyTokenEmulator(), new ExplicitOctalEmulator(), new ReadonlyFunctionTokenEmulator(), new PropertyTokenEmulator(), new AsymmetricVisibilityTokenEmulator(), new PipeOperatorEmulator(), new VoidCastEmulator()];
9615 // Collect emulators that are relevant for the PHP version we're running
9616 // and the PHP version we're targeting for emulation.
9617 foreach ($emulators as $emulator) {
9618 $emulatorPhpVersion = $emulator->getPhpVersion();
9619 if ($this->isForwardEmulationNeeded($emulatorPhpVersion)) {
9620 $this->emulators[] = $emulator;
9621 } elseif ($this->isReverseEmulationNeeded($emulatorPhpVersion)) {
9622 $this->emulators[] = new ReverseEmulator($emulator);
9623 }
9624 }
9625 }
9626 public function tokenize(string $code, ?ErrorHandler $errorHandler = null): array
9627 {
9628 $emulators = array_filter($this->emulators, function ($emulator) use ($code) {
9629 return $emulator->isEmulationNeeded($code);
9630 });
9631 if (empty($emulators)) {
9632 // Nothing to emulate, yay
9633 return parent::tokenize($code, $errorHandler);
9634 }
9635 if ($errorHandler === null) {
9636 $errorHandler = new ErrorHandler\Throwing();
9637 }
9638 $this->patches = [];
9639 foreach ($emulators as $emulator) {
9640 $code = $emulator->preprocessCode($code, $this->patches);
9641 }
9642 $collector = new ErrorHandler\Collecting();
9643 $tokens = parent::tokenize($code, $collector);
9644 $this->sortPatches();
9645 $tokens = $this->fixupTokens($tokens);
9646 $errors = $collector->getErrors();
9647 if (!empty($errors)) {
9648 $this->fixupErrors($errors);
9649 foreach ($errors as $error) {
9650 $errorHandler->handleError($error);
9651 }
9652 }
9653 foreach ($emulators as $emulator) {
9654 $tokens = $emulator->emulate($code, $tokens);
9655 }
9656 return $tokens;
9657 }
9658 private function isForwardEmulationNeeded(PhpVersion $emulatorPhpVersion): bool
9659 {
9660 return $this->hostPhpVersion->older($emulatorPhpVersion) && $this->targetPhpVersion->newerOrEqual($emulatorPhpVersion);
9661 }
9662 private function isReverseEmulationNeeded(PhpVersion $emulatorPhpVersion): bool
9663 {
9664 return $this->hostPhpVersion->newerOrEqual($emulatorPhpVersion) && $this->targetPhpVersion->older($emulatorPhpVersion);
9665 }
9666 private function sortPatches(): void
9667 {
9668 // Patches may be contributed by different emulators.
9669 // Make sure they are sorted by increasing patch position.
9670 usort($this->patches, function ($p1, $p2) {
9671 return $p1[0] <=> $p2[0];
9672 });
9673 }
9674 /**
9675 * @param list<Token> $tokens
9676 * @return list<Token>
9677 */
9678 private function fixupTokens(array $tokens): array
9679 {
9680 if (\count($this->patches) === 0) {
9681 return $tokens;
9682 }
9683 // Load first patch
9684 $patchIdx = 0;
9685 list($patchPos, $patchType, $patchText) = $this->patches[$patchIdx];
9686 // We use a manual loop over the tokens, because we modify the array on the fly
9687 $posDelta = 0;
9688 $lineDelta = 0;
9689 for ($i = 0, $c = \count($tokens); $i < $c; $i++) {
9690 $token = $tokens[$i];
9691 $pos = $token->pos;
9692 $token->pos += $posDelta;
9693 $token->line += $lineDelta;
9694 $localPosDelta = 0;
9695 $len = \strlen($token->text);
9696 while ($patchPos >= $pos && $patchPos < $pos + $len) {
9697 $patchTextLen = \strlen($patchText);
9698 if ($patchType === 'remove') {
9699 if ($patchPos === $pos && $patchTextLen === $len) {
9700 // Remove token entirely
9701 array_splice($tokens, $i, 1, []);
9702 $i--;
9703 $c--;
9704 } else {
9705 // Remove from token string
9706 $token->text = substr_replace($token->text, '', $patchPos - $pos + $localPosDelta, $patchTextLen);
9707 $localPosDelta -= $patchTextLen;
9708 }
9709 $lineDelta -= \substr_count($patchText, "\n");
9710 } elseif ($patchType === 'add') {
9711 // Insert into the token string
9712 $token->text = substr_replace($token->text, $patchText, $patchPos - $pos + $localPosDelta, 0);
9713 $localPosDelta += $patchTextLen;
9714 $lineDelta += \substr_count($patchText, "\n");
9715 } elseif ($patchType === 'replace') {
9716 // Replace inside the token string
9717 $token->text = substr_replace($token->text, $patchText, $patchPos - $pos + $localPosDelta, $patchTextLen);
9718 } else {
9719 assert(\false);
9720 }
9721 // Fetch the next patch
9722 $patchIdx++;
9723 if ($patchIdx >= \count($this->patches)) {
9724 // No more patches. However, we still need to adjust position.
9725 $patchPos = \PHP_INT_MAX;
9726 break;
9727 }
9728 list($patchPos, $patchType, $patchText) = $this->patches[$patchIdx];
9729 }
9730 $posDelta += $localPosDelta;
9731 }
9732 return $tokens;
9733 }
9734 /**
9735 * Fixup line and position information in errors.
9736 *
9737 * @param Error[] $errors
9738 */
9739 private function fixupErrors(array $errors): void
9740 {
9741 foreach ($errors as $error) {
9742 $attrs = $error->getAttributes();
9743 $posDelta = 0;
9744 $lineDelta = 0;
9745 foreach ($this->patches as $patch) {
9746 list($patchPos, $patchType, $patchText) = $patch;
9747 if ($patchPos >= $attrs['startFilePos']) {
9748 // No longer relevant
9749 break;
9750 }
9751 if ($patchType === 'add') {
9752 $posDelta += strlen($patchText);
9753 $lineDelta += substr_count($patchText, "\n");
9754 } elseif ($patchType === 'remove') {
9755 $posDelta -= strlen($patchText);
9756 $lineDelta -= substr_count($patchText, "\n");
9757 }
9758 }
9759 $attrs['startFilePos'] += $posDelta;
9760 $attrs['endFilePos'] += $posDelta;
9761 $attrs['startLine'] += $lineDelta;
9762 $attrs['endLine'] += $lineDelta;
9763 $error->setAttributes($attrs);
9764 }
9765 }
9766 }
9767 <?php
9768
9769 declare (strict_types=1);
9770 namespace PHPUnitPHAR\PhpParser\Lexer\TokenEmulator;
9771
9772 use PHPUnitPHAR\PhpParser\PhpVersion;
9773 use PHPUnitPHAR\PhpParser\Token;
9774 final class AsymmetricVisibilityTokenEmulator extends TokenEmulator
9775 {
9776 public function getPhpVersion(): PhpVersion
9777 {
9778 return PhpVersion::fromComponents(8, 4);
9779 }
9780 public function isEmulationNeeded(string $code): bool
9781 {
9782 $code = strtolower($code);
9783 return strpos($code, 'public(set)') !== \false || strpos($code, 'protected(set)') !== \false || strpos($code, 'private(set)') !== \false;
9784 }
9785 public function emulate(string $code, array $tokens): array
9786 {
9787 $map = [\T_PUBLIC => \T_PUBLIC_SET, \T_PROTECTED => \T_PROTECTED_SET, \T_PRIVATE => \T_PRIVATE_SET];
9788 for ($i = 0, $c = count($tokens); $i < $c; ++$i) {
9789 $token = $tokens[$i];
9790 if (isset($map[$token->id]) && $i + 3 < $c && $tokens[$i + 1]->text === '(' && $tokens[$i + 2]->id === \T_STRING && \strtolower($tokens[$i + 2]->text) === 'set' && $tokens[$i + 3]->text === ')' && $this->isKeywordContext($tokens, $i)) {
9791 array_splice($tokens, $i, 4, [new Token($map[$token->id], $token->text . '(' . $tokens[$i + 2]->text . ')', $token->line, $token->pos)]);
9792 $c -= 3;
9793 }
9794 }
9795 return $tokens;
9796 }
9797 public function reverseEmulate(string $code, array $tokens): array
9798 {
9799 $reverseMap = [\T_PUBLIC_SET => \T_PUBLIC, \T_PROTECTED_SET => \T_PROTECTED, \T_PRIVATE_SET => \T_PRIVATE];
9800 for ($i = 0, $c = count($tokens); $i < $c; ++$i) {
9801 $token = $tokens[$i];
9802 if (isset($reverseMap[$token->id]) && \preg_match('/(public|protected|private)\((set)\)/i', $token->text, $matches)) {
9803 [, $modifier, $set] = $matches;
9804 $modifierLen = \strlen($modifier);
9805 array_splice($tokens, $i, 1, [new Token($reverseMap[$token->id], $modifier, $token->line, $token->pos), new Token(\ord('('), '(', $token->line, $token->pos + $modifierLen), new Token(\T_STRING, $set, $token->line, $token->pos + $modifierLen + 1), new Token(\ord(')'), ')', $token->line, $token->pos + $modifierLen + 4)]);
9806 $i += 3;
9807 $c += 3;
9808 }
9809 }
9810 return $tokens;
9811 }
9812 /** @param Token[] $tokens */
9813 protected function isKeywordContext(array $tokens, int $pos): bool
9814 {
9815 $prevToken = $this->getPreviousNonSpaceToken($tokens, $pos);
9816 if ($prevToken === null) {
9817 return \false;
9818 }
9819 return $prevToken->id !== \T_OBJECT_OPERATOR && $prevToken->id !== \T_NULLSAFE_OBJECT_OPERATOR;
9820 }
9821 /** @param Token[] $tokens */
9822 private function getPreviousNonSpaceToken(array $tokens, int $start): ?Token
9823 {
9824 for ($i = $start - 1; $i >= 0; --$i) {
9825 if ($tokens[$i]->id === \T_WHITESPACE) {
9826 continue;
9827 }
9828 return $tokens[$i];
9829 }
9830 return null;
9831 }
9832 }
9833 <?php
9834
9835 declare (strict_types=1);
9836 namespace PHPUnitPHAR\PhpParser\Lexer\TokenEmulator;
9837
9838 use PHPUnitPHAR\PhpParser\PhpVersion;
9839 use PHPUnitPHAR\PhpParser\Token;
9840 final class AttributeEmulator extends TokenEmulator
9841 {
9842 public function getPhpVersion(): PhpVersion
9843 {
9844 return PhpVersion::fromComponents(8, 0);
9845 }
9846 public function isEmulationNeeded(string $code): bool
9847 {
9848 return strpos($code, '#[') !== \false;
9849 }
9850 public function emulate(string $code, array $tokens): array
9851 {
9852 // We need to manually iterate and manage a count because we'll change
9853 // the tokens array on the way.
9854 for ($i = 0, $c = count($tokens); $i < $c; ++$i) {
9855 $token = $tokens[$i];
9856 if ($token->text === '#' && isset($tokens[$i + 1]) && $tokens[$i + 1]->text === '[') {
9857 array_splice($tokens, $i, 2, [new Token(\T_ATTRIBUTE, '#[', $token->line, $token->pos)]);
9858 $c--;
9859 continue;
9860 }
9861 }
9862 return $tokens;
9863 }
9864 public function reverseEmulate(string $code, array $tokens): array
9865 {
9866 // TODO
9867 return $tokens;
9868 }
9869 public function preprocessCode(string $code, array &$patches): string
9870 {
9871 $pos = 0;
9872 while (\false !== $pos = strpos($code, '#[', $pos)) {
9873 // Replace #[ with %[
9874 $code[$pos] = '%';
9875 $patches[] = [$pos, 'replace', '#'];
9876 $pos += 2;
9877 }
9878 return $code;
9879 }
9880 }
9881 <?php
9882
9883 declare (strict_types=1);
9884 namespace PHPUnitPHAR\PhpParser\Lexer\TokenEmulator;
9885
9886 use PHPUnitPHAR\PhpParser\PhpVersion;
9887 final class EnumTokenEmulator extends KeywordEmulator
9888 {
9889 public function getPhpVersion(): PhpVersion
9890 {
9891 return PhpVersion::fromComponents(8, 1);
9892 }
9893 public function getKeywordString(): string
9894 {
9895 return 'enum';
9896 }
9897 public function getKeywordToken(): int
9898 {
9899 return \T_ENUM;
9900 }
9901 protected function isKeywordContext(array $tokens, int $pos): bool
9902 {
9903 return parent::isKeywordContext($tokens, $pos) && isset($tokens[$pos + 2]) && $tokens[$pos + 1]->id === \T_WHITESPACE && $tokens[$pos + 2]->id === \T_STRING;
9904 }
9905 }
9906 <?php
9907
9908 declare (strict_types=1);
9909 namespace PHPUnitPHAR\PhpParser\Lexer\TokenEmulator;
9910
9911 use PHPUnitPHAR\PhpParser\PhpVersion;
9912 use PHPUnitPHAR\PhpParser\Token;
9913 class ExplicitOctalEmulator extends TokenEmulator
9914 {
9915 public function getPhpVersion(): PhpVersion
9916 {
9917 return PhpVersion::fromComponents(8, 1);
9918 }
9919 public function isEmulationNeeded(string $code): bool
9920 {
9921 return strpos($code, '0o') !== \false || strpos($code, '0O') !== \false;
9922 }
9923 public function emulate(string $code, array $tokens): array
9924 {
9925 for ($i = 0, $c = count($tokens); $i < $c; ++$i) {
9926 $token = $tokens[$i];
9927 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)) {
9928 $tokenKind = $this->resolveIntegerOrFloatToken($tokens[$i + 1]->text);
9929 array_splice($tokens, $i, 2, [new Token($tokenKind, '0' . $tokens[$i + 1]->text, $token->line, $token->pos)]);
9930 $c--;
9931 }
9932 }
9933 return $tokens;
9934 }
9935 private function resolveIntegerOrFloatToken(string $str): int
9936 {
9937 $str = substr($str, 1);
9938 $str = str_replace('_', '', $str);
9939 $num = octdec($str);
9940 return is_float($num) ? \T_DNUMBER : \T_LNUMBER;
9941 }
9942 public function reverseEmulate(string $code, array $tokens): array
9943 {
9944 // Explicit octals were not legal code previously, don't bother.
9945 return $tokens;
9946 }
9947 }
9948 <?php
9949
9950 declare (strict_types=1);
9951 namespace PHPUnitPHAR\PhpParser\Lexer\TokenEmulator;
9952
9953 use PHPUnitPHAR\PhpParser\Token;
9954 abstract class KeywordEmulator extends TokenEmulator
9955 {
9956 abstract public function getKeywordString(): string;
9957 abstract public function getKeywordToken(): int;
9958 public function isEmulationNeeded(string $code): bool
9959 {
9960 return strpos(strtolower($code), $this->getKeywordString()) !== \false;
9961 }
9962 /** @param Token[] $tokens */
9963 protected function isKeywordContext(array $tokens, int $pos): bool
9964 {
9965 $prevToken = $this->getPreviousNonSpaceToken($tokens, $pos);
9966 if ($prevToken === null) {
9967 return \false;
9968 }
9969 return $prevToken->id !== \T_OBJECT_OPERATOR && $prevToken->id !== \T_NULLSAFE_OBJECT_OPERATOR;
9970 }
9971 public function emulate(string $code, array $tokens): array
9972 {
9973 $keywordString = $this->getKeywordString();
9974 foreach ($tokens as $i => $token) {
9975 if ($token->id === \T_STRING && strtolower($token->text) === $keywordString && $this->isKeywordContext($tokens, $i)) {
9976 $token->id = $this->getKeywordToken();
9977 }
9978 }
9979 return $tokens;
9980 }
9981 /** @param Token[] $tokens */
9982 private function getPreviousNonSpaceToken(array $tokens, int $start): ?Token
9983 {
9984 for ($i = $start - 1; $i >= 0; --$i) {
9985 if ($tokens[$i]->id === \T_WHITESPACE) {
9986 continue;
9987 }
9988 return $tokens[$i];
9989 }
9990 return null;
9991 }
9992 public function reverseEmulate(string $code, array $tokens): array
9993 {
9994 $keywordToken = $this->getKeywordToken();
9995 foreach ($tokens as $token) {
9996 if ($token->id === $keywordToken) {
9997 $token->id = \T_STRING;
9998 }
9999 }
10000 return $tokens;
10001 }
10002 }
10003 <?php
10004
10005 declare (strict_types=1);
10006 namespace PHPUnitPHAR\PhpParser\Lexer\TokenEmulator;
10007
10008 use PHPUnitPHAR\PhpParser\PhpVersion;
10009 final class MatchTokenEmulator extends KeywordEmulator
10010 {
10011 public function getPhpVersion(): PhpVersion
10012 {
10013 return PhpVersion::fromComponents(8, 0);
10014 }
10015 public function getKeywordString(): string
10016 {
10017 return 'match';
10018 }
10019 public function getKeywordToken(): int
10020 {
10021 return \T_MATCH;
10022 }
10023 }
10024 <?php
10025
10026 declare (strict_types=1);
10027 namespace PHPUnitPHAR\PhpParser\Lexer\TokenEmulator;
10028
10029 use PHPUnitPHAR\PhpParser\PhpVersion;
10030 use PHPUnitPHAR\PhpParser\Token;
10031 final class NullsafeTokenEmulator extends TokenEmulator
10032 {
10033 public function getPhpVersion(): PhpVersion
10034 {
10035 return PhpVersion::fromComponents(8, 0);
10036 }
10037 public function isEmulationNeeded(string $code): bool
10038 {
10039 return strpos($code, '?->') !== \false;
10040 }
10041 public function emulate(string $code, array $tokens): array
10042 {
10043 // We need to manually iterate and manage a count because we'll change
10044 // the tokens array on the way
10045 for ($i = 0, $c = count($tokens); $i < $c; ++$i) {
10046 $token = $tokens[$i];
10047 if ($token->text === '?' && isset($tokens[$i + 1]) && $tokens[$i + 1]->id === \T_OBJECT_OPERATOR) {
10048 array_splice($tokens, $i, 2, [new Token(\T_NULLSAFE_OBJECT_OPERATOR, '?->', $token->line, $token->pos)]);
10049 $c--;
10050 continue;
10051 }
10052 // Handle ?-> inside encapsed string.
10053 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)) {
10054 $replacement = [new Token(\T_NULLSAFE_OBJECT_OPERATOR, '?->', $token->line, $token->pos), new Token(\T_STRING, $matches[1], $token->line, $token->pos + 3)];
10055 $matchLen = \strlen($matches[0]);
10056 if ($matchLen !== \strlen($token->text)) {
10057 $replacement[] = new Token(\T_ENCAPSED_AND_WHITESPACE, \substr($token->text, $matchLen), $token->line, $token->pos + $matchLen);
10058 }
10059 array_splice($tokens, $i, 1, $replacement);
10060 $c += \count($replacement) - 1;
10061 continue;
10062 }
10063 }
10064 return $tokens;
10065 }
10066 public function reverseEmulate(string $code, array $tokens): array
10067 {
10068 // ?-> was not valid code previously, don't bother.
10069 return $tokens;
10070 }
10071 }
10072 <?php
10073
10074 declare (strict_types=1);
10075 namespace PHPUnitPHAR\PhpParser\Lexer\TokenEmulator;
10076
10077 use PHPUnitPHAR\PhpParser\Lexer\TokenEmulator\TokenEmulator;
10078 use PHPUnitPHAR\PhpParser\PhpVersion;
10079 use PHPUnitPHAR\PhpParser\Token;
10080 class PipeOperatorEmulator extends TokenEmulator
10081 {
10082 public function getPhpVersion(): PhpVersion
10083 {
10084 return PhpVersion::fromComponents(8, 5);
10085 }
10086 public function isEmulationNeeded(string $code): bool
10087 {
10088 return \strpos($code, '|>') !== \false;
10089 }
10090 public function emulate(string $code, array $tokens): array
10091 {
10092 for ($i = 0, $c = count($tokens); $i < $c; ++$i) {
10093 $token = $tokens[$i];
10094 if ($token->text === '|' && isset($tokens[$i + 1]) && $tokens[$i + 1]->text === '>') {
10095 array_splice($tokens, $i, 2, [new Token(\T_PIPE, '|>', $token->line, $token->pos)]);
10096 $c--;
10097 }
10098 }
10099 return $tokens;
10100 }
10101 public function reverseEmulate(string $code, array $tokens): array
10102 {
10103 for ($i = 0, $c = count($tokens); $i < $c; ++$i) {
10104 $token = $tokens[$i];
10105 if ($token->id === \T_PIPE) {
10106 array_splice($tokens, $i, 1, [new Token(\ord('|'), '|', $token->line, $token->pos), new Token(\ord('>'), '>', $token->line, $token->pos + 1)]);
10107 $i++;
10108 $c++;
10109 }
10110 }
10111 return $tokens;
10112 }
10113 }
10114 <?php
10115
10116 declare (strict_types=1);
10117 namespace PHPUnitPHAR\PhpParser\Lexer\TokenEmulator;
10118
10119 use PHPUnitPHAR\PhpParser\PhpVersion;
10120 final class PropertyTokenEmulator extends KeywordEmulator
10121 {
10122 public function getPhpVersion(): PhpVersion
10123 {
10124 return PhpVersion::fromComponents(8, 4);
10125 }
10126 public function getKeywordString(): string
10127 {
10128 return '__property__';
10129 }
10130 public function getKeywordToken(): int
10131 {
10132 return \T_PROPERTY_C;
10133 }
10134 }
10135 <?php
10136
10137 declare (strict_types=1);
10138 namespace PHPUnitPHAR\PhpParser\Lexer\TokenEmulator;
10139
10140 use PHPUnitPHAR\PhpParser\PhpVersion;
10141 /*
10142 * In PHP 8.1, "readonly(" was special cased in the lexer in order to support functions with
10143 * name readonly. In PHP 8.2, this may conflict with readonly properties having a DNF type. For
10144 * this reason, PHP 8.2 instead treats this as T_READONLY and then handles it specially in the
10145 * parser. This emulator only exists to handle this special case, which is skipped by the
10146 * PHP 8.1 ReadonlyTokenEmulator.
10147 */
10148 class ReadonlyFunctionTokenEmulator extends KeywordEmulator
10149 {
10150 public function getKeywordString(): string
10151 {
10152 return 'readonly';
10153 }
10154 public function getKeywordToken(): int
10155 {
10156 return \T_READONLY;
10157 }
10158 public function getPhpVersion(): PhpVersion
10159 {
10160 return PhpVersion::fromComponents(8, 2);
10161 }
10162 public function reverseEmulate(string $code, array $tokens): array
10163 {
10164 // Don't bother
10165 return $tokens;
10166 }
10167 }
10168 <?php
10169
10170 declare (strict_types=1);
10171 namespace PHPUnitPHAR\PhpParser\Lexer\TokenEmulator;
10172
10173 use PHPUnitPHAR\PhpParser\PhpVersion;
10174 final class ReadonlyTokenEmulator extends KeywordEmulator
10175 {
10176 public function getPhpVersion(): PhpVersion
10177 {
10178 return PhpVersion::fromComponents(8, 1);
10179 }
10180 public function getKeywordString(): string
10181 {
10182 return 'readonly';
10183 }
10184 public function getKeywordToken(): int
10185 {
10186 return \T_READONLY;
10187 }
10188 protected function isKeywordContext(array $tokens, int $pos): bool
10189 {
10190 if (!parent::isKeywordContext($tokens, $pos)) {
10191 return \false;
10192 }
10193 // Support "function readonly("
10194 return !(isset($tokens[$pos + 1]) && ($tokens[$pos + 1]->text === '(' || $tokens[$pos + 1]->id === \T_WHITESPACE && isset($tokens[$pos + 2]) && $tokens[$pos + 2]->text === '('));
10195 }
10196 }
10197 <?php
10198
10199 declare (strict_types=1);
10200 namespace PHPUnitPHAR\PhpParser\Lexer\TokenEmulator;
10201
10202 use PHPUnitPHAR\PhpParser\PhpVersion;
10203 /**
10204 * Reverses emulation direction of the inner emulator.
10205 */
10206 final class ReverseEmulator extends TokenEmulator
10207 {
10208 /** @var TokenEmulator Inner emulator */
10209 private TokenEmulator $emulator;
10210 public function __construct(TokenEmulator $emulator)
10211 {
10212 $this->emulator = $emulator;
10213 }
10214 public function getPhpVersion(): PhpVersion
10215 {
10216 return $this->emulator->getPhpVersion();
10217 }
10218 public function isEmulationNeeded(string $code): bool
10219 {
10220 return $this->emulator->isEmulationNeeded($code);
10221 }
10222 public function emulate(string $code, array $tokens): array
10223 {
10224 return $this->emulator->reverseEmulate($code, $tokens);
10225 }
10226 public function reverseEmulate(string $code, array $tokens): array
10227 {
10228 return $this->emulator->emulate($code, $tokens);
10229 }
10230 public function preprocessCode(string $code, array &$patches): string
10231 {
10232 return $code;
10233 }
10234 }
10235 <?php
10236
10237 declare (strict_types=1);
10238 namespace PHPUnitPHAR\PhpParser\Lexer\TokenEmulator;
10239
10240 use PHPUnitPHAR\PhpParser\PhpVersion;
10241 use PHPUnitPHAR\PhpParser\Token;
10242 /** @internal */
10243 abstract class TokenEmulator
10244 {
10245 abstract public function getPhpVersion(): PhpVersion;
10246 abstract public function isEmulationNeeded(string $code): bool;
10247 /**
10248 * @param Token[] $tokens Original tokens
10249 * @return Token[] Modified Tokens
10250 */
10251 abstract public function emulate(string $code, array $tokens): array;
10252 /**
10253 * @param Token[] $tokens Original tokens
10254 * @return Token[] Modified Tokens
10255 */
10256 abstract public function reverseEmulate(string $code, array $tokens): array;
10257 /** @param array{int, string, string}[] $patches */
10258 public function preprocessCode(string $code, array &$patches): string
10259 {
10260 return $code;
10261 }
10262 }
10263 <?php
10264
10265 declare (strict_types=1);
10266 namespace PHPUnitPHAR\PhpParser\Lexer\TokenEmulator;
10267
10268 use PHPUnitPHAR\PhpParser\PhpVersion;
10269 use PHPUnitPHAR\PhpParser\Token;
10270 class VoidCastEmulator extends TokenEmulator
10271 {
10272 public function getPhpVersion(): PhpVersion
10273 {
10274 return PhpVersion::fromComponents(8, 5);
10275 }
10276 public function isEmulationNeeded(string $code): bool
10277 {
10278 return (bool) \preg_match('/\([ \t]*void[ \t]*\)/i', $code);
10279 }
10280 public function emulate(string $code, array $tokens): array
10281 {
10282 for ($i = 0, $c = count($tokens); $i < $c; ++$i) {
10283 $token = $tokens[$i];
10284 if ($token->text !== '(') {
10285 continue;
10286 }
10287 $numTokens = 1;
10288 $text = '(';
10289 $j = $i + 1;
10290 if ($j < $c && $tokens[$j]->id === \T_WHITESPACE && preg_match('/[ \t]+/', $tokens[$j]->text)) {
10291 $text .= $tokens[$j]->text;
10292 $numTokens++;
10293 $j++;
10294 }
10295 if ($j >= $c || $tokens[$j]->id !== \T_STRING || \strtolower($tokens[$j]->text) !== 'void') {
10296 continue;
10297 }
10298 $text .= $tokens[$j]->text;
10299 $numTokens++;
10300 $k = $j + 1;
10301 if ($k < $c && $tokens[$k]->id === \T_WHITESPACE && preg_match('/[ \t]+/', $tokens[$k]->text)) {
10302 $text .= $tokens[$k]->text;
10303 $numTokens++;
10304 $k++;
10305 }
10306 if ($k >= $c || $tokens[$k]->text !== ')') {
10307 continue;
10308 }
10309 $text .= ')';
10310 $numTokens++;
10311 array_splice($tokens, $i, $numTokens, [new Token(\T_VOID_CAST, $text, $token->line, $token->pos)]);
10312 $c -= $numTokens - 1;
10313 }
10314 return $tokens;
10315 }
10316 public function reverseEmulate(string $code, array $tokens): array
10317 {
10318 for ($i = 0, $c = count($tokens); $i < $c; ++$i) {
10319 $token = $tokens[$i];
10320 if ($token->id !== \T_VOID_CAST) {
10321 continue;
10322 }
10323 if (!preg_match('/^\(([ \t]*)(void)([ \t]*)\)$/i', $token->text, $match)) {
10324 throw new \LogicException('Unexpected T_VOID_CAST contents');
10325 }
10326 $newTokens = [];
10327 $pos = $token->pos;
10328 $newTokens[] = new Token(\ord('('), '(', $token->line, $pos);
10329 $pos++;
10330 if ($match[1] !== '') {
10331 $newTokens[] = new Token(\T_WHITESPACE, $match[1], $token->line, $pos);
10332 $pos += \strlen($match[1]);
10333 }
10334 $newTokens[] = new Token(\T_STRING, $match[2], $token->line, $pos);
10335 $pos += \strlen($match[2]);
10336 if ($match[3] !== '') {
10337 $newTokens[] = new Token(\T_WHITESPACE, $match[3], $token->line, $pos);
10338 $pos += \strlen($match[3]);
10339 }
10340 $newTokens[] = new Token(\ord(')'), ')', $token->line, $pos);
10341 array_splice($tokens, $i, 1, $newTokens);
10342 $i += \count($newTokens) - 1;
10343 $c += \count($newTokens) - 1;
10344 }
10345 return $tokens;
10346 }
10347 }
10348 <?php
10349
10350 declare (strict_types=1);
10351 namespace PHPUnitPHAR\PhpParser;
10352
10353 /**
10354 * Modifiers used (as a bit mask) by various flags subnodes, for example on classes, functions,
10355 * properties and constants.
10356 */
10357 final class Modifiers
10358 {
10359 public const PUBLIC = 1;
10360 public const PROTECTED = 2;
10361 public const PRIVATE = 4;
10362 public const STATIC = 8;
10363 public const ABSTRACT = 16;
10364 public const FINAL = 32;
10365 public const READONLY = 64;
10366 public const PUBLIC_SET = 128;
10367 public const PROTECTED_SET = 256;
10368 public const PRIVATE_SET = 512;
10369 public const VISIBILITY_MASK = self::PUBLIC | self::PROTECTED | self::PRIVATE;
10370 public const VISIBILITY_SET_MASK = self::PUBLIC_SET | self::PROTECTED_SET | self::PRIVATE_SET;
10371 private const TO_STRING_MAP = [self::PUBLIC => 'public', self::PROTECTED => 'protected', self::PRIVATE => 'private', self::STATIC => 'static', self::ABSTRACT => 'abstract', self::FINAL => 'final', self::READONLY => 'readonly', self::PUBLIC_SET => 'public(set)', self::PROTECTED_SET => 'protected(set)', self::PRIVATE_SET => 'private(set)'];
10372 public static function toString(int $modifier): string
10373 {
10374 if (!isset(self::TO_STRING_MAP[$modifier])) {
10375 throw new \InvalidArgumentException("Unknown modifier {$modifier}");
10376 }
10377 return self::TO_STRING_MAP[$modifier];
10378 }
10379 private static function isValidModifier(int $modifier): bool
10380 {
10381 $isPow2 = ($modifier & $modifier - 1) == 0 && $modifier != 0;
10382 return $isPow2 && $modifier <= self::PRIVATE_SET;
10383 }
10384 /**
10385 * @internal
10386 */
10387 public static function verifyClassModifier(int $a, int $b): void
10388 {
10389 assert(self::isValidModifier($b));
10390 if (($a & $b) != 0) {
10391 throw new Error('Multiple ' . self::toString($b) . ' modifiers are not allowed');
10392 }
10393 if ($a & 48 && $b & 48) {
10394 throw new Error('Cannot use the final modifier on an abstract class');
10395 }
10396 }
10397 /**
10398 * @internal
10399 */
10400 public static function verifyModifier(int $a, int $b): void
10401 {
10402 assert(self::isValidModifier($b));
10403 if ($a & Modifiers::VISIBILITY_MASK && $b & Modifiers::VISIBILITY_MASK || $a & Modifiers::VISIBILITY_SET_MASK && $b & Modifiers::VISIBILITY_SET_MASK) {
10404 throw new Error('Multiple access type modifiers are not allowed');
10405 }
10406 if (($a & $b) != 0) {
10407 throw new Error('Multiple ' . self::toString($b) . ' modifiers are not allowed');
10408 }
10409 if ($a & 48 && $b & 48) {
10410 throw new Error('Cannot use the final modifier on an abstract class member');
10411 }
10412 }
10413 }
10414 <?php
10415
10416 declare (strict_types=1);
10417 namespace PHPUnitPHAR\PhpParser;
10418
10419 use PHPUnitPHAR\PhpParser\Node\Name;
10420 use PHPUnitPHAR\PhpParser\Node\Name\FullyQualified;
10421 use PHPUnitPHAR\PhpParser\Node\Stmt;
10422 class NameContext
10423 {
10424 /** @var null|Name Current namespace */
10425 protected ?Name $namespace;
10426 /** @var Name[][] Map of format [aliasType => [aliasName => originalName]] */
10427 protected array $aliases = [];
10428 /** @var Name[][] Same as $aliases but preserving original case */
10429 protected array $origAliases = [];
10430 /** @var ErrorHandler Error handler */
10431 protected ErrorHandler $errorHandler;
10432 /**
10433 * Create a name context.
10434 *
10435 * @param ErrorHandler $errorHandler Error handling used to report errors
10436 */
10437 public function __construct(ErrorHandler $errorHandler)
10438 {
10439 $this->errorHandler = $errorHandler;
10440 }
10441 /**
10442 * Start a new namespace.
10443 *
10444 * This also resets the alias table.
10445 *
10446 * @param Name|null $namespace Null is the global namespace
10447 */
10448 public function startNamespace(?Name $namespace = null): void
10449 {
10450 $this->namespace = $namespace;
10451 $this->origAliases = $this->aliases = [Stmt\Use_::TYPE_NORMAL => [], Stmt\Use_::TYPE_FUNCTION => [], Stmt\Use_::TYPE_CONSTANT => []];
10452 }
10453 /**
10454 * Add an alias / import.
10455 *
10456 * @param Name $name Original name
10457 * @param string $aliasName Aliased name
10458 * @param Stmt\Use_::TYPE_* $type One of Stmt\Use_::TYPE_*
10459 * @param array<string, mixed> $errorAttrs Attributes to use to report an error
10460 */
10461 public function addAlias(Name $name, string $aliasName, int $type, array $errorAttrs = []): void
10462 {
10463 // Constant names are case sensitive, everything else case insensitive
10464 if ($type === Stmt\Use_::TYPE_CONSTANT) {
10465 $aliasLookupName = $aliasName;
10466 } else {
10467 $aliasLookupName = strtolower($aliasName);
10468 }
10469 if (isset($this->aliases[$type][$aliasLookupName])) {
10470 $typeStringMap = [Stmt\Use_::TYPE_NORMAL => '', Stmt\Use_::TYPE_FUNCTION => 'function ', Stmt\Use_::TYPE_CONSTANT => 'const '];
10471 $this->errorHandler->handleError(new Error(sprintf('Cannot use %s%s as %s because the name is already in use', $typeStringMap[$type], $name, $aliasName), $errorAttrs));
10472 return;
10473 }
10474 $this->aliases[$type][$aliasLookupName] = $name;
10475 $this->origAliases[$type][$aliasName] = $name;
10476 }
10477 /**
10478 * Get current namespace.
10479 *
10480 * @return null|Name Namespace (or null if global namespace)
10481 */
10482 public function getNamespace(): ?Name
10483 {
10484 return $this->namespace;
10485 }
10486 /**
10487 * Get resolved name.
10488 *
10489 * @param Name $name Name to resolve
10490 * @param Stmt\Use_::TYPE_* $type One of Stmt\Use_::TYPE_{FUNCTION|CONSTANT}
10491 *
10492 * @return null|Name Resolved name, or null if static resolution is not possible
10493 */
10494 public function getResolvedName(Name $name, int $type): ?Name
10495 {
10496 // don't resolve special class names
10497 if ($type === Stmt\Use_::TYPE_NORMAL && $name->isSpecialClassName()) {
10498 if (!$name->isUnqualified()) {
10499 $this->errorHandler->handleError(new Error(sprintf("'\\%s' is an invalid class name", $name->toString()), $name->getAttributes()));
10500 }
10501 return $name;
10502 }
10503 // fully qualified names are already resolved
10504 if ($name->isFullyQualified()) {
10505 return $name;
10506 }
10507 // Try to resolve aliases
10508 if (null !== $resolvedName = $this->resolveAlias($name, $type)) {
10509 return $resolvedName;
10510 }
10511 if ($type !== Stmt\Use_::TYPE_NORMAL && $name->isUnqualified()) {
10512 if (null === $this->namespace) {
10513 // outside of a namespace unaliased unqualified is same as fully qualified
10514 return new FullyQualified($name, $name->getAttributes());
10515 }
10516 // Cannot resolve statically
10517 return null;
10518 }
10519 // if no alias exists prepend current namespace
10520 return FullyQualified::concat($this->namespace, $name, $name->getAttributes());
10521 }
10522 /**
10523 * Get resolved class name.
10524 *
10525 * @param Name $name Class ame to resolve
10526 *
10527 * @return Name Resolved name
10528 */
10529 public function getResolvedClassName(Name $name): Name
10530 {
10531 return $this->getResolvedName($name, Stmt\Use_::TYPE_NORMAL);
10532 }
10533 /**
10534 * Get possible ways of writing a fully qualified name (e.g., by making use of aliases).
10535 *
10536 * @param string $name Fully-qualified name (without leading namespace separator)
10537 * @param Stmt\Use_::TYPE_* $type One of Stmt\Use_::TYPE_*
10538 *
10539 * @return Name[] Possible representations of the name
10540 */
10541 public function getPossibleNames(string $name, int $type): array
10542 {
10543 $lcName = strtolower($name);
10544 if ($type === Stmt\Use_::TYPE_NORMAL) {
10545 // self, parent and static must always be unqualified
10546 if ($lcName === "self" || $lcName === "parent" || $lcName === "static") {
10547 return [new Name($name)];
10548 }
10549 }
10550 // Collect possible ways to write this name, starting with the fully-qualified name
10551 $possibleNames = [new FullyQualified($name)];
10552 if (null !== $nsRelativeName = $this->getNamespaceRelativeName($name, $lcName, $type)) {
10553 // Make sure there is no alias that makes the normally namespace-relative name
10554 // into something else
10555 if (null === $this->resolveAlias($nsRelativeName, $type)) {
10556 $possibleNames[] = $nsRelativeName;
10557 }
10558 }
10559 // Check for relevant namespace use statements
10560 foreach ($this->origAliases[Stmt\Use_::TYPE_NORMAL] as $alias => $orig) {
10561 $lcOrig = $orig->toLowerString();
10562 if (0 === strpos($lcName, $lcOrig . '\\')) {
10563 $possibleNames[] = new Name($alias . substr($name, strlen($lcOrig)));
10564 }
10565 }
10566 // Check for relevant type-specific use statements
10567 foreach ($this->origAliases[$type] as $alias => $orig) {
10568 if ($type === Stmt\Use_::TYPE_CONSTANT) {
10569 // Constants are complicated-sensitive
10570 $normalizedOrig = $this->normalizeConstName($orig->toString());
10571 if ($normalizedOrig === $this->normalizeConstName($name)) {
10572 $possibleNames[] = new Name($alias);
10573 }
10574 } else if ($orig->toLowerString() === $lcName) {
10575 $possibleNames[] = new Name($alias);
10576 }
10577 }
10578 return $possibleNames;
10579 }
10580 /**
10581 * Get shortest representation of this fully-qualified name.
10582 *
10583 * @param string $name Fully-qualified name (without leading namespace separator)
10584 * @param Stmt\Use_::TYPE_* $type One of Stmt\Use_::TYPE_*
10585 *
10586 * @return Name Shortest representation
10587 */
10588 public function getShortName(string $name, int $type): Name
10589 {
10590 $possibleNames = $this->getPossibleNames($name, $type);
10591 // Find shortest name
10592 $shortestName = null;
10593 $shortestLength = \INF;
10594 foreach ($possibleNames as $possibleName) {
10595 $length = strlen($possibleName->toCodeString());
10596 if ($length < $shortestLength) {
10597 $shortestName = $possibleName;
10598 $shortestLength = $length;
10599 }
10600 }
10601 return $shortestName;
10602 }
10603 private function resolveAlias(Name $name, int $type): ?FullyQualified
10604 {
10605 $firstPart = $name->getFirst();
10606 if ($name->isQualified()) {
10607 // resolve aliases for qualified names, always against class alias table
10608 $checkName = strtolower($firstPart);
10609 if (isset($this->aliases[Stmt\Use_::TYPE_NORMAL][$checkName])) {
10610 $alias = $this->aliases[Stmt\Use_::TYPE_NORMAL][$checkName];
10611 return FullyQualified::concat($alias, $name->slice(1), $name->getAttributes());
10612 }
10613 } elseif ($name->isUnqualified()) {
10614 // constant aliases are case-sensitive, function aliases case-insensitive
10615 $checkName = $type === Stmt\Use_::TYPE_CONSTANT ? $firstPart : strtolower($firstPart);
10616 if (isset($this->aliases[$type][$checkName])) {
10617 // resolve unqualified aliases
10618 return new FullyQualified($this->aliases[$type][$checkName], $name->getAttributes());
10619 }
10620 }
10621 // No applicable aliases
10622 return null;
10623 }
10624 private function getNamespaceRelativeName(string $name, string $lcName, int $type): ?Name
10625 {
10626 if (null === $this->namespace) {
10627 return new Name($name);
10628 }
10629 if ($type === Stmt\Use_::TYPE_CONSTANT) {
10630 // The constants true/false/null always resolve to the global symbols, even inside a
10631 // namespace, so they may be used without qualification
10632 if ($lcName === "true" || $lcName === "false" || $lcName === "null") {
10633 return new Name($name);
10634 }
10635 }
10636 $namespacePrefix = strtolower($this->namespace . '\\');
10637 if (0 === strpos($lcName, $namespacePrefix)) {
10638 return new Name(substr($name, strlen($namespacePrefix)));
10639 }
10640 return null;
10641 }
10642 private function normalizeConstName(string $name): string
10643 {
10644 $nsSep = strrpos($name, '\\');
10645 if (\false === $nsSep) {
10646 return $name;
10647 }
10648 // Constants have case-insensitive namespace and case-sensitive short-name
10649 $ns = substr($name, 0, $nsSep);
10650 $shortName = substr($name, $nsSep + 1);
10651 return strtolower($ns) . '\\' . $shortName;
10652 }
10653 }
10654 <?php
10655
10656 declare (strict_types=1);
10657 namespace PHPUnitPHAR\PhpParser;
10658
10659 interface Node
10660 {
10661 /**
10662 * Gets the type of the node.
10663 *
10664 * @psalm-return non-empty-string
10665 * @return string Type of the node
10666 */
10667 public function getType(): string;
10668 /**
10669 * Gets the names of the sub nodes.
10670 *
10671 * @return string[] Names of sub nodes
10672 */
10673 public function getSubNodeNames(): array;
10674 /**
10675 * Gets line the node started in (alias of getStartLine).
10676 *
10677 * @return int Start line (or -1 if not available)
10678 * @phpstan-return -1|positive-int
10679 *
10680 * @deprecated Use getStartLine() instead
10681 */
10682 public function getLine(): int;
10683 /**
10684 * Gets line the node started in.
10685 *
10686 * Requires the 'startLine' attribute to be enabled in the lexer (enabled by default).
10687 *
10688 * @return int Start line (or -1 if not available)
10689 * @phpstan-return -1|positive-int
10690 */
10691 public function getStartLine(): int;
10692 /**
10693 * Gets the line the node ended in.
10694 *
10695 * Requires the 'endLine' attribute to be enabled in the lexer (enabled by default).
10696 *
10697 * @return int End line (or -1 if not available)
10698 * @phpstan-return -1|positive-int
10699 */
10700 public function getEndLine(): int;
10701 /**
10702 * Gets the token offset of the first token that is part of this node.
10703 *
10704 * The offset is an index into the array returned by Lexer::getTokens().
10705 *
10706 * Requires the 'startTokenPos' attribute to be enabled in the lexer (DISABLED by default).
10707 *
10708 * @return int Token start position (or -1 if not available)
10709 */
10710 public function getStartTokenPos(): int;
10711 /**
10712 * Gets the token offset of the last token that is part of this node.
10713 *
10714 * The offset is an index into the array returned by Lexer::getTokens().
10715 *
10716 * Requires the 'endTokenPos' attribute to be enabled in the lexer (DISABLED by default).
10717 *
10718 * @return int Token end position (or -1 if not available)
10719 */
10720 public function getEndTokenPos(): int;
10721 /**
10722 * Gets the file offset of the first character that is part of this node.
10723 *
10724 * Requires the 'startFilePos' attribute to be enabled in the lexer (DISABLED by default).
10725 *
10726 * @return int File start position (or -1 if not available)
10727 */
10728 public function getStartFilePos(): int;
10729 /**
10730 * Gets the file offset of the last character that is part of this node.
10731 *
10732 * Requires the 'endFilePos' attribute to be enabled in the lexer (DISABLED by default).
10733 *
10734 * @return int File end position (or -1 if not available)
10735 */
10736 public function getEndFilePos(): int;
10737 /**
10738 * Gets all comments directly preceding this node.
10739 *
10740 * The comments are also available through the "comments" attribute.
10741 *
10742 * @return Comment[]
10743 */
10744 public function getComments(): array;
10745 /**
10746 * Gets the doc comment of the node.
10747 *
10748 * @return null|Comment\Doc Doc comment object or null
10749 */
10750 public function getDocComment(): ?Comment\Doc;
10751 /**
10752 * Sets the doc comment of the node.
10753 *
10754 * This will either replace an existing doc comment or add it to the comments array.
10755 *
10756 * @param Comment\Doc $docComment Doc comment to set
10757 */
10758 public function setDocComment(Comment\Doc $docComment): void;
10759 /**
10760 * Sets an attribute on a node.
10761 *
10762 * @param mixed $value
10763 */
10764 public function setAttribute(string $key, $value): void;
10765 /**
10766 * Returns whether an attribute exists.
10767 */
10768 public function hasAttribute(string $key): bool;
10769 /**
10770 * Returns the value of an attribute.
10771 *
10772 * @param mixed $default
10773 *
10774 * @return mixed
10775 */
10776 public function getAttribute(string $key, $default = null);
10777 /**
10778 * Returns all the attributes of this node.
10779 *
10780 * @return array<string, mixed>
10781 */
10782 public function getAttributes(): array;
10783 /**
10784 * Replaces all the attributes of this node.
10785 *
10786 * @param array<string, mixed> $attributes
10787 */
10788 public function setAttributes(array $attributes): void;
10789 }
10790 <?php
10791
10792 declare (strict_types=1);
10793 namespace PHPUnitPHAR\PhpParser\Node;
10794
10795 use PHPUnitPHAR\PhpParser\NodeAbstract;
10796 class Arg extends NodeAbstract
10797 {
10798 /** @var Identifier|null Parameter name (for named parameters) */
10799 public ?Identifier $name;
10800 /** @var Expr Value to pass */
10801 public Expr $value;
10802 /** @var bool Whether to pass by ref */
10803 public bool $byRef;
10804 /** @var bool Whether to unpack the argument */
10805 public bool $unpack;
10806 /**
10807 * Constructs a function call argument node.
10808 *
10809 * @param Expr $value Value to pass
10810 * @param bool $byRef Whether to pass by ref
10811 * @param bool $unpack Whether to unpack the argument
10812 * @param array<string, mixed> $attributes Additional attributes
10813 * @param Identifier|null $name Parameter name (for named parameters)
10814 */
10815 public function __construct(Expr $value, bool $byRef = \false, bool $unpack = \false, array $attributes = [], ?Identifier $name = null)
10816 {
10817 $this->attributes = $attributes;
10818 $this->name = $name;
10819 $this->value = $value;
10820 $this->byRef = $byRef;
10821 $this->unpack = $unpack;
10822 }
10823 public function getSubNodeNames(): array
10824 {
10825 return ['name', 'value', 'byRef', 'unpack'];
10826 }
10827 public function getType(): string
10828 {
10829 return 'Arg';
10830 }
10831 }
10832 <?php
10833
10834 declare (strict_types=1);
10835 namespace PHPUnitPHAR\PhpParser\Node;
10836
10837 use PHPUnitPHAR\PhpParser\NodeAbstract;
10838 class ArrayItem extends NodeAbstract
10839 {
10840 /** @var null|Expr Key */
10841 public ?Expr $key;
10842 /** @var Expr Value */
10843 public Expr $value;
10844 /** @var bool Whether to assign by reference */
10845 public bool $byRef;
10846 /** @var bool Whether to unpack the argument */
10847 public bool $unpack;
10848 /**
10849 * Constructs an array item node.
10850 *
10851 * @param Expr $value Value
10852 * @param null|Expr $key Key
10853 * @param bool $byRef Whether to assign by reference
10854 * @param array<string, mixed> $attributes Additional attributes
10855 */
10856 public function __construct(Expr $value, ?Expr $key = null, bool $byRef = \false, array $attributes = [], bool $unpack = \false)
10857 {
10858 $this->attributes = $attributes;
10859 $this->key = $key;
10860 $this->value = $value;
10861 $this->byRef = $byRef;
10862 $this->unpack = $unpack;
10863 }
10864 public function getSubNodeNames(): array
10865 {
10866 return ['key', 'value', 'byRef', 'unpack'];
10867 }
10868 public function getType(): string
10869 {
10870 return 'ArrayItem';
10871 }
10872 }
10873 // @deprecated compatibility alias
10874 class_alias(ArrayItem::class, Expr\ArrayItem::class);
10875 <?php
10876
10877 declare (strict_types=1);
10878 namespace PHPUnitPHAR\PhpParser\Node;
10879
10880 use PHPUnitPHAR\PhpParser\Node;
10881 use PHPUnitPHAR\PhpParser\NodeAbstract;
10882 class Attribute extends NodeAbstract
10883 {
10884 /** @var Name Attribute name */
10885 public Name $name;
10886 /** @var list<Arg> Attribute arguments */
10887 public array $args;
10888 /**
10889 * @param Node\Name $name Attribute name
10890 * @param list<Arg> $args Attribute arguments
10891 * @param array<string, mixed> $attributes Additional node attributes
10892 */
10893 public function __construct(Name $name, array $args = [], array $attributes = [])
10894 {
10895 $this->attributes = $attributes;
10896 $this->name = $name;
10897 $this->args = $args;
10898 }
10899 public function getSubNodeNames(): array
10900 {
10901 return ['name', 'args'];
10902 }
10903 public function getType(): string
10904 {
10905 return 'Attribute';
10906 }
10907 }
10908 <?php
10909
10910 declare (strict_types=1);
10911 namespace PHPUnitPHAR\PhpParser\Node;
10912
10913 use PHPUnitPHAR\PhpParser\NodeAbstract;
10914 class AttributeGroup extends NodeAbstract
10915 {
10916 /** @var Attribute[] Attributes */
10917 public array $attrs;
10918 /**
10919 * @param Attribute[] $attrs PHP attributes
10920 * @param array<string, mixed> $attributes Additional node attributes
10921 */
10922 public function __construct(array $attrs, array $attributes = [])
10923 {
10924 $this->attributes = $attributes;
10925 $this->attrs = $attrs;
10926 }
10927 public function getSubNodeNames(): array
10928 {
10929 return ['attrs'];
10930 }
10931 public function getType(): string
10932 {
10933 return 'AttributeGroup';
10934 }
10935 }
10936 <?php
10937
10938 declare (strict_types=1);
10939 namespace PHPUnitPHAR\PhpParser\Node;
10940
10941 use PHPUnitPHAR\PhpParser\NodeAbstract;
10942 class ClosureUse extends NodeAbstract
10943 {
10944 /** @var Expr\Variable Variable to use */
10945 public Expr\Variable $var;
10946 /** @var bool Whether to use by reference */
10947 public bool $byRef;
10948 /**
10949 * Constructs a closure use node.
10950 *
10951 * @param Expr\Variable $var Variable to use
10952 * @param bool $byRef Whether to use by reference
10953 * @param array<string, mixed> $attributes Additional attributes
10954 */
10955 public function __construct(Expr\Variable $var, bool $byRef = \false, array $attributes = [])
10956 {
10957 $this->attributes = $attributes;
10958 $this->var = $var;
10959 $this->byRef = $byRef;
10960 }
10961 public function getSubNodeNames(): array
10962 {
10963 return ['var', 'byRef'];
10964 }
10965 public function getType(): string
10966 {
10967 return 'ClosureUse';
10968 }
10969 }
10970 // @deprecated compatibility alias
10971 class_alias(ClosureUse::class, Expr\ClosureUse::class);
10972 <?php
10973
10974 declare (strict_types=1);
10975 namespace PHPUnitPHAR\PhpParser\Node;
10976
10977 use PHPUnitPHAR\PhpParser\NodeAbstract;
10978 /**
10979 * This is a base class for complex types, including nullable types and union types.
10980 *
10981 * It does not provide any shared behavior and exists only for type-checking purposes.
10982 */
10983 abstract class ComplexType extends NodeAbstract
10984 {
10985 }
10986 <?php
10987
10988 declare (strict_types=1);
10989 namespace PHPUnitPHAR\PhpParser\Node;
10990
10991 use PHPUnitPHAR\PhpParser\NodeAbstract;
10992 class Const_ extends NodeAbstract
10993 {
10994 /** @var Identifier Name */
10995 public Identifier $name;
10996 /** @var Expr Value */
10997 public Expr $value;
10998 /** @var Name|null Namespaced name (if using NameResolver) */
10999 public ?Name $namespacedName;
11000 /**
11001 * Constructs a const node for use in class const and const statements.
11002 *
11003 * @param string|Identifier $name Name
11004 * @param Expr $value Value
11005 * @param array<string, mixed> $attributes Additional attributes
11006 */
11007 public function __construct($name, Expr $value, array $attributes = [])
11008 {
11009 $this->attributes = $attributes;
11010 $this->name = \is_string($name) ? new Identifier($name) : $name;
11011 $this->value = $value;
11012 }
11013 public function getSubNodeNames(): array
11014 {
11015 return ['name', 'value'];
11016 }
11017 public function getType(): string
11018 {
11019 return 'Const';
11020 }
11021 }
11022 <?php
11023
11024 declare (strict_types=1);
11025 namespace PHPUnitPHAR\PhpParser\Node;
11026
11027 use PHPUnitPHAR\PhpParser\Node;
11028 use PHPUnitPHAR\PhpParser\NodeAbstract;
11029 class DeclareItem extends NodeAbstract
11030 {
11031 /** @var Node\Identifier Key */
11032 public Identifier $key;
11033 /** @var Node\Expr Value */
11034 public Expr $value;
11035 /**
11036 * Constructs a declare key=>value pair node.
11037 *
11038 * @param string|Node\Identifier $key Key
11039 * @param Node\Expr $value Value
11040 * @param array<string, mixed> $attributes Additional attributes
11041 */
11042 public function __construct($key, Node\Expr $value, array $attributes = [])
11043 {
11044 $this->attributes = $attributes;
11045 $this->key = \is_string($key) ? new Node\Identifier($key) : $key;
11046 $this->value = $value;
11047 }
11048 public function getSubNodeNames(): array
11049 {
11050 return ['key', 'value'];
11051 }
11052 public function getType(): string
11053 {
11054 return 'DeclareItem';
11055 }
11056 }
11057 // @deprecated compatibility alias
11058 class_alias(DeclareItem::class, Stmt\DeclareDeclare::class);
11059 <?php
11060
11061 declare (strict_types=1);
11062 namespace PHPUnitPHAR\PhpParser\Node;
11063
11064 use PHPUnitPHAR\PhpParser\NodeAbstract;
11065 abstract class Expr extends NodeAbstract
11066 {
11067 }
11068 <?php
11069
11070 declare (strict_types=1);
11071 namespace PHPUnitPHAR\PhpParser\Node\Expr;
11072
11073 use PHPUnitPHAR\PhpParser\Node\Expr;
11074 class ArrayDimFetch extends Expr
11075 {
11076 /** @var Expr Variable */
11077 public Expr $var;
11078 /** @var null|Expr Array index / dim */
11079 public ?Expr $dim;
11080 /**
11081 * Constructs an array index fetch node.
11082 *
11083 * @param Expr $var Variable
11084 * @param null|Expr $dim Array index / dim
11085 * @param array<string, mixed> $attributes Additional attributes
11086 */
11087 public function __construct(Expr $var, ?Expr $dim = null, array $attributes = [])
11088 {
11089 $this->attributes = $attributes;
11090 $this->var = $var;
11091 $this->dim = $dim;
11092 }
11093 public function getSubNodeNames(): array
11094 {
11095 return ['var', 'dim'];
11096 }
11097 public function getType(): string
11098 {
11099 return 'Expr_ArrayDimFetch';
11100 }
11101 }
11102 <?php
11103
11104 declare (strict_types=1);
11105 namespace PHPUnitPHAR\PhpParser\Node\Expr;
11106
11107 use PHPUnitPHAR\PhpParser\Node\ArrayItem;
11108 use PHPUnitPHAR\PhpParser\Node\Expr;
11109 class Array_ extends Expr
11110 {
11111 // For use in "kind" attribute
11112 public const KIND_LONG = 1;
11113 // array() syntax
11114 public const KIND_SHORT = 2;
11115 // [] syntax
11116 /** @var ArrayItem[] Items */
11117 public array $items;
11118 /**
11119 * Constructs an array node.
11120 *
11121 * @param ArrayItem[] $items Items of the array
11122 * @param array<string, mixed> $attributes Additional attributes
11123 */
11124 public function __construct(array $items = [], array $attributes = [])
11125 {
11126 $this->attributes = $attributes;
11127 $this->items = $items;
11128 }
11129 public function getSubNodeNames(): array
11130 {
11131 return ['items'];
11132 }
11133 public function getType(): string
11134 {
11135 return 'Expr_Array';
11136 }
11137 }
11138 <?php
11139
11140 declare (strict_types=1);
11141 namespace PHPUnitPHAR\PhpParser\Node\Expr;
11142
11143 use PHPUnitPHAR\PhpParser\Node;
11144 use PHPUnitPHAR\PhpParser\Node\Expr;
11145 use PHPUnitPHAR\PhpParser\Node\FunctionLike;
11146 class ArrowFunction extends Expr implements FunctionLike
11147 {
11148 /** @var bool Whether the closure is static */
11149 public bool $static;
11150 /** @var bool Whether to return by reference */
11151 public bool $byRef;
11152 /** @var Node\Param[] */
11153 public array $params = [];
11154 /** @var null|Node\Identifier|Node\Name|Node\ComplexType */
11155 public ?Node $returnType;
11156 /** @var Expr Expression body */
11157 public Expr $expr;
11158 /** @var Node\AttributeGroup[] */
11159 public array $attrGroups;
11160 /**
11161 * @param array{
11162 * expr: Expr,
11163 * static?: bool,
11164 * byRef?: bool,
11165 * params?: Node\Param[],
11166 * returnType?: null|Node\Identifier|Node\Name|Node\ComplexType,
11167 * attrGroups?: Node\AttributeGroup[]
11168 * } $subNodes Array of the following subnodes:
11169 * 'expr' : Expression body
11170 * 'static' => false : Whether the closure is static
11171 * 'byRef' => false : Whether to return by reference
11172 * 'params' => array() : Parameters
11173 * 'returnType' => null : Return type
11174 * 'attrGroups' => array() : PHP attribute groups
11175 * @param array<string, mixed> $attributes Additional attributes
11176 */
11177 public function __construct(array $subNodes, array $attributes = [])
11178 {
11179 $this->attributes = $attributes;
11180 $this->static = $subNodes['static'] ?? \false;
11181 $this->byRef = $subNodes['byRef'] ?? \false;
11182 $this->params = $subNodes['params'] ?? [];
11183 $this->returnType = $subNodes['returnType'] ?? null;
11184 $this->expr = $subNodes['expr'];
11185 $this->attrGroups = $subNodes['attrGroups'] ?? [];
11186 }
11187 public function getSubNodeNames(): array
11188 {
11189 return ['attrGroups', 'static', 'byRef', 'params', 'returnType', 'expr'];
11190 }
11191 public function returnsByRef(): bool
11192 {
11193 return $this->byRef;
11194 }
11195 public function getParams(): array
11196 {
11197 return $this->params;
11198 }
11199 public function getReturnType()
11200 {
11201 return $this->returnType;
11202 }
11203 public function getAttrGroups(): array
11204 {
11205 return $this->attrGroups;
11206 }
11207 /**
11208 * @return Node\Stmt\Return_[]
11209 */
11210 public function getStmts(): array
11211 {
11212 return [new Node\Stmt\Return_($this->expr)];
11213 }
11214 public function getType(): string
11215 {
11216 return 'Expr_ArrowFunction';
11217 }
11218 }
11219 <?php
11220
11221 declare (strict_types=1);
11222 namespace PHPUnitPHAR\PhpParser\Node\Expr;
11223
11224 use PHPUnitPHAR\PhpParser\Node\Expr;
11225 class Assign extends Expr
11226 {
11227 /** @var Expr Variable */
11228 public Expr $var;
11229 /** @var Expr Expression */
11230 public Expr $expr;
11231 /**
11232 * Constructs an assignment node.
11233 *
11234 * @param Expr $var Variable
11235 * @param Expr $expr Expression
11236 * @param array<string, mixed> $attributes Additional attributes
11237 */
11238 public function __construct(Expr $var, Expr $expr, array $attributes = [])
11239 {
11240 $this->attributes = $attributes;
11241 $this->var = $var;
11242 $this->expr = $expr;
11243 }
11244 public function getSubNodeNames(): array
11245 {
11246 return ['var', 'expr'];
11247 }
11248 public function getType(): string
11249 {
11250 return 'Expr_Assign';
11251 }
11252 }
11253 <?php
11254
11255 declare (strict_types=1);
11256 namespace PHPUnitPHAR\PhpParser\Node\Expr;
11257
11258 use PHPUnitPHAR\PhpParser\Node\Expr;
11259 abstract class AssignOp extends Expr
11260 {
11261 /** @var Expr Variable */
11262 public Expr $var;
11263 /** @var Expr Expression */
11264 public Expr $expr;
11265 /**
11266 * Constructs a compound assignment operation node.
11267 *
11268 * @param Expr $var Variable
11269 * @param Expr $expr Expression
11270 * @param array<string, mixed> $attributes Additional attributes
11271 */
11272 public function __construct(Expr $var, Expr $expr, array $attributes = [])
11273 {
11274 $this->attributes = $attributes;
11275 $this->var = $var;
11276 $this->expr = $expr;
11277 }
11278 public function getSubNodeNames(): array
11279 {
11280 return ['var', 'expr'];
11281 }
11282 }
11283 <?php
11284
11285 declare (strict_types=1);
11286 namespace PHPUnitPHAR\PhpParser\Node\Expr\AssignOp;
11287
11288 use PHPUnitPHAR\PhpParser\Node\Expr\AssignOp;
11289 class BitwiseAnd extends AssignOp
11290 {
11291 public function getType(): string
11292 {
11293 return 'Expr_AssignOp_BitwiseAnd';
11294 }
11295 }
11296 <?php
11297
11298 declare (strict_types=1);
11299 namespace PHPUnitPHAR\PhpParser\Node\Expr\AssignOp;
11300
11301 use PHPUnitPHAR\PhpParser\Node\Expr\AssignOp;
11302 class BitwiseOr extends AssignOp
11303 {
11304 public function getType(): string
11305 {
11306 return 'Expr_AssignOp_BitwiseOr';
11307 }
11308 }
11309 <?php
11310
11311 declare (strict_types=1);
11312 namespace PHPUnitPHAR\PhpParser\Node\Expr\AssignOp;
11313
11314 use PHPUnitPHAR\PhpParser\Node\Expr\AssignOp;
11315 class BitwiseXor extends AssignOp
11316 {
11317 public function getType(): string
11318 {
11319 return 'Expr_AssignOp_BitwiseXor';
11320 }
11321 }
11322 <?php
11323
11324 declare (strict_types=1);
11325 namespace PHPUnitPHAR\PhpParser\Node\Expr\AssignOp;
11326
11327 use PHPUnitPHAR\PhpParser\Node\Expr\AssignOp;
11328 class Coalesce extends AssignOp
11329 {
11330 public function getType(): string
11331 {
11332 return 'Expr_AssignOp_Coalesce';
11333 }
11334 }
11335 <?php
11336
11337 declare (strict_types=1);
11338 namespace PHPUnitPHAR\PhpParser\Node\Expr\AssignOp;
11339
11340 use PHPUnitPHAR\PhpParser\Node\Expr\AssignOp;
11341 class Concat extends AssignOp
11342 {
11343 public function getType(): string
11344 {
11345 return 'Expr_AssignOp_Concat';
11346 }
11347 }
11348 <?php
11349
11350 declare (strict_types=1);
11351 namespace PHPUnitPHAR\PhpParser\Node\Expr\AssignOp;
11352
11353 use PHPUnitPHAR\PhpParser\Node\Expr\AssignOp;
11354 class Div extends AssignOp
11355 {
11356 public function getType(): string
11357 {
11358 return 'Expr_AssignOp_Div';
11359 }
11360 }
11361 <?php
11362
11363 declare (strict_types=1);
11364 namespace PHPUnitPHAR\PhpParser\Node\Expr\AssignOp;
11365
11366 use PHPUnitPHAR\PhpParser\Node\Expr\AssignOp;
11367 class Minus extends AssignOp
11368 {
11369 public function getType(): string
11370 {
11371 return 'Expr_AssignOp_Minus';
11372 }
11373 }
11374 <?php
11375
11376 declare (strict_types=1);
11377 namespace PHPUnitPHAR\PhpParser\Node\Expr\AssignOp;
11378
11379 use PHPUnitPHAR\PhpParser\Node\Expr\AssignOp;
11380 class Mod extends AssignOp
11381 {
11382 public function getType(): string
11383 {
11384 return 'Expr_AssignOp_Mod';
11385 }
11386 }
11387 <?php
11388
11389 declare (strict_types=1);
11390 namespace PHPUnitPHAR\PhpParser\Node\Expr\AssignOp;
11391
11392 use PHPUnitPHAR\PhpParser\Node\Expr\AssignOp;
11393 class Mul extends AssignOp
11394 {
11395 public function getType(): string
11396 {
11397 return 'Expr_AssignOp_Mul';
11398 }
11399 }
11400 <?php
11401
11402 declare (strict_types=1);
11403 namespace PHPUnitPHAR\PhpParser\Node\Expr\AssignOp;
11404
11405 use PHPUnitPHAR\PhpParser\Node\Expr\AssignOp;
11406 class Plus extends AssignOp
11407 {
11408 public function getType(): string
11409 {
11410 return 'Expr_AssignOp_Plus';
11411 }
11412 }
11413 <?php
11414
11415 declare (strict_types=1);
11416 namespace PHPUnitPHAR\PhpParser\Node\Expr\AssignOp;
11417
11418 use PHPUnitPHAR\PhpParser\Node\Expr\AssignOp;
11419 class Pow extends AssignOp
11420 {
11421 public function getType(): string
11422 {
11423 return 'Expr_AssignOp_Pow';
11424 }
11425 }
11426 <?php
11427
11428 declare (strict_types=1);
11429 namespace PHPUnitPHAR\PhpParser\Node\Expr\AssignOp;
11430
11431 use PHPUnitPHAR\PhpParser\Node\Expr\AssignOp;
11432 class ShiftLeft extends AssignOp
11433 {
11434 public function getType(): string
11435 {
11436 return 'Expr_AssignOp_ShiftLeft';
11437 }
11438 }
11439 <?php
11440
11441 declare (strict_types=1);
11442 namespace PHPUnitPHAR\PhpParser\Node\Expr\AssignOp;
11443
11444 use PHPUnitPHAR\PhpParser\Node\Expr\AssignOp;
11445 class ShiftRight extends AssignOp
11446 {
11447 public function getType(): string
11448 {
11449 return 'Expr_AssignOp_ShiftRight';
11450 }
11451 }
11452 <?php
11453
11454 declare (strict_types=1);
11455 namespace PHPUnitPHAR\PhpParser\Node\Expr;
11456
11457 use PHPUnitPHAR\PhpParser\Node\Expr;
11458 class AssignRef extends Expr
11459 {
11460 /** @var Expr Variable reference is assigned to */
11461 public Expr $var;
11462 /** @var Expr Variable which is referenced */
11463 public Expr $expr;
11464 /**
11465 * Constructs an assignment node.
11466 *
11467 * @param Expr $var Variable
11468 * @param Expr $expr Expression
11469 * @param array<string, mixed> $attributes Additional attributes
11470 */
11471 public function __construct(Expr $var, Expr $expr, array $attributes = [])
11472 {
11473 $this->attributes = $attributes;
11474 $this->var = $var;
11475 $this->expr = $expr;
11476 }
11477 public function getSubNodeNames(): array
11478 {
11479 return ['var', 'expr'];
11480 }
11481 public function getType(): string
11482 {
11483 return 'Expr_AssignRef';
11484 }
11485 }
11486 <?php
11487
11488 declare (strict_types=1);
11489 namespace PHPUnitPHAR\PhpParser\Node\Expr;
11490
11491 use PHPUnitPHAR\PhpParser\Node\Expr;
11492 abstract class BinaryOp extends Expr
11493 {
11494 /** @var Expr The left hand side expression */
11495 public Expr $left;
11496 /** @var Expr The right hand side expression */
11497 public Expr $right;
11498 /**
11499 * Constructs a binary operator node.
11500 *
11501 * @param Expr $left The left hand side expression
11502 * @param Expr $right The right hand side expression
11503 * @param array<string, mixed> $attributes Additional attributes
11504 */
11505 public function __construct(Expr $left, Expr $right, array $attributes = [])
11506 {
11507 $this->attributes = $attributes;
11508 $this->left = $left;
11509 $this->right = $right;
11510 }
11511 public function getSubNodeNames(): array
11512 {
11513 return ['left', 'right'];
11514 }
11515 /**
11516 * Get the operator sigil for this binary operation.
11517 *
11518 * In the case there are multiple possible sigils for an operator, this method does not
11519 * necessarily return the one used in the parsed code.
11520 */
11521 abstract public function getOperatorSigil(): string;
11522 }
11523 <?php
11524
11525 declare (strict_types=1);
11526 namespace PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp;
11527
11528 use PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp;
11529 class BitwiseAnd extends BinaryOp
11530 {
11531 public function getOperatorSigil(): string
11532 {
11533 return '&';
11534 }
11535 public function getType(): string
11536 {
11537 return 'Expr_BinaryOp_BitwiseAnd';
11538 }
11539 }
11540 <?php
11541
11542 declare (strict_types=1);
11543 namespace PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp;
11544
11545 use PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp;
11546 class BitwiseOr extends BinaryOp
11547 {
11548 public function getOperatorSigil(): string
11549 {
11550 return '|';
11551 }
11552 public function getType(): string
11553 {
11554 return 'Expr_BinaryOp_BitwiseOr';
11555 }
11556 }
11557 <?php
11558
11559 declare (strict_types=1);
11560 namespace PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp;
11561
11562 use PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp;
11563 class BitwiseXor extends BinaryOp
11564 {
11565 public function getOperatorSigil(): string
11566 {
11567 return '^';
11568 }
11569 public function getType(): string
11570 {
11571 return 'Expr_BinaryOp_BitwiseXor';
11572 }
11573 }
11574 <?php
11575
11576 declare (strict_types=1);
11577 namespace PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp;
11578
11579 use PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp;
11580 class BooleanAnd extends BinaryOp
11581 {
11582 public function getOperatorSigil(): string
11583 {
11584 return '&&';
11585 }
11586 public function getType(): string
11587 {
11588 return 'Expr_BinaryOp_BooleanAnd';
11589 }
11590 }
11591 <?php
11592
11593 declare (strict_types=1);
11594 namespace PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp;
11595
11596 use PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp;
11597 class BooleanOr extends BinaryOp
11598 {
11599 public function getOperatorSigil(): string
11600 {
11601 return '||';
11602 }
11603 public function getType(): string
11604 {
11605 return 'Expr_BinaryOp_BooleanOr';
11606 }
11607 }
11608 <?php
11609
11610 declare (strict_types=1);
11611 namespace PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp;
11612
11613 use PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp;
11614 class Coalesce extends BinaryOp
11615 {
11616 public function getOperatorSigil(): string
11617 {
11618 return '??';
11619 }
11620 public function getType(): string
11621 {
11622 return 'Expr_BinaryOp_Coalesce';
11623 }
11624 }
11625 <?php
11626
11627 declare (strict_types=1);
11628 namespace PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp;
11629
11630 use PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp;
11631 class Concat extends BinaryOp
11632 {
11633 public function getOperatorSigil(): string
11634 {
11635 return '.';
11636 }
11637 public function getType(): string
11638 {
11639 return 'Expr_BinaryOp_Concat';
11640 }
11641 }
11642 <?php
11643
11644 declare (strict_types=1);
11645 namespace PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp;
11646
11647 use PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp;
11648 class Div extends BinaryOp
11649 {
11650 public function getOperatorSigil(): string
11651 {
11652 return '/';
11653 }
11654 public function getType(): string
11655 {
11656 return 'Expr_BinaryOp_Div';
11657 }
11658 }
11659 <?php
11660
11661 declare (strict_types=1);
11662 namespace PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp;
11663
11664 use PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp;
11665 class Equal extends BinaryOp
11666 {
11667 public function getOperatorSigil(): string
11668 {
11669 return '==';
11670 }
11671 public function getType(): string
11672 {
11673 return 'Expr_BinaryOp_Equal';
11674 }
11675 }
11676 <?php
11677
11678 declare (strict_types=1);
11679 namespace PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp;
11680
11681 use PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp;
11682 class Greater extends BinaryOp
11683 {
11684 public function getOperatorSigil(): string
11685 {
11686 return '>';
11687 }
11688 public function getType(): string
11689 {
11690 return 'Expr_BinaryOp_Greater';
11691 }
11692 }
11693 <?php
11694
11695 declare (strict_types=1);
11696 namespace PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp;
11697
11698 use PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp;
11699 class GreaterOrEqual extends BinaryOp
11700 {
11701 public function getOperatorSigil(): string
11702 {
11703 return '>=';
11704 }
11705 public function getType(): string
11706 {
11707 return 'Expr_BinaryOp_GreaterOrEqual';
11708 }
11709 }
11710 <?php
11711
11712 declare (strict_types=1);
11713 namespace PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp;
11714
11715 use PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp;
11716 class Identical extends BinaryOp
11717 {
11718 public function getOperatorSigil(): string
11719 {
11720 return '===';
11721 }
11722 public function getType(): string
11723 {
11724 return 'Expr_BinaryOp_Identical';
11725 }
11726 }
11727 <?php
11728
11729 declare (strict_types=1);
11730 namespace PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp;
11731
11732 use PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp;
11733 class LogicalAnd extends BinaryOp
11734 {
11735 public function getOperatorSigil(): string
11736 {
11737 return 'and';
11738 }
11739 public function getType(): string
11740 {
11741 return 'Expr_BinaryOp_LogicalAnd';
11742 }
11743 }
11744 <?php
11745
11746 declare (strict_types=1);
11747 namespace PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp;
11748
11749 use PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp;
11750 class LogicalOr extends BinaryOp
11751 {
11752 public function getOperatorSigil(): string
11753 {
11754 return 'or';
11755 }
11756 public function getType(): string
11757 {
11758 return 'Expr_BinaryOp_LogicalOr';
11759 }
11760 }
11761 <?php
11762
11763 declare (strict_types=1);
11764 namespace PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp;
11765
11766 use PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp;
11767 class LogicalXor extends BinaryOp
11768 {
11769 public function getOperatorSigil(): string
11770 {
11771 return 'xor';
11772 }
11773 public function getType(): string
11774 {
11775 return 'Expr_BinaryOp_LogicalXor';
11776 }
11777 }
11778 <?php
11779
11780 declare (strict_types=1);
11781 namespace PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp;
11782
11783 use PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp;
11784 class Minus extends BinaryOp
11785 {
11786 public function getOperatorSigil(): string
11787 {
11788 return '-';
11789 }
11790 public function getType(): string
11791 {
11792 return 'Expr_BinaryOp_Minus';
11793 }
11794 }
11795 <?php
11796
11797 declare (strict_types=1);
11798 namespace PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp;
11799
11800 use PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp;
11801 class Mod extends BinaryOp
11802 {
11803 public function getOperatorSigil(): string
11804 {
11805 return '%';
11806 }
11807 public function getType(): string
11808 {
11809 return 'Expr_BinaryOp_Mod';
11810 }
11811 }
11812 <?php
11813
11814 declare (strict_types=1);
11815 namespace PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp;
11816
11817 use PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp;
11818 class Mul extends BinaryOp
11819 {
11820 public function getOperatorSigil(): string
11821 {
11822 return '*';
11823 }
11824 public function getType(): string
11825 {
11826 return 'Expr_BinaryOp_Mul';
11827 }
11828 }
11829 <?php
11830
11831 declare (strict_types=1);
11832 namespace PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp;
11833
11834 use PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp;
11835 class NotEqual extends BinaryOp
11836 {
11837 public function getOperatorSigil(): string
11838 {
11839 return '!=';
11840 }
11841 public function getType(): string
11842 {
11843 return 'Expr_BinaryOp_NotEqual';
11844 }
11845 }
11846 <?php
11847
11848 declare (strict_types=1);
11849 namespace PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp;
11850
11851 use PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp;
11852 class NotIdentical extends BinaryOp
11853 {
11854 public function getOperatorSigil(): string
11855 {
11856 return '!==';
11857 }
11858 public function getType(): string
11859 {
11860 return 'Expr_BinaryOp_NotIdentical';
11861 }
11862 }
11863 <?php
11864
11865 declare (strict_types=1);
11866 namespace PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp;
11867
11868 use PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp;
11869 class Pipe extends BinaryOp
11870 {
11871 public function getOperatorSigil(): string
11872 {
11873 return '|>';
11874 }
11875 public function getType(): string
11876 {
11877 return 'Expr_BinaryOp_Pipe';
11878 }
11879 }
11880 <?php
11881
11882 declare (strict_types=1);
11883 namespace PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp;
11884
11885 use PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp;
11886 class Plus extends BinaryOp
11887 {
11888 public function getOperatorSigil(): string
11889 {
11890 return '+';
11891 }
11892 public function getType(): string
11893 {
11894 return 'Expr_BinaryOp_Plus';
11895 }
11896 }
11897 <?php
11898
11899 declare (strict_types=1);
11900 namespace PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp;
11901
11902 use PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp;
11903 class Pow extends BinaryOp
11904 {
11905 public function getOperatorSigil(): string
11906 {
11907 return '**';
11908 }
11909 public function getType(): string
11910 {
11911 return 'Expr_BinaryOp_Pow';
11912 }
11913 }
11914 <?php
11915
11916 declare (strict_types=1);
11917 namespace PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp;
11918
11919 use PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp;
11920 class ShiftLeft extends BinaryOp
11921 {
11922 public function getOperatorSigil(): string
11923 {
11924 return '<<';
11925 }
11926 public function getType(): string
11927 {
11928 return 'Expr_BinaryOp_ShiftLeft';
11929 }
11930 }
11931 <?php
11932
11933 declare (strict_types=1);
11934 namespace PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp;
11935
11936 use PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp;
11937 class ShiftRight extends BinaryOp
11938 {
11939 public function getOperatorSigil(): string
11940 {
11941 return '>>';
11942 }
11943 public function getType(): string
11944 {
11945 return 'Expr_BinaryOp_ShiftRight';
11946 }
11947 }
11948 <?php
11949
11950 declare (strict_types=1);
11951 namespace PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp;
11952
11953 use PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp;
11954 class Smaller extends BinaryOp
11955 {
11956 public function getOperatorSigil(): string
11957 {
11958 return '<';
11959 }
11960 public function getType(): string
11961 {
11962 return 'Expr_BinaryOp_Smaller';
11963 }
11964 }
11965 <?php
11966
11967 declare (strict_types=1);
11968 namespace PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp;
11969
11970 use PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp;
11971 class SmallerOrEqual extends BinaryOp
11972 {
11973 public function getOperatorSigil(): string
11974 {
11975 return '<=';
11976 }
11977 public function getType(): string
11978 {
11979 return 'Expr_BinaryOp_SmallerOrEqual';
11980 }
11981 }
11982 <?php
11983
11984 declare (strict_types=1);
11985 namespace PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp;
11986
11987 use PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp;
11988 class Spaceship extends BinaryOp
11989 {
11990 public function getOperatorSigil(): string
11991 {
11992 return '<=>';
11993 }
11994 public function getType(): string
11995 {
11996 return 'Expr_BinaryOp_Spaceship';
11997 }
11998 }
11999 <?php
12000
12001 declare (strict_types=1);
12002 namespace PHPUnitPHAR\PhpParser\Node\Expr;
12003
12004 use PHPUnitPHAR\PhpParser\Node\Expr;
12005 class BitwiseNot extends Expr
12006 {
12007 /** @var Expr Expression */
12008 public Expr $expr;
12009 /**
12010 * Constructs a bitwise not node.
12011 *
12012 * @param Expr $expr Expression
12013 * @param array<string, mixed> $attributes Additional attributes
12014 */
12015 public function __construct(Expr $expr, array $attributes = [])
12016 {
12017 $this->attributes = $attributes;
12018 $this->expr = $expr;
12019 }
12020 public function getSubNodeNames(): array
12021 {
12022 return ['expr'];
12023 }
12024 public function getType(): string
12025 {
12026 return 'Expr_BitwiseNot';
12027 }
12028 }
12029 <?php
12030
12031 declare (strict_types=1);
12032 namespace PHPUnitPHAR\PhpParser\Node\Expr;
12033
12034 use PHPUnitPHAR\PhpParser\Node\Expr;
12035 class BooleanNot extends Expr
12036 {
12037 /** @var Expr Expression */
12038 public Expr $expr;
12039 /**
12040 * Constructs a boolean not node.
12041 *
12042 * @param Expr $expr Expression
12043 * @param array<string, mixed> $attributes Additional attributes
12044 */
12045 public function __construct(Expr $expr, array $attributes = [])
12046 {
12047 $this->attributes = $attributes;
12048 $this->expr = $expr;
12049 }
12050 public function getSubNodeNames(): array
12051 {
12052 return ['expr'];
12053 }
12054 public function getType(): string
12055 {
12056 return 'Expr_BooleanNot';
12057 }
12058 }
12059 <?php
12060
12061 declare (strict_types=1);
12062 namespace PHPUnitPHAR\PhpParser\Node\Expr;
12063
12064 use PHPUnitPHAR\PhpParser\Node\Arg;
12065 use PHPUnitPHAR\PhpParser\Node\Expr;
12066 use PHPUnitPHAR\PhpParser\Node\VariadicPlaceholder;
12067 abstract class CallLike extends Expr
12068 {
12069 /**
12070 * Return raw arguments, which may be actual Args, or VariadicPlaceholders for first-class
12071 * callables.
12072 *
12073 * @return array<Arg|VariadicPlaceholder>
12074 */
12075 abstract public function getRawArgs(): array;
12076 /**
12077 * Returns whether this call expression is actually a first class callable.
12078 */
12079 public function isFirstClassCallable(): bool
12080 {
12081 $rawArgs = $this->getRawArgs();
12082 return count($rawArgs) === 1 && current($rawArgs) instanceof VariadicPlaceholder;
12083 }
12084 /**
12085 * Assert that this is not a first-class callable and return only ordinary Args.
12086 *
12087 * @return Arg[]
12088 */
12089 public function getArgs(): array
12090 {
12091 assert(!$this->isFirstClassCallable());
12092 return $this->getRawArgs();
12093 }
12094 /**
12095 * Retrieves a specific argument from the raw arguments.
12096 *
12097 * Returns the named argument that matches the given `$name`, or the
12098 * positional (unnamed) argument that exists at the given `$position`,
12099 * otherwise, returns `null` for first-class callables or if no match is found.
12100 */
12101 public function getArg(string $name, int $position): ?Arg
12102 {
12103 if ($this->isFirstClassCallable()) {
12104 return null;
12105 }
12106 foreach ($this->getRawArgs() as $i => $arg) {
12107 if ($arg->unpack) {
12108 continue;
12109 }
12110 if ($arg->name !== null && $arg->name->toString() === $name || $arg->name === null && $i === $position) {
12111 return $arg;
12112 }
12113 }
12114 return null;
12115 }
12116 }
12117 <?php
12118
12119 declare (strict_types=1);
12120 namespace PHPUnitPHAR\PhpParser\Node\Expr;
12121
12122 use PHPUnitPHAR\PhpParser\Node\Expr;
12123 abstract class Cast extends Expr
12124 {
12125 /** @var Expr Expression */
12126 public Expr $expr;
12127 /**
12128 * Constructs a cast node.
12129 *
12130 * @param Expr $expr Expression
12131 * @param array<string, mixed> $attributes Additional attributes
12132 */
12133 public function __construct(Expr $expr, array $attributes = [])
12134 {
12135 $this->attributes = $attributes;
12136 $this->expr = $expr;
12137 }
12138 public function getSubNodeNames(): array
12139 {
12140 return ['expr'];
12141 }
12142 }
12143 <?php
12144
12145 declare (strict_types=1);
12146 namespace PHPUnitPHAR\PhpParser\Node\Expr\Cast;
12147
12148 use PHPUnitPHAR\PhpParser\Node\Expr\Cast;
12149 class Array_ extends Cast
12150 {
12151 public function getType(): string
12152 {
12153 return 'Expr_Cast_Array';
12154 }
12155 }
12156 <?php
12157
12158 declare (strict_types=1);
12159 namespace PHPUnitPHAR\PhpParser\Node\Expr\Cast;
12160
12161 use PHPUnitPHAR\PhpParser\Node\Expr\Cast;
12162 class Bool_ extends Cast
12163 {
12164 // For use in "kind" attribute
12165 public const KIND_BOOL = 1;
12166 // "bool" syntax
12167 public const KIND_BOOLEAN = 2;
12168 // "boolean" syntax
12169 public function getType(): string
12170 {
12171 return 'Expr_Cast_Bool';
12172 }
12173 }
12174 <?php
12175
12176 declare (strict_types=1);
12177 namespace PHPUnitPHAR\PhpParser\Node\Expr\Cast;
12178
12179 use PHPUnitPHAR\PhpParser\Node\Expr\Cast;
12180 class Double extends Cast
12181 {
12182 // For use in "kind" attribute
12183 public const KIND_DOUBLE = 1;
12184 // "double" syntax
12185 public const KIND_FLOAT = 2;
12186 // "float" syntax
12187 public const KIND_REAL = 3;
12188 // "real" syntax
12189 public function getType(): string
12190 {
12191 return 'Expr_Cast_Double';
12192 }
12193 }
12194 <?php
12195
12196 declare (strict_types=1);
12197 namespace PHPUnitPHAR\PhpParser\Node\Expr\Cast;
12198
12199 use PHPUnitPHAR\PhpParser\Node\Expr\Cast;
12200 class Int_ extends Cast
12201 {
12202 // For use in "kind" attribute
12203 public const KIND_INT = 1;
12204 // "int" syntax
12205 public const KIND_INTEGER = 2;
12206 // "integer" syntax
12207 public function getType(): string
12208 {
12209 return 'Expr_Cast_Int';
12210 }
12211 }
12212 <?php
12213
12214 declare (strict_types=1);
12215 namespace PHPUnitPHAR\PhpParser\Node\Expr\Cast;
12216
12217 use PHPUnitPHAR\PhpParser\Node\Expr\Cast;
12218 class Object_ extends Cast
12219 {
12220 public function getType(): string
12221 {
12222 return 'Expr_Cast_Object';
12223 }
12224 }
12225 <?php
12226
12227 declare (strict_types=1);
12228 namespace PHPUnitPHAR\PhpParser\Node\Expr\Cast;
12229
12230 use PHPUnitPHAR\PhpParser\Node\Expr\Cast;
12231 class String_ extends Cast
12232 {
12233 // For use in "kind" attribute
12234 public const KIND_STRING = 1;
12235 // "string" syntax
12236 public const KIND_BINARY = 2;
12237 // "binary" syntax
12238 public function getType(): string
12239 {
12240 return 'Expr_Cast_String';
12241 }
12242 }
12243 <?php
12244
12245 declare (strict_types=1);
12246 namespace PHPUnitPHAR\PhpParser\Node\Expr\Cast;
12247
12248 use PHPUnitPHAR\PhpParser\Node\Expr\Cast;
12249 class Unset_ extends Cast
12250 {
12251 public function getType(): string
12252 {
12253 return 'Expr_Cast_Unset';
12254 }
12255 }
12256 <?php
12257
12258 declare (strict_types=1);
12259 namespace PHPUnitPHAR\PhpParser\Node\Expr\Cast;
12260
12261 use PHPUnitPHAR\PhpParser\Node\Expr\Cast;
12262 class Void_ extends Cast
12263 {
12264 public function getType(): string
12265 {
12266 return 'Expr_Cast_Void';
12267 }
12268 }
12269 <?php
12270
12271 declare (strict_types=1);
12272 namespace PHPUnitPHAR\PhpParser\Node\Expr;
12273
12274 use PHPUnitPHAR\PhpParser\Node;
12275 use PHPUnitPHAR\PhpParser\Node\Expr;
12276 use PHPUnitPHAR\PhpParser\Node\Identifier;
12277 use PHPUnitPHAR\PhpParser\Node\Name;
12278 class ClassConstFetch extends Expr
12279 {
12280 /** @var Name|Expr Class name */
12281 public Node $class;
12282 /** @var Identifier|Expr|Error Constant name */
12283 public Node $name;
12284 /**
12285 * Constructs a class const fetch node.
12286 *
12287 * @param Name|Expr $class Class name
12288 * @param string|Identifier|Expr|Error $name Constant name
12289 * @param array<string, mixed> $attributes Additional attributes
12290 */
12291 public function __construct(Node $class, $name, array $attributes = [])
12292 {
12293 $this->attributes = $attributes;
12294 $this->class = $class;
12295 $this->name = \is_string($name) ? new Identifier($name) : $name;
12296 }
12297 public function getSubNodeNames(): array
12298 {
12299 return ['class', 'name'];
12300 }
12301 public function getType(): string
12302 {
12303 return 'Expr_ClassConstFetch';
12304 }
12305 }
12306 <?php
12307
12308 declare (strict_types=1);
12309 namespace PHPUnitPHAR\PhpParser\Node\Expr;
12310
12311 use PHPUnitPHAR\PhpParser\Node\Expr;
12312 class Clone_ extends Expr
12313 {
12314 /** @var Expr Expression */
12315 public Expr $expr;
12316 /**
12317 * Constructs a clone node.
12318 *
12319 * @param Expr $expr Expression
12320 * @param array<string, mixed> $attributes Additional attributes
12321 */
12322 public function __construct(Expr $expr, array $attributes = [])
12323 {
12324 $this->attributes = $attributes;
12325 $this->expr = $expr;
12326 }
12327 public function getSubNodeNames(): array
12328 {
12329 return ['expr'];
12330 }
12331 public function getType(): string
12332 {
12333 return 'Expr_Clone';
12334 }
12335 }
12336 <?php
12337
12338 declare (strict_types=1);
12339 namespace PHPUnitPHAR\PhpParser\Node\Expr;
12340
12341 use PHPUnitPHAR\PhpParser\Node;
12342 use PHPUnitPHAR\PhpParser\Node\ClosureUse;
12343 use PHPUnitPHAR\PhpParser\Node\Expr;
12344 use PHPUnitPHAR\PhpParser\Node\FunctionLike;
12345 class Closure extends Expr implements FunctionLike
12346 {
12347 /** @var bool Whether the closure is static */
12348 public bool $static;
12349 /** @var bool Whether to return by reference */
12350 public bool $byRef;
12351 /** @var Node\Param[] Parameters */
12352 public array $params;
12353 /** @var ClosureUse[] use()s */
12354 public array $uses;
12355 /** @var null|Node\Identifier|Node\Name|Node\ComplexType Return type */
12356 public ?Node $returnType;
12357 /** @var Node\Stmt[] Statements */
12358 public array $stmts;
12359 /** @var Node\AttributeGroup[] PHP attribute groups */
12360 public array $attrGroups;
12361 /**
12362 * Constructs a lambda function node.
12363 *
12364 * @param array{
12365 * static?: bool,
12366 * byRef?: bool,
12367 * params?: Node\Param[],
12368 * uses?: ClosureUse[],
12369 * returnType?: null|Node\Identifier|Node\Name|Node\ComplexType,
12370 * stmts?: Node\Stmt[],
12371 * attrGroups?: Node\AttributeGroup[],
12372 * } $subNodes Array of the following optional subnodes:
12373 * 'static' => false : Whether the closure is static
12374 * 'byRef' => false : Whether to return by reference
12375 * 'params' => array(): Parameters
12376 * 'uses' => array(): use()s
12377 * 'returnType' => null : Return type
12378 * 'stmts' => array(): Statements
12379 * 'attrGroups' => array(): PHP attributes groups
12380 * @param array<string, mixed> $attributes Additional attributes
12381 */
12382 public function __construct(array $subNodes = [], array $attributes = [])
12383 {
12384 $this->attributes = $attributes;
12385 $this->static = $subNodes['static'] ?? \false;
12386 $this->byRef = $subNodes['byRef'] ?? \false;
12387 $this->params = $subNodes['params'] ?? [];
12388 $this->uses = $subNodes['uses'] ?? [];
12389 $this->returnType = $subNodes['returnType'] ?? null;
12390 $this->stmts = $subNodes['stmts'] ?? [];
12391 $this->attrGroups = $subNodes['attrGroups'] ?? [];
12392 }
12393 public function getSubNodeNames(): array
12394 {
12395 return ['attrGroups', 'static', 'byRef', 'params', 'uses', 'returnType', 'stmts'];
12396 }
12397 public function returnsByRef(): bool
12398 {
12399 return $this->byRef;
12400 }
12401 public function getParams(): array
12402 {
12403 return $this->params;
12404 }
12405 public function getReturnType()
12406 {
12407 return $this->returnType;
12408 }
12409 /** @return Node\Stmt[] */
12410 public function getStmts(): array
12411 {
12412 return $this->stmts;
12413 }
12414 public function getAttrGroups(): array
12415 {
12416 return $this->attrGroups;
12417 }
12418 public function getType(): string
12419 {
12420 return 'Expr_Closure';
12421 }
12422 }
12423 <?php
12424
12425 declare (strict_types=1);
12426 namespace PHPUnitPHAR\PhpParser\Node\Expr;
12427
12428 use PHPUnitPHAR\PhpParser\Node\Expr;
12429 use PHPUnitPHAR\PhpParser\Node\Name;
12430 class ConstFetch extends Expr
12431 {
12432 /** @var Name Constant name */
12433 public Name $name;
12434 /**
12435 * Constructs a const fetch node.
12436 *
12437 * @param Name $name Constant name
12438 * @param array<string, mixed> $attributes Additional attributes
12439 */
12440 public function __construct(Name $name, array $attributes = [])
12441 {
12442 $this->attributes = $attributes;
12443 $this->name = $name;
12444 }
12445 public function getSubNodeNames(): array
12446 {
12447 return ['name'];
12448 }
12449 public function getType(): string
12450 {
12451 return 'Expr_ConstFetch';
12452 }
12453 }
12454 <?php
12455
12456 declare (strict_types=1);
12457 namespace PHPUnitPHAR\PhpParser\Node\Expr;
12458
12459 use PHPUnitPHAR\PhpParser\Node\Expr;
12460 class Empty_ extends Expr
12461 {
12462 /** @var Expr Expression */
12463 public Expr $expr;
12464 /**
12465 * Constructs an empty() node.
12466 *
12467 * @param Expr $expr Expression
12468 * @param array<string, mixed> $attributes Additional attributes
12469 */
12470 public function __construct(Expr $expr, array $attributes = [])
12471 {
12472 $this->attributes = $attributes;
12473 $this->expr = $expr;
12474 }
12475 public function getSubNodeNames(): array
12476 {
12477 return ['expr'];
12478 }
12479 public function getType(): string
12480 {
12481 return 'Expr_Empty';
12482 }
12483 }
12484 <?php
12485
12486 declare (strict_types=1);
12487 namespace PHPUnitPHAR\PhpParser\Node\Expr;
12488
12489 use PHPUnitPHAR\PhpParser\Node\Expr;
12490 /**
12491 * Error node used during parsing with error recovery.
12492 *
12493 * An error node may be placed at a position where an expression is required, but an error occurred.
12494 * Error nodes will not be present if the parser is run in throwOnError mode (the default).
12495 */
12496 class Error extends Expr
12497 {
12498 /**
12499 * Constructs an error node.
12500 *
12501 * @param array<string, mixed> $attributes Additional attributes
12502 */
12503 public function __construct(array $attributes = [])
12504 {
12505 $this->attributes = $attributes;
12506 }
12507 public function getSubNodeNames(): array
12508 {
12509 return [];
12510 }
12511 public function getType(): string
12512 {
12513 return 'Expr_Error';
12514 }
12515 }
12516 <?php
12517
12518 declare (strict_types=1);
12519 namespace PHPUnitPHAR\PhpParser\Node\Expr;
12520
12521 use PHPUnitPHAR\PhpParser\Node\Expr;
12522 class ErrorSuppress extends Expr
12523 {
12524 /** @var Expr Expression */
12525 public Expr $expr;
12526 /**
12527 * Constructs an error suppress node.
12528 *
12529 * @param Expr $expr Expression
12530 * @param array<string, mixed> $attributes Additional attributes
12531 */
12532 public function __construct(Expr $expr, array $attributes = [])
12533 {
12534 $this->attributes = $attributes;
12535 $this->expr = $expr;
12536 }
12537 public function getSubNodeNames(): array
12538 {
12539 return ['expr'];
12540 }
12541 public function getType(): string
12542 {
12543 return 'Expr_ErrorSuppress';
12544 }
12545 }
12546 <?php
12547
12548 declare (strict_types=1);
12549 namespace PHPUnitPHAR\PhpParser\Node\Expr;
12550
12551 use PHPUnitPHAR\PhpParser\Node\Expr;
12552 class Eval_ extends Expr
12553 {
12554 /** @var Expr Expression */
12555 public Expr $expr;
12556 /**
12557 * Constructs an eval() node.
12558 *
12559 * @param Expr $expr Expression
12560 * @param array<string, mixed> $attributes Additional attributes
12561 */
12562 public function __construct(Expr $expr, array $attributes = [])
12563 {
12564 $this->attributes = $attributes;
12565 $this->expr = $expr;
12566 }
12567 public function getSubNodeNames(): array
12568 {
12569 return ['expr'];
12570 }
12571 public function getType(): string
12572 {
12573 return 'Expr_Eval';
12574 }
12575 }
12576 <?php
12577
12578 declare (strict_types=1);
12579 namespace PHPUnitPHAR\PhpParser\Node\Expr;
12580
12581 use PHPUnitPHAR\PhpParser\Node\Expr;
12582 class Exit_ extends Expr
12583 {
12584 /* For use in "kind" attribute */
12585 public const KIND_EXIT = 1;
12586 public const KIND_DIE = 2;
12587 /** @var null|Expr Expression */
12588 public ?Expr $expr;
12589 /**
12590 * Constructs an exit() node.
12591 *
12592 * @param null|Expr $expr Expression
12593 * @param array<string, mixed> $attributes Additional attributes
12594 */
12595 public function __construct(?Expr $expr = null, array $attributes = [])
12596 {
12597 $this->attributes = $attributes;
12598 $this->expr = $expr;
12599 }
12600 public function getSubNodeNames(): array
12601 {
12602 return ['expr'];
12603 }
12604 public function getType(): string
12605 {
12606 return 'Expr_Exit';
12607 }
12608 }
12609 <?php
12610
12611 declare (strict_types=1);
12612 namespace PHPUnitPHAR\PhpParser\Node\Expr;
12613
12614 use PHPUnitPHAR\PhpParser\Node;
12615 use PHPUnitPHAR\PhpParser\Node\Expr;
12616 class FuncCall extends CallLike
12617 {
12618 /** @var Node\Name|Expr Function name */
12619 public Node $name;
12620 /** @var array<Node\Arg|Node\VariadicPlaceholder> Arguments */
12621 public array $args;
12622 /**
12623 * Constructs a function call node.
12624 *
12625 * @param Node\Name|Expr $name Function name
12626 * @param array<Node\Arg|Node\VariadicPlaceholder> $args Arguments
12627 * @param array<string, mixed> $attributes Additional attributes
12628 */
12629 public function __construct(Node $name, array $args = [], array $attributes = [])
12630 {
12631 $this->attributes = $attributes;
12632 $this->name = $name;
12633 $this->args = $args;
12634 }
12635 public function getSubNodeNames(): array
12636 {
12637 return ['name', 'args'];
12638 }
12639 public function getType(): string
12640 {
12641 return 'Expr_FuncCall';
12642 }
12643 public function getRawArgs(): array
12644 {
12645 return $this->args;
12646 }
12647 }
12648 <?php
12649
12650 declare (strict_types=1);
12651 namespace PHPUnitPHAR\PhpParser\Node\Expr;
12652
12653 use PHPUnitPHAR\PhpParser\Node\Expr;
12654 class Include_ extends Expr
12655 {
12656 public const TYPE_INCLUDE = 1;
12657 public const TYPE_INCLUDE_ONCE = 2;
12658 public const TYPE_REQUIRE = 3;
12659 public const TYPE_REQUIRE_ONCE = 4;
12660 /** @var Expr Expression */
12661 public Expr $expr;
12662 /** @var int Type of include */
12663 public int $type;
12664 /**
12665 * Constructs an include node.
12666 *
12667 * @param Expr $expr Expression
12668 * @param int $type Type of include
12669 * @param array<string, mixed> $attributes Additional attributes
12670 */
12671 public function __construct(Expr $expr, int $type, array $attributes = [])
12672 {
12673 $this->attributes = $attributes;
12674 $this->expr = $expr;
12675 $this->type = $type;
12676 }
12677 public function getSubNodeNames(): array
12678 {
12679 return ['expr', 'type'];
12680 }
12681 public function getType(): string
12682 {
12683 return 'Expr_Include';
12684 }
12685 }
12686 <?php
12687
12688 declare (strict_types=1);
12689 namespace PHPUnitPHAR\PhpParser\Node\Expr;
12690
12691 use PHPUnitPHAR\PhpParser\Node;
12692 use PHPUnitPHAR\PhpParser\Node\Expr;
12693 use PHPUnitPHAR\PhpParser\Node\Name;
12694 class Instanceof_ extends Expr
12695 {
12696 /** @var Expr Expression */
12697 public Expr $expr;
12698 /** @var Name|Expr Class name */
12699 public Node $class;
12700 /**
12701 * Constructs an instanceof check node.
12702 *
12703 * @param Expr $expr Expression
12704 * @param Name|Expr $class Class name
12705 * @param array<string, mixed> $attributes Additional attributes
12706 */
12707 public function __construct(Expr $expr, Node $class, array $attributes = [])
12708 {
12709 $this->attributes = $attributes;
12710 $this->expr = $expr;
12711 $this->class = $class;
12712 }
12713 public function getSubNodeNames(): array
12714 {
12715 return ['expr', 'class'];
12716 }
12717 public function getType(): string
12718 {
12719 return 'Expr_Instanceof';
12720 }
12721 }
12722 <?php
12723
12724 declare (strict_types=1);
12725 namespace PHPUnitPHAR\PhpParser\Node\Expr;
12726
12727 use PHPUnitPHAR\PhpParser\Node\Expr;
12728 class Isset_ extends Expr
12729 {
12730 /** @var Expr[] Variables */
12731 public array $vars;
12732 /**
12733 * Constructs an array node.
12734 *
12735 * @param Expr[] $vars Variables
12736 * @param array<string, mixed> $attributes Additional attributes
12737 */
12738 public function __construct(array $vars, array $attributes = [])
12739 {
12740 $this->attributes = $attributes;
12741 $this->vars = $vars;
12742 }
12743 public function getSubNodeNames(): array
12744 {
12745 return ['vars'];
12746 }
12747 public function getType(): string
12748 {
12749 return 'Expr_Isset';
12750 }
12751 }
12752 <?php
12753
12754 declare (strict_types=1);
12755 namespace PHPUnitPHAR\PhpParser\Node\Expr;
12756
12757 use PHPUnitPHAR\PhpParser\Node\ArrayItem;
12758 use PHPUnitPHAR\PhpParser\Node\Expr;
12759 class List_ extends Expr
12760 {
12761 // For use in "kind" attribute
12762 public const KIND_LIST = 1;
12763 // list() syntax
12764 public const KIND_ARRAY = 2;
12765 // [] syntax
12766 /** @var (ArrayItem|null)[] List of items to assign to */
12767 public array $items;
12768 /**
12769 * Constructs a list() destructuring node.
12770 *
12771 * @param (ArrayItem|null)[] $items List of items to assign to
12772 * @param array<string, mixed> $attributes Additional attributes
12773 */
12774 public function __construct(array $items, array $attributes = [])
12775 {
12776 $this->attributes = $attributes;
12777 $this->items = $items;
12778 }
12779 public function getSubNodeNames(): array
12780 {
12781 return ['items'];
12782 }
12783 public function getType(): string
12784 {
12785 return 'Expr_List';
12786 }
12787 }
12788 <?php
12789
12790 declare (strict_types=1);
12791 namespace PHPUnitPHAR\PhpParser\Node\Expr;
12792
12793 use PHPUnitPHAR\PhpParser\Node;
12794 use PHPUnitPHAR\PhpParser\Node\MatchArm;
12795 class Match_ extends Node\Expr
12796 {
12797 /** @var Node\Expr Condition */
12798 public Node\Expr $cond;
12799 /** @var MatchArm[] */
12800 public array $arms;
12801 /**
12802 * @param Node\Expr $cond Condition
12803 * @param MatchArm[] $arms
12804 * @param array<string, mixed> $attributes Additional attributes
12805 */
12806 public function __construct(Node\Expr $cond, array $arms = [], array $attributes = [])
12807 {
12808 $this->attributes = $attributes;
12809 $this->cond = $cond;
12810 $this->arms = $arms;
12811 }
12812 public function getSubNodeNames(): array
12813 {
12814 return ['cond', 'arms'];
12815 }
12816 public function getType(): string
12817 {
12818 return 'Expr_Match';
12819 }
12820 }
12821 <?php
12822
12823 declare (strict_types=1);
12824 namespace PHPUnitPHAR\PhpParser\Node\Expr;
12825
12826 use PHPUnitPHAR\PhpParser\Node;
12827 use PHPUnitPHAR\PhpParser\Node\Arg;
12828 use PHPUnitPHAR\PhpParser\Node\Expr;
12829 use PHPUnitPHAR\PhpParser\Node\Identifier;
12830 use PHPUnitPHAR\PhpParser\Node\VariadicPlaceholder;
12831 class MethodCall extends CallLike
12832 {
12833 /** @var Expr Variable holding object */
12834 public Expr $var;
12835 /** @var Identifier|Expr Method name */
12836 public Node $name;
12837 /** @var array<Arg|VariadicPlaceholder> Arguments */
12838 public array $args;
12839 /**
12840 * Constructs a function call node.
12841 *
12842 * @param Expr $var Variable holding object
12843 * @param string|Identifier|Expr $name Method name
12844 * @param array<Arg|VariadicPlaceholder> $args Arguments
12845 * @param array<string, mixed> $attributes Additional attributes
12846 */
12847 public function __construct(Expr $var, $name, array $args = [], array $attributes = [])
12848 {
12849 $this->attributes = $attributes;
12850 $this->var = $var;
12851 $this->name = \is_string($name) ? new Identifier($name) : $name;
12852 $this->args = $args;
12853 }
12854 public function getSubNodeNames(): array
12855 {
12856 return ['var', 'name', 'args'];
12857 }
12858 public function getType(): string
12859 {
12860 return 'Expr_MethodCall';
12861 }
12862 public function getRawArgs(): array
12863 {
12864 return $this->args;
12865 }
12866 }
12867 <?php
12868
12869 declare (strict_types=1);
12870 namespace PHPUnitPHAR\PhpParser\Node\Expr;
12871
12872 use PHPUnitPHAR\PhpParser\Node;
12873 use PHPUnitPHAR\PhpParser\Node\Arg;
12874 use PHPUnitPHAR\PhpParser\Node\Expr;
12875 use PHPUnitPHAR\PhpParser\Node\VariadicPlaceholder;
12876 class New_ extends CallLike
12877 {
12878 /** @var Node\Name|Expr|Node\Stmt\Class_ Class name */
12879 public Node $class;
12880 /** @var array<Arg|VariadicPlaceholder> Arguments */
12881 public array $args;
12882 /**
12883 * Constructs a function call node.
12884 *
12885 * @param Node\Name|Expr|Node\Stmt\Class_ $class Class name (or class node for anonymous classes)
12886 * @param array<Arg|VariadicPlaceholder> $args Arguments
12887 * @param array<string, mixed> $attributes Additional attributes
12888 */
12889 public function __construct(Node $class, array $args = [], array $attributes = [])
12890 {
12891 $this->attributes = $attributes;
12892 $this->class = $class;
12893 $this->args = $args;
12894 }
12895 public function getSubNodeNames(): array
12896 {
12897 return ['class', 'args'];
12898 }
12899 public function getType(): string
12900 {
12901 return 'Expr_New';
12902 }
12903 public function getRawArgs(): array
12904 {
12905 return $this->args;
12906 }
12907 }
12908 <?php
12909
12910 declare (strict_types=1);
12911 namespace PHPUnitPHAR\PhpParser\Node\Expr;
12912
12913 use PHPUnitPHAR\PhpParser\Node;
12914 use PHPUnitPHAR\PhpParser\Node\Arg;
12915 use PHPUnitPHAR\PhpParser\Node\Expr;
12916 use PHPUnitPHAR\PhpParser\Node\Identifier;
12917 use PHPUnitPHAR\PhpParser\Node\VariadicPlaceholder;
12918 class NullsafeMethodCall extends CallLike
12919 {
12920 /** @var Expr Variable holding object */
12921 public Expr $var;
12922 /** @var Identifier|Expr Method name */
12923 public Node $name;
12924 /** @var array<Arg|VariadicPlaceholder> Arguments */
12925 public array $args;
12926 /**
12927 * Constructs a nullsafe method call node.
12928 *
12929 * @param Expr $var Variable holding object
12930 * @param string|Identifier|Expr $name Method name
12931 * @param array<Arg|VariadicPlaceholder> $args Arguments
12932 * @param array<string, mixed> $attributes Additional attributes
12933 */
12934 public function __construct(Expr $var, $name, array $args = [], array $attributes = [])
12935 {
12936 $this->attributes = $attributes;
12937 $this->var = $var;
12938 $this->name = \is_string($name) ? new Identifier($name) : $name;
12939 $this->args = $args;
12940 }
12941 public function getSubNodeNames(): array
12942 {
12943 return ['var', 'name', 'args'];
12944 }
12945 public function getType(): string
12946 {
12947 return 'Expr_NullsafeMethodCall';
12948 }
12949 public function getRawArgs(): array
12950 {
12951 return $this->args;
12952 }
12953 }
12954 <?php
12955
12956 declare (strict_types=1);
12957 namespace PHPUnitPHAR\PhpParser\Node\Expr;
12958
12959 use PHPUnitPHAR\PhpParser\Node;
12960 use PHPUnitPHAR\PhpParser\Node\Expr;
12961 use PHPUnitPHAR\PhpParser\Node\Identifier;
12962 class NullsafePropertyFetch extends Expr
12963 {
12964 /** @var Expr Variable holding object */
12965 public Expr $var;
12966 /** @var Identifier|Expr Property name */
12967 public Node $name;
12968 /**
12969 * Constructs a nullsafe property fetch node.
12970 *
12971 * @param Expr $var Variable holding object
12972 * @param string|Identifier|Expr $name Property name
12973 * @param array<string, mixed> $attributes Additional attributes
12974 */
12975 public function __construct(Expr $var, $name, array $attributes = [])
12976 {
12977 $this->attributes = $attributes;
12978 $this->var = $var;
12979 $this->name = \is_string($name) ? new Identifier($name) : $name;
12980 }
12981 public function getSubNodeNames(): array
12982 {
12983 return ['var', 'name'];
12984 }
12985 public function getType(): string
12986 {
12987 return 'Expr_NullsafePropertyFetch';
12988 }
12989 }
12990 <?php
12991
12992 declare (strict_types=1);
12993 namespace PHPUnitPHAR\PhpParser\Node\Expr;
12994
12995 use PHPUnitPHAR\PhpParser\Node\Expr;
12996 class PostDec extends Expr
12997 {
12998 /** @var Expr Variable */
12999 public Expr $var;
13000 /**
13001 * Constructs a post decrement node.
13002 *
13003 * @param Expr $var Variable
13004 * @param array<string, mixed> $attributes Additional attributes
13005 */
13006 public function __construct(Expr $var, array $attributes = [])
13007 {
13008 $this->attributes = $attributes;
13009 $this->var = $var;
13010 }
13011 public function getSubNodeNames(): array
13012 {
13013 return ['var'];
13014 }
13015 public function getType(): string
13016 {
13017 return 'Expr_PostDec';
13018 }
13019 }
13020 <?php
13021
13022 declare (strict_types=1);
13023 namespace PHPUnitPHAR\PhpParser\Node\Expr;
13024
13025 use PHPUnitPHAR\PhpParser\Node\Expr;
13026 class PostInc extends Expr
13027 {
13028 /** @var Expr Variable */
13029 public Expr $var;
13030 /**
13031 * Constructs a post increment node.
13032 *
13033 * @param Expr $var Variable
13034 * @param array<string, mixed> $attributes Additional attributes
13035 */
13036 public function __construct(Expr $var, array $attributes = [])
13037 {
13038 $this->attributes = $attributes;
13039 $this->var = $var;
13040 }
13041 public function getSubNodeNames(): array
13042 {
13043 return ['var'];
13044 }
13045 public function getType(): string
13046 {
13047 return 'Expr_PostInc';
13048 }
13049 }
13050 <?php
13051
13052 declare (strict_types=1);
13053 namespace PHPUnitPHAR\PhpParser\Node\Expr;
13054
13055 use PHPUnitPHAR\PhpParser\Node\Expr;
13056 class PreDec extends Expr
13057 {
13058 /** @var Expr Variable */
13059 public Expr $var;
13060 /**
13061 * Constructs a pre decrement node.
13062 *
13063 * @param Expr $var Variable
13064 * @param array<string, mixed> $attributes Additional attributes
13065 */
13066 public function __construct(Expr $var, array $attributes = [])
13067 {
13068 $this->attributes = $attributes;
13069 $this->var = $var;
13070 }
13071 public function getSubNodeNames(): array
13072 {
13073 return ['var'];
13074 }
13075 public function getType(): string
13076 {
13077 return 'Expr_PreDec';
13078 }
13079 }
13080 <?php
13081
13082 declare (strict_types=1);
13083 namespace PHPUnitPHAR\PhpParser\Node\Expr;
13084
13085 use PHPUnitPHAR\PhpParser\Node\Expr;
13086 class PreInc extends Expr
13087 {
13088 /** @var Expr Variable */
13089 public Expr $var;
13090 /**
13091 * Constructs a pre increment node.
13092 *
13093 * @param Expr $var Variable
13094 * @param array<string, mixed> $attributes Additional attributes
13095 */
13096 public function __construct(Expr $var, array $attributes = [])
13097 {
13098 $this->attributes = $attributes;
13099 $this->var = $var;
13100 }
13101 public function getSubNodeNames(): array
13102 {
13103 return ['var'];
13104 }
13105 public function getType(): string
13106 {
13107 return 'Expr_PreInc';
13108 }
13109 }
13110 <?php
13111
13112 declare (strict_types=1);
13113 namespace PHPUnitPHAR\PhpParser\Node\Expr;
13114
13115 use PHPUnitPHAR\PhpParser\Node\Expr;
13116 class Print_ extends Expr
13117 {
13118 /** @var Expr Expression */
13119 public Expr $expr;
13120 /**
13121 * Constructs an print() node.
13122 *
13123 * @param Expr $expr Expression
13124 * @param array<string, mixed> $attributes Additional attributes
13125 */
13126 public function __construct(Expr $expr, array $attributes = [])
13127 {
13128 $this->attributes = $attributes;
13129 $this->expr = $expr;
13130 }
13131 public function getSubNodeNames(): array
13132 {
13133 return ['expr'];
13134 }
13135 public function getType(): string
13136 {
13137 return 'Expr_Print';
13138 }
13139 }
13140 <?php
13141
13142 declare (strict_types=1);
13143 namespace PHPUnitPHAR\PhpParser\Node\Expr;
13144
13145 use PHPUnitPHAR\PhpParser\Node;
13146 use PHPUnitPHAR\PhpParser\Node\Expr;
13147 use PHPUnitPHAR\PhpParser\Node\Identifier;
13148 class PropertyFetch extends Expr
13149 {
13150 /** @var Expr Variable holding object */
13151 public Expr $var;
13152 /** @var Identifier|Expr Property name */
13153 public Node $name;
13154 /**
13155 * Constructs a function call node.
13156 *
13157 * @param Expr $var Variable holding object
13158 * @param string|Identifier|Expr $name Property name
13159 * @param array<string, mixed> $attributes Additional attributes
13160 */
13161 public function __construct(Expr $var, $name, array $attributes = [])
13162 {
13163 $this->attributes = $attributes;
13164 $this->var = $var;
13165 $this->name = \is_string($name) ? new Identifier($name) : $name;
13166 }
13167 public function getSubNodeNames(): array
13168 {
13169 return ['var', 'name'];
13170 }
13171 public function getType(): string
13172 {
13173 return 'Expr_PropertyFetch';
13174 }
13175 }
13176 <?php
13177
13178 declare (strict_types=1);
13179 namespace PHPUnitPHAR\PhpParser\Node\Expr;
13180
13181 use PHPUnitPHAR\PhpParser\Node\Expr;
13182 use PHPUnitPHAR\PhpParser\Node\InterpolatedStringPart;
13183 class ShellExec extends Expr
13184 {
13185 /** @var (Expr|InterpolatedStringPart)[] Interpolated string array */
13186 public array $parts;
13187 /**
13188 * Constructs a shell exec (backtick) node.
13189 *
13190 * @param (Expr|InterpolatedStringPart)[] $parts Interpolated string array
13191 * @param array<string, mixed> $attributes Additional attributes
13192 */
13193 public function __construct(array $parts, array $attributes = [])
13194 {
13195 $this->attributes = $attributes;
13196 $this->parts = $parts;
13197 }
13198 public function getSubNodeNames(): array
13199 {
13200 return ['parts'];
13201 }
13202 public function getType(): string
13203 {
13204 return 'Expr_ShellExec';
13205 }
13206 }
13207 <?php
13208
13209 declare (strict_types=1);
13210 namespace PHPUnitPHAR\PhpParser\Node\Expr;
13211
13212 use PHPUnitPHAR\PhpParser\Node;
13213 use PHPUnitPHAR\PhpParser\Node\Arg;
13214 use PHPUnitPHAR\PhpParser\Node\Expr;
13215 use PHPUnitPHAR\PhpParser\Node\Identifier;
13216 use PHPUnitPHAR\PhpParser\Node\VariadicPlaceholder;
13217 class StaticCall extends CallLike
13218 {
13219 /** @var Node\Name|Expr Class name */
13220 public Node $class;
13221 /** @var Identifier|Expr Method name */
13222 public Node $name;
13223 /** @var array<Arg|VariadicPlaceholder> Arguments */
13224 public array $args;
13225 /**
13226 * Constructs a static method call node.
13227 *
13228 * @param Node\Name|Expr $class Class name
13229 * @param string|Identifier|Expr $name Method name
13230 * @param array<Arg|VariadicPlaceholder> $args Arguments
13231 * @param array<string, mixed> $attributes Additional attributes
13232 */
13233 public function __construct(Node $class, $name, array $args = [], array $attributes = [])
13234 {
13235 $this->attributes = $attributes;
13236 $this->class = $class;
13237 $this->name = \is_string($name) ? new Identifier($name) : $name;
13238 $this->args = $args;
13239 }
13240 public function getSubNodeNames(): array
13241 {
13242 return ['class', 'name', 'args'];
13243 }
13244 public function getType(): string
13245 {
13246 return 'Expr_StaticCall';
13247 }
13248 public function getRawArgs(): array
13249 {
13250 return $this->args;
13251 }
13252 }
13253 <?php
13254
13255 declare (strict_types=1);
13256 namespace PHPUnitPHAR\PhpParser\Node\Expr;
13257
13258 use PHPUnitPHAR\PhpParser\Node;
13259 use PHPUnitPHAR\PhpParser\Node\Expr;
13260 use PHPUnitPHAR\PhpParser\Node\Name;
13261 use PHPUnitPHAR\PhpParser\Node\VarLikeIdentifier;
13262 class StaticPropertyFetch extends Expr
13263 {
13264 /** @var Name|Expr Class name */
13265 public Node $class;
13266 /** @var VarLikeIdentifier|Expr Property name */
13267 public Node $name;
13268 /**
13269 * Constructs a static property fetch node.
13270 *
13271 * @param Name|Expr $class Class name
13272 * @param string|VarLikeIdentifier|Expr $name Property name
13273 * @param array<string, mixed> $attributes Additional attributes
13274 */
13275 public function __construct(Node $class, $name, array $attributes = [])
13276 {
13277 $this->attributes = $attributes;
13278 $this->class = $class;
13279 $this->name = \is_string($name) ? new VarLikeIdentifier($name) : $name;
13280 }
13281 public function getSubNodeNames(): array
13282 {
13283 return ['class', 'name'];
13284 }
13285 public function getType(): string
13286 {
13287 return 'Expr_StaticPropertyFetch';
13288 }
13289 }
13290 <?php
13291
13292 declare (strict_types=1);
13293 namespace PHPUnitPHAR\PhpParser\Node\Expr;
13294
13295 use PHPUnitPHAR\PhpParser\Node\Expr;
13296 class Ternary extends Expr
13297 {
13298 /** @var Expr Condition */
13299 public Expr $cond;
13300 /** @var null|Expr Expression for true */
13301 public ?Expr $if;
13302 /** @var Expr Expression for false */
13303 public Expr $else;
13304 /**
13305 * Constructs a ternary operator node.
13306 *
13307 * @param Expr $cond Condition
13308 * @param null|Expr $if Expression for true
13309 * @param Expr $else Expression for false
13310 * @param array<string, mixed> $attributes Additional attributes
13311 */
13312 public function __construct(Expr $cond, ?Expr $if, Expr $else, array $attributes = [])
13313 {
13314 $this->attributes = $attributes;
13315 $this->cond = $cond;
13316 $this->if = $if;
13317 $this->else = $else;
13318 }
13319 public function getSubNodeNames(): array
13320 {
13321 return ['cond', 'if', 'else'];
13322 }
13323 public function getType(): string
13324 {
13325 return 'Expr_Ternary';
13326 }
13327 }
13328 <?php
13329
13330 declare (strict_types=1);
13331 namespace PHPUnitPHAR\PhpParser\Node\Expr;
13332
13333 use PHPUnitPHAR\PhpParser\Node;
13334 class Throw_ extends Node\Expr
13335 {
13336 /** @var Node\Expr Expression */
13337 public Node\Expr $expr;
13338 /**
13339 * Constructs a throw expression node.
13340 *
13341 * @param Node\Expr $expr Expression
13342 * @param array<string, mixed> $attributes Additional attributes
13343 */
13344 public function __construct(Node\Expr $expr, array $attributes = [])
13345 {
13346 $this->attributes = $attributes;
13347 $this->expr = $expr;
13348 }
13349 public function getSubNodeNames(): array
13350 {
13351 return ['expr'];
13352 }
13353 public function getType(): string
13354 {
13355 return 'Expr_Throw';
13356 }
13357 }
13358 <?php
13359
13360 declare (strict_types=1);
13361 namespace PHPUnitPHAR\PhpParser\Node\Expr;
13362
13363 use PHPUnitPHAR\PhpParser\Node\Expr;
13364 class UnaryMinus extends Expr
13365 {
13366 /** @var Expr Expression */
13367 public Expr $expr;
13368 /**
13369 * Constructs a unary minus node.
13370 *
13371 * @param Expr $expr Expression
13372 * @param array<string, mixed> $attributes Additional attributes
13373 */
13374 public function __construct(Expr $expr, array $attributes = [])
13375 {
13376 $this->attributes = $attributes;
13377 $this->expr = $expr;
13378 }
13379 public function getSubNodeNames(): array
13380 {
13381 return ['expr'];
13382 }
13383 public function getType(): string
13384 {
13385 return 'Expr_UnaryMinus';
13386 }
13387 }
13388 <?php
13389
13390 declare (strict_types=1);
13391 namespace PHPUnitPHAR\PhpParser\Node\Expr;
13392
13393 use PHPUnitPHAR\PhpParser\Node\Expr;
13394 class UnaryPlus extends Expr
13395 {
13396 /** @var Expr Expression */
13397 public Expr $expr;
13398 /**
13399 * Constructs a unary plus node.
13400 *
13401 * @param Expr $expr Expression
13402 * @param array<string, mixed> $attributes Additional attributes
13403 */
13404 public function __construct(Expr $expr, array $attributes = [])
13405 {
13406 $this->attributes = $attributes;
13407 $this->expr = $expr;
13408 }
13409 public function getSubNodeNames(): array
13410 {
13411 return ['expr'];
13412 }
13413 public function getType(): string
13414 {
13415 return 'Expr_UnaryPlus';
13416 }
13417 }
13418 <?php
13419
13420 declare (strict_types=1);
13421 namespace PHPUnitPHAR\PhpParser\Node\Expr;
13422
13423 use PHPUnitPHAR\PhpParser\Node\Expr;
13424 class Variable extends Expr
13425 {
13426 /** @var string|Expr Name */
13427 public $name;
13428 /**
13429 * Constructs a variable node.
13430 *
13431 * @param string|Expr $name Name
13432 * @param array<string, mixed> $attributes Additional attributes
13433 */
13434 public function __construct($name, array $attributes = [])
13435 {
13436 $this->attributes = $attributes;
13437 $this->name = $name;
13438 }
13439 public function getSubNodeNames(): array
13440 {
13441 return ['name'];
13442 }
13443 public function getType(): string
13444 {
13445 return 'Expr_Variable';
13446 }
13447 }
13448 <?php
13449
13450 declare (strict_types=1);
13451 namespace PHPUnitPHAR\PhpParser\Node\Expr;
13452
13453 use PHPUnitPHAR\PhpParser\Node\Expr;
13454 class YieldFrom extends Expr
13455 {
13456 /** @var Expr Expression to yield from */
13457 public Expr $expr;
13458 /**
13459 * Constructs an "yield from" node.
13460 *
13461 * @param Expr $expr Expression
13462 * @param array<string, mixed> $attributes Additional attributes
13463 */
13464 public function __construct(Expr $expr, array $attributes = [])
13465 {
13466 $this->attributes = $attributes;
13467 $this->expr = $expr;
13468 }
13469 public function getSubNodeNames(): array
13470 {
13471 return ['expr'];
13472 }
13473 public function getType(): string
13474 {
13475 return 'Expr_YieldFrom';
13476 }
13477 }
13478 <?php
13479
13480 declare (strict_types=1);
13481 namespace PHPUnitPHAR\PhpParser\Node\Expr;
13482
13483 use PHPUnitPHAR\PhpParser\Node\Expr;
13484 class Yield_ extends Expr
13485 {
13486 /** @var null|Expr Key expression */
13487 public ?Expr $key;
13488 /** @var null|Expr Value expression */
13489 public ?Expr $value;
13490 /**
13491 * Constructs a yield expression node.
13492 *
13493 * @param null|Expr $value Value expression
13494 * @param null|Expr $key Key expression
13495 * @param array<string, mixed> $attributes Additional attributes
13496 */
13497 public function __construct(?Expr $value = null, ?Expr $key = null, array $attributes = [])
13498 {
13499 $this->attributes = $attributes;
13500 $this->key = $key;
13501 $this->value = $value;
13502 }
13503 public function getSubNodeNames(): array
13504 {
13505 return ['key', 'value'];
13506 }
13507 public function getType(): string
13508 {
13509 return 'Expr_Yield';
13510 }
13511 }
13512 <?php
13513
13514 declare (strict_types=1);
13515 namespace PHPUnitPHAR\PhpParser\Node;
13516
13517 use PHPUnitPHAR\PhpParser\Node;
13518 interface FunctionLike extends Node
13519 {
13520 /**
13521 * Whether to return by reference
13522 */
13523 public function returnsByRef(): bool;
13524 /**
13525 * List of parameters
13526 *
13527 * @return Param[]
13528 */
13529 public function getParams(): array;
13530 /**
13531 * Get the declared return type or null
13532 *
13533 * @return null|Identifier|Name|ComplexType
13534 */
13535 public function getReturnType();
13536 /**
13537 * The function body
13538 *
13539 * @return Stmt[]|null
13540 */
13541 public function getStmts(): ?array;
13542 /**
13543 * Get PHP attribute groups.
13544 *
13545 * @return AttributeGroup[]
13546 */
13547 public function getAttrGroups(): array;
13548 }
13549 <?php
13550
13551 declare (strict_types=1);
13552 namespace PHPUnitPHAR\PhpParser\Node;
13553
13554 use PHPUnitPHAR\PhpParser\NodeAbstract;
13555 /**
13556 * Represents a non-namespaced name. Namespaced names are represented using Name nodes.
13557 */
13558 class Identifier extends NodeAbstract
13559 {
13560 /**
13561 * @psalm-var non-empty-string
13562 * @var string Identifier as string
13563 */
13564 public string $name;
13565 /** @var array<string, bool> */
13566 private static array $specialClassNames = ['self' => \true, 'parent' => \true, 'static' => \true];
13567 /**
13568 * Constructs an identifier node.
13569 *
13570 * @param string $name Identifier as string
13571 * @param array<string, mixed> $attributes Additional attributes
13572 */
13573 public function __construct(string $name, array $attributes = [])
13574 {
13575 if ($name === '') {
13576 throw new \InvalidArgumentException('Identifier name cannot be empty');
13577 }
13578 $this->attributes = $attributes;
13579 $this->name = $name;
13580 }
13581 public function getSubNodeNames(): array
13582 {
13583 return ['name'];
13584 }
13585 /**
13586 * Get identifier as string.
13587 *
13588 * @psalm-return non-empty-string
13589 * @return string Identifier as string.
13590 */
13591 public function toString(): string
13592 {
13593 return $this->name;
13594 }
13595 /**
13596 * Get lowercased identifier as string.
13597 *
13598 * @psalm-return non-empty-string&lowercase-string
13599 * @return string Lowercased identifier as string
13600 */
13601 public function toLowerString(): string
13602 {
13603 return strtolower($this->name);
13604 }
13605 /**
13606 * Checks whether the identifier is a special class name (self, parent or static).
13607 *
13608 * @return bool Whether identifier is a special class name
13609 */
13610 public function isSpecialClassName(): bool
13611 {
13612 return isset(self::$specialClassNames[strtolower($this->name)]);
13613 }
13614 /**
13615 * Get identifier as string.
13616 *
13617 * @psalm-return non-empty-string
13618 * @return string Identifier as string
13619 */
13620 public function __toString(): string
13621 {
13622 return $this->name;
13623 }
13624 public function getType(): string
13625 {
13626 return 'Identifier';
13627 }
13628 }
13629 <?php
13630
13631 declare (strict_types=1);
13632 namespace PHPUnitPHAR\PhpParser\Node;
13633
13634 use PHPUnitPHAR\PhpParser\NodeAbstract;
13635 class InterpolatedStringPart extends NodeAbstract
13636 {
13637 /** @var string String value */
13638 public string $value;
13639 /**
13640 * Constructs a node representing a string part of an interpolated string.
13641 *
13642 * @param string $value String value
13643 * @param array<string, mixed> $attributes Additional attributes
13644 */
13645 public function __construct(string $value, array $attributes = [])
13646 {
13647 $this->attributes = $attributes;
13648 $this->value = $value;
13649 }
13650 public function getSubNodeNames(): array
13651 {
13652 return ['value'];
13653 }
13654 public function getType(): string
13655 {
13656 return 'InterpolatedStringPart';
13657 }
13658 }
13659 // @deprecated compatibility alias
13660 class_alias(InterpolatedStringPart::class, Scalar\EncapsedStringPart::class);
13661 <?php
13662
13663 declare (strict_types=1);
13664 namespace PHPUnitPHAR\PhpParser\Node;
13665
13666 class IntersectionType extends ComplexType
13667 {
13668 /** @var (Identifier|Name)[] Types */
13669 public array $types;
13670 /**
13671 * Constructs an intersection type.
13672 *
13673 * @param (Identifier|Name)[] $types Types
13674 * @param array<string, mixed> $attributes Additional attributes
13675 */
13676 public function __construct(array $types, array $attributes = [])
13677 {
13678 $this->attributes = $attributes;
13679 $this->types = $types;
13680 }
13681 public function getSubNodeNames(): array
13682 {
13683 return ['types'];
13684 }
13685 public function getType(): string
13686 {
13687 return 'IntersectionType';
13688 }
13689 }
13690 <?php
13691
13692 declare (strict_types=1);
13693 namespace PHPUnitPHAR\PhpParser\Node;
13694
13695 use PHPUnitPHAR\PhpParser\Node;
13696 use PHPUnitPHAR\PhpParser\NodeAbstract;
13697 class MatchArm extends NodeAbstract
13698 {
13699 /** @var null|list<Node\Expr> */
13700 public ?array $conds;
13701 public Expr $body;
13702 /**
13703 * @param null|list<Node\Expr> $conds
13704 */
13705 public function __construct(?array $conds, Node\Expr $body, array $attributes = [])
13706 {
13707 $this->conds = $conds;
13708 $this->body = $body;
13709 $this->attributes = $attributes;
13710 }
13711 public function getSubNodeNames(): array
13712 {
13713 return ['conds', 'body'];
13714 }
13715 public function getType(): string
13716 {
13717 return 'MatchArm';
13718 }
13719 }
13720 <?php
13721
13722 declare (strict_types=1);
13723 namespace PHPUnitPHAR\PhpParser\Node;
13724
13725 use PHPUnitPHAR\PhpParser\NodeAbstract;
13726 class Name extends NodeAbstract
13727 {
13728 /**
13729 * @psalm-var non-empty-string
13730 * @var string Name as string
13731 */
13732 public string $name;
13733 /** @var array<string, bool> */
13734 private static array $specialClassNames = ['self' => \true, 'parent' => \true, 'static' => \true];
13735 /**
13736 * Constructs a name node.
13737 *
13738 * @param string|string[]|self $name Name as string, part array or Name instance (copy ctor)
13739 * @param array<string, mixed> $attributes Additional attributes
13740 */
13741 final public function __construct($name, array $attributes = [])
13742 {
13743 $this->attributes = $attributes;
13744 $this->name = self::prepareName($name);
13745 }
13746 public function getSubNodeNames(): array
13747 {
13748 return ['name'];
13749 }
13750 /**
13751 * Get parts of name (split by the namespace separator).
13752 *
13753 * @psalm-return non-empty-list<string>
13754 * @return string[] Parts of name
13755 */
13756 public function getParts(): array
13757 {
13758 return \explode('\\', $this->name);
13759 }
13760 /**
13761 * Gets the first part of the name, i.e. everything before the first namespace separator.
13762 *
13763 * @return string First part of the name
13764 */
13765 public function getFirst(): string
13766 {
13767 if (\false !== $pos = \strpos($this->name, '\\')) {
13768 return \substr($this->name, 0, $pos);
13769 }
13770 return $this->name;
13771 }
13772 /**
13773 * Gets the last part of the name, i.e. everything after the last namespace separator.
13774 *
13775 * @return string Last part of the name
13776 */
13777 public function getLast(): string
13778 {
13779 if (\false !== $pos = \strrpos($this->name, '\\')) {
13780 return \substr($this->name, $pos + 1);
13781 }
13782 return $this->name;
13783 }
13784 /**
13785 * Checks whether the name is unqualified. (E.g. Name)
13786 *
13787 * @return bool Whether the name is unqualified
13788 */
13789 public function isUnqualified(): bool
13790 {
13791 return \false === \strpos($this->name, '\\');
13792 }
13793 /**
13794 * Checks whether the name is qualified. (E.g. Name\Name)
13795 *
13796 * @return bool Whether the name is qualified
13797 */
13798 public function isQualified(): bool
13799 {
13800 return \false !== \strpos($this->name, '\\');
13801 }
13802 /**
13803 * Checks whether the name is fully qualified. (E.g. \Name)
13804 *
13805 * @return bool Whether the name is fully qualified
13806 */
13807 public function isFullyQualified(): bool
13808 {
13809 return \false;
13810 }
13811 /**
13812 * Checks whether the name is explicitly relative to the current namespace. (E.g. namespace\Name)
13813 *
13814 * @return bool Whether the name is relative
13815 */
13816 public function isRelative(): bool
13817 {
13818 return \false;
13819 }
13820 /**
13821 * Returns a string representation of the name itself, without taking the name type into
13822 * account (e.g., not including a leading backslash for fully qualified names).
13823 *
13824 * @psalm-return non-empty-string
13825 * @return string String representation
13826 */
13827 public function toString(): string
13828 {
13829 return $this->name;
13830 }
13831 /**
13832 * Returns a string representation of the name as it would occur in code (e.g., including
13833 * leading backslash for fully qualified names.
13834 *
13835 * @psalm-return non-empty-string
13836 * @return string String representation
13837 */
13838 public function toCodeString(): string
13839 {
13840 return $this->toString();
13841 }
13842 /**
13843 * Returns lowercased string representation of the name, without taking the name type into
13844 * account (e.g., no leading backslash for fully qualified names).
13845 *
13846 * @psalm-return non-empty-string&lowercase-string
13847 * @return string Lowercased string representation
13848 */
13849 public function toLowerString(): string
13850 {
13851 return strtolower($this->name);
13852 }
13853 /**
13854 * Checks whether the identifier is a special class name (self, parent or static).
13855 *
13856 * @return bool Whether identifier is a special class name
13857 */
13858 public function isSpecialClassName(): bool
13859 {
13860 return isset(self::$specialClassNames[strtolower($this->name)]);
13861 }
13862 /**
13863 * Returns a string representation of the name by imploding the namespace parts with the
13864 * namespace separator.
13865 *
13866 * @psalm-return non-empty-string
13867 * @return string String representation
13868 */
13869 public function __toString(): string
13870 {
13871 return $this->name;
13872 }
13873 /**
13874 * Gets a slice of a name (similar to array_slice).
13875 *
13876 * This method returns a new instance of the same type as the original and with the same
13877 * attributes.
13878 *
13879 * If the slice is empty, null is returned. The null value will be correctly handled in
13880 * concatenations using concat().
13881 *
13882 * Offset and length have the same meaning as in array_slice().
13883 *
13884 * @param int $offset Offset to start the slice at (may be negative)
13885 * @param int|null $length Length of the slice (may be negative)
13886 *
13887 * @return static|null Sliced name
13888 */
13889 public function slice(int $offset, ?int $length = null)
13890 {
13891 if ($offset === 1 && $length === null) {
13892 // Short-circuit the common case.
13893 if (\false !== $pos = \strpos($this->name, '\\')) {
13894 return new static(\substr($this->name, $pos + 1));
13895 }
13896 return null;
13897 }
13898 $parts = \explode('\\', $this->name);
13899 $numParts = \count($parts);
13900 $realOffset = $offset < 0 ? $offset + $numParts : $offset;
13901 if ($realOffset < 0 || $realOffset > $numParts) {
13902 throw new \OutOfBoundsException(sprintf('Offset %d is out of bounds', $offset));
13903 }
13904 if (null === $length) {
13905 $realLength = $numParts - $realOffset;
13906 } else {
13907 $realLength = $length < 0 ? $length + $numParts - $realOffset : $length;
13908 if ($realLength < 0 || $realLength > $numParts - $realOffset) {
13909 throw new \OutOfBoundsException(sprintf('Length %d is out of bounds', $length));
13910 }
13911 }
13912 if ($realLength === 0) {
13913 // Empty slice is represented as null
13914 return null;
13915 }
13916 return new static(array_slice($parts, $realOffset, $realLength), $this->attributes);
13917 }
13918 /**
13919 * Concatenate two names, yielding a new Name instance.
13920 *
13921 * The type of the generated instance depends on which class this method is called on, for
13922 * example Name\FullyQualified::concat() will yield a Name\FullyQualified instance.
13923 *
13924 * If one of the arguments is null, a new instance of the other name will be returned. If both
13925 * arguments are null, null will be returned. As such, writing
13926 * Name::concat($namespace, $shortName)
13927 * where $namespace is a Name node or null will work as expected.
13928 *
13929 * @param string|string[]|self|null $name1 The first name
13930 * @param string|string[]|self|null $name2 The second name
13931 * @param array<string, mixed> $attributes Attributes to assign to concatenated name
13932 *
13933 * @return static|null Concatenated name
13934 */
13935 public static function concat($name1, $name2, array $attributes = [])
13936 {
13937 if (null === $name1 && null === $name2) {
13938 return null;
13939 }
13940 if (null === $name1) {
13941 return new static($name2, $attributes);
13942 }
13943 if (null === $name2) {
13944 return new static($name1, $attributes);
13945 } else {
13946 return new static(self::prepareName($name1) . '\\' . self::prepareName($name2), $attributes);
13947 }
13948 }
13949 /**
13950 * Prepares a (string, array or Name node) name for use in name changing methods by converting
13951 * it to a string.
13952 *
13953 * @param string|string[]|self $name Name to prepare
13954 *
13955 * @psalm-return non-empty-string
13956 * @return string Prepared name
13957 */
13958 private static function prepareName($name): string
13959 {
13960 if (\is_string($name)) {
13961 if ('' === $name) {
13962 throw new \InvalidArgumentException('Name cannot be empty');
13963 }
13964 return $name;
13965 }
13966 if (\is_array($name)) {
13967 if (empty($name)) {
13968 throw new \InvalidArgumentException('Name cannot be empty');
13969 }
13970 return implode('\\', $name);
13971 }
13972 if ($name instanceof self) {
13973 return $name->name;
13974 }
13975 throw new \InvalidArgumentException('Expected string, array of parts or Name instance');
13976 }
13977 public function getType(): string
13978 {
13979 return 'Name';
13980 }
13981 }
13982 <?php
13983
13984 declare (strict_types=1);
13985 namespace PHPUnitPHAR\PhpParser\Node\Name;
13986
13987 class FullyQualified extends \PHPUnitPHAR\PhpParser\Node\Name
13988 {
13989 /**
13990 * Checks whether the name is unqualified. (E.g. Name)
13991 *
13992 * @return bool Whether the name is unqualified
13993 */
13994 public function isUnqualified(): bool
13995 {
13996 return \false;
13997 }
13998 /**
13999 * Checks whether the name is qualified. (E.g. Name\Name)
14000 *
14001 * @return bool Whether the name is qualified
14002 */
14003 public function isQualified(): bool
14004 {
14005 return \false;
14006 }
14007 /**
14008 * Checks whether the name is fully qualified. (E.g. \Name)
14009 *
14010 * @return bool Whether the name is fully qualified
14011 */
14012 public function isFullyQualified(): bool
14013 {
14014 return \true;
14015 }
14016 /**
14017 * Checks whether the name is explicitly relative to the current namespace. (E.g. namespace\Name)
14018 *
14019 * @return bool Whether the name is relative
14020 */
14021 public function isRelative(): bool
14022 {
14023 return \false;
14024 }
14025 public function toCodeString(): string
14026 {
14027 return '\\' . $this->toString();
14028 }
14029 public function getType(): string
14030 {
14031 return 'Name_FullyQualified';
14032 }
14033 }
14034 <?php
14035
14036 declare (strict_types=1);
14037 namespace PHPUnitPHAR\PhpParser\Node\Name;
14038
14039 class Relative extends \PHPUnitPHAR\PhpParser\Node\Name
14040 {
14041 /**
14042 * Checks whether the name is unqualified. (E.g. Name)
14043 *
14044 * @return bool Whether the name is unqualified
14045 */
14046 public function isUnqualified(): bool
14047 {
14048 return \false;
14049 }
14050 /**
14051 * Checks whether the name is qualified. (E.g. Name\Name)
14052 *
14053 * @return bool Whether the name is qualified
14054 */
14055 public function isQualified(): bool
14056 {
14057 return \false;
14058 }
14059 /**
14060 * Checks whether the name is fully qualified. (E.g. \Name)
14061 *
14062 * @return bool Whether the name is fully qualified
14063 */
14064 public function isFullyQualified(): bool
14065 {
14066 return \false;
14067 }
14068 /**
14069 * Checks whether the name is explicitly relative to the current namespace. (E.g. namespace\Name)
14070 *
14071 * @return bool Whether the name is relative
14072 */
14073 public function isRelative(): bool
14074 {
14075 return \true;
14076 }
14077 public function toCodeString(): string
14078 {
14079 return 'namespace\\' . $this->toString();
14080 }
14081 public function getType(): string
14082 {
14083 return 'Name_Relative';
14084 }
14085 }
14086 <?php
14087
14088 declare (strict_types=1);
14089 namespace PHPUnitPHAR\PhpParser\Node;
14090
14091 use PHPUnitPHAR\PhpParser\Node;
14092 class NullableType extends ComplexType
14093 {
14094 /** @var Identifier|Name Type */
14095 public Node $type;
14096 /**
14097 * Constructs a nullable type (wrapping another type).
14098 *
14099 * @param Identifier|Name $type Type
14100 * @param array<string, mixed> $attributes Additional attributes
14101 */
14102 public function __construct(Node $type, array $attributes = [])
14103 {
14104 $this->attributes = $attributes;
14105 $this->type = $type;
14106 }
14107 public function getSubNodeNames(): array
14108 {
14109 return ['type'];
14110 }
14111 public function getType(): string
14112 {
14113 return 'NullableType';
14114 }
14115 }
14116 <?php
14117
14118 declare (strict_types=1);
14119 namespace PHPUnitPHAR\PhpParser\Node;
14120
14121 use PHPUnitPHAR\PhpParser\Modifiers;
14122 use PHPUnitPHAR\PhpParser\Node;
14123 use PHPUnitPHAR\PhpParser\NodeAbstract;
14124 class Param extends NodeAbstract
14125 {
14126 /** @var null|Identifier|Name|ComplexType Type declaration */
14127 public ?Node $type;
14128 /** @var bool Whether parameter is passed by reference */
14129 public bool $byRef;
14130 /** @var bool Whether this is a variadic argument */
14131 public bool $variadic;
14132 /** @var Expr\Variable|Expr\Error Parameter variable */
14133 public Expr $var;
14134 /** @var null|Expr Default value */
14135 public ?Expr $default;
14136 /** @var int Optional visibility flags */
14137 public int $flags;
14138 /** @var AttributeGroup[] PHP attribute groups */
14139 public array $attrGroups;
14140 /** @var PropertyHook[] Property hooks for promoted properties */
14141 public array $hooks;
14142 /**
14143 * Constructs a parameter node.
14144 *
14145 * @param Expr\Variable|Expr\Error $var Parameter variable
14146 * @param null|Expr $default Default value
14147 * @param null|Identifier|Name|ComplexType $type Type declaration
14148 * @param bool $byRef Whether is passed by reference
14149 * @param bool $variadic Whether this is a variadic argument
14150 * @param array<string, mixed> $attributes Additional attributes
14151 * @param int $flags Optional visibility flags
14152 * @param list<AttributeGroup> $attrGroups PHP attribute groups
14153 * @param PropertyHook[] $hooks Property hooks for promoted properties
14154 */
14155 public function __construct(Expr $var, ?Expr $default = null, ?Node $type = null, bool $byRef = \false, bool $variadic = \false, array $attributes = [], int $flags = 0, array $attrGroups = [], array $hooks = [])
14156 {
14157 $this->attributes = $attributes;
14158 $this->type = $type;
14159 $this->byRef = $byRef;
14160 $this->variadic = $variadic;
14161 $this->var = $var;
14162 $this->default = $default;
14163 $this->flags = $flags;
14164 $this->attrGroups = $attrGroups;
14165 $this->hooks = $hooks;
14166 }
14167 public function getSubNodeNames(): array
14168 {
14169 return ['attrGroups', 'flags', 'type', 'byRef', 'variadic', 'var', 'default', 'hooks'];
14170 }
14171 public function getType(): string
14172 {
14173 return 'Param';
14174 }
14175 /**
14176 * Whether this parameter uses constructor property promotion.
14177 */
14178 public function isPromoted(): bool
14179 {
14180 return $this->flags !== 0 || $this->hooks !== [];
14181 }
14182 public function isFinal(): bool
14183 {
14184 return (bool) ($this->flags & Modifiers::FINAL);
14185 }
14186 public function isPublic(): bool
14187 {
14188 $public = (bool) ($this->flags & Modifiers::PUBLIC);
14189 if ($public) {
14190 return \true;
14191 }
14192 if (!$this->isPromoted()) {
14193 return \false;
14194 }
14195 return ($this->flags & Modifiers::VISIBILITY_MASK) === 0;
14196 }
14197 public function isProtected(): bool
14198 {
14199 return (bool) ($this->flags & Modifiers::PROTECTED);
14200 }
14201 public function isPrivate(): bool
14202 {
14203 return (bool) ($this->flags & Modifiers::PRIVATE);
14204 }
14205 public function isReadonly(): bool
14206 {
14207 return (bool) ($this->flags & Modifiers::READONLY);
14208 }
14209 /**
14210 * Whether the promoted property has explicit public(set) visibility.
14211 */
14212 public function isPublicSet(): bool
14213 {
14214 return (bool) ($this->flags & Modifiers::PUBLIC_SET);
14215 }
14216 /**
14217 * Whether the promoted property has explicit protected(set) visibility.
14218 */
14219 public function isProtectedSet(): bool
14220 {
14221 return (bool) ($this->flags & Modifiers::PROTECTED_SET);
14222 }
14223 /**
14224 * Whether the promoted property has explicit private(set) visibility.
14225 */
14226 public function isPrivateSet(): bool
14227 {
14228 return (bool) ($this->flags & Modifiers::PRIVATE_SET);
14229 }
14230 }
14231 <?php
14232
14233 declare (strict_types=1);
14234 namespace PHPUnitPHAR\PhpParser\Node;
14235
14236 use PHPUnitPHAR\PhpParser\Modifiers;
14237 use PHPUnitPHAR\PhpParser\Node\Expr\Assign;
14238 use PHPUnitPHAR\PhpParser\Node\Expr\PropertyFetch;
14239 use PHPUnitPHAR\PhpParser\Node\Expr\Variable;
14240 use PHPUnitPHAR\PhpParser\Node\Stmt\Expression;
14241 use PHPUnitPHAR\PhpParser\Node\Stmt\Return_;
14242 use PHPUnitPHAR\PhpParser\NodeAbstract;
14243 class PropertyHook extends NodeAbstract implements FunctionLike
14244 {
14245 /** @var AttributeGroup[] PHP attribute groups */
14246 public array $attrGroups;
14247 /** @var int Modifiers */
14248 public int $flags;
14249 /** @var bool Whether hook returns by reference */
14250 public bool $byRef;
14251 /** @var Identifier Hook name */
14252 public Identifier $name;
14253 /** @var Param[] Parameters */
14254 public array $params;
14255 /** @var null|Expr|Stmt[] Hook body */
14256 public $body;
14257 /**
14258 * Constructs a property hook node.
14259 *
14260 * @param string|Identifier $name Hook name
14261 * @param null|Expr|Stmt[] $body Hook body
14262 * @param array{
14263 * flags?: int,
14264 * byRef?: bool,
14265 * params?: Param[],
14266 * attrGroups?: AttributeGroup[],
14267 * } $subNodes Array of the following optional subnodes:
14268 * 'flags => 0 : Flags
14269 * 'byRef' => false : Whether hook returns by reference
14270 * 'params' => array(): Parameters
14271 * 'attrGroups' => array(): PHP attribute groups
14272 * @param array<string, mixed> $attributes Additional attributes
14273 */
14274 public function __construct($name, $body, array $subNodes = [], array $attributes = [])
14275 {
14276 $this->attributes = $attributes;
14277 $this->name = \is_string($name) ? new Identifier($name) : $name;
14278 $this->body = $body;
14279 $this->flags = $subNodes['flags'] ?? 0;
14280 $this->byRef = $subNodes['byRef'] ?? \false;
14281 $this->params = $subNodes['params'] ?? [];
14282 $this->attrGroups = $subNodes['attrGroups'] ?? [];
14283 }
14284 public function returnsByRef(): bool
14285 {
14286 return $this->byRef;
14287 }
14288 public function getParams(): array
14289 {
14290 return $this->params;
14291 }
14292 public function getReturnType()
14293 {
14294 return null;
14295 }
14296 /**
14297 * Whether the property hook is final.
14298 */
14299 public function isFinal(): bool
14300 {
14301 return (bool) ($this->flags & Modifiers::FINAL);
14302 }
14303 public function getStmts(): ?array
14304 {
14305 if ($this->body instanceof Expr) {
14306 $name = $this->name->toLowerString();
14307 if ($name === 'get') {
14308 return [new Return_($this->body)];
14309 }
14310 if ($name === 'set') {
14311 if (!$this->hasAttribute('propertyName')) {
14312 throw new \LogicException('Can only use getStmts() on a "set" hook if the "propertyName" attribute is set');
14313 }
14314 $propName = $this->getAttribute('propertyName');
14315 $prop = new PropertyFetch(new Variable('this'), (string) $propName);
14316 return [new Expression(new Assign($prop, $this->body))];
14317 }
14318 throw new \LogicException('Unknown property hook "' . $name . '"');
14319 }
14320 return $this->body;
14321 }
14322 public function getAttrGroups(): array
14323 {
14324 return $this->attrGroups;
14325 }
14326 public function getType(): string
14327 {
14328 return 'PropertyHook';
14329 }
14330 public function getSubNodeNames(): array
14331 {
14332 return ['attrGroups', 'flags', 'byRef', 'name', 'params', 'body'];
14333 }
14334 }
14335 <?php
14336
14337 declare (strict_types=1);
14338 namespace PHPUnitPHAR\PhpParser\Node;
14339
14340 use PHPUnitPHAR\PhpParser\Node;
14341 use PHPUnitPHAR\PhpParser\NodeAbstract;
14342 class PropertyItem extends NodeAbstract
14343 {
14344 /** @var Node\VarLikeIdentifier Name */
14345 public VarLikeIdentifier $name;
14346 /** @var null|Node\Expr Default */
14347 public ?Expr $default;
14348 /**
14349 * Constructs a class property item node.
14350 *
14351 * @param string|Node\VarLikeIdentifier $name Name
14352 * @param null|Node\Expr $default Default value
14353 * @param array<string, mixed> $attributes Additional attributes
14354 */
14355 public function __construct($name, ?Node\Expr $default = null, array $attributes = [])
14356 {
14357 $this->attributes = $attributes;
14358 $this->name = \is_string($name) ? new Node\VarLikeIdentifier($name) : $name;
14359 $this->default = $default;
14360 }
14361 public function getSubNodeNames(): array
14362 {
14363 return ['name', 'default'];
14364 }
14365 public function getType(): string
14366 {
14367 return 'PropertyItem';
14368 }
14369 }
14370 // @deprecated compatibility alias
14371 class_alias(PropertyItem::class, Stmt\PropertyProperty::class);
14372 <?php
14373
14374 declare (strict_types=1);
14375 namespace PHPUnitPHAR\PhpParser\Node;
14376
14377 abstract class Scalar extends Expr
14378 {
14379 }
14380 <?php
14381
14382 declare (strict_types=1);
14383 namespace PHPUnitPHAR\PhpParser\Node\Scalar;
14384
14385 use PHPUnitPHAR\PhpParser\Node\Scalar;
14386 class Float_ extends Scalar
14387 {
14388 /** @var float Number value */
14389 public float $value;
14390 /**
14391 * Constructs a float number scalar node.
14392 *
14393 * @param float $value Value of the number
14394 * @param array<string, mixed> $attributes Additional attributes
14395 */
14396 public function __construct(float $value, array $attributes = [])
14397 {
14398 $this->attributes = $attributes;
14399 $this->value = $value;
14400 }
14401 public function getSubNodeNames(): array
14402 {
14403 return ['value'];
14404 }
14405 /**
14406 * @param mixed[] $attributes
14407 */
14408 public static function fromString(string $str, array $attributes = []): Float_
14409 {
14410 $attributes['rawValue'] = $str;
14411 $float = self::parse($str);
14412 return new Float_($float, $attributes);
14413 }
14414 /**
14415 * @internal
14416 *
14417 * Parses a DNUMBER token like PHP would.
14418 *
14419 * @param string $str A string number
14420 *
14421 * @return float The parsed number
14422 */
14423 public static function parse(string $str): float
14424 {
14425 $str = str_replace('_', '', $str);
14426 // Check whether this is one of the special integer notations.
14427 if ('0' === $str[0]) {
14428 // hex
14429 if ('x' === $str[1] || 'X' === $str[1]) {
14430 return hexdec($str);
14431 }
14432 // bin
14433 if ('b' === $str[1] || 'B' === $str[1]) {
14434 return bindec($str);
14435 }
14436 // oct, but only if the string does not contain any of '.eE'.
14437 if (\false === strpbrk($str, '.eE')) {
14438 // substr($str, 0, strcspn($str, '89')) cuts the string at the first invalid digit
14439 // (8 or 9) so that only the digits before that are used.
14440 return octdec(substr($str, 0, strcspn($str, '89')));
14441 }
14442 }
14443 // dec
14444 return (float) $str;
14445 }
14446 public function getType(): string
14447 {
14448 return 'Scalar_Float';
14449 }
14450 }
14451 // @deprecated compatibility alias
14452 class_alias(Float_::class, DNumber::class);
14453 <?php
14454
14455 declare (strict_types=1);
14456 namespace PHPUnitPHAR\PhpParser\Node\Scalar;
14457
14458 use PHPUnitPHAR\PhpParser\Error;
14459 use PHPUnitPHAR\PhpParser\Node\Scalar;
14460 class Int_ extends Scalar
14461 {
14462 /* For use in "kind" attribute */
14463 public const KIND_BIN = 2;
14464 public const KIND_OCT = 8;
14465 public const KIND_DEC = 10;
14466 public const KIND_HEX = 16;
14467 /** @var int Number value */
14468 public int $value;
14469 /**
14470 * Constructs an integer number scalar node.
14471 *
14472 * @param int $value Value of the number
14473 * @param array<string, mixed> $attributes Additional attributes
14474 */
14475 public function __construct(int $value, array $attributes = [])
14476 {
14477 $this->attributes = $attributes;
14478 $this->value = $value;
14479 }
14480 public function getSubNodeNames(): array
14481 {
14482 return ['value'];
14483 }
14484 /**
14485 * Constructs an Int node from a string number literal.
14486 *
14487 * @param string $str String number literal (decimal, octal, hex or binary)
14488 * @param array<string, mixed> $attributes Additional attributes
14489 * @param bool $allowInvalidOctal Whether to allow invalid octal numbers (PHP 5)
14490 *
14491 * @return Int_ The constructed LNumber, including kind attribute
14492 */
14493 public static function fromString(string $str, array $attributes = [], bool $allowInvalidOctal = \false): Int_
14494 {
14495 $attributes['rawValue'] = $str;
14496 $str = str_replace('_', '', $str);
14497 if ('0' !== $str[0] || '0' === $str) {
14498 $attributes['kind'] = Int_::KIND_DEC;
14499 return new Int_((int) $str, $attributes);
14500 }
14501 if ('x' === $str[1] || 'X' === $str[1]) {
14502 $attributes['kind'] = Int_::KIND_HEX;
14503 return new Int_(hexdec($str), $attributes);
14504 }
14505 if ('b' === $str[1] || 'B' === $str[1]) {
14506 $attributes['kind'] = Int_::KIND_BIN;
14507 return new Int_(bindec($str), $attributes);
14508 }
14509 if (!$allowInvalidOctal && strpbrk($str, '89')) {
14510 throw new Error('Invalid numeric literal', $attributes);
14511 }
14512 // Strip optional explicit octal prefix.
14513 if ('o' === $str[1] || 'O' === $str[1]) {
14514 $str = substr($str, 2);
14515 }
14516 // use intval instead of octdec to get proper cutting behavior with malformed numbers
14517 $attributes['kind'] = Int_::KIND_OCT;
14518 return new Int_(intval($str, 8), $attributes);
14519 }
14520 public function getType(): string
14521 {
14522 return 'Scalar_Int';
14523 }
14524 }
14525 // @deprecated compatibility alias
14526 class_alias(Int_::class, LNumber::class);
14527 <?php
14528
14529 declare (strict_types=1);
14530 namespace PHPUnitPHAR\PhpParser\Node\Scalar;
14531
14532 use PHPUnitPHAR\PhpParser\Node\Expr;
14533 use PHPUnitPHAR\PhpParser\Node\InterpolatedStringPart;
14534 use PHPUnitPHAR\PhpParser\Node\Scalar;
14535 class InterpolatedString extends Scalar
14536 {
14537 /** @var (Expr|InterpolatedStringPart)[] list of string parts */
14538 public array $parts;
14539 /**
14540 * Constructs an interpolated string node.
14541 *
14542 * @param (Expr|InterpolatedStringPart)[] $parts Interpolated string parts
14543 * @param array<string, mixed> $attributes Additional attributes
14544 */
14545 public function __construct(array $parts, array $attributes = [])
14546 {
14547 $this->attributes = $attributes;
14548 $this->parts = $parts;
14549 }
14550 public function getSubNodeNames(): array
14551 {
14552 return ['parts'];
14553 }
14554 public function getType(): string
14555 {
14556 return 'Scalar_InterpolatedString';
14557 }
14558 }
14559 // @deprecated compatibility alias
14560 class_alias(InterpolatedString::class, Encapsed::class);
14561 <?php
14562
14563 declare (strict_types=1);
14564 namespace PHPUnitPHAR\PhpParser\Node\Scalar;
14565
14566 use PHPUnitPHAR\PhpParser\Node\Scalar;
14567 abstract class MagicConst extends Scalar
14568 {
14569 /**
14570 * Constructs a magic constant node.
14571 *
14572 * @param array<string, mixed> $attributes Additional attributes
14573 */
14574 public function __construct(array $attributes = [])
14575 {
14576 $this->attributes = $attributes;
14577 }
14578 public function getSubNodeNames(): array
14579 {
14580 return [];
14581 }
14582 /**
14583 * Get name of magic constant.
14584 *
14585 * @return string Name of magic constant
14586 */
14587 abstract public function getName(): string;
14588 }
14589 <?php
14590
14591 declare (strict_types=1);
14592 namespace PHPUnitPHAR\PhpParser\Node\Scalar\MagicConst;
14593
14594 use PHPUnitPHAR\PhpParser\Node\Scalar\MagicConst;
14595 class Class_ extends MagicConst
14596 {
14597 public function getName(): string
14598 {
14599 return '__CLASS__';
14600 }
14601 public function getType(): string
14602 {
14603 return 'Scalar_MagicConst_Class';
14604 }
14605 }
14606 <?php
14607
14608 declare (strict_types=1);
14609 namespace PHPUnitPHAR\PhpParser\Node\Scalar\MagicConst;
14610
14611 use PHPUnitPHAR\PhpParser\Node\Scalar\MagicConst;
14612 class Dir extends MagicConst
14613 {
14614 public function getName(): string
14615 {
14616 return '__DIR__';
14617 }
14618 public function getType(): string
14619 {
14620 return 'Scalar_MagicConst_Dir';
14621 }
14622 }
14623 <?php
14624
14625 declare (strict_types=1);
14626 namespace PHPUnitPHAR\PhpParser\Node\Scalar\MagicConst;
14627
14628 use PHPUnitPHAR\PhpParser\Node\Scalar\MagicConst;
14629 class File extends MagicConst
14630 {
14631 public function getName(): string
14632 {
14633 return '__FILE__';
14634 }
14635 public function getType(): string
14636 {
14637 return 'Scalar_MagicConst_File';
14638 }
14639 }
14640 <?php
14641
14642 declare (strict_types=1);
14643 namespace PHPUnitPHAR\PhpParser\Node\Scalar\MagicConst;
14644
14645 use PHPUnitPHAR\PhpParser\Node\Scalar\MagicConst;
14646 class Function_ extends MagicConst
14647 {
14648 public function getName(): string
14649 {
14650 return '__FUNCTION__';
14651 }
14652 public function getType(): string
14653 {
14654 return 'Scalar_MagicConst_Function';
14655 }
14656 }
14657 <?php
14658
14659 declare (strict_types=1);
14660 namespace PHPUnitPHAR\PhpParser\Node\Scalar\MagicConst;
14661
14662 use PHPUnitPHAR\PhpParser\Node\Scalar\MagicConst;
14663 class Line extends MagicConst
14664 {
14665 public function getName(): string
14666 {
14667 return '__LINE__';
14668 }
14669 public function getType(): string
14670 {
14671 return 'Scalar_MagicConst_Line';
14672 }
14673 }
14674 <?php
14675
14676 declare (strict_types=1);
14677 namespace PHPUnitPHAR\PhpParser\Node\Scalar\MagicConst;
14678
14679 use PHPUnitPHAR\PhpParser\Node\Scalar\MagicConst;
14680 class Method extends MagicConst
14681 {
14682 public function getName(): string
14683 {
14684 return '__METHOD__';
14685 }
14686 public function getType(): string
14687 {
14688 return 'Scalar_MagicConst_Method';
14689 }
14690 }
14691 <?php
14692
14693 declare (strict_types=1);
14694 namespace PHPUnitPHAR\PhpParser\Node\Scalar\MagicConst;
14695
14696 use PHPUnitPHAR\PhpParser\Node\Scalar\MagicConst;
14697 class Namespace_ extends MagicConst
14698 {
14699 public function getName(): string
14700 {
14701 return '__NAMESPACE__';
14702 }
14703 public function getType(): string
14704 {
14705 return 'Scalar_MagicConst_Namespace';
14706 }
14707 }
14708 <?php
14709
14710 declare (strict_types=1);
14711 namespace PHPUnitPHAR\PhpParser\Node\Scalar\MagicConst;
14712
14713 use PHPUnitPHAR\PhpParser\Node\Scalar\MagicConst;
14714 class Property extends MagicConst
14715 {
14716 public function getName(): string
14717 {
14718 return '__PROPERTY__';
14719 }
14720 public function getType(): string
14721 {
14722 return 'Scalar_MagicConst_Property';
14723 }
14724 }
14725 <?php
14726
14727 declare (strict_types=1);
14728 namespace PHPUnitPHAR\PhpParser\Node\Scalar\MagicConst;
14729
14730 use PHPUnitPHAR\PhpParser\Node\Scalar\MagicConst;
14731 class Trait_ extends MagicConst
14732 {
14733 public function getName(): string
14734 {
14735 return '__TRAIT__';
14736 }
14737 public function getType(): string
14738 {
14739 return 'Scalar_MagicConst_Trait';
14740 }
14741 }
14742 <?php
14743
14744 declare (strict_types=1);
14745 namespace PHPUnitPHAR\PhpParser\Node\Scalar;
14746
14747 use PHPUnitPHAR\PhpParser\Error;
14748 use PHPUnitPHAR\PhpParser\Node\Scalar;
14749 class String_ extends Scalar
14750 {
14751 /* For use in "kind" attribute */
14752 public const KIND_SINGLE_QUOTED = 1;
14753 public const KIND_DOUBLE_QUOTED = 2;
14754 public const KIND_HEREDOC = 3;
14755 public const KIND_NOWDOC = 4;
14756 /** @var string String value */
14757 public string $value;
14758 /** @var array<string, string> Escaped character to its decoded value */
14759 protected static array $replacements = ['\\' => '\\', '$' => '$', 'n' => "\n", 'r' => "\r", 't' => "\t", 'f' => "\f", 'v' => "\v", 'e' => "\x1b"];
14760 /**
14761 * Constructs a string scalar node.
14762 *
14763 * @param string $value Value of the string
14764 * @param array<string, mixed> $attributes Additional attributes
14765 */
14766 public function __construct(string $value, array $attributes = [])
14767 {
14768 $this->attributes = $attributes;
14769 $this->value = $value;
14770 }
14771 public function getSubNodeNames(): array
14772 {
14773 return ['value'];
14774 }
14775 /**
14776 * @param array<string, mixed> $attributes
14777 * @param bool $parseUnicodeEscape Whether to parse PHP 7 \u escapes
14778 */
14779 public static function fromString(string $str, array $attributes = [], bool $parseUnicodeEscape = \true): self
14780 {
14781 $attributes['kind'] = $str[0] === "'" || $str[1] === "'" && ($str[0] === 'b' || $str[0] === 'B') ? Scalar\String_::KIND_SINGLE_QUOTED : Scalar\String_::KIND_DOUBLE_QUOTED;
14782 $attributes['rawValue'] = $str;
14783 $string = self::parse($str, $parseUnicodeEscape);
14784 return new self($string, $attributes);
14785 }
14786 /**
14787 * @internal
14788 *
14789 * Parses a string token.
14790 *
14791 * @param string $str String token content
14792 * @param bool $parseUnicodeEscape Whether to parse PHP 7 \u escapes
14793 *
14794 * @return string The parsed string
14795 */
14796 public static function parse(string $str, bool $parseUnicodeEscape = \true): string
14797 {
14798 $bLength = 0;
14799 if ('b' === $str[0] || 'B' === $str[0]) {
14800 $bLength = 1;
14801 }
14802 if ('\'' === $str[$bLength]) {
14803 return str_replace(['\\\\', '\\\''], ['\\', '\''], substr($str, $bLength + 1, -1));
14804 } else {
14805 return self::parseEscapeSequences(substr($str, $bLength + 1, -1), '"', $parseUnicodeEscape);
14806 }
14807 }
14808 /**
14809 * @internal
14810 *
14811 * Parses escape sequences in strings (all string types apart from single quoted).
14812 *
14813 * @param string $str String without quotes
14814 * @param null|string $quote Quote type
14815 * @param bool $parseUnicodeEscape Whether to parse PHP 7 \u escapes
14816 *
14817 * @return string String with escape sequences parsed
14818 */
14819 public static function parseEscapeSequences(string $str, ?string $quote, bool $parseUnicodeEscape = \true): string
14820 {
14821 if (null !== $quote) {
14822 $str = str_replace('\\' . $quote, $quote, $str);
14823 }
14824 $extra = '';
14825 if ($parseUnicodeEscape) {
14826 $extra = '|u\{([0-9a-fA-F]+)\}';
14827 }
14828 return preg_replace_callback('~\\\\([\\\\$nrtfve]|[xX][0-9a-fA-F]{1,2}|[0-7]{1,3}' . $extra . ')~', function ($matches) {
14829 $str = $matches[1];
14830 if (isset(self::$replacements[$str])) {
14831 return self::$replacements[$str];
14832 }
14833 if ('x' === $str[0] || 'X' === $str[0]) {
14834 return chr(hexdec(substr($str, 1)));
14835 }
14836 if ('u' === $str[0]) {
14837 $dec = hexdec($matches[2]);
14838 // If it overflowed to float, treat as INT_MAX, it will throw an error anyway.
14839 return self::codePointToUtf8(\is_int($dec) ? $dec : \PHP_INT_MAX);
14840 } else {
14841 return chr(octdec($str) & 255);
14842 }
14843 }, $str);
14844 }
14845 /**
14846 * Converts a Unicode code point to its UTF-8 encoded representation.
14847 *
14848 * @param int $num Code point
14849 *
14850 * @return string UTF-8 representation of code point
14851 */
14852 private static function codePointToUtf8(int $num): string
14853 {
14854 if ($num <= 0x7f) {
14855 return chr($num);
14856 }
14857 if ($num <= 0x7ff) {
14858 return chr(($num >> 6) + 0xc0) . chr(($num & 0x3f) + 0x80);
14859 }
14860 if ($num <= 0xffff) {
14861 return chr(($num >> 12) + 0xe0) . chr(($num >> 6 & 0x3f) + 0x80) . chr(($num & 0x3f) + 0x80);
14862 }
14863 if ($num <= 0x1fffff) {
14864 return chr(($num >> 18) + 0xf0) . chr(($num >> 12 & 0x3f) + 0x80) . chr(($num >> 6 & 0x3f) + 0x80) . chr(($num & 0x3f) + 0x80);
14865 }
14866 throw new Error('Invalid UTF-8 codepoint escape sequence: Codepoint too large');
14867 }
14868 public function getType(): string
14869 {
14870 return 'Scalar_String';
14871 }
14872 }
14873 <?php
14874
14875 declare (strict_types=1);
14876 namespace PHPUnitPHAR\PhpParser\Node;
14877
14878 use PHPUnitPHAR\PhpParser\Node;
14879 use PHPUnitPHAR\PhpParser\NodeAbstract;
14880 class StaticVar extends NodeAbstract
14881 {
14882 /** @var Expr\Variable Variable */
14883 public Expr\Variable $var;
14884 /** @var null|Node\Expr Default value */
14885 public ?Expr $default;
14886 /**
14887 * Constructs a static variable node.
14888 *
14889 * @param Expr\Variable $var Name
14890 * @param null|Node\Expr $default Default value
14891 * @param array<string, mixed> $attributes Additional attributes
14892 */
14893 public function __construct(Expr\Variable $var, ?Node\Expr $default = null, array $attributes = [])
14894 {
14895 $this->attributes = $attributes;
14896 $this->var = $var;
14897 $this->default = $default;
14898 }
14899 public function getSubNodeNames(): array
14900 {
14901 return ['var', 'default'];
14902 }
14903 public function getType(): string
14904 {
14905 return 'StaticVar';
14906 }
14907 }
14908 // @deprecated compatibility alias
14909 class_alias(StaticVar::class, Stmt\StaticVar::class);
14910 <?php
14911
14912 declare (strict_types=1);
14913 namespace PHPUnitPHAR\PhpParser\Node;
14914
14915 use PHPUnitPHAR\PhpParser\NodeAbstract;
14916 abstract class Stmt extends NodeAbstract
14917 {
14918 }
14919 <?php
14920
14921 declare (strict_types=1);
14922 namespace PHPUnitPHAR\PhpParser\Node\Stmt;
14923
14924 use PHPUnitPHAR\PhpParser\Node\Stmt;
14925 class Block extends Stmt
14926 {
14927 /** @var Stmt[] Statements */
14928 public array $stmts;
14929 /**
14930 * A block of statements.
14931 *
14932 * @param Stmt[] $stmts Statements
14933 * @param array<string, mixed> $attributes Additional attributes
14934 */
14935 public function __construct(array $stmts, array $attributes = [])
14936 {
14937 $this->attributes = $attributes;
14938 $this->stmts = $stmts;
14939 }
14940 public function getType(): string
14941 {
14942 return 'Stmt_Block';
14943 }
14944 public function getSubNodeNames(): array
14945 {
14946 return ['stmts'];
14947 }
14948 }
14949 <?php
14950
14951 declare (strict_types=1);
14952 namespace PHPUnitPHAR\PhpParser\Node\Stmt;
14953
14954 use PHPUnitPHAR\PhpParser\Node;
14955 class Break_ extends Node\Stmt
14956 {
14957 /** @var null|Node\Expr Number of loops to break */
14958 public ?Node\Expr $num;
14959 /**
14960 * Constructs a break node.
14961 *
14962 * @param null|Node\Expr $num Number of loops to break
14963 * @param array<string, mixed> $attributes Additional attributes
14964 */
14965 public function __construct(?Node\Expr $num = null, array $attributes = [])
14966 {
14967 $this->attributes = $attributes;
14968 $this->num = $num;
14969 }
14970 public function getSubNodeNames(): array
14971 {
14972 return ['num'];
14973 }
14974 public function getType(): string
14975 {
14976 return 'Stmt_Break';
14977 }
14978 }
14979 <?php
14980
14981 declare (strict_types=1);
14982 namespace PHPUnitPHAR\PhpParser\Node\Stmt;
14983
14984 use PHPUnitPHAR\PhpParser\Node;
14985 class Case_ extends Node\Stmt
14986 {
14987 /** @var null|Node\Expr Condition (null for default) */
14988 public ?Node\Expr $cond;
14989 /** @var Node\Stmt[] Statements */
14990 public array $stmts;
14991 /**
14992 * Constructs a case node.
14993 *
14994 * @param null|Node\Expr $cond Condition (null for default)
14995 * @param Node\Stmt[] $stmts Statements
14996 * @param array<string, mixed> $attributes Additional attributes
14997 */
14998 public function __construct(?Node\Expr $cond, array $stmts = [], array $attributes = [])
14999 {
15000 $this->attributes = $attributes;
15001 $this->cond = $cond;
15002 $this->stmts = $stmts;
15003 }
15004 public function getSubNodeNames(): array
15005 {
15006 return ['cond', 'stmts'];
15007 }
15008 public function getType(): string
15009 {
15010 return 'Stmt_Case';
15011 }
15012 }
15013 <?php
15014
15015 declare (strict_types=1);
15016 namespace PHPUnitPHAR\PhpParser\Node\Stmt;
15017
15018 use PHPUnitPHAR\PhpParser\Node;
15019 use PHPUnitPHAR\PhpParser\Node\Expr;
15020 class Catch_ extends Node\Stmt
15021 {
15022 /** @var Node\Name[] Types of exceptions to catch */
15023 public array $types;
15024 /** @var Expr\Variable|null Variable for exception */
15025 public ?Expr\Variable $var;
15026 /** @var Node\Stmt[] Statements */
15027 public array $stmts;
15028 /**
15029 * Constructs a catch node.
15030 *
15031 * @param Node\Name[] $types Types of exceptions to catch
15032 * @param Expr\Variable|null $var Variable for exception
15033 * @param Node\Stmt[] $stmts Statements
15034 * @param array<string, mixed> $attributes Additional attributes
15035 */
15036 public function __construct(array $types, ?Expr\Variable $var = null, array $stmts = [], array $attributes = [])
15037 {
15038 $this->attributes = $attributes;
15039 $this->types = $types;
15040 $this->var = $var;
15041 $this->stmts = $stmts;
15042 }
15043 public function getSubNodeNames(): array
15044 {
15045 return ['types', 'var', 'stmts'];
15046 }
15047 public function getType(): string
15048 {
15049 return 'Stmt_Catch';
15050 }
15051 }
15052 <?php
15053
15054 declare (strict_types=1);
15055 namespace PHPUnitPHAR\PhpParser\Node\Stmt;
15056
15057 use PHPUnitPHAR\PhpParser\Modifiers;
15058 use PHPUnitPHAR\PhpParser\Node;
15059 class ClassConst extends Node\Stmt
15060 {
15061 /** @var int Modifiers */
15062 public int $flags;
15063 /** @var Node\Const_[] Constant declarations */
15064 public array $consts;
15065 /** @var Node\AttributeGroup[] PHP attribute groups */
15066 public array $attrGroups;
15067 /** @var Node\Identifier|Node\Name|Node\ComplexType|null Type declaration */
15068 public ?Node $type;
15069 /**
15070 * Constructs a class const list node.
15071 *
15072 * @param Node\Const_[] $consts Constant declarations
15073 * @param int $flags Modifiers
15074 * @param array<string, mixed> $attributes Additional attributes
15075 * @param list<Node\AttributeGroup> $attrGroups PHP attribute groups
15076 * @param null|Node\Identifier|Node\Name|Node\ComplexType $type Type declaration
15077 */
15078 public function __construct(array $consts, int $flags = 0, array $attributes = [], array $attrGroups = [], ?Node $type = null)
15079 {
15080 $this->attributes = $attributes;
15081 $this->flags = $flags;
15082 $this->consts = $consts;
15083 $this->attrGroups = $attrGroups;
15084 $this->type = $type;
15085 }
15086 public function getSubNodeNames(): array
15087 {
15088 return ['attrGroups', 'flags', 'type', 'consts'];
15089 }
15090 /**
15091 * Whether constant is explicitly or implicitly public.
15092 */
15093 public function isPublic(): bool
15094 {
15095 return ($this->flags & Modifiers::PUBLIC) !== 0 || ($this->flags & Modifiers::VISIBILITY_MASK) === 0;
15096 }
15097 /**
15098 * Whether constant is protected.
15099 */
15100 public function isProtected(): bool
15101 {
15102 return (bool) ($this->flags & Modifiers::PROTECTED);
15103 }
15104 /**
15105 * Whether constant is private.
15106 */
15107 public function isPrivate(): bool
15108 {
15109 return (bool) ($this->flags & Modifiers::PRIVATE);
15110 }
15111 /**
15112 * Whether constant is final.
15113 */
15114 public function isFinal(): bool
15115 {
15116 return (bool) ($this->flags & Modifiers::FINAL);
15117 }
15118 public function getType(): string
15119 {
15120 return 'Stmt_ClassConst';
15121 }
15122 }
15123 <?php
15124
15125 declare (strict_types=1);
15126 namespace PHPUnitPHAR\PhpParser\Node\Stmt;
15127
15128 use PHPUnitPHAR\PhpParser\Node;
15129 use PHPUnitPHAR\PhpParser\Node\PropertyItem;
15130 abstract class ClassLike extends Node\Stmt
15131 {
15132 /** @var Node\Identifier|null Name */
15133 public ?Node\Identifier $name;
15134 /** @var Node\Stmt[] Statements */
15135 public array $stmts;
15136 /** @var Node\AttributeGroup[] PHP attribute groups */
15137 public array $attrGroups;
15138 /** @var Node\Name|null Namespaced name (if using NameResolver) */
15139 public ?Node\Name $namespacedName;
15140 /**
15141 * @return list<TraitUse>
15142 */
15143 public function getTraitUses(): array
15144 {
15145 $traitUses = [];
15146 foreach ($this->stmts as $stmt) {
15147 if ($stmt instanceof TraitUse) {
15148 $traitUses[] = $stmt;
15149 }
15150 }
15151 return $traitUses;
15152 }
15153 /**
15154 * @return list<ClassConst>
15155 */
15156 public function getConstants(): array
15157 {
15158 $constants = [];
15159 foreach ($this->stmts as $stmt) {
15160 if ($stmt instanceof ClassConst) {
15161 $constants[] = $stmt;
15162 }
15163 }
15164 return $constants;
15165 }
15166 /**
15167 * @return list<Property>
15168 */
15169 public function getProperties(): array
15170 {
15171 $properties = [];
15172 foreach ($this->stmts as $stmt) {
15173 if ($stmt instanceof Property) {
15174 $properties[] = $stmt;
15175 }
15176 }
15177 return $properties;
15178 }
15179 /**
15180 * Gets property with the given name defined directly in this class/interface/trait.
15181 *
15182 * @param string $name Name of the property
15183 *
15184 * @return Property|null Property node or null if the property does not exist
15185 */
15186 public function getProperty(string $name): ?Property
15187 {
15188 foreach ($this->stmts as $stmt) {
15189 if ($stmt instanceof Property) {
15190 foreach ($stmt->props as $prop) {
15191 if ($prop instanceof PropertyItem && $name === $prop->name->toString()) {
15192 return $stmt;
15193 }
15194 }
15195 }
15196 }
15197 return null;
15198 }
15199 /**
15200 * Gets all methods defined directly in this class/interface/trait
15201 *
15202 * @return list<ClassMethod>
15203 */
15204 public function getMethods(): array
15205 {
15206 $methods = [];
15207 foreach ($this->stmts as $stmt) {
15208 if ($stmt instanceof ClassMethod) {
15209 $methods[] = $stmt;
15210 }
15211 }
15212 return $methods;
15213 }
15214 /**
15215 * Gets method with the given name defined directly in this class/interface/trait.
15216 *
15217 * @param string $name Name of the method (compared case-insensitively)
15218 *
15219 * @return ClassMethod|null Method node or null if the method does not exist
15220 */
15221 public function getMethod(string $name): ?ClassMethod
15222 {
15223 $lowerName = strtolower($name);
15224 foreach ($this->stmts as $stmt) {
15225 if ($stmt instanceof ClassMethod && $lowerName === $stmt->name->toLowerString()) {
15226 return $stmt;
15227 }
15228 }
15229 return null;
15230 }
15231 }
15232 <?php
15233
15234 declare (strict_types=1);
15235 namespace PHPUnitPHAR\PhpParser\Node\Stmt;
15236
15237 use PHPUnitPHAR\PhpParser\Modifiers;
15238 use PHPUnitPHAR\PhpParser\Node;
15239 use PHPUnitPHAR\PhpParser\Node\FunctionLike;
15240 class ClassMethod extends Node\Stmt implements FunctionLike
15241 {
15242 /** @var int Flags */
15243 public int $flags;
15244 /** @var bool Whether to return by reference */
15245 public bool $byRef;
15246 /** @var Node\Identifier Name */
15247 public Node\Identifier $name;
15248 /** @var Node\Param[] Parameters */
15249 public array $params;
15250 /** @var null|Node\Identifier|Node\Name|Node\ComplexType Return type */
15251 public ?Node $returnType;
15252 /** @var Node\Stmt[]|null Statements */
15253 public ?array $stmts;
15254 /** @var Node\AttributeGroup[] PHP attribute groups */
15255 public array $attrGroups;
15256 /** @var array<string, bool> */
15257 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];
15258 /**
15259 * Constructs a class method node.
15260 *
15261 * @param string|Node\Identifier $name Name
15262 * @param array{
15263 * flags?: int,
15264 * byRef?: bool,
15265 * params?: Node\Param[],
15266 * returnType?: null|Node\Identifier|Node\Name|Node\ComplexType,
15267 * stmts?: Node\Stmt[]|null,
15268 * attrGroups?: Node\AttributeGroup[],
15269 * } $subNodes Array of the following optional subnodes:
15270 * 'flags => 0 : Flags
15271 * 'byRef' => false : Whether to return by reference
15272 * 'params' => array() : Parameters
15273 * 'returnType' => null : Return type
15274 * 'stmts' => array() : Statements
15275 * 'attrGroups' => array() : PHP attribute groups
15276 * @param array<string, mixed> $attributes Additional attributes
15277 */
15278 public function __construct($name, array $subNodes = [], array $attributes = [])
15279 {
15280 $this->attributes = $attributes;
15281 $this->flags = $subNodes['flags'] ?? $subNodes['type'] ?? 0;
15282 $this->byRef = $subNodes['byRef'] ?? \false;
15283 $this->name = \is_string($name) ? new Node\Identifier($name) : $name;
15284 $this->params = $subNodes['params'] ?? [];
15285 $this->returnType = $subNodes['returnType'] ?? null;
15286 $this->stmts = array_key_exists('stmts', $subNodes) ? $subNodes['stmts'] : [];
15287 $this->attrGroups = $subNodes['attrGroups'] ?? [];
15288 }
15289 public function getSubNodeNames(): array
15290 {
15291 return ['attrGroups', 'flags', 'byRef', 'name', 'params', 'returnType', 'stmts'];
15292 }
15293 public function returnsByRef(): bool
15294 {
15295 return $this->byRef;
15296 }
15297 public function getParams(): array
15298 {
15299 return $this->params;
15300 }
15301 public function getReturnType()
15302 {
15303 return $this->returnType;
15304 }
15305 public function getStmts(): ?array
15306 {
15307 return $this->stmts;
15308 }
15309 public function getAttrGroups(): array
15310 {
15311 return $this->attrGroups;
15312 }
15313 /**
15314 * Whether the method is explicitly or implicitly public.
15315 */
15316 public function isPublic(): bool
15317 {
15318 return ($this->flags & Modifiers::PUBLIC) !== 0 || ($this->flags & Modifiers::VISIBILITY_MASK) === 0;
15319 }
15320 /**
15321 * Whether the method is protected.
15322 */
15323 public function isProtected(): bool
15324 {
15325 return (bool) ($this->flags & Modifiers::PROTECTED);
15326 }
15327 /**
15328 * Whether the method is private.
15329 */
15330 public function isPrivate(): bool
15331 {
15332 return (bool) ($this->flags & Modifiers::PRIVATE);
15333 }
15334 /**
15335 * Whether the method is abstract.
15336 */
15337 public function isAbstract(): bool
15338 {
15339 return (bool) ($this->flags & Modifiers::ABSTRACT);
15340 }
15341 /**
15342 * Whether the method is final.
15343 */
15344 public function isFinal(): bool
15345 {
15346 return (bool) ($this->flags & Modifiers::FINAL);
15347 }
15348 /**
15349 * Whether the method is static.
15350 */
15351 public function isStatic(): bool
15352 {
15353 return (bool) ($this->flags & Modifiers::STATIC);
15354 }
15355 /**
15356 * Whether the method is magic.
15357 */
15358 public function isMagic(): bool
15359 {
15360 return isset(self::$magicNames[$this->name->toLowerString()]);
15361 }
15362 public function getType(): string
15363 {
15364 return 'Stmt_ClassMethod';
15365 }
15366 }
15367 <?php
15368
15369 declare (strict_types=1);
15370 namespace PHPUnitPHAR\PhpParser\Node\Stmt;
15371
15372 use PHPUnitPHAR\PhpParser\Modifiers;
15373 use PHPUnitPHAR\PhpParser\Node;
15374 class Class_ extends ClassLike
15375 {
15376 /** @deprecated Use Modifiers::PUBLIC instead */
15377 public const MODIFIER_PUBLIC = 1;
15378 /** @deprecated Use Modifiers::PROTECTED instead */
15379 public const MODIFIER_PROTECTED = 2;
15380 /** @deprecated Use Modifiers::PRIVATE instead */
15381 public const MODIFIER_PRIVATE = 4;
15382 /** @deprecated Use Modifiers::STATIC instead */
15383 public const MODIFIER_STATIC = 8;
15384 /** @deprecated Use Modifiers::ABSTRACT instead */
15385 public const MODIFIER_ABSTRACT = 16;
15386 /** @deprecated Use Modifiers::FINAL instead */
15387 public const MODIFIER_FINAL = 32;
15388 /** @deprecated Use Modifiers::READONLY instead */
15389 public const MODIFIER_READONLY = 64;
15390 /** @deprecated Use Modifiers::VISIBILITY_MASK instead */
15391 public const VISIBILITY_MODIFIER_MASK = 7;
15392 // 1 | 2 | 4
15393 /** @var int Modifiers */
15394 public int $flags;
15395 /** @var null|Node\Name Name of extended class */
15396 public ?Node\Name $extends;
15397 /** @var Node\Name[] Names of implemented interfaces */
15398 public array $implements;
15399 /**
15400 * Constructs a class node.
15401 *
15402 * @param string|Node\Identifier|null $name Name
15403 * @param array{
15404 * flags?: int,
15405 * extends?: Node\Name|null,
15406 * implements?: Node\Name[],
15407 * stmts?: Node\Stmt[],
15408 * attrGroups?: Node\AttributeGroup[],
15409 * } $subNodes Array of the following optional subnodes:
15410 * 'flags' => 0 : Flags
15411 * 'extends' => null : Name of extended class
15412 * 'implements' => array(): Names of implemented interfaces
15413 * 'stmts' => array(): Statements
15414 * 'attrGroups' => array(): PHP attribute groups
15415 * @param array<string, mixed> $attributes Additional attributes
15416 */
15417 public function __construct($name, array $subNodes = [], array $attributes = [])
15418 {
15419 $this->attributes = $attributes;
15420 $this->flags = $subNodes['flags'] ?? $subNodes['type'] ?? 0;
15421 $this->name = \is_string($name) ? new Node\Identifier($name) : $name;
15422 $this->extends = $subNodes['extends'] ?? null;
15423 $this->implements = $subNodes['implements'] ?? [];
15424 $this->stmts = $subNodes['stmts'] ?? [];
15425 $this->attrGroups = $subNodes['attrGroups'] ?? [];
15426 }
15427 public function getSubNodeNames(): array
15428 {
15429 return ['attrGroups', 'flags', 'name', 'extends', 'implements', 'stmts'];
15430 }
15431 /**
15432 * Whether the class is explicitly abstract.
15433 */
15434 public function isAbstract(): bool
15435 {
15436 return (bool) ($this->flags & Modifiers::ABSTRACT);
15437 }
15438 /**
15439 * Whether the class is final.
15440 */
15441 public function isFinal(): bool
15442 {
15443 return (bool) ($this->flags & Modifiers::FINAL);
15444 }
15445 public function isReadonly(): bool
15446 {
15447 return (bool) ($this->flags & Modifiers::READONLY);
15448 }
15449 /**
15450 * Whether the class is anonymous.
15451 */
15452 public function isAnonymous(): bool
15453 {
15454 return null === $this->name;
15455 }
15456 public function getType(): string
15457 {
15458 return 'Stmt_Class';
15459 }
15460 }
15461 <?php
15462
15463 declare (strict_types=1);
15464 namespace PHPUnitPHAR\PhpParser\Node\Stmt;
15465
15466 use PHPUnitPHAR\PhpParser\Node;
15467 class Const_ extends Node\Stmt
15468 {
15469 /** @var Node\Const_[] Constant declarations */
15470 public array $consts;
15471 /** @var Node\AttributeGroup[] PHP attribute groups */
15472 public array $attrGroups;
15473 /**
15474 * Constructs a const list node.
15475 *
15476 * @param Node\Const_[] $consts Constant declarations
15477 * @param array<string, mixed> $attributes Additional attributes
15478 * @param list<Node\AttributeGroup> $attrGroups PHP attribute groups
15479 */
15480 public function __construct(array $consts, array $attributes = [], array $attrGroups = [])
15481 {
15482 $this->attributes = $attributes;
15483 $this->attrGroups = $attrGroups;
15484 $this->consts = $consts;
15485 }
15486 public function getSubNodeNames(): array
15487 {
15488 return ['attrGroups', 'consts'];
15489 }
15490 public function getType(): string
15491 {
15492 return 'Stmt_Const';
15493 }
15494 }
15495 <?php
15496
15497 declare (strict_types=1);
15498 namespace PHPUnitPHAR\PhpParser\Node\Stmt;
15499
15500 use PHPUnitPHAR\PhpParser\Node;
15501 class Continue_ extends Node\Stmt
15502 {
15503 /** @var null|Node\Expr Number of loops to continue */
15504 public ?Node\Expr $num;
15505 /**
15506 * Constructs a continue node.
15507 *
15508 * @param null|Node\Expr $num Number of loops to continue
15509 * @param array<string, mixed> $attributes Additional attributes
15510 */
15511 public function __construct(?Node\Expr $num = null, array $attributes = [])
15512 {
15513 $this->attributes = $attributes;
15514 $this->num = $num;
15515 }
15516 public function getSubNodeNames(): array
15517 {
15518 return ['num'];
15519 }
15520 public function getType(): string
15521 {
15522 return 'Stmt_Continue';
15523 }
15524 }
15525 <?php
15526
15527 declare (strict_types=1);
15528 namespace PHPUnitPHAR\PhpParser\Node\Stmt;
15529
15530 use PHPUnitPHAR\PhpParser\Node;
15531 use PHPUnitPHAR\PhpParser\Node\DeclareItem;
15532 class Declare_ extends Node\Stmt
15533 {
15534 /** @var DeclareItem[] List of declares */
15535 public array $declares;
15536 /** @var Node\Stmt[]|null Statements */
15537 public ?array $stmts;
15538 /**
15539 * Constructs a declare node.
15540 *
15541 * @param DeclareItem[] $declares List of declares
15542 * @param Node\Stmt[]|null $stmts Statements
15543 * @param array<string, mixed> $attributes Additional attributes
15544 */
15545 public function __construct(array $declares, ?array $stmts = null, array $attributes = [])
15546 {
15547 $this->attributes = $attributes;
15548 $this->declares = $declares;
15549 $this->stmts = $stmts;
15550 }
15551 public function getSubNodeNames(): array
15552 {
15553 return ['declares', 'stmts'];
15554 }
15555 public function getType(): string
15556 {
15557 return 'Stmt_Declare';
15558 }
15559 }
15560 <?php
15561
15562 declare (strict_types=1);
15563 namespace PHPUnitPHAR\PhpParser\Node\Stmt;
15564
15565 use PHPUnitPHAR\PhpParser\Node;
15566 class Do_ extends Node\Stmt
15567 {
15568 /** @var Node\Stmt[] Statements */
15569 public array $stmts;
15570 /** @var Node\Expr Condition */
15571 public Node\Expr $cond;
15572 /**
15573 * Constructs a do while node.
15574 *
15575 * @param Node\Expr $cond Condition
15576 * @param Node\Stmt[] $stmts Statements
15577 * @param array<string, mixed> $attributes Additional attributes
15578 */
15579 public function __construct(Node\Expr $cond, array $stmts = [], array $attributes = [])
15580 {
15581 $this->attributes = $attributes;
15582 $this->cond = $cond;
15583 $this->stmts = $stmts;
15584 }
15585 public function getSubNodeNames(): array
15586 {
15587 return ['stmts', 'cond'];
15588 }
15589 public function getType(): string
15590 {
15591 return 'Stmt_Do';
15592 }
15593 }
15594 <?php
15595
15596 declare (strict_types=1);
15597 namespace PHPUnitPHAR\PhpParser\Node\Stmt;
15598
15599 use PHPUnitPHAR\PhpParser\Node;
15600 class Echo_ extends Node\Stmt
15601 {
15602 /** @var Node\Expr[] Expressions */
15603 public array $exprs;
15604 /**
15605 * Constructs an echo node.
15606 *
15607 * @param Node\Expr[] $exprs Expressions
15608 * @param array<string, mixed> $attributes Additional attributes
15609 */
15610 public function __construct(array $exprs, array $attributes = [])
15611 {
15612 $this->attributes = $attributes;
15613 $this->exprs = $exprs;
15614 }
15615 public function getSubNodeNames(): array
15616 {
15617 return ['exprs'];
15618 }
15619 public function getType(): string
15620 {
15621 return 'Stmt_Echo';
15622 }
15623 }
15624 <?php
15625
15626 declare (strict_types=1);
15627 namespace PHPUnitPHAR\PhpParser\Node\Stmt;
15628
15629 use PHPUnitPHAR\PhpParser\Node;
15630 class ElseIf_ extends Node\Stmt
15631 {
15632 /** @var Node\Expr Condition */
15633 public Node\Expr $cond;
15634 /** @var Node\Stmt[] Statements */
15635 public array $stmts;
15636 /**
15637 * Constructs an elseif node.
15638 *
15639 * @param Node\Expr $cond Condition
15640 * @param Node\Stmt[] $stmts Statements
15641 * @param array<string, mixed> $attributes Additional attributes
15642 */
15643 public function __construct(Node\Expr $cond, array $stmts = [], array $attributes = [])
15644 {
15645 $this->attributes = $attributes;
15646 $this->cond = $cond;
15647 $this->stmts = $stmts;
15648 }
15649 public function getSubNodeNames(): array
15650 {
15651 return ['cond', 'stmts'];
15652 }
15653 public function getType(): string
15654 {
15655 return 'Stmt_ElseIf';
15656 }
15657 }
15658 <?php
15659
15660 declare (strict_types=1);
15661 namespace PHPUnitPHAR\PhpParser\Node\Stmt;
15662
15663 use PHPUnitPHAR\PhpParser\Node;
15664 class Else_ extends Node\Stmt
15665 {
15666 /** @var Node\Stmt[] Statements */
15667 public array $stmts;
15668 /**
15669 * Constructs an else node.
15670 *
15671 * @param Node\Stmt[] $stmts Statements
15672 * @param array<string, mixed> $attributes Additional attributes
15673 */
15674 public function __construct(array $stmts = [], array $attributes = [])
15675 {
15676 $this->attributes = $attributes;
15677 $this->stmts = $stmts;
15678 }
15679 public function getSubNodeNames(): array
15680 {
15681 return ['stmts'];
15682 }
15683 public function getType(): string
15684 {
15685 return 'Stmt_Else';
15686 }
15687 }
15688 <?php
15689
15690 declare (strict_types=1);
15691 namespace PHPUnitPHAR\PhpParser\Node\Stmt;
15692
15693 use PHPUnitPHAR\PhpParser\Node;
15694 use PHPUnitPHAR\PhpParser\Node\AttributeGroup;
15695 class EnumCase extends Node\Stmt
15696 {
15697 /** @var Node\Identifier Enum case name */
15698 public Node\Identifier $name;
15699 /** @var Node\Expr|null Enum case expression */
15700 public ?Node\Expr $expr;
15701 /** @var Node\AttributeGroup[] PHP attribute groups */
15702 public array $attrGroups;
15703 /**
15704 * @param string|Node\Identifier $name Enum case name
15705 * @param Node\Expr|null $expr Enum case expression
15706 * @param list<AttributeGroup> $attrGroups PHP attribute groups
15707 * @param array<string, mixed> $attributes Additional attributes
15708 */
15709 public function __construct($name, ?Node\Expr $expr = null, array $attrGroups = [], array $attributes = [])
15710 {
15711 parent::__construct($attributes);
15712 $this->name = \is_string($name) ? new Node\Identifier($name) : $name;
15713 $this->expr = $expr;
15714 $this->attrGroups = $attrGroups;
15715 }
15716 public function getSubNodeNames(): array
15717 {
15718 return ['attrGroups', 'name', 'expr'];
15719 }
15720 public function getType(): string
15721 {
15722 return 'Stmt_EnumCase';
15723 }
15724 }
15725 <?php
15726
15727 declare (strict_types=1);
15728 namespace PHPUnitPHAR\PhpParser\Node\Stmt;
15729
15730 use PHPUnitPHAR\PhpParser\Node;
15731 class Enum_ extends ClassLike
15732 {
15733 /** @var null|Node\Identifier Scalar Type */
15734 public ?Node $scalarType;
15735 /** @var Node\Name[] Names of implemented interfaces */
15736 public array $implements;
15737 /**
15738 * @param string|Node\Identifier|null $name Name
15739 * @param array{
15740 * scalarType?: Node\Identifier|null,
15741 * implements?: Node\Name[],
15742 * stmts?: Node\Stmt[],
15743 * attrGroups?: Node\AttributeGroup[],
15744 * } $subNodes Array of the following optional subnodes:
15745 * 'scalarType' => null : Scalar type
15746 * 'implements' => array() : Names of implemented interfaces
15747 * 'stmts' => array() : Statements
15748 * 'attrGroups' => array() : PHP attribute groups
15749 * @param array<string, mixed> $attributes Additional attributes
15750 */
15751 public function __construct($name, array $subNodes = [], array $attributes = [])
15752 {
15753 $this->name = \is_string($name) ? new Node\Identifier($name) : $name;
15754 $this->scalarType = $subNodes['scalarType'] ?? null;
15755 $this->implements = $subNodes['implements'] ?? [];
15756 $this->stmts = $subNodes['stmts'] ?? [];
15757 $this->attrGroups = $subNodes['attrGroups'] ?? [];
15758 parent::__construct($attributes);
15759 }
15760 public function getSubNodeNames(): array
15761 {
15762 return ['attrGroups', 'name', 'scalarType', 'implements', 'stmts'];
15763 }
15764 public function getType(): string
15765 {
15766 return 'Stmt_Enum';
15767 }
15768 }
15769 <?php
15770
15771 declare (strict_types=1);
15772 namespace PHPUnitPHAR\PhpParser\Node\Stmt;
15773
15774 use PHPUnitPHAR\PhpParser\Node;
15775 /**
15776 * Represents statements of type "expr;"
15777 */
15778 class Expression extends Node\Stmt
15779 {
15780 /** @var Node\Expr Expression */
15781 public Node\Expr $expr;
15782 /**
15783 * Constructs an expression statement.
15784 *
15785 * @param Node\Expr $expr Expression
15786 * @param array<string, mixed> $attributes Additional attributes
15787 */
15788 public function __construct(Node\Expr $expr, array $attributes = [])
15789 {
15790 $this->attributes = $attributes;
15791 $this->expr = $expr;
15792 }
15793 public function getSubNodeNames(): array
15794 {
15795 return ['expr'];
15796 }
15797 public function getType(): string
15798 {
15799 return 'Stmt_Expression';
15800 }
15801 }
15802 <?php
15803
15804 declare (strict_types=1);
15805 namespace PHPUnitPHAR\PhpParser\Node\Stmt;
15806
15807 use PHPUnitPHAR\PhpParser\Node;
15808 class Finally_ extends Node\Stmt
15809 {
15810 /** @var Node\Stmt[] Statements */
15811 public array $stmts;
15812 /**
15813 * Constructs a finally node.
15814 *
15815 * @param Node\Stmt[] $stmts Statements
15816 * @param array<string, mixed> $attributes Additional attributes
15817 */
15818 public function __construct(array $stmts = [], array $attributes = [])
15819 {
15820 $this->attributes = $attributes;
15821 $this->stmts = $stmts;
15822 }
15823 public function getSubNodeNames(): array
15824 {
15825 return ['stmts'];
15826 }
15827 public function getType(): string
15828 {
15829 return 'Stmt_Finally';
15830 }
15831 }
15832 <?php
15833
15834 declare (strict_types=1);
15835 namespace PHPUnitPHAR\PhpParser\Node\Stmt;
15836
15837 use PHPUnitPHAR\PhpParser\Node;
15838 class For_ extends Node\Stmt
15839 {
15840 /** @var Node\Expr[] Init expressions */
15841 public array $init;
15842 /** @var Node\Expr[] Loop conditions */
15843 public array $cond;
15844 /** @var Node\Expr[] Loop expressions */
15845 public array $loop;
15846 /** @var Node\Stmt[] Statements */
15847 public array $stmts;
15848 /**
15849 * Constructs a for loop node.
15850 *
15851 * @param array{
15852 * init?: Node\Expr[],
15853 * cond?: Node\Expr[],
15854 * loop?: Node\Expr[],
15855 * stmts?: Node\Stmt[],
15856 * } $subNodes Array of the following optional subnodes:
15857 * 'init' => array(): Init expressions
15858 * 'cond' => array(): Loop conditions
15859 * 'loop' => array(): Loop expressions
15860 * 'stmts' => array(): Statements
15861 * @param array<string, mixed> $attributes Additional attributes
15862 */
15863 public function __construct(array $subNodes = [], array $attributes = [])
15864 {
15865 $this->attributes = $attributes;
15866 $this->init = $subNodes['init'] ?? [];
15867 $this->cond = $subNodes['cond'] ?? [];
15868 $this->loop = $subNodes['loop'] ?? [];
15869 $this->stmts = $subNodes['stmts'] ?? [];
15870 }
15871 public function getSubNodeNames(): array
15872 {
15873 return ['init', 'cond', 'loop', 'stmts'];
15874 }
15875 public function getType(): string
15876 {
15877 return 'Stmt_For';
15878 }
15879 }
15880 <?php
15881
15882 declare (strict_types=1);
15883 namespace PHPUnitPHAR\PhpParser\Node\Stmt;
15884
15885 use PHPUnitPHAR\PhpParser\Node;
15886 class Foreach_ extends Node\Stmt
15887 {
15888 /** @var Node\Expr Expression to iterate */
15889 public Node\Expr $expr;
15890 /** @var null|Node\Expr Variable to assign key to */
15891 public ?Node\Expr $keyVar;
15892 /** @var bool Whether to assign value by reference */
15893 public bool $byRef;
15894 /** @var Node\Expr Variable to assign value to */
15895 public Node\Expr $valueVar;
15896 /** @var Node\Stmt[] Statements */
15897 public array $stmts;
15898 /**
15899 * Constructs a foreach node.
15900 *
15901 * @param Node\Expr $expr Expression to iterate
15902 * @param Node\Expr $valueVar Variable to assign value to
15903 * @param array{
15904 * keyVar?: Node\Expr|null,
15905 * byRef?: bool,
15906 * stmts?: Node\Stmt[],
15907 * } $subNodes Array of the following optional subnodes:
15908 * 'keyVar' => null : Variable to assign key to
15909 * 'byRef' => false : Whether to assign value by reference
15910 * 'stmts' => array(): Statements
15911 * @param array<string, mixed> $attributes Additional attributes
15912 */
15913 public function __construct(Node\Expr $expr, Node\Expr $valueVar, array $subNodes = [], array $attributes = [])
15914 {
15915 $this->attributes = $attributes;
15916 $this->expr = $expr;
15917 $this->keyVar = $subNodes['keyVar'] ?? null;
15918 $this->byRef = $subNodes['byRef'] ?? \false;
15919 $this->valueVar = $valueVar;
15920 $this->stmts = $subNodes['stmts'] ?? [];
15921 }
15922 public function getSubNodeNames(): array
15923 {
15924 return ['expr', 'keyVar', 'byRef', 'valueVar', 'stmts'];
15925 }
15926 public function getType(): string
15927 {
15928 return 'Stmt_Foreach';
15929 }
15930 }
15931 <?php
15932
15933 declare (strict_types=1);
15934 namespace PHPUnitPHAR\PhpParser\Node\Stmt;
15935
15936 use PHPUnitPHAR\PhpParser\Node;
15937 use PHPUnitPHAR\PhpParser\Node\FunctionLike;
15938 class Function_ extends Node\Stmt implements FunctionLike
15939 {
15940 /** @var bool Whether function returns by reference */
15941 public bool $byRef;
15942 /** @var Node\Identifier Name */
15943 public Node\Identifier $name;
15944 /** @var Node\Param[] Parameters */
15945 public array $params;
15946 /** @var null|Node\Identifier|Node\Name|Node\ComplexType Return type */
15947 public ?Node $returnType;
15948 /** @var Node\Stmt[] Statements */
15949 public array $stmts;
15950 /** @var Node\AttributeGroup[] PHP attribute groups */
15951 public array $attrGroups;
15952 /** @var Node\Name|null Namespaced name (if using NameResolver) */
15953 public ?Node\Name $namespacedName;
15954 /**
15955 * Constructs a function node.
15956 *
15957 * @param string|Node\Identifier $name Name
15958 * @param array{
15959 * byRef?: bool,
15960 * params?: Node\Param[],
15961 * returnType?: null|Node\Identifier|Node\Name|Node\ComplexType,
15962 * stmts?: Node\Stmt[],
15963 * attrGroups?: Node\AttributeGroup[],
15964 * } $subNodes Array of the following optional subnodes:
15965 * 'byRef' => false : Whether to return by reference
15966 * 'params' => array(): Parameters
15967 * 'returnType' => null : Return type
15968 * 'stmts' => array(): Statements
15969 * 'attrGroups' => array(): PHP attribute groups
15970 * @param array<string, mixed> $attributes Additional attributes
15971 */
15972 public function __construct($name, array $subNodes = [], array $attributes = [])
15973 {
15974 $this->attributes = $attributes;
15975 $this->byRef = $subNodes['byRef'] ?? \false;
15976 $this->name = \is_string($name) ? new Node\Identifier($name) : $name;
15977 $this->params = $subNodes['params'] ?? [];
15978 $this->returnType = $subNodes['returnType'] ?? null;
15979 $this->stmts = $subNodes['stmts'] ?? [];
15980 $this->attrGroups = $subNodes['attrGroups'] ?? [];
15981 }
15982 public function getSubNodeNames(): array
15983 {
15984 return ['attrGroups', 'byRef', 'name', 'params', 'returnType', 'stmts'];
15985 }
15986 public function returnsByRef(): bool
15987 {
15988 return $this->byRef;
15989 }
15990 public function getParams(): array
15991 {
15992 return $this->params;
15993 }
15994 public function getReturnType()
15995 {
15996 return $this->returnType;
15997 }
15998 public function getAttrGroups(): array
15999 {
16000 return $this->attrGroups;
16001 }
16002 /** @return Node\Stmt[] */
16003 public function getStmts(): array
16004 {
16005 return $this->stmts;
16006 }
16007 public function getType(): string
16008 {
16009 return 'Stmt_Function';
16010 }
16011 }
16012 <?php
16013
16014 declare (strict_types=1);
16015 namespace PHPUnitPHAR\PhpParser\Node\Stmt;
16016
16017 use PHPUnitPHAR\PhpParser\Node;
16018 class Global_ extends Node\Stmt
16019 {
16020 /** @var Node\Expr[] Variables */
16021 public array $vars;
16022 /**
16023 * Constructs a global variables list node.
16024 *
16025 * @param Node\Expr[] $vars Variables to unset
16026 * @param array<string, mixed> $attributes Additional attributes
16027 */
16028 public function __construct(array $vars, array $attributes = [])
16029 {
16030 $this->attributes = $attributes;
16031 $this->vars = $vars;
16032 }
16033 public function getSubNodeNames(): array
16034 {
16035 return ['vars'];
16036 }
16037 public function getType(): string
16038 {
16039 return 'Stmt_Global';
16040 }
16041 }
16042 <?php
16043
16044 declare (strict_types=1);
16045 namespace PHPUnitPHAR\PhpParser\Node\Stmt;
16046
16047 use PHPUnitPHAR\PhpParser\Node\Identifier;
16048 use PHPUnitPHAR\PhpParser\Node\Stmt;
16049 class Goto_ extends Stmt
16050 {
16051 /** @var Identifier Name of label to jump to */
16052 public Identifier $name;
16053 /**
16054 * Constructs a goto node.
16055 *
16056 * @param string|Identifier $name Name of label to jump to
16057 * @param array<string, mixed> $attributes Additional attributes
16058 */
16059 public function __construct($name, array $attributes = [])
16060 {
16061 $this->attributes = $attributes;
16062 $this->name = \is_string($name) ? new Identifier($name) : $name;
16063 }
16064 public function getSubNodeNames(): array
16065 {
16066 return ['name'];
16067 }
16068 public function getType(): string
16069 {
16070 return 'Stmt_Goto';
16071 }
16072 }
16073 <?php
16074
16075 declare (strict_types=1);
16076 namespace PHPUnitPHAR\PhpParser\Node\Stmt;
16077
16078 use PHPUnitPHAR\PhpParser\Node\Name;
16079 use PHPUnitPHAR\PhpParser\Node\Stmt;
16080 use PHPUnitPHAR\PhpParser\Node\UseItem;
16081 class GroupUse extends Stmt
16082 {
16083 /**
16084 * @var Use_::TYPE_* Type of group use
16085 */
16086 public int $type;
16087 /** @var Name Prefix for uses */
16088 public Name $prefix;
16089 /** @var UseItem[] Uses */
16090 public array $uses;
16091 /**
16092 * Constructs a group use node.
16093 *
16094 * @param Name $prefix Prefix for uses
16095 * @param UseItem[] $uses Uses
16096 * @param Use_::TYPE_* $type Type of group use
16097 * @param array<string, mixed> $attributes Additional attributes
16098 */
16099 public function __construct(Name $prefix, array $uses, int $type = Use_::TYPE_NORMAL, array $attributes = [])
16100 {
16101 $this->attributes = $attributes;
16102 $this->type = $type;
16103 $this->prefix = $prefix;
16104 $this->uses = $uses;
16105 }
16106 public function getSubNodeNames(): array
16107 {
16108 return ['type', 'prefix', 'uses'];
16109 }
16110 public function getType(): string
16111 {
16112 return 'Stmt_GroupUse';
16113 }
16114 }
16115 <?php
16116
16117 declare (strict_types=1);
16118 namespace PHPUnitPHAR\PhpParser\Node\Stmt;
16119
16120 use PHPUnitPHAR\PhpParser\Node\Stmt;
16121 class HaltCompiler extends Stmt
16122 {
16123 /** @var string Remaining text after halt compiler statement. */
16124 public string $remaining;
16125 /**
16126 * Constructs a __halt_compiler node.
16127 *
16128 * @param string $remaining Remaining text after halt compiler statement.
16129 * @param array<string, mixed> $attributes Additional attributes
16130 */
16131 public function __construct(string $remaining, array $attributes = [])
16132 {
16133 $this->attributes = $attributes;
16134 $this->remaining = $remaining;
16135 }
16136 public function getSubNodeNames(): array
16137 {
16138 return ['remaining'];
16139 }
16140 public function getType(): string
16141 {
16142 return 'Stmt_HaltCompiler';
16143 }
16144 }
16145 <?php
16146
16147 declare (strict_types=1);
16148 namespace PHPUnitPHAR\PhpParser\Node\Stmt;
16149
16150 use PHPUnitPHAR\PhpParser\Node;
16151 class If_ extends Node\Stmt
16152 {
16153 /** @var Node\Expr Condition expression */
16154 public Node\Expr $cond;
16155 /** @var Node\Stmt[] Statements */
16156 public array $stmts;
16157 /** @var ElseIf_[] Elseif clauses */
16158 public array $elseifs;
16159 /** @var null|Else_ Else clause */
16160 public ?Else_ $else;
16161 /**
16162 * Constructs an if node.
16163 *
16164 * @param Node\Expr $cond Condition
16165 * @param array{
16166 * stmts?: Node\Stmt[],
16167 * elseifs?: ElseIf_[],
16168 * else?: Else_|null,
16169 * } $subNodes Array of the following optional subnodes:
16170 * 'stmts' => array(): Statements
16171 * 'elseifs' => array(): Elseif clauses
16172 * 'else' => null : Else clause
16173 * @param array<string, mixed> $attributes Additional attributes
16174 */
16175 public function __construct(Node\Expr $cond, array $subNodes = [], array $attributes = [])
16176 {
16177 $this->attributes = $attributes;
16178 $this->cond = $cond;
16179 $this->stmts = $subNodes['stmts'] ?? [];
16180 $this->elseifs = $subNodes['elseifs'] ?? [];
16181 $this->else = $subNodes['else'] ?? null;
16182 }
16183 public function getSubNodeNames(): array
16184 {
16185 return ['cond', 'stmts', 'elseifs', 'else'];
16186 }
16187 public function getType(): string
16188 {
16189 return 'Stmt_If';
16190 }
16191 }
16192 <?php
16193
16194 declare (strict_types=1);
16195 namespace PHPUnitPHAR\PhpParser\Node\Stmt;
16196
16197 use PHPUnitPHAR\PhpParser\Node\Stmt;
16198 class InlineHTML extends Stmt
16199 {
16200 /** @var string String */
16201 public string $value;
16202 /**
16203 * Constructs an inline HTML node.
16204 *
16205 * @param string $value String
16206 * @param array<string, mixed> $attributes Additional attributes
16207 */
16208 public function __construct(string $value, array $attributes = [])
16209 {
16210 $this->attributes = $attributes;
16211 $this->value = $value;
16212 }
16213 public function getSubNodeNames(): array
16214 {
16215 return ['value'];
16216 }
16217 public function getType(): string
16218 {
16219 return 'Stmt_InlineHTML';
16220 }
16221 }
16222 <?php
16223
16224 declare (strict_types=1);
16225 namespace PHPUnitPHAR\PhpParser\Node\Stmt;
16226
16227 use PHPUnitPHAR\PhpParser\Node;
16228 class Interface_ extends ClassLike
16229 {
16230 /** @var Node\Name[] Extended interfaces */
16231 public array $extends;
16232 /**
16233 * Constructs a class node.
16234 *
16235 * @param string|Node\Identifier $name Name
16236 * @param array{
16237 * extends?: Node\Name[],
16238 * stmts?: Node\Stmt[],
16239 * attrGroups?: Node\AttributeGroup[],
16240 * } $subNodes Array of the following optional subnodes:
16241 * 'extends' => array(): Name of extended interfaces
16242 * 'stmts' => array(): Statements
16243 * 'attrGroups' => array(): PHP attribute groups
16244 * @param array<string, mixed> $attributes Additional attributes
16245 */
16246 public function __construct($name, array $subNodes = [], array $attributes = [])
16247 {
16248 $this->attributes = $attributes;
16249 $this->name = \is_string($name) ? new Node\Identifier($name) : $name;
16250 $this->extends = $subNodes['extends'] ?? [];
16251 $this->stmts = $subNodes['stmts'] ?? [];
16252 $this->attrGroups = $subNodes['attrGroups'] ?? [];
16253 }
16254 public function getSubNodeNames(): array
16255 {
16256 return ['attrGroups', 'name', 'extends', 'stmts'];
16257 }
16258 public function getType(): string
16259 {
16260 return 'Stmt_Interface';
16261 }
16262 }
16263 <?php
16264
16265 declare (strict_types=1);
16266 namespace PHPUnitPHAR\PhpParser\Node\Stmt;
16267
16268 use PHPUnitPHAR\PhpParser\Node\Identifier;
16269 use PHPUnitPHAR\PhpParser\Node\Stmt;
16270 class Label extends Stmt
16271 {
16272 /** @var Identifier Name */
16273 public Identifier $name;
16274 /**
16275 * Constructs a label node.
16276 *
16277 * @param string|Identifier $name Name
16278 * @param array<string, mixed> $attributes Additional attributes
16279 */
16280 public function __construct($name, array $attributes = [])
16281 {
16282 $this->attributes = $attributes;
16283 $this->name = \is_string($name) ? new Identifier($name) : $name;
16284 }
16285 public function getSubNodeNames(): array
16286 {
16287 return ['name'];
16288 }
16289 public function getType(): string
16290 {
16291 return 'Stmt_Label';
16292 }
16293 }
16294 <?php
16295
16296 declare (strict_types=1);
16297 namespace PHPUnitPHAR\PhpParser\Node\Stmt;
16298
16299 use PHPUnitPHAR\PhpParser\Node;
16300 class Namespace_ extends Node\Stmt
16301 {
16302 /* For use in the "kind" attribute */
16303 public const KIND_SEMICOLON = 1;
16304 public const KIND_BRACED = 2;
16305 /** @var null|Node\Name Name */
16306 public ?Node\Name $name;
16307 /** @var Node\Stmt[] Statements */
16308 public $stmts;
16309 /**
16310 * Constructs a namespace node.
16311 *
16312 * @param null|Node\Name $name Name
16313 * @param null|Node\Stmt[] $stmts Statements
16314 * @param array<string, mixed> $attributes Additional attributes
16315 */
16316 public function __construct(?Node\Name $name = null, ?array $stmts = [], array $attributes = [])
16317 {
16318 $this->attributes = $attributes;
16319 $this->name = $name;
16320 $this->stmts = $stmts;
16321 }
16322 public function getSubNodeNames(): array
16323 {
16324 return ['name', 'stmts'];
16325 }
16326 public function getType(): string
16327 {
16328 return 'Stmt_Namespace';
16329 }
16330 }
16331 <?php
16332
16333 declare (strict_types=1);
16334 namespace PHPUnitPHAR\PhpParser\Node\Stmt;
16335
16336 use PHPUnitPHAR\PhpParser\Node;
16337 /** Nop/empty statement (;). */
16338 class Nop extends Node\Stmt
16339 {
16340 public function getSubNodeNames(): array
16341 {
16342 return [];
16343 }
16344 public function getType(): string
16345 {
16346 return 'Stmt_Nop';
16347 }
16348 }
16349 <?php
16350
16351 declare (strict_types=1);
16352 namespace PHPUnitPHAR\PhpParser\Node\Stmt;
16353
16354 use PHPUnitPHAR\PhpParser\Modifiers;
16355 use PHPUnitPHAR\PhpParser\Node;
16356 use PHPUnitPHAR\PhpParser\Node\ComplexType;
16357 use PHPUnitPHAR\PhpParser\Node\Identifier;
16358 use PHPUnitPHAR\PhpParser\Node\Name;
16359 use PHPUnitPHAR\PhpParser\Node\PropertyItem;
16360 class Property extends Node\Stmt
16361 {
16362 /** @var int Modifiers */
16363 public int $flags;
16364 /** @var PropertyItem[] Properties */
16365 public array $props;
16366 /** @var null|Identifier|Name|ComplexType Type declaration */
16367 public ?Node $type;
16368 /** @var Node\AttributeGroup[] PHP attribute groups */
16369 public array $attrGroups;
16370 /** @var Node\PropertyHook[] Property hooks */
16371 public array $hooks;
16372 /**
16373 * Constructs a class property list node.
16374 *
16375 * @param int $flags Modifiers
16376 * @param PropertyItem[] $props Properties
16377 * @param array<string, mixed> $attributes Additional attributes
16378 * @param null|Identifier|Name|ComplexType $type Type declaration
16379 * @param Node\AttributeGroup[] $attrGroups PHP attribute groups
16380 * @param Node\PropertyHook[] $hooks Property hooks
16381 */
16382 public function __construct(int $flags, array $props, array $attributes = [], ?Node $type = null, array $attrGroups = [], array $hooks = [])
16383 {
16384 $this->attributes = $attributes;
16385 $this->flags = $flags;
16386 $this->props = $props;
16387 $this->type = $type;
16388 $this->attrGroups = $attrGroups;
16389 $this->hooks = $hooks;
16390 }
16391 public function getSubNodeNames(): array
16392 {
16393 return ['attrGroups', 'flags', 'type', 'props', 'hooks'];
16394 }
16395 /**
16396 * Whether the property is explicitly or implicitly public.
16397 */
16398 public function isPublic(): bool
16399 {
16400 return ($this->flags & Modifiers::PUBLIC) !== 0 || ($this->flags & Modifiers::VISIBILITY_MASK) === 0;
16401 }
16402 /**
16403 * Whether the property is protected.
16404 */
16405 public function isProtected(): bool
16406 {
16407 return (bool) ($this->flags & Modifiers::PROTECTED);
16408 }
16409 /**
16410 * Whether the property is private.
16411 */
16412 public function isPrivate(): bool
16413 {
16414 return (bool) ($this->flags & Modifiers::PRIVATE);
16415 }
16416 /**
16417 * Whether the property is static.
16418 */
16419 public function isStatic(): bool
16420 {
16421 return (bool) ($this->flags & Modifiers::STATIC);
16422 }
16423 /**
16424 * Whether the property is readonly.
16425 */
16426 public function isReadonly(): bool
16427 {
16428 return (bool) ($this->flags & Modifiers::READONLY);
16429 }
16430 /**
16431 * Whether the property is abstract.
16432 */
16433 public function isAbstract(): bool
16434 {
16435 return (bool) ($this->flags & Modifiers::ABSTRACT);
16436 }
16437 /**
16438 * Whether the property is final.
16439 */
16440 public function isFinal(): bool
16441 {
16442 return (bool) ($this->flags & Modifiers::FINAL);
16443 }
16444 /**
16445 * Whether the property has explicit public(set) visibility.
16446 */
16447 public function isPublicSet(): bool
16448 {
16449 return (bool) ($this->flags & Modifiers::PUBLIC_SET);
16450 }
16451 /**
16452 * Whether the property has explicit protected(set) visibility.
16453 */
16454 public function isProtectedSet(): bool
16455 {
16456 return (bool) ($this->flags & Modifiers::PROTECTED_SET);
16457 }
16458 /**
16459 * Whether the property has explicit private(set) visibility.
16460 */
16461 public function isPrivateSet(): bool
16462 {
16463 return (bool) ($this->flags & Modifiers::PRIVATE_SET);
16464 }
16465 public function getType(): string
16466 {
16467 return 'Stmt_Property';
16468 }
16469 }
16470 <?php
16471
16472 declare (strict_types=1);
16473 namespace PHPUnitPHAR\PhpParser\Node\Stmt;
16474
16475 use PHPUnitPHAR\PhpParser\Node;
16476 class Return_ extends Node\Stmt
16477 {
16478 /** @var null|Node\Expr Expression */
16479 public ?Node\Expr $expr;
16480 /**
16481 * Constructs a return node.
16482 *
16483 * @param null|Node\Expr $expr Expression
16484 * @param array<string, mixed> $attributes Additional attributes
16485 */
16486 public function __construct(?Node\Expr $expr = null, array $attributes = [])
16487 {
16488 $this->attributes = $attributes;
16489 $this->expr = $expr;
16490 }
16491 public function getSubNodeNames(): array
16492 {
16493 return ['expr'];
16494 }
16495 public function getType(): string
16496 {
16497 return 'Stmt_Return';
16498 }
16499 }
16500 <?php
16501
16502 declare (strict_types=1);
16503 namespace PHPUnitPHAR\PhpParser\Node\Stmt;
16504
16505 use PHPUnitPHAR\PhpParser\Node\StaticVar;
16506 use PHPUnitPHAR\PhpParser\Node\Stmt;
16507 class Static_ extends Stmt
16508 {
16509 /** @var StaticVar[] Variable definitions */
16510 public array $vars;
16511 /**
16512 * Constructs a static variables list node.
16513 *
16514 * @param StaticVar[] $vars Variable definitions
16515 * @param array<string, mixed> $attributes Additional attributes
16516 */
16517 public function __construct(array $vars, array $attributes = [])
16518 {
16519 $this->attributes = $attributes;
16520 $this->vars = $vars;
16521 }
16522 public function getSubNodeNames(): array
16523 {
16524 return ['vars'];
16525 }
16526 public function getType(): string
16527 {
16528 return 'Stmt_Static';
16529 }
16530 }
16531 <?php
16532
16533 declare (strict_types=1);
16534 namespace PHPUnitPHAR\PhpParser\Node\Stmt;
16535
16536 use PHPUnitPHAR\PhpParser\Node;
16537 class Switch_ extends Node\Stmt
16538 {
16539 /** @var Node\Expr Condition */
16540 public Node\Expr $cond;
16541 /** @var Case_[] Case list */
16542 public array $cases;
16543 /**
16544 * Constructs a case node.
16545 *
16546 * @param Node\Expr $cond Condition
16547 * @param Case_[] $cases Case list
16548 * @param array<string, mixed> $attributes Additional attributes
16549 */
16550 public function __construct(Node\Expr $cond, array $cases, array $attributes = [])
16551 {
16552 $this->attributes = $attributes;
16553 $this->cond = $cond;
16554 $this->cases = $cases;
16555 }
16556 public function getSubNodeNames(): array
16557 {
16558 return ['cond', 'cases'];
16559 }
16560 public function getType(): string
16561 {
16562 return 'Stmt_Switch';
16563 }
16564 }
16565 <?php
16566
16567 declare (strict_types=1);
16568 namespace PHPUnitPHAR\PhpParser\Node\Stmt;
16569
16570 use PHPUnitPHAR\PhpParser\Node;
16571 class TraitUse extends Node\Stmt
16572 {
16573 /** @var Node\Name[] Traits */
16574 public array $traits;
16575 /** @var TraitUseAdaptation[] Adaptations */
16576 public array $adaptations;
16577 /**
16578 * Constructs a trait use node.
16579 *
16580 * @param Node\Name[] $traits Traits
16581 * @param TraitUseAdaptation[] $adaptations Adaptations
16582 * @param array<string, mixed> $attributes Additional attributes
16583 */
16584 public function __construct(array $traits, array $adaptations = [], array $attributes = [])
16585 {
16586 $this->attributes = $attributes;
16587 $this->traits = $traits;
16588 $this->adaptations = $adaptations;
16589 }
16590 public function getSubNodeNames(): array
16591 {
16592 return ['traits', 'adaptations'];
16593 }
16594 public function getType(): string
16595 {
16596 return 'Stmt_TraitUse';
16597 }
16598 }
16599 <?php
16600
16601 declare (strict_types=1);
16602 namespace PHPUnitPHAR\PhpParser\Node\Stmt;
16603
16604 use PHPUnitPHAR\PhpParser\Node;
16605 abstract class TraitUseAdaptation extends Node\Stmt
16606 {
16607 /** @var Node\Name|null Trait name */
16608 public ?Node\Name $trait;
16609 /** @var Node\Identifier Method name */
16610 public Node\Identifier $method;
16611 }
16612 <?php
16613
16614 declare (strict_types=1);
16615 namespace PHPUnitPHAR\PhpParser\Node\Stmt\TraitUseAdaptation;
16616
16617 use PHPUnitPHAR\PhpParser\Node;
16618 class Alias extends Node\Stmt\TraitUseAdaptation
16619 {
16620 /** @var null|int New modifier */
16621 public ?int $newModifier;
16622 /** @var null|Node\Identifier New name */
16623 public ?Node\Identifier $newName;
16624 /**
16625 * Constructs a trait use precedence adaptation node.
16626 *
16627 * @param null|Node\Name $trait Trait name
16628 * @param string|Node\Identifier $method Method name
16629 * @param null|int $newModifier New modifier
16630 * @param null|string|Node\Identifier $newName New name
16631 * @param array<string, mixed> $attributes Additional attributes
16632 */
16633 public function __construct(?Node\Name $trait, $method, ?int $newModifier, $newName, array $attributes = [])
16634 {
16635 $this->attributes = $attributes;
16636 $this->trait = $trait;
16637 $this->method = \is_string($method) ? new Node\Identifier($method) : $method;
16638 $this->newModifier = $newModifier;
16639 $this->newName = \is_string($newName) ? new Node\Identifier($newName) : $newName;
16640 }
16641 public function getSubNodeNames(): array
16642 {
16643 return ['trait', 'method', 'newModifier', 'newName'];
16644 }
16645 public function getType(): string
16646 {
16647 return 'Stmt_TraitUseAdaptation_Alias';
16648 }
16649 }
16650 <?php
16651
16652 declare (strict_types=1);
16653 namespace PHPUnitPHAR\PhpParser\Node\Stmt\TraitUseAdaptation;
16654
16655 use PHPUnitPHAR\PhpParser\Node;
16656 class Precedence extends Node\Stmt\TraitUseAdaptation
16657 {
16658 /** @var Node\Name[] Overwritten traits */
16659 public array $insteadof;
16660 /**
16661 * Constructs a trait use precedence adaptation node.
16662 *
16663 * @param Node\Name $trait Trait name
16664 * @param string|Node\Identifier $method Method name
16665 * @param Node\Name[] $insteadof Overwritten traits
16666 * @param array<string, mixed> $attributes Additional attributes
16667 */
16668 public function __construct(Node\Name $trait, $method, array $insteadof, array $attributes = [])
16669 {
16670 $this->attributes = $attributes;
16671 $this->trait = $trait;
16672 $this->method = \is_string($method) ? new Node\Identifier($method) : $method;
16673 $this->insteadof = $insteadof;
16674 }
16675 public function getSubNodeNames(): array
16676 {
16677 return ['trait', 'method', 'insteadof'];
16678 }
16679 public function getType(): string
16680 {
16681 return 'Stmt_TraitUseAdaptation_Precedence';
16682 }
16683 }
16684 <?php
16685
16686 declare (strict_types=1);
16687 namespace PHPUnitPHAR\PhpParser\Node\Stmt;
16688
16689 use PHPUnitPHAR\PhpParser\Node;
16690 class Trait_ extends ClassLike
16691 {
16692 /**
16693 * Constructs a trait node.
16694 *
16695 * @param string|Node\Identifier $name Name
16696 * @param array{
16697 * stmts?: Node\Stmt[],
16698 * attrGroups?: Node\AttributeGroup[],
16699 * } $subNodes Array of the following optional subnodes:
16700 * 'stmts' => array(): Statements
16701 * 'attrGroups' => array(): PHP attribute groups
16702 * @param array<string, mixed> $attributes Additional attributes
16703 */
16704 public function __construct($name, array $subNodes = [], array $attributes = [])
16705 {
16706 $this->attributes = $attributes;
16707 $this->name = \is_string($name) ? new Node\Identifier($name) : $name;
16708 $this->stmts = $subNodes['stmts'] ?? [];
16709 $this->attrGroups = $subNodes['attrGroups'] ?? [];
16710 }
16711 public function getSubNodeNames(): array
16712 {
16713 return ['attrGroups', 'name', 'stmts'];
16714 }
16715 public function getType(): string
16716 {
16717 return 'Stmt_Trait';
16718 }
16719 }
16720 <?php
16721
16722 declare (strict_types=1);
16723 namespace PHPUnitPHAR\PhpParser\Node\Stmt;
16724
16725 use PHPUnitPHAR\PhpParser\Node;
16726 class TryCatch extends Node\Stmt
16727 {
16728 /** @var Node\Stmt[] Statements */
16729 public array $stmts;
16730 /** @var Catch_[] Catches */
16731 public array $catches;
16732 /** @var null|Finally_ Optional finally node */
16733 public ?Finally_ $finally;
16734 /**
16735 * Constructs a try catch node.
16736 *
16737 * @param Node\Stmt[] $stmts Statements
16738 * @param Catch_[] $catches Catches
16739 * @param null|Finally_ $finally Optional finally node
16740 * @param array<string, mixed> $attributes Additional attributes
16741 */
16742 public function __construct(array $stmts, array $catches, ?Finally_ $finally = null, array $attributes = [])
16743 {
16744 $this->attributes = $attributes;
16745 $this->stmts = $stmts;
16746 $this->catches = $catches;
16747 $this->finally = $finally;
16748 }
16749 public function getSubNodeNames(): array
16750 {
16751 return ['stmts', 'catches', 'finally'];
16752 }
16753 public function getType(): string
16754 {
16755 return 'Stmt_TryCatch';
16756 }
16757 }
16758 <?php
16759
16760 declare (strict_types=1);
16761 namespace PHPUnitPHAR\PhpParser\Node\Stmt;
16762
16763 use PHPUnitPHAR\PhpParser\Node;
16764 class Unset_ extends Node\Stmt
16765 {
16766 /** @var Node\Expr[] Variables to unset */
16767 public array $vars;
16768 /**
16769 * Constructs an unset node.
16770 *
16771 * @param Node\Expr[] $vars Variables to unset
16772 * @param array<string, mixed> $attributes Additional attributes
16773 */
16774 public function __construct(array $vars, array $attributes = [])
16775 {
16776 $this->attributes = $attributes;
16777 $this->vars = $vars;
16778 }
16779 public function getSubNodeNames(): array
16780 {
16781 return ['vars'];
16782 }
16783 public function getType(): string
16784 {
16785 return 'Stmt_Unset';
16786 }
16787 }
16788 <?php
16789
16790 declare (strict_types=1);
16791 namespace PHPUnitPHAR\PhpParser\Node\Stmt;
16792
16793 use PHPUnitPHAR\PhpParser\Node\Stmt;
16794 use PHPUnitPHAR\PhpParser\Node\UseItem;
16795 class Use_ extends Stmt
16796 {
16797 /**
16798 * Unknown type. Both Stmt\Use_ / Stmt\GroupUse and Stmt\UseUse have a $type property, one of them will always be
16799 * TYPE_UNKNOWN while the other has one of the three other possible types. For normal use statements the type on the
16800 * Stmt\UseUse is unknown. It's only the other way around for mixed group use declarations.
16801 */
16802 public const TYPE_UNKNOWN = 0;
16803 /** Class or namespace import */
16804 public const TYPE_NORMAL = 1;
16805 /** Function import */
16806 public const TYPE_FUNCTION = 2;
16807 /** Constant import */
16808 public const TYPE_CONSTANT = 3;
16809 /** @var self::TYPE_* Type of alias */
16810 public int $type;
16811 /** @var UseItem[] Aliases */
16812 public array $uses;
16813 /**
16814 * Constructs an alias (use) list node.
16815 *
16816 * @param UseItem[] $uses Aliases
16817 * @param Stmt\Use_::TYPE_* $type Type of alias
16818 * @param array<string, mixed> $attributes Additional attributes
16819 */
16820 public function __construct(array $uses, int $type = self::TYPE_NORMAL, array $attributes = [])
16821 {
16822 $this->attributes = $attributes;
16823 $this->type = $type;
16824 $this->uses = $uses;
16825 }
16826 public function getSubNodeNames(): array
16827 {
16828 return ['type', 'uses'];
16829 }
16830 public function getType(): string
16831 {
16832 return 'Stmt_Use';
16833 }
16834 }
16835 <?php
16836
16837 declare (strict_types=1);
16838 namespace PHPUnitPHAR\PhpParser\Node\Stmt;
16839
16840 use PHPUnitPHAR\PhpParser\Node;
16841 class While_ extends Node\Stmt
16842 {
16843 /** @var Node\Expr Condition */
16844 public Node\Expr $cond;
16845 /** @var Node\Stmt[] Statements */
16846 public array $stmts;
16847 /**
16848 * Constructs a while node.
16849 *
16850 * @param Node\Expr $cond Condition
16851 * @param Node\Stmt[] $stmts Statements
16852 * @param array<string, mixed> $attributes Additional attributes
16853 */
16854 public function __construct(Node\Expr $cond, array $stmts = [], array $attributes = [])
16855 {
16856 $this->attributes = $attributes;
16857 $this->cond = $cond;
16858 $this->stmts = $stmts;
16859 }
16860 public function getSubNodeNames(): array
16861 {
16862 return ['cond', 'stmts'];
16863 }
16864 public function getType(): string
16865 {
16866 return 'Stmt_While';
16867 }
16868 }
16869 <?php
16870
16871 declare (strict_types=1);
16872 namespace PHPUnitPHAR\PhpParser\Node;
16873
16874 class UnionType extends ComplexType
16875 {
16876 /** @var (Identifier|Name|IntersectionType)[] Types */
16877 public array $types;
16878 /**
16879 * Constructs a union type.
16880 *
16881 * @param (Identifier|Name|IntersectionType)[] $types Types
16882 * @param array<string, mixed> $attributes Additional attributes
16883 */
16884 public function __construct(array $types, array $attributes = [])
16885 {
16886 $this->attributes = $attributes;
16887 $this->types = $types;
16888 }
16889 public function getSubNodeNames(): array
16890 {
16891 return ['types'];
16892 }
16893 public function getType(): string
16894 {
16895 return 'UnionType';
16896 }
16897 }
16898 <?php
16899
16900 declare (strict_types=1);
16901 namespace PHPUnitPHAR\PhpParser\Node;
16902
16903 use PHPUnitPHAR\PhpParser\Node;
16904 use PHPUnitPHAR\PhpParser\NodeAbstract;
16905 use PHPUnitPHAR\PhpParser\Node\Stmt\Use_;
16906 class UseItem extends NodeAbstract
16907 {
16908 /**
16909 * @var Use_::TYPE_* One of the Stmt\Use_::TYPE_* constants. Will only differ from TYPE_UNKNOWN for mixed group uses
16910 */
16911 public int $type;
16912 /** @var Node\Name Namespace, class, function or constant to alias */
16913 public Name $name;
16914 /** @var Identifier|null Alias */
16915 public ?Identifier $alias;
16916 /**
16917 * Constructs an alias (use) item node.
16918 *
16919 * @param Node\Name $name Namespace/Class to alias
16920 * @param null|string|Identifier $alias Alias
16921 * @param Use_::TYPE_* $type Type of the use element (for mixed group use only)
16922 * @param array<string, mixed> $attributes Additional attributes
16923 */
16924 public function __construct(Node\Name $name, $alias = null, int $type = Use_::TYPE_UNKNOWN, array $attributes = [])
16925 {
16926 $this->attributes = $attributes;
16927 $this->type = $type;
16928 $this->name = $name;
16929 $this->alias = \is_string($alias) ? new Identifier($alias) : $alias;
16930 }
16931 public function getSubNodeNames(): array
16932 {
16933 return ['type', 'name', 'alias'];
16934 }
16935 /**
16936 * Get alias. If not explicitly given this is the last component of the used name.
16937 */
16938 public function getAlias(): Identifier
16939 {
16940 if (null !== $this->alias) {
16941 return $this->alias;
16942 }
16943 return new Identifier($this->name->getLast());
16944 }
16945 public function getType(): string
16946 {
16947 return 'UseItem';
16948 }
16949 }
16950 // @deprecated compatibility alias
16951 class_alias(UseItem::class, Stmt\UseUse::class);
16952 <?php
16953
16954 declare (strict_types=1);
16955 namespace PHPUnitPHAR\PhpParser\Node;
16956
16957 /**
16958 * Represents a name that is written in source code with a leading dollar,
16959 * but is not a proper variable. The leading dollar is not stored as part of the name.
16960 *
16961 * Examples: Names in property declarations are formatted as variables. Names in static property
16962 * lookups are also formatted as variables.
16963 */
16964 class VarLikeIdentifier extends Identifier
16965 {
16966 public function getType(): string
16967 {
16968 return 'VarLikeIdentifier';
16969 }
16970 }
16971 <?php
16972
16973 declare (strict_types=1);
16974 namespace PHPUnitPHAR\PhpParser\Node;
16975
16976 use PHPUnitPHAR\PhpParser\NodeAbstract;
16977 /**
16978 * Represents the "..." in "foo(...)" of the first-class callable syntax.
16979 */
16980 class VariadicPlaceholder extends NodeAbstract
16981 {
16982 /**
16983 * Create a variadic argument placeholder (first-class callable syntax).
16984 *
16985 * @param array<string, mixed> $attributes Additional attributes
16986 */
16987 public function __construct(array $attributes = [])
16988 {
16989 $this->attributes = $attributes;
16990 }
16991 public function getType(): string
16992 {
16993 return 'VariadicPlaceholder';
16994 }
16995 public function getSubNodeNames(): array
16996 {
16997 return [];
16998 }
16999 }
17000 <?php
17001
17002 declare (strict_types=1);
17003 namespace PHPUnitPHAR\PhpParser;
17004
17005 abstract class NodeAbstract implements Node, \JsonSerializable
17006 {
17007 /** @var array<string, mixed> Attributes */
17008 protected array $attributes;
17009 /**
17010 * Creates a Node.
17011 *
17012 * @param array<string, mixed> $attributes Array of attributes
17013 */
17014 public function __construct(array $attributes = [])
17015 {
17016 $this->attributes = $attributes;
17017 }
17018 /**
17019 * Gets line the node started in (alias of getStartLine).
17020 *
17021 * @return int Start line (or -1 if not available)
17022 * @phpstan-return -1|positive-int
17023 */
17024 public function getLine(): int
17025 {
17026 return $this->attributes['startLine'] ?? -1;
17027 }
17028 /**
17029 * Gets line the node started in.
17030 *
17031 * Requires the 'startLine' attribute to be enabled in the lexer (enabled by default).
17032 *
17033 * @return int Start line (or -1 if not available)
17034 * @phpstan-return -1|positive-int
17035 */
17036 public function getStartLine(): int
17037 {
17038 return $this->attributes['startLine'] ?? -1;
17039 }
17040 /**
17041 * Gets the line the node ended in.
17042 *
17043 * Requires the 'endLine' attribute to be enabled in the lexer (enabled by default).
17044 *
17045 * @return int End line (or -1 if not available)
17046 * @phpstan-return -1|positive-int
17047 */
17048 public function getEndLine(): int
17049 {
17050 return $this->attributes['endLine'] ?? -1;
17051 }
17052 /**
17053 * Gets the token offset of the first token that is part of this node.
17054 *
17055 * The offset is an index into the array returned by Lexer::getTokens().
17056 *
17057 * Requires the 'startTokenPos' attribute to be enabled in the lexer (DISABLED by default).
17058 *
17059 * @return int Token start position (or -1 if not available)
17060 */
17061 public function getStartTokenPos(): int
17062 {
17063 return $this->attributes['startTokenPos'] ?? -1;
17064 }
17065 /**
17066 * Gets the token offset of the last token that is part of this node.
17067 *
17068 * The offset is an index into the array returned by Lexer::getTokens().
17069 *
17070 * Requires the 'endTokenPos' attribute to be enabled in the lexer (DISABLED by default).
17071 *
17072 * @return int Token end position (or -1 if not available)
17073 */
17074 public function getEndTokenPos(): int
17075 {
17076 return $this->attributes['endTokenPos'] ?? -1;
17077 }
17078 /**
17079 * Gets the file offset of the first character that is part of this node.
17080 *
17081 * Requires the 'startFilePos' attribute to be enabled in the lexer (DISABLED by default).
17082 *
17083 * @return int File start position (or -1 if not available)
17084 */
17085 public function getStartFilePos(): int
17086 {
17087 return $this->attributes['startFilePos'] ?? -1;
17088 }
17089 /**
17090 * Gets the file offset of the last character that is part of this node.
17091 *
17092 * Requires the 'endFilePos' attribute to be enabled in the lexer (DISABLED by default).
17093 *
17094 * @return int File end position (or -1 if not available)
17095 */
17096 public function getEndFilePos(): int
17097 {
17098 return $this->attributes['endFilePos'] ?? -1;
17099 }
17100 /**
17101 * Gets all comments directly preceding this node.
17102 *
17103 * The comments are also available through the "comments" attribute.
17104 *
17105 * @return Comment[]
17106 */
17107 public function getComments(): array
17108 {
17109 return $this->attributes['comments'] ?? [];
17110 }
17111 /**
17112 * Gets the doc comment of the node.
17113 *
17114 * @return null|Comment\Doc Doc comment object or null
17115 */
17116 public function getDocComment(): ?Comment\Doc
17117 {
17118 $comments = $this->getComments();
17119 for ($i = count($comments) - 1; $i >= 0; $i--) {
17120 $comment = $comments[$i];
17121 if ($comment instanceof Comment\Doc) {
17122 return $comment;
17123 }
17124 }
17125 return null;
17126 }
17127 /**
17128 * Sets the doc comment of the node.
17129 *
17130 * This will either replace an existing doc comment or add it to the comments array.
17131 *
17132 * @param Comment\Doc $docComment Doc comment to set
17133 */
17134 public function setDocComment(Comment\Doc $docComment): void
17135 {
17136 $comments = $this->getComments();
17137 for ($i = count($comments) - 1; $i >= 0; $i--) {
17138 if ($comments[$i] instanceof Comment\Doc) {
17139 // Replace existing doc comment.
17140 $comments[$i] = $docComment;
17141 $this->setAttribute('comments', $comments);
17142 return;
17143 }
17144 }
17145 // Append new doc comment.
17146 $comments[] = $docComment;
17147 $this->setAttribute('comments', $comments);
17148 }
17149 public function setAttribute(string $key, $value): void
17150 {
17151 $this->attributes[$key] = $value;
17152 }
17153 public function hasAttribute(string $key): bool
17154 {
17155 return array_key_exists($key, $this->attributes);
17156 }
17157 public function getAttribute(string $key, $default = null)
17158 {
17159 if (array_key_exists($key, $this->attributes)) {
17160 return $this->attributes[$key];
17161 }
17162 return $default;
17163 }
17164 public function getAttributes(): array
17165 {
17166 return $this->attributes;
17167 }
17168 public function setAttributes(array $attributes): void
17169 {
17170 $this->attributes = $attributes;
17171 }
17172 /**
17173 * @return array<string, mixed>
17174 */
17175 public function jsonSerialize(): array
17176 {
17177 return ['nodeType' => $this->getType()] + get_object_vars($this);
17178 }
17179 }
17180 <?php
17181
17182 declare (strict_types=1);
17183 namespace PHPUnitPHAR\PhpParser;
17184
17185 use PHPUnitPHAR\PhpParser\Node\Expr\Array_;
17186 use PHPUnitPHAR\PhpParser\Node\Expr\Include_;
17187 use PHPUnitPHAR\PhpParser\Node\Expr\List_;
17188 use PHPUnitPHAR\PhpParser\Node\Scalar\Int_;
17189 use PHPUnitPHAR\PhpParser\Node\Scalar\InterpolatedString;
17190 use PHPUnitPHAR\PhpParser\Node\Scalar\String_;
17191 use PHPUnitPHAR\PhpParser\Node\Stmt\GroupUse;
17192 use PHPUnitPHAR\PhpParser\Node\Stmt\Use_;
17193 use PHPUnitPHAR\PhpParser\Node\UseItem;
17194 class NodeDumper
17195 {
17196 private bool $dumpComments;
17197 private bool $dumpPositions;
17198 private bool $dumpOtherAttributes;
17199 private ?string $code;
17200 private string $res;
17201 private string $nl;
17202 private const IGNORE_ATTRIBUTES = ['comments' => \true, 'startLine' => \true, 'endLine' => \true, 'startFilePos' => \true, 'endFilePos' => \true, 'startTokenPos' => \true, 'endTokenPos' => \true];
17203 /**
17204 * Constructs a NodeDumper.
17205 *
17206 * Supported options:
17207 * * bool dumpComments: Whether comments should be dumped.
17208 * * bool dumpPositions: Whether line/offset information should be dumped. To dump offset
17209 * information, the code needs to be passed to dump().
17210 * * bool dumpOtherAttributes: Whether non-comment, non-position attributes should be dumped.
17211 *
17212 * @param array $options Options (see description)
17213 */
17214 public function __construct(array $options = [])
17215 {
17216 $this->dumpComments = !empty($options['dumpComments']);
17217 $this->dumpPositions = !empty($options['dumpPositions']);
17218 $this->dumpOtherAttributes = !empty($options['dumpOtherAttributes']);
17219 }
17220 /**
17221 * Dumps a node or array.
17222 *
17223 * @param array|Node $node Node or array to dump
17224 * @param string|null $code Code corresponding to dumped AST. This only needs to be passed if
17225 * the dumpPositions option is enabled and the dumping of node offsets
17226 * is desired.
17227 *
17228 * @return string Dumped value
17229 */
17230 public function dump($node, ?string $code = null): string
17231 {
17232 $this->code = $code;
17233 $this->res = '';
17234 $this->nl = "\n";
17235 $this->dumpRecursive($node, \false);
17236 return $this->res;
17237 }
17238 /** @param mixed $node */
17239 protected function dumpRecursive($node, bool $indent = \true): void
17240 {
17241 if ($indent) {
17242 $this->nl .= " ";
17243 }
17244 if ($node instanceof Node) {
17245 $this->res .= $node->getType();
17246 if ($this->dumpPositions && null !== $p = $this->dumpPosition($node)) {
17247 $this->res .= $p;
17248 }
17249 $this->res .= '(';
17250 foreach ($node->getSubNodeNames() as $key) {
17251 $this->res .= "{$this->nl} " . $key . ': ';
17252 $value = $node->{$key};
17253 if (\is_int($value)) {
17254 if ('flags' === $key || 'newModifier' === $key) {
17255 $this->res .= $this->dumpFlags($value);
17256 continue;
17257 }
17258 if ('type' === $key && $node instanceof Include_) {
17259 $this->res .= $this->dumpIncludeType($value);
17260 continue;
17261 }
17262 if ('type' === $key && ($node instanceof Use_ || $node instanceof UseItem || $node instanceof GroupUse)) {
17263 $this->res .= $this->dumpUseType($value);
17264 continue;
17265 }
17266 }
17267 $this->dumpRecursive($value);
17268 }
17269 if ($this->dumpComments && $comments = $node->getComments()) {
17270 $this->res .= "{$this->nl} comments: ";
17271 $this->dumpRecursive($comments);
17272 }
17273 if ($this->dumpOtherAttributes) {
17274 foreach ($node->getAttributes() as $key => $value) {
17275 if (isset(self::IGNORE_ATTRIBUTES[$key])) {
17276 continue;
17277 }
17278 $this->res .= "{$this->nl} {$key}: ";
17279 if (\is_int($value)) {
17280 if ('kind' === $key) {
17281 if ($node instanceof Int_) {
17282 $this->res .= $this->dumpIntKind($value);
17283 continue;
17284 }
17285 if ($node instanceof String_ || $node instanceof InterpolatedString) {
17286 $this->res .= $this->dumpStringKind($value);
17287 continue;
17288 }
17289 if ($node instanceof Array_) {
17290 $this->res .= $this->dumpArrayKind($value);
17291 continue;
17292 }
17293 if ($node instanceof List_) {
17294 $this->res .= $this->dumpListKind($value);
17295 continue;
17296 }
17297 }
17298 }
17299 $this->dumpRecursive($value);
17300 }
17301 }
17302 $this->res .= "{$this->nl})";
17303 } elseif (\is_array($node)) {
17304 $this->res .= 'array(';
17305 foreach ($node as $key => $value) {
17306 $this->res .= "{$this->nl} " . $key . ': ';
17307 $this->dumpRecursive($value);
17308 }
17309 $this->res .= "{$this->nl})";
17310 } elseif ($node instanceof Comment) {
17311 $this->res .= \str_replace("\n", $this->nl, $node->getReformattedText());
17312 } elseif (\is_string($node)) {
17313 $this->res .= \str_replace("\n", $this->nl, $node);
17314 } elseif (\is_int($node) || \is_float($node)) {
17315 $this->res .= $node;
17316 } elseif (null === $node) {
17317 $this->res .= 'null';
17318 } elseif (\false === $node) {
17319 $this->res .= 'false';
17320 } elseif (\true === $node) {
17321 $this->res .= 'true';
17322 } else {
17323 throw new \InvalidArgumentException('Can only dump nodes and arrays.');
17324 }
17325 if ($indent) {
17326 $this->nl = \substr($this->nl, 0, -4);
17327 }
17328 }
17329 protected function dumpFlags(int $flags): string
17330 {
17331 $strs = [];
17332 if ($flags & Modifiers::PUBLIC) {
17333 $strs[] = 'PUBLIC';
17334 }
17335 if ($flags & Modifiers::PROTECTED) {
17336 $strs[] = 'PROTECTED';
17337 }
17338 if ($flags & Modifiers::PRIVATE) {
17339 $strs[] = 'PRIVATE';
17340 }
17341 if ($flags & Modifiers::ABSTRACT) {
17342 $strs[] = 'ABSTRACT';
17343 }
17344 if ($flags & Modifiers::STATIC) {
17345 $strs[] = 'STATIC';
17346 }
17347 if ($flags & Modifiers::FINAL) {
17348 $strs[] = 'FINAL';
17349 }
17350 if ($flags & Modifiers::READONLY) {
17351 $strs[] = 'READONLY';
17352 }
17353 if ($flags & Modifiers::PUBLIC_SET) {
17354 $strs[] = 'PUBLIC_SET';
17355 }
17356 if ($flags & Modifiers::PROTECTED_SET) {
17357 $strs[] = 'PROTECTED_SET';
17358 }
17359 if ($flags & Modifiers::PRIVATE_SET) {
17360 $strs[] = 'PRIVATE_SET';
17361 }
17362 if ($strs) {
17363 return implode(' | ', $strs) . ' (' . $flags . ')';
17364 } else {
17365 return (string) $flags;
17366 }
17367 }
17368 /** @param array<int, string> $map */
17369 private function dumpEnum(int $value, array $map): string
17370 {
17371 if (!isset($map[$value])) {
17372 return (string) $value;
17373 }
17374 return $map[$value] . ' (' . $value . ')';
17375 }
17376 private function dumpIncludeType(int $type): string
17377 {
17378 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']);
17379 }
17380 private function dumpUseType(int $type): string
17381 {
17382 return $this->dumpEnum($type, [Use_::TYPE_UNKNOWN => 'TYPE_UNKNOWN', Use_::TYPE_NORMAL => 'TYPE_NORMAL', Use_::TYPE_FUNCTION => 'TYPE_FUNCTION', Use_::TYPE_CONSTANT => 'TYPE_CONSTANT']);
17383 }
17384 private function dumpIntKind(int $kind): string
17385 {
17386 return $this->dumpEnum($kind, [Int_::KIND_BIN => 'KIND_BIN', Int_::KIND_OCT => 'KIND_OCT', Int_::KIND_DEC => 'KIND_DEC', Int_::KIND_HEX => 'KIND_HEX']);
17387 }
17388 private function dumpStringKind(int $kind): string
17389 {
17390 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']);
17391 }
17392 private function dumpArrayKind(int $kind): string
17393 {
17394 return $this->dumpEnum($kind, [Array_::KIND_LONG => 'KIND_LONG', Array_::KIND_SHORT => 'KIND_SHORT']);
17395 }
17396 private function dumpListKind(int $kind): string
17397 {
17398 return $this->dumpEnum($kind, [List_::KIND_LIST => 'KIND_LIST', List_::KIND_ARRAY => 'KIND_ARRAY']);
17399 }
17400 /**
17401 * Dump node position, if possible.
17402 *
17403 * @param Node $node Node for which to dump position
17404 *
17405 * @return string|null Dump of position, or null if position information not available
17406 */
17407 protected function dumpPosition(Node $node): ?string
17408 {
17409 if (!$node->hasAttribute('startLine') || !$node->hasAttribute('endLine')) {
17410 return null;
17411 }
17412 $start = $node->getStartLine();
17413 $end = $node->getEndLine();
17414 if ($node->hasAttribute('startFilePos') && $node->hasAttribute('endFilePos') && null !== $this->code) {
17415 $start .= ':' . $this->toColumn($this->code, $node->getStartFilePos());
17416 $end .= ':' . $this->toColumn($this->code, $node->getEndFilePos());
17417 }
17418 return "[{$start} - {$end}]";
17419 }
17420 // Copied from Error class
17421 private function toColumn(string $code, int $pos): int
17422 {
17423 if ($pos > strlen($code)) {
17424 throw new \RuntimeException('Invalid position information');
17425 }
17426 $lineStartPos = strrpos($code, "\n", $pos - strlen($code));
17427 if (\false === $lineStartPos) {
17428 $lineStartPos = -1;
17429 }
17430 return $pos - $lineStartPos;
17431 }
17432 }
17433 <?php
17434
17435 declare (strict_types=1);
17436 namespace PHPUnitPHAR\PhpParser;
17437
17438 use PHPUnitPHAR\PhpParser\NodeVisitor\FindingVisitor;
17439 use PHPUnitPHAR\PhpParser\NodeVisitor\FirstFindingVisitor;
17440 class NodeFinder
17441 {
17442 /**
17443 * Find all nodes satisfying a filter callback.
17444 *
17445 * @param Node|Node[] $nodes Single node or array of nodes to search in
17446 * @param callable $filter Filter callback: function(Node $node) : bool
17447 *
17448 * @return Node[] Found nodes satisfying the filter callback
17449 */
17450 public function find($nodes, callable $filter): array
17451 {
17452 if ($nodes === []) {
17453 return [];
17454 }
17455 if (!is_array($nodes)) {
17456 $nodes = [$nodes];
17457 }
17458 $visitor = new FindingVisitor($filter);
17459 $traverser = new NodeTraverser($visitor);
17460 $traverser->traverse($nodes);
17461 return $visitor->getFoundNodes();
17462 }
17463 /**
17464 * Find all nodes that are instances of a certain class.
17465 * @template TNode as Node
17466 *
17467 * @param Node|Node[] $nodes Single node or array of nodes to search in
17468 * @param class-string<TNode> $class Class name
17469 *
17470 * @return TNode[] Found nodes (all instances of $class)
17471 */
17472 public function findInstanceOf($nodes, string $class): array
17473 {
17474 return $this->find($nodes, function ($node) use ($class) {
17475 return $node instanceof $class;
17476 });
17477 }
17478 /**
17479 * Find first node satisfying a filter callback.
17480 *
17481 * @param Node|Node[] $nodes Single node or array of nodes to search in
17482 * @param callable $filter Filter callback: function(Node $node) : bool
17483 *
17484 * @return null|Node Found node (or null if none found)
17485 */
17486 public function findFirst($nodes, callable $filter): ?Node
17487 {
17488 if ($nodes === []) {
17489 return null;
17490 }
17491 if (!is_array($nodes)) {
17492 $nodes = [$nodes];
17493 }
17494 $visitor = new FirstFindingVisitor($filter);
17495 $traverser = new NodeTraverser($visitor);
17496 $traverser->traverse($nodes);
17497 return $visitor->getFoundNode();
17498 }
17499 /**
17500 * Find first node that is an instance of a certain class.
17501 *
17502 * @template TNode as Node
17503 *
17504 * @param Node|Node[] $nodes Single node or array of nodes to search in
17505 * @param class-string<TNode> $class Class name
17506 *
17507 * @return null|TNode Found node, which is an instance of $class (or null if none found)
17508 */
17509 public function findFirstInstanceOf($nodes, string $class): ?Node
17510 {
17511 return $this->findFirst($nodes, function ($node) use ($class) {
17512 return $node instanceof $class;
17513 });
17514 }
17515 }
17516 <?php
17517
17518 declare (strict_types=1);
17519 namespace PHPUnitPHAR\PhpParser;
17520
17521 class NodeTraverser implements NodeTraverserInterface
17522 {
17523 /**
17524 * @deprecated Use NodeVisitor::DONT_TRAVERSE_CHILDREN instead.
17525 */
17526 public const DONT_TRAVERSE_CHILDREN = NodeVisitor::DONT_TRAVERSE_CHILDREN;
17527 /**
17528 * @deprecated Use NodeVisitor::STOP_TRAVERSAL instead.
17529 */
17530 public const STOP_TRAVERSAL = NodeVisitor::STOP_TRAVERSAL;
17531 /**
17532 * @deprecated Use NodeVisitor::REMOVE_NODE instead.
17533 */
17534 public const REMOVE_NODE = NodeVisitor::REMOVE_NODE;
17535 /**
17536 * @deprecated Use NodeVisitor::DONT_TRAVERSE_CURRENT_AND_CHILDREN instead.
17537 */
17538 public const DONT_TRAVERSE_CURRENT_AND_CHILDREN = NodeVisitor::DONT_TRAVERSE_CURRENT_AND_CHILDREN;
17539 /** @var list<NodeVisitor> Visitors */
17540 protected array $visitors = [];
17541 /** @var bool Whether traversal should be stopped */
17542 protected bool $stopTraversal;
17543 /**
17544 * Create a traverser with the given visitors.
17545 *
17546 * @param NodeVisitor ...$visitors Node visitors
17547 */
17548 public function __construct(NodeVisitor ...$visitors)
17549 {
17550 $this->visitors = $visitors;
17551 }
17552 /**
17553 * Adds a visitor.
17554 *
17555 * @param NodeVisitor $visitor Visitor to add
17556 */
17557 public function addVisitor(NodeVisitor $visitor): void
17558 {
17559 $this->visitors[] = $visitor;
17560 }
17561 /**
17562 * Removes an added visitor.
17563 */
17564 public function removeVisitor(NodeVisitor $visitor): void
17565 {
17566 $index = array_search($visitor, $this->visitors);
17567 if ($index !== \false) {
17568 array_splice($this->visitors, $index, 1, []);
17569 }
17570 }
17571 /**
17572 * Traverses an array of nodes using the registered visitors.
17573 *
17574 * @param Node[] $nodes Array of nodes
17575 *
17576 * @return Node[] Traversed array of nodes
17577 */
17578 public function traverse(array $nodes): array
17579 {
17580 $this->stopTraversal = \false;
17581 foreach ($this->visitors as $visitor) {
17582 if (null !== $return = $visitor->beforeTraverse($nodes)) {
17583 $nodes = $return;
17584 }
17585 }
17586 $nodes = $this->traverseArray($nodes);
17587 for ($i = \count($this->visitors) - 1; $i >= 0; --$i) {
17588 $visitor = $this->visitors[$i];
17589 if (null !== $return = $visitor->afterTraverse($nodes)) {
17590 $nodes = $return;
17591 }
17592 }
17593 return $nodes;
17594 }
17595 /**
17596 * Recursively traverse a node.
17597 *
17598 * @param Node $node Node to traverse.
17599 */
17600 protected function traverseNode(Node $node): void
17601 {
17602 foreach ($node->getSubNodeNames() as $name) {
17603 $subNode = $node->{$name};
17604 if (\is_array($subNode)) {
17605 $node->{$name} = $this->traverseArray($subNode);
17606 if ($this->stopTraversal) {
17607 break;
17608 }
17609 continue;
17610 }
17611 if (!$subNode instanceof Node) {
17612 continue;
17613 }
17614 $traverseChildren = \true;
17615 $visitorIndex = -1;
17616 foreach ($this->visitors as $visitorIndex => $visitor) {
17617 $return = $visitor->enterNode($subNode);
17618 if (null !== $return) {
17619 if ($return instanceof Node) {
17620 $this->ensureReplacementReasonable($subNode, $return);
17621 $subNode = $node->{$name} = $return;
17622 } elseif (NodeVisitor::DONT_TRAVERSE_CHILDREN === $return) {
17623 $traverseChildren = \false;
17624 } elseif (NodeVisitor::DONT_TRAVERSE_CURRENT_AND_CHILDREN === $return) {
17625 $traverseChildren = \false;
17626 break;
17627 } elseif (NodeVisitor::STOP_TRAVERSAL === $return) {
17628 $this->stopTraversal = \true;
17629 break 2;
17630 } elseif (NodeVisitor::REPLACE_WITH_NULL === $return) {
17631 $node->{$name} = null;
17632 continue 2;
17633 } else {
17634 throw new \LogicException('enterNode() returned invalid value of type ' . gettype($return));
17635 }
17636 }
17637 }
17638 if ($traverseChildren) {
17639 $this->traverseNode($subNode);
17640 if ($this->stopTraversal) {
17641 break;
17642 }
17643 }
17644 for (; $visitorIndex >= 0; --$visitorIndex) {
17645 $visitor = $this->visitors[$visitorIndex];
17646 $return = $visitor->leaveNode($subNode);
17647 if (null !== $return) {
17648 if ($return instanceof Node) {
17649 $this->ensureReplacementReasonable($subNode, $return);
17650 $subNode = $node->{$name} = $return;
17651 } elseif (NodeVisitor::STOP_TRAVERSAL === $return) {
17652 $this->stopTraversal = \true;
17653 break 2;
17654 } elseif (NodeVisitor::REPLACE_WITH_NULL === $return) {
17655 $node->{$name} = null;
17656 break;
17657 } elseif (\is_array($return)) {
17658 throw new \LogicException('leaveNode() may only return an array ' . 'if the parent structure is an array');
17659 } else {
17660 throw new \LogicException('leaveNode() returned invalid value of type ' . gettype($return));
17661 }
17662 }
17663 }
17664 }
17665 }
17666 /**
17667 * Recursively traverse array (usually of nodes).
17668 *
17669 * @param Node[] $nodes Array to traverse
17670 *
17671 * @return Node[] Result of traversal (may be original array or changed one)
17672 */
17673 protected function traverseArray(array $nodes): array
17674 {
17675 $doNodes = [];
17676 foreach ($nodes as $i => $node) {
17677 if (!$node instanceof Node) {
17678 if (\is_array($node)) {
17679 throw new \LogicException('Invalid node structure: Contains nested arrays');
17680 }
17681 continue;
17682 }
17683 $traverseChildren = \true;
17684 $visitorIndex = -1;
17685 foreach ($this->visitors as $visitorIndex => $visitor) {
17686 $return = $visitor->enterNode($node);
17687 if (null !== $return) {
17688 if ($return instanceof Node) {
17689 $this->ensureReplacementReasonable($node, $return);
17690 $nodes[$i] = $node = $return;
17691 } elseif (\is_array($return)) {
17692 $doNodes[] = [$i, $return];
17693 continue 2;
17694 } elseif (NodeVisitor::REMOVE_NODE === $return) {
17695 $doNodes[] = [$i, []];
17696 continue 2;
17697 } elseif (NodeVisitor::DONT_TRAVERSE_CHILDREN === $return) {
17698 $traverseChildren = \false;
17699 } elseif (NodeVisitor::DONT_TRAVERSE_CURRENT_AND_CHILDREN === $return) {
17700 $traverseChildren = \false;
17701 break;
17702 } elseif (NodeVisitor::STOP_TRAVERSAL === $return) {
17703 $this->stopTraversal = \true;
17704 break 2;
17705 } elseif (NodeVisitor::REPLACE_WITH_NULL === $return) {
17706 throw new \LogicException('REPLACE_WITH_NULL can not be used if the parent structure is an array');
17707 } else {
17708 throw new \LogicException('enterNode() returned invalid value of type ' . gettype($return));
17709 }
17710 }
17711 }
17712 if ($traverseChildren) {
17713 $this->traverseNode($node);
17714 if ($this->stopTraversal) {
17715 break;
17716 }
17717 }
17718 for (; $visitorIndex >= 0; --$visitorIndex) {
17719 $visitor = $this->visitors[$visitorIndex];
17720 $return = $visitor->leaveNode($node);
17721 if (null !== $return) {
17722 if ($return instanceof Node) {
17723 $this->ensureReplacementReasonable($node, $return);
17724 $nodes[$i] = $node = $return;
17725 } elseif (\is_array($return)) {
17726 $doNodes[] = [$i, $return];
17727 break;
17728 } elseif (NodeVisitor::REMOVE_NODE === $return) {
17729 $doNodes[] = [$i, []];
17730 break;
17731 } elseif (NodeVisitor::STOP_TRAVERSAL === $return) {
17732 $this->stopTraversal = \true;
17733 break 2;
17734 } elseif (NodeVisitor::REPLACE_WITH_NULL === $return) {
17735 throw new \LogicException('REPLACE_WITH_NULL can not be used if the parent structure is an array');
17736 } else {
17737 throw new \LogicException('leaveNode() returned invalid value of type ' . gettype($return));
17738 }
17739 }
17740 }
17741 }
17742 if (!empty($doNodes)) {
17743 while (list($i, $replace) = array_pop($doNodes)) {
17744 array_splice($nodes, $i, 1, $replace);
17745 }
17746 }
17747 return $nodes;
17748 }
17749 private function ensureReplacementReasonable(Node $old, Node $new): void
17750 {
17751 if ($old instanceof Node\Stmt && $new instanceof Node\Expr) {
17752 throw new \LogicException("Trying to replace statement ({$old->getType()}) " . "with expression ({$new->getType()}). Are you missing a " . "Stmt_Expression wrapper?");
17753 }
17754 if ($old instanceof Node\Expr && $new instanceof Node\Stmt) {
17755 throw new \LogicException("Trying to replace expression ({$old->getType()}) " . "with statement ({$new->getType()})");
17756 }
17757 }
17758 }
17759 <?php
17760
17761 declare (strict_types=1);
17762 namespace PHPUnitPHAR\PhpParser;
17763
17764 interface NodeTraverserInterface
17765 {
17766 /**
17767 * Adds a visitor.
17768 *
17769 * @param NodeVisitor $visitor Visitor to add
17770 */
17771 public function addVisitor(NodeVisitor $visitor): void;
17772 /**
17773 * Removes an added visitor.
17774 */
17775 public function removeVisitor(NodeVisitor $visitor): void;
17776 /**
17777 * Traverses an array of nodes using the registered visitors.
17778 *
17779 * @param Node[] $nodes Array of nodes
17780 *
17781 * @return Node[] Traversed array of nodes
17782 */
17783 public function traverse(array $nodes): array;
17784 }
17785 <?php
17786
17787 declare (strict_types=1);
17788 namespace PHPUnitPHAR\PhpParser;
17789
17790 interface NodeVisitor
17791 {
17792 /**
17793 * If NodeVisitor::enterNode() returns DONT_TRAVERSE_CHILDREN, child nodes
17794 * of the current node will not be traversed for any visitors.
17795 *
17796 * For subsequent visitors enterNode() will still be called on the current
17797 * node and leaveNode() will also be invoked for the current node.
17798 */
17799 public const DONT_TRAVERSE_CHILDREN = 1;
17800 /**
17801 * If NodeVisitor::enterNode() or NodeVisitor::leaveNode() returns
17802 * STOP_TRAVERSAL, traversal is aborted.
17803 *
17804 * The afterTraverse() method will still be invoked.
17805 */
17806 public const STOP_TRAVERSAL = 2;
17807 /**
17808 * If NodeVisitor::leaveNode() returns REMOVE_NODE for a node that occurs
17809 * in an array, it will be removed from the array.
17810 *
17811 * For subsequent visitors leaveNode() will still be invoked for the
17812 * removed node.
17813 */
17814 public const REMOVE_NODE = 3;
17815 /**
17816 * If NodeVisitor::enterNode() returns DONT_TRAVERSE_CURRENT_AND_CHILDREN, child nodes
17817 * of the current node will not be traversed for any visitors.
17818 *
17819 * For subsequent visitors enterNode() will not be called as well.
17820 * leaveNode() will be invoked for visitors that has enterNode() method invoked.
17821 */
17822 public const DONT_TRAVERSE_CURRENT_AND_CHILDREN = 4;
17823 /**
17824 * If NodeVisitor::enterNode() or NodeVisitor::leaveNode() returns REPLACE_WITH_NULL,
17825 * the node will be replaced with null. This is not a legal return value if the node is part
17826 * of an array, rather than another node.
17827 */
17828 public const REPLACE_WITH_NULL = 5;
17829 /**
17830 * Called once before traversal.
17831 *
17832 * Return value semantics:
17833 * * null: $nodes stays as-is
17834 * * otherwise: $nodes is set to the return value
17835 *
17836 * @param Node[] $nodes Array of nodes
17837 *
17838 * @return null|Node[] Array of nodes
17839 */
17840 public function beforeTraverse(array $nodes);
17841 /**
17842 * Called when entering a node.
17843 *
17844 * Return value semantics:
17845 * * null
17846 * => $node stays as-is
17847 * * array (of Nodes)
17848 * => The return value is merged into the parent array (at the position of the $node)
17849 * * NodeVisitor::REMOVE_NODE
17850 * => $node is removed from the parent array
17851 * * NodeVisitor::REPLACE_WITH_NULL
17852 * => $node is replaced with null
17853 * * NodeVisitor::DONT_TRAVERSE_CHILDREN
17854 * => Children of $node are not traversed. $node stays as-is
17855 * * NodeVisitor::DONT_TRAVERSE_CURRENT_AND_CHILDREN
17856 * => Further visitors for the current node are skipped, and its children are not
17857 * traversed. $node stays as-is.
17858 * * NodeVisitor::STOP_TRAVERSAL
17859 * => Traversal is aborted. $node stays as-is
17860 * * otherwise
17861 * => $node is set to the return value
17862 *
17863 * @param Node $node Node
17864 *
17865 * @return null|int|Node|Node[] Replacement node (or special return value)
17866 */
17867 public function enterNode(Node $node);
17868 /**
17869 * Called when leaving a node.
17870 *
17871 * Return value semantics:
17872 * * null
17873 * => $node stays as-is
17874 * * NodeVisitor::REMOVE_NODE
17875 * => $node is removed from the parent array
17876 * * NodeVisitor::REPLACE_WITH_NULL
17877 * => $node is replaced with null
17878 * * NodeVisitor::STOP_TRAVERSAL
17879 * => Traversal is aborted. $node stays as-is
17880 * * array (of Nodes)
17881 * => The return value is merged into the parent array (at the position of the $node)
17882 * * otherwise
17883 * => $node is set to the return value
17884 *
17885 * @param Node $node Node
17886 *
17887 * @return null|int|Node|Node[] Replacement node (or special return value)
17888 */
17889 public function leaveNode(Node $node);
17890 /**
17891 * Called once after traversal.
17892 *
17893 * Return value semantics:
17894 * * null: $nodes stays as-is
17895 * * otherwise: $nodes is set to the return value
17896 *
17897 * @param Node[] $nodes Array of nodes
17898 *
17899 * @return null|Node[] Array of nodes
17900 */
17901 public function afterTraverse(array $nodes);
17902 }
17903 <?php
17904
17905 declare (strict_types=1);
17906 namespace PHPUnitPHAR\PhpParser\NodeVisitor;
17907
17908 use PHPUnitPHAR\PhpParser\Node;
17909 use PHPUnitPHAR\PhpParser\NodeVisitorAbstract;
17910 /**
17911 * Visitor cloning all nodes and linking to the original nodes using an attribute.
17912 *
17913 * This visitor is required to perform format-preserving pretty prints.
17914 */
17915 class CloningVisitor extends NodeVisitorAbstract
17916 {
17917 public function enterNode(Node $origNode)
17918 {
17919 $node = clone $origNode;
17920 $node->setAttribute('origNode', $origNode);
17921 return $node;
17922 }
17923 }
17924 <?php
17925
17926 declare (strict_types=1);
17927 namespace PHPUnitPHAR\PhpParser\NodeVisitor;
17928
17929 use PHPUnitPHAR\PhpParser\Comment;
17930 use PHPUnitPHAR\PhpParser\Node;
17931 use PHPUnitPHAR\PhpParser\NodeVisitorAbstract;
17932 use PHPUnitPHAR\PhpParser\Token;
17933 class CommentAnnotatingVisitor extends NodeVisitorAbstract
17934 {
17935 /** @var int Last seen token start position */
17936 private int $pos = 0;
17937 /** @var Token[] Token array */
17938 private array $tokens;
17939 /** @var list<int> Token positions of comments */
17940 private array $commentPositions = [];
17941 /**
17942 * Create a comment annotation visitor.
17943 *
17944 * @param Token[] $tokens Token array
17945 */
17946 public function __construct(array $tokens)
17947 {
17948 $this->tokens = $tokens;
17949 // Collect positions of comments. We use this to avoid traversing parts of the AST where
17950 // there are no comments.
17951 foreach ($tokens as $i => $token) {
17952 if ($token->id === \T_COMMENT || $token->id === \T_DOC_COMMENT) {
17953 $this->commentPositions[] = $i;
17954 }
17955 }
17956 }
17957 public function enterNode(Node $node)
17958 {
17959 $nextCommentPos = current($this->commentPositions);
17960 if ($nextCommentPos === \false) {
17961 // No more comments.
17962 return self::STOP_TRAVERSAL;
17963 }
17964 $oldPos = $this->pos;
17965 $this->pos = $pos = $node->getStartTokenPos();
17966 if ($nextCommentPos > $oldPos && $nextCommentPos < $pos) {
17967 $comments = [];
17968 while (--$pos >= $oldPos) {
17969 $token = $this->tokens[$pos];
17970 if ($token->id === \T_DOC_COMMENT) {
17971 $comments[] = new Comment\Doc($token->text, $token->line, $token->pos, $pos, $token->getEndLine(), $token->getEndPos() - 1, $pos);
17972 continue;
17973 }
17974 if ($token->id === \T_COMMENT) {
17975 $comments[] = new Comment($token->text, $token->line, $token->pos, $pos, $token->getEndLine(), $token->getEndPos() - 1, $pos);
17976 continue;
17977 }
17978 if ($token->id !== \T_WHITESPACE) {
17979 break;
17980 }
17981 }
17982 if (!empty($comments)) {
17983 $node->setAttribute('comments', array_reverse($comments));
17984 }
17985 do {
17986 $nextCommentPos = next($this->commentPositions);
17987 } while ($nextCommentPos !== \false && $nextCommentPos < $this->pos);
17988 }
17989 $endPos = $node->getEndTokenPos();
17990 if ($nextCommentPos > $endPos) {
17991 // Skip children if there are no comments located inside this node.
17992 $this->pos = $endPos;
17993 return self::DONT_TRAVERSE_CHILDREN;
17994 }
17995 return null;
17996 }
17997 }
17998 <?php
17999
18000 declare (strict_types=1);
18001 namespace PHPUnitPHAR\PhpParser\NodeVisitor;
18002
18003 use PHPUnitPHAR\PhpParser\Node;
18004 use PHPUnitPHAR\PhpParser\NodeVisitorAbstract;
18005 /**
18006 * This visitor can be used to find and collect all nodes satisfying some criterion determined by
18007 * a filter callback.
18008 */
18009 class FindingVisitor extends NodeVisitorAbstract
18010 {
18011 /** @var callable Filter callback */
18012 protected $filterCallback;
18013 /** @var list<Node> Found nodes */
18014 protected array $foundNodes;
18015 public function __construct(callable $filterCallback)
18016 {
18017 $this->filterCallback = $filterCallback;
18018 }
18019 /**
18020 * Get found nodes satisfying the filter callback.
18021 *
18022 * Nodes are returned in pre-order.
18023 *
18024 * @return list<Node> Found nodes
18025 */
18026 public function getFoundNodes(): array
18027 {
18028 return $this->foundNodes;
18029 }
18030 public function beforeTraverse(array $nodes): ?array
18031 {
18032 $this->foundNodes = [];
18033 return null;
18034 }
18035 public function enterNode(Node $node)
18036 {
18037 $filterCallback = $this->filterCallback;
18038 if ($filterCallback($node)) {
18039 $this->foundNodes[] = $node;
18040 }
18041 return null;
18042 }
18043 }
18044 <?php
18045
18046 declare (strict_types=1);
18047 namespace PHPUnitPHAR\PhpParser\NodeVisitor;
18048
18049 use PHPUnitPHAR\PhpParser\Node;
18050 use PHPUnitPHAR\PhpParser\NodeVisitor;
18051 use PHPUnitPHAR\PhpParser\NodeVisitorAbstract;
18052 /**
18053 * This visitor can be used to find the first node satisfying some criterion determined by
18054 * a filter callback.
18055 */
18056 class FirstFindingVisitor extends NodeVisitorAbstract
18057 {
18058 /** @var callable Filter callback */
18059 protected $filterCallback;
18060 /** @var null|Node Found node */
18061 protected ?Node $foundNode;
18062 public function __construct(callable $filterCallback)
18063 {
18064 $this->filterCallback = $filterCallback;
18065 }
18066 /**
18067 * Get found node satisfying the filter callback.
18068 *
18069 * Returns null if no node satisfies the filter callback.
18070 *
18071 * @return null|Node Found node (or null if not found)
18072 */
18073 public function getFoundNode(): ?Node
18074 {
18075 return $this->foundNode;
18076 }
18077 public function beforeTraverse(array $nodes): ?array
18078 {
18079 $this->foundNode = null;
18080 return null;
18081 }
18082 public function enterNode(Node $node)
18083 {
18084 $filterCallback = $this->filterCallback;
18085 if ($filterCallback($node)) {
18086 $this->foundNode = $node;
18087 return NodeVisitor::STOP_TRAVERSAL;
18088 }
18089 return null;
18090 }
18091 }
18092 <?php
18093
18094 declare (strict_types=1);
18095 namespace PHPUnitPHAR\PhpParser\NodeVisitor;
18096
18097 use PHPUnitPHAR\PhpParser\ErrorHandler;
18098 use PHPUnitPHAR\PhpParser\NameContext;
18099 use PHPUnitPHAR\PhpParser\Node;
18100 use PHPUnitPHAR\PhpParser\Node\Expr;
18101 use PHPUnitPHAR\PhpParser\Node\Name;
18102 use PHPUnitPHAR\PhpParser\Node\Name\FullyQualified;
18103 use PHPUnitPHAR\PhpParser\Node\Stmt;
18104 use PHPUnitPHAR\PhpParser\NodeVisitorAbstract;
18105 class NameResolver extends NodeVisitorAbstract
18106 {
18107 /** @var NameContext Naming context */
18108 protected NameContext $nameContext;
18109 /** @var bool Whether to preserve original names */
18110 protected bool $preserveOriginalNames;
18111 /** @var bool Whether to replace resolved nodes in place, or to add resolvedNode attributes */
18112 protected bool $replaceNodes;
18113 /**
18114 * Constructs a name resolution visitor.
18115 *
18116 * Options:
18117 * * preserveOriginalNames (default false): An "originalName" attribute will be added to
18118 * all name nodes that underwent resolution.
18119 * * replaceNodes (default true): Resolved names are replaced in-place. Otherwise, a
18120 * resolvedName attribute is added. (Names that cannot be statically resolved receive a
18121 * namespacedName attribute, as usual.)
18122 *
18123 * @param ErrorHandler|null $errorHandler Error handler
18124 * @param array{preserveOriginalNames?: bool, replaceNodes?: bool} $options Options
18125 */
18126 public function __construct(?ErrorHandler $errorHandler = null, array $options = [])
18127 {
18128 $this->nameContext = new NameContext($errorHandler ?? new ErrorHandler\Throwing());
18129 $this->preserveOriginalNames = $options['preserveOriginalNames'] ?? \false;
18130 $this->replaceNodes = $options['replaceNodes'] ?? \true;
18131 }
18132 /**
18133 * Get name resolution context.
18134 */
18135 public function getNameContext(): NameContext
18136 {
18137 return $this->nameContext;
18138 }
18139 public function beforeTraverse(array $nodes): ?array
18140 {
18141 $this->nameContext->startNamespace();
18142 return null;
18143 }
18144 public function enterNode(Node $node)
18145 {
18146 if ($node instanceof Stmt\Namespace_) {
18147 $this->nameContext->startNamespace($node->name);
18148 } elseif ($node instanceof Stmt\Use_) {
18149 foreach ($node->uses as $use) {
18150 $this->addAlias($use, $node->type, null);
18151 }
18152 } elseif ($node instanceof Stmt\GroupUse) {
18153 foreach ($node->uses as $use) {
18154 $this->addAlias($use, $node->type, $node->prefix);
18155 }
18156 } elseif ($node instanceof Stmt\Class_) {
18157 if (null !== $node->extends) {
18158 $node->extends = $this->resolveClassName($node->extends);
18159 }
18160 foreach ($node->implements as &$interface) {
18161 $interface = $this->resolveClassName($interface);
18162 }
18163 $this->resolveAttrGroups($node);
18164 if (null !== $node->name) {
18165 $this->addNamespacedName($node);
18166 } else {
18167 $node->namespacedName = null;
18168 }
18169 } elseif ($node instanceof Stmt\Interface_) {
18170 foreach ($node->extends as &$interface) {
18171 $interface = $this->resolveClassName($interface);
18172 }
18173 $this->resolveAttrGroups($node);
18174 $this->addNamespacedName($node);
18175 } elseif ($node instanceof Stmt\Enum_) {
18176 foreach ($node->implements as &$interface) {
18177 $interface = $this->resolveClassName($interface);
18178 }
18179 $this->resolveAttrGroups($node);
18180 $this->addNamespacedName($node);
18181 } elseif ($node instanceof Stmt\Trait_) {
18182 $this->resolveAttrGroups($node);
18183 $this->addNamespacedName($node);
18184 } elseif ($node instanceof Stmt\Function_) {
18185 $this->resolveSignature($node);
18186 $this->resolveAttrGroups($node);
18187 $this->addNamespacedName($node);
18188 } elseif ($node instanceof Stmt\ClassMethod || $node instanceof Expr\Closure || $node instanceof Expr\ArrowFunction) {
18189 $this->resolveSignature($node);
18190 $this->resolveAttrGroups($node);
18191 } elseif ($node instanceof Stmt\Property) {
18192 if (null !== $node->type) {
18193 $node->type = $this->resolveType($node->type);
18194 }
18195 $this->resolveAttrGroups($node);
18196 } elseif ($node instanceof Node\PropertyHook) {
18197 foreach ($node->params as $param) {
18198 $param->type = $this->resolveType($param->type);
18199 $this->resolveAttrGroups($param);
18200 }
18201 $this->resolveAttrGroups($node);
18202 } elseif ($node instanceof Stmt\Const_) {
18203 foreach ($node->consts as $const) {
18204 $this->addNamespacedName($const);
18205 }
18206 $this->resolveAttrGroups($node);
18207 } elseif ($node instanceof Stmt\ClassConst) {
18208 if (null !== $node->type) {
18209 $node->type = $this->resolveType($node->type);
18210 }
18211 $this->resolveAttrGroups($node);
18212 } elseif ($node instanceof Stmt\EnumCase) {
18213 $this->resolveAttrGroups($node);
18214 } elseif ($node instanceof Expr\StaticCall || $node instanceof Expr\StaticPropertyFetch || $node instanceof Expr\ClassConstFetch || $node instanceof Expr\New_ || $node instanceof Expr\Instanceof_) {
18215 if ($node->class instanceof Name) {
18216 $node->class = $this->resolveClassName($node->class);
18217 }
18218 } elseif ($node instanceof Stmt\Catch_) {
18219 foreach ($node->types as &$type) {
18220 $type = $this->resolveClassName($type);
18221 }
18222 } elseif ($node instanceof Expr\FuncCall) {
18223 if ($node->name instanceof Name) {
18224 $node->name = $this->resolveName($node->name, Stmt\Use_::TYPE_FUNCTION);
18225 }
18226 } elseif ($node instanceof Expr\ConstFetch) {
18227 $node->name = $this->resolveName($node->name, Stmt\Use_::TYPE_CONSTANT);
18228 } elseif ($node instanceof Stmt\TraitUse) {
18229 foreach ($node->traits as &$trait) {
18230 $trait = $this->resolveClassName($trait);
18231 }
18232 foreach ($node->adaptations as $adaptation) {
18233 if (null !== $adaptation->trait) {
18234 $adaptation->trait = $this->resolveClassName($adaptation->trait);
18235 }
18236 if ($adaptation instanceof Stmt\TraitUseAdaptation\Precedence) {
18237 foreach ($adaptation->insteadof as &$insteadof) {
18238 $insteadof = $this->resolveClassName($insteadof);
18239 }
18240 }
18241 }
18242 }
18243 return null;
18244 }
18245 /** @param Stmt\Use_::TYPE_* $type */
18246 private function addAlias(Node\UseItem $use, int $type, ?Name $prefix = null): void
18247 {
18248 // Add prefix for group uses
18249 $name = $prefix ? Name::concat($prefix, $use->name) : $use->name;
18250 // Type is determined either by individual element or whole use declaration
18251 $type |= $use->type;
18252 $this->nameContext->addAlias($name, (string) $use->getAlias(), $type, $use->getAttributes());
18253 }
18254 /** @param Stmt\Function_|Stmt\ClassMethod|Expr\Closure|Expr\ArrowFunction $node */
18255 private function resolveSignature($node): void
18256 {
18257 foreach ($node->params as $param) {
18258 $param->type = $this->resolveType($param->type);
18259 $this->resolveAttrGroups($param);
18260 }
18261 $node->returnType = $this->resolveType($node->returnType);
18262 }
18263 /**
18264 * @template T of Node\Identifier|Name|Node\ComplexType|null
18265 * @param T $node
18266 * @return T
18267 */
18268 private function resolveType(?Node $node): ?Node
18269 {
18270 if ($node instanceof Name) {
18271 return $this->resolveClassName($node);
18272 }
18273 if ($node instanceof Node\NullableType) {
18274 $node->type = $this->resolveType($node->type);
18275 return $node;
18276 }
18277 if ($node instanceof Node\UnionType || $node instanceof Node\IntersectionType) {
18278 foreach ($node->types as &$type) {
18279 $type = $this->resolveType($type);
18280 }
18281 return $node;
18282 }
18283 return $node;
18284 }
18285 /**
18286 * Resolve name, according to name resolver options.
18287 *
18288 * @param Name $name Function or constant name to resolve
18289 * @param Stmt\Use_::TYPE_* $type One of Stmt\Use_::TYPE_*
18290 *
18291 * @return Name Resolved name, or original name with attribute
18292 */
18293 protected function resolveName(Name $name, int $type): Name
18294 {
18295 if (!$this->replaceNodes) {
18296 $resolvedName = $this->nameContext->getResolvedName($name, $type);
18297 if (null !== $resolvedName) {
18298 $name->setAttribute('resolvedName', $resolvedName);
18299 } else {
18300 $name->setAttribute('namespacedName', FullyQualified::concat($this->nameContext->getNamespace(), $name, $name->getAttributes()));
18301 }
18302 return $name;
18303 }
18304 if ($this->preserveOriginalNames) {
18305 // Save the original name
18306 $originalName = $name;
18307 $name = clone $originalName;
18308 $name->setAttribute('originalName', $originalName);
18309 }
18310 $resolvedName = $this->nameContext->getResolvedName($name, $type);
18311 if (null !== $resolvedName) {
18312 return $resolvedName;
18313 }
18314 // unqualified names inside a namespace cannot be resolved at compile-time
18315 // add the namespaced version of the name as an attribute
18316 $name->setAttribute('namespacedName', FullyQualified::concat($this->nameContext->getNamespace(), $name, $name->getAttributes()));
18317 return $name;
18318 }
18319 protected function resolveClassName(Name $name): Name
18320 {
18321 return $this->resolveName($name, Stmt\Use_::TYPE_NORMAL);
18322 }
18323 protected function addNamespacedName(Node $node): void
18324 {
18325 $node->namespacedName = Name::concat($this->nameContext->getNamespace(), (string) $node->name);
18326 }
18327 protected function resolveAttrGroups(Node $node): void
18328 {
18329 foreach ($node->attrGroups as $attrGroup) {
18330 foreach ($attrGroup->attrs as $attr) {
18331 $attr->name = $this->resolveClassName($attr->name);
18332 }
18333 }
18334 }
18335 }
18336 <?php
18337
18338 declare (strict_types=1);
18339 namespace PHPUnitPHAR\PhpParser\NodeVisitor;
18340
18341 use PHPUnitPHAR\PhpParser\Node;
18342 use PHPUnitPHAR\PhpParser\NodeVisitorAbstract;
18343 /**
18344 * Visitor that connects a child node to its parent node
18345 * as well as its sibling nodes.
18346 *
18347 * With <code>$weakReferences=false</code> on the child node, the parent node can be accessed through
18348 * <code>$node->getAttribute('parent')</code>, the previous
18349 * node can be accessed through <code>$node->getAttribute('previous')</code>,
18350 * and the next node can be accessed through <code>$node->getAttribute('next')</code>.
18351 *
18352 * With <code>$weakReferences=true</code> attribute names are prefixed by "weak_", e.g. "weak_parent".
18353 */
18354 final class NodeConnectingVisitor extends NodeVisitorAbstract
18355 {
18356 /**
18357 * @var Node[]
18358 */
18359 private array $stack = [];
18360 /**
18361 * @var ?Node
18362 */
18363 private $previous;
18364 private bool $weakReferences;
18365 public function __construct(bool $weakReferences = \false)
18366 {
18367 $this->weakReferences = $weakReferences;
18368 }
18369 public function beforeTraverse(array $nodes)
18370 {
18371 $this->stack = [];
18372 $this->previous = null;
18373 }
18374 public function enterNode(Node $node)
18375 {
18376 if (!empty($this->stack)) {
18377 $parent = $this->stack[count($this->stack) - 1];
18378 if ($this->weakReferences) {
18379 $node->setAttribute('weak_parent', \WeakReference::create($parent));
18380 } else {
18381 $node->setAttribute('parent', $parent);
18382 }
18383 }
18384 if ($this->previous !== null) {
18385 if ($this->weakReferences) {
18386 if ($this->previous->getAttribute('weak_parent') === $node->getAttribute('weak_parent')) {
18387 $node->setAttribute('weak_previous', \WeakReference::create($this->previous));
18388 $this->previous->setAttribute('weak_next', \WeakReference::create($node));
18389 }
18390 } elseif ($this->previous->getAttribute('parent') === $node->getAttribute('parent')) {
18391 $node->setAttribute('previous', $this->previous);
18392 $this->previous->setAttribute('next', $node);
18393 }
18394 }
18395 $this->stack[] = $node;
18396 }
18397 public function leaveNode(Node $node)
18398 {
18399 $this->previous = $node;
18400 array_pop($this->stack);
18401 }
18402 }
18403 <?php
18404
18405 declare (strict_types=1);
18406 namespace PHPUnitPHAR\PhpParser\NodeVisitor;
18407
18408 use PHPUnitPHAR\PhpParser\Node;
18409 use PHPUnitPHAR\PhpParser\NodeVisitorAbstract;
18410 use function array_pop;
18411 use function count;
18412 /**
18413 * Visitor that connects a child node to its parent node.
18414 *
18415 * With <code>$weakReferences=false</code> on the child node, the parent node can be accessed through
18416 * <code>$node->getAttribute('parent')</code>.
18417 *
18418 * With <code>$weakReferences=true</code> the attribute name is "weak_parent" instead.
18419 */
18420 final class ParentConnectingVisitor extends NodeVisitorAbstract
18421 {
18422 /**
18423 * @var Node[]
18424 */
18425 private array $stack = [];
18426 private bool $weakReferences;
18427 public function __construct(bool $weakReferences = \false)
18428 {
18429 $this->weakReferences = $weakReferences;
18430 }
18431 public function beforeTraverse(array $nodes)
18432 {
18433 $this->stack = [];
18434 }
18435 public function enterNode(Node $node)
18436 {
18437 if (!empty($this->stack)) {
18438 $parent = $this->stack[count($this->stack) - 1];
18439 if ($this->weakReferences) {
18440 $node->setAttribute('weak_parent', \WeakReference::create($parent));
18441 } else {
18442 $node->setAttribute('parent', $parent);
18443 }
18444 }
18445 $this->stack[] = $node;
18446 }
18447 public function leaveNode(Node $node)
18448 {
18449 array_pop($this->stack);
18450 }
18451 }
18452 <?php
18453
18454 declare (strict_types=1);
18455 namespace PHPUnitPHAR\PhpParser;
18456
18457 /**
18458 * @codeCoverageIgnore
18459 */
18460 abstract class NodeVisitorAbstract implements NodeVisitor
18461 {
18462 public function beforeTraverse(array $nodes)
18463 {
18464 return null;
18465 }
18466 public function enterNode(Node $node)
18467 {
18468 return null;
18469 }
18470 public function leaveNode(Node $node)
18471 {
18472 return null;
18473 }
18474 public function afterTraverse(array $nodes)
18475 {
18476 return null;
18477 }
18478 }
18479 <?php
18480
18481 declare (strict_types=1);
18482 namespace PHPUnitPHAR\PhpParser;
18483
18484 interface Parser
18485 {
18486 /**
18487 * Parses PHP code into a node tree.
18488 *
18489 * @param string $code The source code to parse
18490 * @param ErrorHandler|null $errorHandler Error handler to use for lexer/parser errors, defaults
18491 * to ErrorHandler\Throwing.
18492 *
18493 * @return Node\Stmt[]|null Array of statements (or null non-throwing error handler is used and
18494 * the parser was unable to recover from an error).
18495 */
18496 public function parse(string $code, ?ErrorHandler $errorHandler = null): ?array;
18497 /**
18498 * Return tokens for the last parse.
18499 *
18500 * @return Token[]
18501 */
18502 public function getTokens(): array;
18503 }
18504 <?php
18505
18506 declare (strict_types=1);
18507 namespace PHPUnitPHAR\PhpParser\Parser;
18508
18509 use PHPUnitPHAR\PhpParser\Error;
18510 use PHPUnitPHAR\PhpParser\Modifiers;
18511 use PHPUnitPHAR\PhpParser\Node;
18512 use PHPUnitPHAR\PhpParser\Node\Expr;
18513 use PHPUnitPHAR\PhpParser\Node\Name;
18514 use PHPUnitPHAR\PhpParser\Node\Scalar;
18515 use PHPUnitPHAR\PhpParser\Node\Stmt;
18516 /* This is an automatically GENERATED file, which should not be manually edited.
18517 * Instead edit one of the following:
18518 * * the grammar file grammar/php.y
18519 * * the skeleton file grammar/parser.template
18520 * * the preprocessing script grammar/rebuildParsers.php
18521 */
18522 class Php7 extends \PHPUnitPHAR\PhpParser\ParserAbstract
18523 {
18524 public const YYERRTOK = 256;
18525 public const T_VOID_CAST = 257;
18526 public const T_THROW = 258;
18527 public const T_INCLUDE = 259;
18528 public const T_INCLUDE_ONCE = 260;
18529 public const T_EVAL = 261;
18530 public const T_REQUIRE = 262;
18531 public const T_REQUIRE_ONCE = 263;
18532 public const T_LOGICAL_OR = 264;
18533 public const T_LOGICAL_XOR = 265;
18534 public const T_LOGICAL_AND = 266;
18535 public const T_PRINT = 267;
18536 public const T_YIELD = 268;
18537 public const T_DOUBLE_ARROW = 269;
18538 public const T_YIELD_FROM = 270;
18539 public const T_PLUS_EQUAL = 271;
18540 public const T_MINUS_EQUAL = 272;
18541 public const T_MUL_EQUAL = 273;
18542 public const T_DIV_EQUAL = 274;
18543 public const T_CONCAT_EQUAL = 275;
18544 public const T_MOD_EQUAL = 276;
18545 public const T_AND_EQUAL = 277;
18546 public const T_OR_EQUAL = 278;
18547 public const T_XOR_EQUAL = 279;
18548 public const T_SL_EQUAL = 280;
18549 public const T_SR_EQUAL = 281;
18550 public const T_POW_EQUAL = 282;
18551 public const T_COALESCE_EQUAL = 283;
18552 public const T_COALESCE = 284;
18553 public const T_BOOLEAN_OR = 285;
18554 public const T_BOOLEAN_AND = 286;
18555 public const T_AMPERSAND_NOT_FOLLOWED_BY_VAR_OR_VARARG = 287;
18556 public const T_AMPERSAND_FOLLOWED_BY_VAR_OR_VARARG = 288;
18557 public const T_IS_EQUAL = 289;
18558 public const T_IS_NOT_EQUAL = 290;
18559 public const T_IS_IDENTICAL = 291;
18560 public const T_IS_NOT_IDENTICAL = 292;
18561 public const T_SPACESHIP = 293;
18562 public const T_IS_SMALLER_OR_EQUAL = 294;
18563 public const T_IS_GREATER_OR_EQUAL = 295;
18564 public const T_SL = 296;
18565 public const T_SR = 297;
18566 public const T_INSTANCEOF = 298;
18567 public const T_INC = 299;
18568 public const T_DEC = 300;
18569 public const T_INT_CAST = 301;
18570 public const T_DOUBLE_CAST = 302;
18571 public const T_STRING_CAST = 303;
18572 public const T_ARRAY_CAST = 304;
18573 public const T_OBJECT_CAST = 305;
18574 public const T_BOOL_CAST = 306;
18575 public const T_UNSET_CAST = 307;
18576 public const T_POW = 308;
18577 public const T_NEW = 309;
18578 public const T_CLONE = 310;
18579 public const T_EXIT = 311;
18580 public const T_IF = 312;
18581 public const T_ELSEIF = 313;
18582 public const T_ELSE = 314;
18583 public const T_ENDIF = 315;
18584 public const T_LNUMBER = 316;
18585 public const T_DNUMBER = 317;
18586 public const T_STRING = 318;
18587 public const T_STRING_VARNAME = 319;
18588 public const T_VARIABLE = 320;
18589 public const T_NUM_STRING = 321;
18590 public const T_INLINE_HTML = 322;
18591 public const T_ENCAPSED_AND_WHITESPACE = 323;
18592 public const T_CONSTANT_ENCAPSED_STRING = 324;
18593 public const T_ECHO = 325;
18594 public const T_DO = 326;
18595 public const T_WHILE = 327;
18596 public const T_ENDWHILE = 328;
18597 public const T_FOR = 329;
18598 public const T_ENDFOR = 330;
18599 public const T_FOREACH = 331;
18600 public const T_ENDFOREACH = 332;
18601 public const T_DECLARE = 333;
18602 public const T_ENDDECLARE = 334;
18603 public const T_AS = 335;
18604 public const T_SWITCH = 336;
18605 public const T_MATCH = 337;
18606 public const T_ENDSWITCH = 338;
18607 public const T_CASE = 339;
18608 public const T_DEFAULT = 340;
18609 public const T_BREAK = 341;
18610 public const T_CONTINUE = 342;
18611 public const T_GOTO = 343;
18612 public const T_FUNCTION = 344;
18613 public const T_FN = 345;
18614 public const T_CONST = 346;
18615 public const T_RETURN = 347;
18616 public const T_TRY = 348;
18617 public const T_CATCH = 349;
18618 public const T_FINALLY = 350;
18619 public const T_USE = 351;
18620 public const T_INSTEADOF = 352;
18621 public const T_GLOBAL = 353;
18622 public const T_STATIC = 354;
18623 public const T_ABSTRACT = 355;
18624 public const T_FINAL = 356;
18625 public const T_PRIVATE = 357;
18626 public const T_PROTECTED = 358;
18627 public const T_PUBLIC = 359;
18628 public const T_READONLY = 360;
18629 public const T_PUBLIC_SET = 361;
18630 public const T_PROTECTED_SET = 362;
18631 public const T_PRIVATE_SET = 363;
18632 public const T_VAR = 364;
18633 public const T_UNSET = 365;
18634 public const T_ISSET = 366;
18635 public const T_EMPTY = 367;
18636 public const T_HALT_COMPILER = 368;
18637 public const T_CLASS = 369;
18638 public const T_TRAIT = 370;
18639 public const T_INTERFACE = 371;
18640 public const T_ENUM = 372;
18641 public const T_EXTENDS = 373;
18642 public const T_IMPLEMENTS = 374;
18643 public const T_OBJECT_OPERATOR = 375;
18644 public const T_NULLSAFE_OBJECT_OPERATOR = 376;
18645 public const T_LIST = 377;
18646 public const T_ARRAY = 378;
18647 public const T_CALLABLE = 379;
18648 public const T_CLASS_C = 380;
18649 public const T_TRAIT_C = 381;
18650 public const T_METHOD_C = 382;
18651 public const T_FUNC_C = 383;
18652 public const T_PROPERTY_C = 384;
18653 public const T_LINE = 385;
18654 public const T_FILE = 386;
18655 public const T_START_HEREDOC = 387;
18656 public const T_END_HEREDOC = 388;
18657 public const T_DOLLAR_OPEN_CURLY_BRACES = 389;
18658 public const T_CURLY_OPEN = 390;
18659 public const T_PAAMAYIM_NEKUDOTAYIM = 391;
18660 public const T_NAMESPACE = 392;
18661 public const T_NS_C = 393;
18662 public const T_DIR = 394;
18663 public const T_NS_SEPARATOR = 395;
18664 public const T_ELLIPSIS = 396;
18665 public const T_NAME_FULLY_QUALIFIED = 397;
18666 public const T_NAME_QUALIFIED = 398;
18667 public const T_NAME_RELATIVE = 399;
18668 public const T_ATTRIBUTE = 400;
18669 protected int $tokenToSymbolMapSize = 401;
18670 protected int $actionTableSize = 1578;
18671 protected int $gotoTableSize = 698;
18672 protected int $invalidSymbol = 173;
18673 protected int $errorSymbol = 1;
18674 protected int $defaultAction = -32766;
18675 protected int $unexpectedTokenRule = 32767;
18676 protected int $YY2TBLSTATE = 445;
18677 protected int $numNonLeafStates = 754;
18678 protected array $symbolToName = array("EOF", "error", "T_VOID_CAST", "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_PUBLIC_SET", "T_PROTECTED_SET", "T_PRIVATE_SET", "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_PROPERTY_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", "';'", "']'", "'('", "')'", "'{'", "'}'", "'`'", "'\"'", "'\$'");
18679 protected array $tokenToSymbol = array(0, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 57, 171, 173, 172, 56, 173, 173, 166, 167, 54, 51, 9, 52, 53, 55, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 32, 164, 45, 17, 47, 31, 69, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 71, 173, 165, 37, 173, 170, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 168, 36, 169, 59, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 12, 13, 14, 15, 16, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 33, 34, 35, 38, 39, 40, 41, 42, 43, 44, 46, 48, 49, 50, 58, 60, 61, 62, 63, 64, 65, 66, 67, 68, 70, 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, 159, 160, 161, 162, 163);
18680 protected array $action = array(133, 134, 135, 575, 136, 137, 1049, 766, 767, 768, 138, 41, 850, -341, 495, 1390, -32766, -32766, -32766, 1008, 841, 1145, 1146, 1147, 1141, 1140, 1139, 1148, 1142, 1143, 1144, -32766, -32766, -32766, -195, 760, 759, -32766, -194, -32766, -32766, -32766, -32766, -32766, -32766, -32766, -32767, -32767, -32767, -32767, -32767, 0, -32766, 3, 4, 769, 1145, 1146, 1147, 1141, 1140, 1139, 1148, 1142, 1143, 1144, 388, 389, 448, 272, 53, 391, 773, 774, 775, 776, 433, 5, 434, 571, 337, 39, 254, 29, 298, 830, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 806, 576, 807, 808, 809, 810, 798, 799, 353, 354, 801, 802, 787, 788, 789, 791, 792, 793, 364, 833, 834, 835, 836, 837, 577, -382, 306, -382, 794, 795, 578, 579, 244, 818, 816, 817, 829, 813, 814, 1313, 38, 580, 581, 812, 582, 583, 584, 585, 1325, 586, 587, 481, 482, -628, 496, 1009, 815, 588, 589, 140, 139, -628, 133, 134, 135, 575, 136, 137, 1085, 766, 767, 768, 138, 41, -32766, -341, 1046, 1041, 1040, 1039, 1045, 1042, 1043, 1044, -32766, -32766, -32766, -32767, -32767, -32767, -32767, 106, 107, 108, 109, 110, -195, 760, 759, 1058, -194, -32766, -32766, -32766, 149, -32766, 852, -32766, -32766, -32766, -32766, -32766, -32766, -32766, 936, 303, 257, 769, -32766, -32766, -32766, 850, -32766, 297, -32766, -32766, -32766, -32766, -32766, 1371, 1355, 272, 53, 391, 773, 774, 775, 776, -625, -32766, 434, -32766, -32766, -32766, -32766, 730, -625, 830, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 806, 576, 807, 808, 809, 810, 798, 799, 353, 354, 801, 802, 787, 788, 789, 791, 792, 793, 364, 833, 834, 835, 836, 837, 577, -579, -275, 317, 794, 795, 578, 579, -577, 818, 816, 817, 829, 813, 814, 957, 926, 580, 581, 812, 582, 583, 584, 585, 144, 586, 587, 841, 336, -32766, -32766, -32766, 815, 588, 589, -628, 139, -628, 133, 134, 135, 575, 136, 137, 1082, 766, 767, 768, 138, 41, -32766, 1375, -32766, -32766, -32766, -32766, -32766, -32766, -32766, 1374, 629, 388, 389, -32766, -32766, -32766, -32766, -32766, -579, -579, 1081, 433, 321, 760, 759, -577, -577, -32766, 1293, -32766, -32766, 111, 112, 113, -579, 282, 843, 851, 623, 1400, 936, -577, 1401, 769, 333, 938, -585, 114, -579, 725, 294, 298, 1119, -584, 349, -577, 752, 272, 53, 391, 773, 774, 775, 776, 145, 86, 434, 306, 336, 336, -625, 731, -625, 830, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 806, 576, 807, 808, 809, 810, 798, 799, 353, 354, 801, 802, 787, 788, 789, 791, 792, 793, 364, 833, 834, 835, 836, 837, 577, -576, 850, -578, 794, 795, 578, 579, 845, 818, 816, 817, 829, 813, 814, 727, 926, 580, 581, 812, 582, 583, 584, 585, 740, 586, 587, 243, 1055, -32766, -32766, -85, 815, 588, 589, 878, 152, 879, 133, 134, 135, 575, 136, 137, 1087, 766, 767, 768, 138, 41, 350, 961, 960, 1058, 1058, 1058, -32766, -32766, -32766, 841, -32766, 131, 977, 978, 400, 1055, 10, 979, -576, -576, -578, -578, 378, 760, 759, 936, 973, 290, 297, 297, -32766, 846, 936, 154, -576, 79, -578, 382, 849, 936, 1058, 336, 878, 769, 879, 938, -583, -85, -576, 725, -578, 959, 108, 109, 110, 1058, 732, 272, 53, 391, 773, 774, 775, 776, 290, 155, 434, 470, 471, 472, 735, 760, 759, 830, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 806, 576, 807, 808, 809, 810, 798, 799, 353, 354, 801, 802, 787, 788, 789, 791, 792, 793, 364, 833, 834, 835, 836, 837, 577, 926, 434, 847, 794, 795, 578, 579, 926, 818, 816, 817, 829, 813, 814, 926, 398, 580, 581, 812, 582, 583, 584, 585, 452, 586, 587, 157, 87, 88, 89, 453, 815, 588, 589, 454, 152, 790, 761, 762, 763, 764, 765, 158, 766, 767, 768, 803, 804, 40, 27, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 1134, 282, 1055, 455, -32766, 994, 1288, 1287, 1289, 725, 390, 389, 938, 114, 856, 1120, 725, 769, 159, 938, 433, 672, 23, 725, 1118, 691, 692, 1058, -32766, 153, 416, 770, 771, 772, 773, 774, 775, 776, -78, -619, 839, -619, -581, 386, 387, 392, 393, 830, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 806, 828, 807, 808, 809, 810, 798, 799, 800, 827, 801, 802, 787, 788, 789, 791, 792, 793, 832, 833, 834, 835, 836, 837, 838, 161, 663, 664, 794, 795, 796, 797, 36, 818, 816, 817, 829, 813, 814, -58, -57, 805, 811, 812, 819, 820, 822, 821, -87, 823, 824, -581, -581, 128, 129, 141, 815, 826, 825, 54, 55, 56, 57, 527, 58, 59, 142, -110, 148, 162, 60, 61, -110, 62, -110, 936, 163, 164, 165, 313, 166, -581, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, 1293, -84, 953, -78, -73, -72, -71, -70, -69, -68, -67, -66, -65, 742, -46, 63, 64, -18, -575, 1286, 146, 65, 51, 66, 251, 252, 67, 68, 69, 70, 71, 72, 73, 74, 281, 31, 273, 47, 450, 528, 291, -357, 741, 1319, 1320, 529, 744, 850, 935, 151, 295, 1317, 45, 22, 530, 1284, 531, -309, 532, -305, 533, 286, 936, 534, 535, 287, 926, 292, 48, 49, 456, 385, 384, 293, 50, 536, 342, 296, 282, 1057, 376, 348, 850, 299, 300, -575, -575, 1279, 114, 307, 308, 701, 538, 539, 540, 150, 841, -32766, 1288, 1287, 1289, -575, 850, 294, 542, 543, 1402, 1305, 1306, 1307, 1308, 1310, 1302, 1303, 305, -575, 716, -110, -110, 130, 1309, 1304, -110, 593, 1288, 1287, 1289, 306, 13, 673, 75, -110, 1152, 678, 331, 332, 336, -154, -154, -154, -32766, 718, 694, -4, 936, 938, 926, 314, 478, 725, 506, 1324, -154, 705, -154, 679, -154, 695, -154, 974, 1326, -541, 306, 312, 311, 79, 849, 661, 383, 43, 320, 336, 37, 1252, 0, 0, 52, 0, 0, 977, 978, 0, 760, 759, 537, -32766, 0, 0, 0, 706, 0, 0, 912, 973, -110, -110, -110, 35, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, -531, 11, 707, 708, 31, 274, 30, 380, 955, 599, -613, 306, 627, 0, 938, 0, 850, 926, 725, -154, 1317, 1288, 1287, 1289, 44, -612, 749, 290, 750, 1194, 1196, 869, 309, 310, 917, 1018, 995, 1002, 992, 383, -575, 446, 1003, 915, 990, 1123, 304, 1126, 381, 1127, 977, 978, 1124, 1125, 1131, 537, 1279, 1314, 861, 330, 760, 759, 132, 541, 973, -110, -110, -110, 1341, 1359, 1393, 1293, 666, 542, 543, -611, 1305, 1306, 1307, 1308, 1310, 1302, 1303, -585, -584, -583, -582, 21, -525, 1309, 1304, 1, 32, 760, 759, 33, 938, -32766, -278, 77, 725, -4, -16, 1286, 332, 336, 42, -575, -575, 46, -32766, -32766, -32766, 76, -32766, 80, -32766, 81, -32766, 82, 83, -32766, 84, -575, 85, 147, -32766, -32766, -32766, 156, -32766, 160, -32766, -32766, 249, 379, 1286, -575, -32766, 430, 31, 273, 338, -32766, -32766, -32766, 365, -32766, 366, -32766, -32766, -32766, 850, 850, -32766, 367, 1317, 368, 369, -32766, -32766, -32766, 370, 371, 372, -32766, -32766, 373, 374, 375, 377, -32766, 430, 447, 570, 31, 274, -276, -275, 15, 16, 78, 17, -32766, 18, 20, 414, 850, -110, -110, 497, 1317, 1279, -110, 498, 505, 508, 509, 510, 511, 515, 516, -110, 517, 525, 604, 711, 1088, 1084, 1234, 543, -32766, 1305, 1306, 1307, 1308, 1310, 1302, 1303, 1315, 1086, 1083, -50, 1064, 1274, 1309, 1304, 1279, 1060, -280, -102, 14, 19, 306, 24, 77, 79, 415, 303, 413, 332, 336, 336, 618, 624, 543, 652, 1305, 1306, 1307, 1308, 1310, 1302, 1303, 717, 143, 1238, 1292, 1235, 1372, 1309, 1304, 726, 729, 733, -32766, 734, 736, 737, 738, 77, 1286, 419, 739, 743, 332, 336, 728, -32766, -32766, -32766, 746, -32766, 913, -32766, 1397, -32766, 1399, 872, -32766, 871, 967, 1010, 1398, -32766, -32766, -32766, 966, -32766, 964, -32766, -32766, 965, 968, 1286, 1267, -32766, 430, 946, 956, 944, -32766, -32766, -32766, 1000, -32766, 1001, -32766, -32766, -32766, 650, 1396, -32766, 1353, 1342, 1360, 1369, -32766, -32766, -32766, 1318, -32766, 336, -32766, -32766, 936, 0, 1286, 0, -32766, 430, 0, 0, 0, -32766, -32766, -32766, 0, -32766, 0, -32766, -32766, -32766, 0, 0, -32766, 0, 0, 936, 0, -32766, -32766, -32766, 0, -32766, 0, -32766, -32766, 0, 0, 1286, 0, -32766, 430, 0, 0, 0, -32766, -32766, -32766, 0, -32766, 0, -32766, -32766, -32766, 0, 0, -32766, 0, 0, 0, 501, -32766, -32766, -32766, 0, -32766, 0, -32766, -32766, 0, 0, 1286, 606, -32766, 430, 0, 0, 0, -32766, -32766, -32766, 0, -32766, 0, -32766, -32766, -32766, 926, 0, -32766, 2, 0, 0, 0, -32766, -32766, -32766, 0, 0, 0, -32766, -32766, 0, -253, -253, -253, -32766, 430, 0, 383, 926, 0, 0, 0, 0, 0, 0, 0, -32766, 0, 977, 978, 0, 0, 0, 537, -252, -252, -252, 0, 0, 0, 383, 912, 973, -110, -110, -110, 0, 0, 0, 0, 0, 977, 978, 0, 0, 0, 537, 0, 0, 0, 0, 0, 0, 0, 912, 973, -110, -110, -110, -32766, 0, 0, 0, 0, 938, 1286, 0, 0, 725, -253, 0, 0, -32766, -32766, -32766, 0, -32766, 0, -32766, 0, -32766, 0, 0, -32766, 0, 0, 0, 938, -32766, -32766, -32766, 725, -252, 0, -32766, -32766, 0, 0, 0, 0, -32766, 430, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -32766);
18681 protected array $actionCheck = array(3, 4, 5, 6, 7, 8, 1, 10, 11, 12, 13, 14, 83, 9, 32, 86, 10, 11, 12, 32, 81, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 10, 11, 12, 9, 38, 39, 31, 9, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 0, 31, 9, 9, 58, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 107, 108, 109, 72, 73, 74, 75, 76, 77, 78, 117, 9, 81, 86, 71, 152, 153, 9, 31, 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, 107, 163, 109, 127, 128, 129, 130, 15, 132, 133, 134, 135, 136, 137, 1, 9, 140, 141, 142, 143, 144, 145, 146, 151, 148, 149, 138, 139, 1, 168, 164, 155, 156, 157, 9, 159, 9, 3, 4, 5, 6, 7, 8, 167, 10, 11, 12, 13, 14, 117, 167, 119, 120, 121, 122, 123, 124, 125, 126, 10, 11, 12, 45, 46, 47, 48, 49, 50, 51, 52, 53, 167, 38, 39, 142, 167, 10, 11, 12, 9, 31, 1, 33, 34, 35, 36, 37, 38, 39, 1, 167, 9, 58, 10, 11, 12, 83, 31, 166, 33, 34, 35, 36, 37, 1, 1, 72, 73, 74, 75, 76, 77, 78, 1, 31, 81, 33, 34, 35, 36, 32, 9, 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, 71, 167, 9, 127, 128, 129, 130, 71, 132, 133, 134, 135, 136, 137, 1, 85, 140, 141, 142, 143, 144, 145, 146, 168, 148, 149, 81, 172, 10, 11, 12, 155, 156, 157, 165, 159, 167, 3, 4, 5, 6, 7, 8, 167, 10, 11, 12, 13, 14, 31, 1, 33, 34, 35, 10, 10, 11, 12, 9, 52, 107, 108, 10, 11, 12, 10, 11, 138, 139, 1, 117, 9, 38, 39, 138, 139, 31, 1, 33, 34, 54, 55, 56, 154, 58, 81, 164, 1, 81, 1, 154, 84, 58, 9, 164, 166, 70, 168, 168, 31, 31, 164, 166, 9, 168, 168, 72, 73, 74, 75, 76, 77, 78, 168, 168, 81, 163, 172, 172, 165, 32, 167, 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, 71, 83, 71, 127, 128, 129, 130, 161, 132, 133, 134, 135, 136, 137, 168, 85, 140, 141, 142, 143, 144, 145, 146, 168, 148, 149, 98, 117, 117, 117, 32, 155, 156, 157, 107, 159, 109, 3, 4, 5, 6, 7, 8, 167, 10, 11, 12, 13, 14, 9, 73, 74, 142, 142, 142, 10, 11, 12, 81, 141, 15, 118, 119, 107, 117, 109, 123, 138, 139, 138, 139, 9, 38, 39, 1, 132, 166, 166, 166, 117, 81, 1, 15, 154, 166, 154, 9, 160, 1, 142, 172, 107, 58, 109, 164, 166, 98, 168, 168, 168, 123, 51, 52, 53, 142, 32, 72, 73, 74, 75, 76, 77, 78, 166, 15, 81, 133, 134, 135, 32, 38, 39, 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, 85, 81, 161, 127, 128, 129, 130, 85, 132, 133, 134, 135, 136, 137, 85, 9, 140, 141, 142, 143, 144, 145, 146, 9, 148, 149, 15, 10, 11, 12, 9, 155, 156, 157, 9, 159, 3, 4, 5, 6, 7, 8, 15, 10, 11, 12, 13, 14, 31, 102, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 127, 58, 117, 9, 117, 164, 160, 161, 162, 168, 107, 108, 164, 70, 9, 169, 168, 58, 15, 164, 117, 76, 77, 168, 1, 76, 77, 142, 141, 102, 103, 72, 73, 74, 75, 76, 77, 78, 17, 165, 81, 167, 71, 107, 108, 107, 108, 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, 15, 112, 113, 127, 128, 129, 130, 15, 132, 133, 134, 135, 136, 137, 17, 17, 140, 141, 142, 143, 144, 145, 146, 32, 148, 149, 138, 139, 17, 17, 17, 155, 156, 157, 2, 3, 4, 5, 6, 7, 8, 17, 102, 17, 17, 13, 14, 107, 16, 109, 1, 17, 17, 17, 114, 17, 168, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 1, 32, 39, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 51, 52, 32, 71, 81, 32, 57, 71, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 32, 71, 72, 73, 74, 75, 32, 169, 32, 79, 80, 81, 32, 83, 32, 32, 38, 87, 88, 89, 90, 117, 92, 36, 94, 36, 96, 36, 1, 99, 100, 36, 85, 36, 104, 105, 106, 107, 108, 36, 110, 111, 36, 38, 58, 141, 116, 117, 83, 38, 38, 138, 139, 123, 70, 138, 139, 78, 128, 129, 130, 71, 81, 86, 160, 161, 162, 154, 83, 31, 140, 141, 84, 143, 144, 145, 146, 147, 148, 149, 150, 168, 81, 118, 119, 168, 156, 157, 123, 90, 160, 161, 162, 163, 98, 91, 166, 132, 83, 97, 170, 171, 172, 76, 77, 78, 141, 93, 95, 0, 1, 164, 85, 115, 98, 168, 98, 151, 91, 81, 93, 101, 95, 101, 97, 132, 151, 154, 163, 137, 136, 166, 160, 114, 107, 164, 136, 172, 168, 170, -1, -1, 71, -1, -1, 118, 119, -1, 38, 39, 123, 141, -1, -1, -1, 117, -1, -1, 131, 132, 133, 134, 135, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 154, 154, 141, 142, 71, 72, 154, 154, 159, 158, 166, 163, 158, -1, 164, -1, 83, 85, 168, 169, 87, 160, 161, 162, 164, 166, 164, 166, 164, 60, 61, 164, 138, 139, 164, 164, 164, 164, 164, 107, 71, 109, 164, 164, 164, 164, 114, 164, 154, 164, 118, 119, 164, 164, 164, 123, 123, 165, 165, 168, 38, 39, 168, 131, 132, 133, 134, 135, 165, 165, 165, 1, 165, 140, 141, 166, 143, 144, 145, 146, 147, 148, 149, 166, 166, 166, 166, 155, 166, 156, 157, 166, 166, 38, 39, 166, 164, 75, 167, 166, 168, 169, 32, 81, 171, 172, 166, 138, 139, 166, 88, 89, 90, 166, 92, 166, 94, 166, 96, 166, 166, 99, 166, 154, 166, 166, 104, 105, 106, 166, 75, 166, 110, 111, 166, 168, 81, 168, 116, 117, 71, 72, 166, 88, 89, 90, 166, 92, 166, 94, 128, 96, 83, 83, 99, 166, 87, 166, 166, 104, 105, 106, 166, 166, 166, 110, 111, 166, 166, 166, 166, 116, 117, 166, 166, 71, 72, 167, 167, 167, 167, 159, 167, 128, 167, 167, 167, 83, 118, 119, 167, 87, 123, 123, 167, 167, 167, 167, 167, 167, 167, 167, 132, 167, 167, 167, 167, 167, 167, 167, 141, 141, 143, 144, 145, 146, 147, 148, 149, 167, 167, 167, 32, 167, 167, 156, 157, 123, 167, 167, 167, 167, 167, 163, 167, 166, 166, 169, 167, 167, 171, 172, 172, 167, 167, 141, 167, 143, 144, 145, 146, 147, 148, 149, 167, 32, 167, 167, 167, 167, 156, 157, 168, 168, 168, 75, 168, 168, 168, 168, 166, 81, 169, 168, 168, 171, 172, 168, 88, 89, 90, 169, 92, 169, 94, 169, 96, 169, 169, 99, 169, 169, 169, 169, 104, 105, 106, 169, 75, 169, 110, 111, 169, 169, 81, 169, 116, 117, 169, 169, 169, 88, 89, 90, 169, 92, 169, 94, 128, 96, 169, 169, 99, 169, 169, 169, 169, 104, 105, 106, 171, 75, 172, 110, 111, 1, -1, 81, -1, 116, 117, -1, -1, -1, 88, 89, 90, -1, 92, -1, 94, 128, 96, -1, -1, 99, -1, -1, 1, -1, 104, 105, 106, -1, 75, -1, 110, 111, -1, -1, 81, -1, 116, 117, -1, -1, -1, 88, 89, 90, -1, 92, -1, 94, 128, 96, -1, -1, 99, -1, -1, -1, 103, 104, 105, 106, -1, 75, -1, 110, 111, -1, -1, 81, 82, 116, 117, -1, -1, -1, 88, 89, 90, -1, 92, -1, 94, 128, 96, 85, -1, 99, 166, -1, -1, -1, 104, 105, 106, -1, -1, -1, 110, 111, -1, 101, 102, 103, 116, 117, -1, 107, 85, -1, -1, -1, -1, -1, -1, -1, 128, -1, 118, 119, -1, -1, -1, 123, 101, 102, 103, -1, -1, -1, 107, 131, 132, 133, 134, 135, -1, -1, -1, -1, -1, 118, 119, -1, -1, -1, 123, -1, -1, -1, -1, -1, -1, -1, 131, 132, 133, 134, 135, 75, -1, -1, -1, -1, 164, 81, -1, -1, 168, 169, -1, -1, 88, 89, 90, -1, 92, -1, 94, -1, 96, -1, -1, 99, -1, -1, -1, 164, 104, 105, 106, 168, 169, -1, 110, 111, -1, -1, -1, -1, 116, 117, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 128);
18682 protected array $actionBase = array(0, 155, -3, 313, 471, 471, 881, 963, 1365, 1388, 892, 134, 515, -61, 367, 524, 524, 801, 524, 209, 510, 283, 517, 517, 517, 920, 855, 628, 628, 855, 628, 1053, 1053, 1053, 1053, 1086, 1086, 1320, 1320, 1353, 1254, 1221, 1449, 1449, 1449, 1449, 1449, 1287, 1449, 1449, 1449, 1449, 1449, 1287, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 201, -13, 44, 365, 744, 1102, 1120, 1107, 1121, 1096, 1095, 1103, 1108, 1122, 1183, 1185, 837, 1186, 1187, 1182, 1188, 1110, 938, 1098, 1118, 612, 612, 612, 612, 612, 612, 612, 612, 612, 612, 612, 612, 612, 612, 612, 612, 612, 612, 612, 612, 612, 612, 612, 612, 612, 612, 612, 612, 323, 482, 334, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 964, 964, 21, 21, 21, 324, 1135, 1100, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 297, 204, 1000, 187, 170, 170, 6, 6, 6, 6, 6, 692, 53, 1101, 819, 819, 138, 138, 138, 138, 542, 14, 347, 355, -41, 348, 232, 384, 384, 487, 487, 554, 554, 349, 349, 554, 554, 554, 399, 399, 399, 399, 208, 215, 366, 364, -7, 864, 224, 224, 224, 224, 864, 864, 864, 864, 829, 1190, 864, 1011, 1027, 864, 864, 368, 767, 767, 925, 305, 305, 305, 767, 421, -71, -71, 421, 380, -71, 225, 286, 556, 847, 572, 543, 556, 640, 771, 233, 148, 826, 605, 826, 1094, 831, 831, 802, 792, 921, 1140, 1123, 874, 1176, 876, 1178, 420, 9, 791, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1191, 519, 1094, 436, 1191, 1191, 1191, 519, 519, 519, 519, 519, 519, 519, 519, 805, 519, 519, 641, 436, 614, 618, 436, 860, 519, 877, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, -18, 201, 201, -13, 292, 292, 201, 216, 5, 292, 292, 292, 292, 201, 201, 201, 201, 605, 840, 882, 607, 435, 885, 29, 840, 840, 840, 4, 113, 25, 841, 843, 393, 835, 835, 835, 869, 956, 956, 835, 839, 835, 869, 835, 835, 956, 956, 879, 956, 146, 609, 373, 514, 616, 956, 272, 835, 835, 835, 835, 854, 956, 45, 68, 620, 835, 203, 191, 835, 835, 854, 848, 828, 846, 956, 956, 956, 854, 499, 846, 846, 846, 893, 895, 873, 822, 363, 341, 674, 127, 783, 822, 822, 835, 601, 873, 822, 873, 822, 880, 822, 822, 822, 873, 822, 839, 477, 822, 779, 786, 663, 74, 822, 51, 978, 980, 743, 982, 971, 984, 1038, 985, 987, 1125, 953, 999, 974, 989, 1039, 960, 957, 836, 763, 764, 878, 827, 951, 838, 838, 838, 948, 949, 838, 838, 838, 838, 838, 838, 838, 838, 763, 923, 884, 853, 1013, 765, 776, 1069, 820, 1145, 823, 1011, 978, 987, 789, 974, 989, 960, 957, 800, 799, 797, 798, 796, 795, 793, 794, 808, 1071, 1072, 990, 825, 778, 1049, 1020, 1143, 922, 1022, 1023, 1050, 1073, 898, 1083, 1147, 844, 1149, 1150, 924, 1028, 1126, 838, 940, 875, 934, 1027, 950, 763, 935, 1084, 1085, 1043, 824, 1054, 1058, 998, 870, 842, 936, 1152, 1029, 1032, 1033, 1127, 1129, 891, 1044, 962, 1059, 872, 1099, 1060, 1061, 1062, 1063, 1130, 1153, 1131, 890, 1132, 901, 858, 1041, 856, 1154, 504, 851, 857, 866, 1035, 536, 1007, 1136, 1134, 1155, 1064, 1065, 1067, 1159, 1161, 994, 902, 1046, 867, 1048, 1042, 903, 904, 606, 865, 1087, 845, 849, 859, 622, 672, 1164, 1165, 1167, 996, 830, 833, 905, 909, 1088, 832, 1092, 1170, 737, 910, 1171, 1070, 787, 788, 690, 750, 749, 790, 868, 1137, 883, 852, 850, 1034, 788, 834, 911, 1172, 912, 914, 916, 1068, 919, 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, 784, 784, 784, 784, 784, 784, 784, 784, 784, 628, 628, 628, 628, 784, 784, 784, 784, 784, 784, 784, 628, 784, 784, 784, 628, 628, 0, 0, 628, 0, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 612, 612, 612, 612, 612, 612, 612, 612, 612, 612, 612, 612, 612, 612, 612, 612, 612, 612, 612, 612, 612, 612, 612, 612, 612, 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, 612, 612, 612, 612, 612, 612, 612, 612, 612, 612, 612, 612, 612, 612, 612, 612, 612, 612, 612, 612, 612, 612, 612, 758, 758, 612, 612, 612, 612, 758, 758, 758, 758, 758, 758, 758, 758, 758, 758, 612, 612, 0, 612, 612, 612, 612, 612, 612, 612, 612, 879, 758, 758, 758, 758, 305, 305, 305, 305, -96, -96, 758, 758, 380, 758, 380, 758, 758, 305, 305, 758, 758, 758, 758, 758, 758, 758, 758, 758, 758, 758, 0, 0, 0, 436, -71, 758, 839, 839, 839, 839, 758, 758, 758, 758, -71, -71, 758, 414, 414, 758, 758, 0, 0, 0, 0, 0, 0, 0, 0, 436, 0, 0, 436, 0, 0, 839, 839, 758, 380, 879, 328, 758, 0, 0, 0, 0, 436, 839, 436, 519, -71, -71, 519, 519, 292, 201, 328, 596, 596, 596, 596, 0, 0, 605, 879, 879, 879, 879, 879, 879, 879, 879, 879, 879, 879, 839, 0, 879, 0, 839, 839, 839, 0, 0, 0, 0, 0, 0, 0, 0, 956, 0, 0, 0, 0, 0, 0, 0, 839, 0, 956, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 839, 0, 0, 0, 0, 0, 0, 0, 0, 0, 838, 870, 0, 0, 870, 0, 838, 838, 838, 0, 0, 0, 865, 832);
18683 protected array $actionDefault = array(3, 32767, 32767, 32767, 102, 102, 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, 631, 631, 631, 631, 32767, 32767, 257, 102, 32767, 32767, 500, 415, 415, 415, 32767, 32767, 32767, 573, 573, 573, 573, 573, 17, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 500, 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, 36, 7, 8, 10, 11, 49, 338, 100, 32767, 32767, 32767, 32767, 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, 624, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 403, 494, 504, 482, 483, 485, 486, 414, 574, 630, 344, 627, 342, 413, 146, 354, 343, 245, 261, 505, 262, 506, 509, 510, 218, 400, 150, 151, 446, 501, 448, 499, 503, 447, 420, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 418, 419, 502, 32767, 32767, 479, 478, 477, 444, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 102, 32767, 445, 449, 417, 452, 450, 451, 468, 469, 466, 467, 470, 32767, 323, 32767, 32767, 32767, 471, 472, 473, 474, 381, 379, 32767, 32767, 111, 323, 111, 32767, 32767, 459, 460, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 517, 567, 476, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 102, 32767, 32767, 32767, 100, 569, 441, 443, 537, 454, 455, 453, 421, 32767, 542, 32767, 102, 32767, 544, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 568, 32767, 575, 575, 32767, 530, 100, 196, 32767, 543, 196, 196, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 638, 530, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 32767, 196, 110, 32767, 32767, 32767, 100, 196, 196, 196, 196, 196, 196, 196, 196, 545, 196, 196, 191, 32767, 271, 273, 102, 592, 196, 547, 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, 530, 464, 139, 32767, 532, 139, 575, 456, 457, 458, 575, 575, 575, 319, 296, 32767, 32767, 32767, 32767, 32767, 545, 545, 100, 100, 100, 100, 32767, 32767, 32767, 32767, 111, 516, 99, 99, 99, 99, 99, 103, 101, 32767, 32767, 32767, 32767, 226, 32767, 101, 101, 99, 32767, 101, 101, 32767, 32767, 226, 228, 215, 230, 32767, 596, 597, 226, 101, 230, 230, 230, 250, 250, 519, 325, 101, 99, 101, 101, 198, 325, 325, 32767, 101, 519, 325, 519, 325, 200, 325, 325, 325, 519, 325, 32767, 101, 325, 217, 403, 99, 99, 325, 32767, 32767, 32767, 532, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 225, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 562, 32767, 580, 594, 462, 463, 465, 579, 577, 487, 488, 489, 490, 491, 492, 493, 496, 626, 32767, 536, 32767, 32767, 32767, 353, 32767, 636, 32767, 32767, 32767, 9, 74, 525, 42, 43, 51, 57, 551, 552, 553, 554, 548, 549, 555, 550, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 637, 32767, 575, 32767, 32767, 32767, 32767, 461, 557, 602, 32767, 32767, 576, 629, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 139, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 562, 32767, 137, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 558, 32767, 32767, 32767, 575, 32767, 32767, 32767, 32767, 321, 318, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 575, 32767, 32767, 32767, 32767, 32767, 298, 32767, 315, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 399, 532, 301, 303, 304, 32767, 32767, 32767, 32767, 375, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 153, 153, 3, 3, 356, 153, 153, 153, 356, 356, 153, 356, 356, 356, 153, 153, 153, 153, 153, 153, 283, 186, 265, 268, 250, 250, 153, 367, 153);
18684 protected array $goto = array(202, 169, 202, 202, 202, 1056, 842, 712, 359, 670, 671, 598, 688, 689, 690, 748, 653, 655, 591, 929, 675, 930, 1090, 721, 699, 702, 1028, 710, 719, 1024, 171, 171, 171, 171, 226, 203, 199, 199, 181, 183, 221, 199, 199, 199, 199, 199, 1180, 200, 200, 200, 200, 200, 1180, 193, 194, 195, 196, 197, 198, 223, 221, 224, 550, 551, 431, 552, 555, 556, 557, 558, 559, 560, 561, 562, 172, 173, 174, 201, 175, 176, 177, 170, 178, 179, 180, 182, 220, 222, 225, 245, 248, 259, 260, 262, 263, 264, 265, 266, 267, 268, 269, 275, 276, 277, 278, 288, 289, 326, 327, 328, 437, 438, 439, 613, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 184, 242, 185, 194, 195, 196, 197, 198, 223, 204, 205, 206, 207, 246, 186, 187, 208, 188, 209, 205, 189, 247, 204, 168, 210, 211, 190, 212, 213, 214, 191, 215, 216, 192, 217, 218, 219, 285, 283, 285, 285, 870, 1089, 1091, 1094, 615, 255, 255, 255, 255, 255, 441, 677, 614, 1130, 884, 867, 436, 329, 323, 324, 345, 608, 440, 346, 442, 654, 724, 492, 521, 715, 896, 1128, 993, 883, 494, 253, 253, 253, 253, 250, 256, 489, 1361, 1362, 1386, 1386, 925, 920, 921, 934, 876, 922, 873, 923, 924, 874, 877, 363, 928, 881, 480, 480, 868, 880, 1386, 848, 474, 363, 363, 480, 1117, 1112, 1113, 1114, 1229, 351, 362, 362, 362, 362, 1389, 1389, 429, 363, 363, 1017, 902, 363, 989, 1403, 747, 360, 361, 566, 1026, 1021, 1056, 1285, 1285, 1285, 569, 352, 351, 363, 363, 605, 1056, 1285, 848, 1056, 848, 1056, 1056, 1137, 1138, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 357, 1261, 962, 637, 674, 1285, 1262, 1265, 963, 1266, 1285, 1285, 1285, 1285, 1376, 435, 1285, 628, 402, 1285, 1285, 1368, 1368, 1368, 1368, 1347, 574, 567, 1062, 1061, 1059, 1059, 958, 958, 697, 970, 1014, 942, 1051, 1067, 1068, 943, 565, 565, 565, 603, 513, 522, 514, 863, 676, 863, 565, 709, 520, 1176, 318, 567, 574, 600, 601, 319, 611, 617, 844, 633, 634, 1080, 8, 709, 9, 449, 709, 28, 1065, 1066, 467, 335, 316, 569, 698, 987, 987, 987, 987, 1363, 1364, 467, 639, 639, 981, 988, 609, 631, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1335, 1335, 863, 469, 682, 469, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 347, 258, 258, 626, 640, 643, 644, 645, 646, 667, 668, 669, 723, 632, 460, 860, 460, 460, 460, 1358, 1358, 1358, 553, 553, 1278, 985, 420, 720, 553, 1358, 553, 553, 553, 553, 553, 553, 553, 553, 451, 889, 568, 595, 568, 647, 649, 651, 568, 976, 595, 411, 405, 473, 886, 1276, 1370, 1370, 1370, 1370, 909, 866, 909, 909, 1036, 483, 612, 484, 485, 751, 563, 563, 563, 563, 894, 619, 1101, 1394, 1395, 412, 1332, 1332, 898, 490, 1151, 1354, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 279, 1105, 334, 334, 334, 998, 892, 0, 1280, 1047, 0, 0, 863, 0, 0, 460, 460, 460, 460, 460, 460, 460, 460, 460, 460, 460, 0, 0, 460, 1103, 554, 554, 0, 1356, 1356, 1103, 554, 554, 554, 554, 554, 554, 554, 554, 554, 554, 621, 622, 417, 418, 947, 1166, 0, 686, 0, 687, 0, 422, 423, 424, 0, 700, 1033, 0, 425, 1281, 1282, 0, 1268, 355, 888, 0, 680, 1012, 858, 0, 0, 0, 882, 443, 0, 1268, 0, 897, 885, 1100, 1104, 0, 0, 0, 1275, 0, 443, 0, 1283, 1344, 1345, 996, 0, 0, 1063, 1063, 0, 0, 0, 681, 1074, 1070, 1071, 404, 407, 616, 620, 0, 0, 0, 0, 0, 0, 0, 986, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1149, 901, 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, 1031, 1031);
18685 protected array $gotoCheck = array(42, 42, 42, 42, 42, 73, 6, 73, 97, 86, 86, 48, 86, 86, 86, 48, 48, 48, 127, 65, 48, 65, 131, 9, 48, 48, 48, 48, 48, 48, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 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, 130, 130, 130, 134, 5, 5, 5, 5, 5, 66, 66, 8, 8, 35, 26, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 8, 84, 8, 8, 35, 8, 49, 35, 84, 5, 5, 5, 5, 5, 5, 185, 185, 185, 191, 191, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 14, 15, 15, 157, 157, 27, 15, 191, 12, 159, 14, 14, 157, 15, 15, 15, 15, 159, 177, 24, 24, 24, 24, 191, 191, 43, 14, 14, 50, 45, 14, 50, 14, 50, 97, 97, 50, 50, 50, 73, 73, 73, 73, 14, 177, 177, 14, 14, 181, 73, 73, 12, 73, 12, 73, 73, 148, 148, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 188, 79, 79, 56, 56, 73, 79, 79, 79, 79, 73, 73, 73, 73, 190, 13, 73, 13, 62, 73, 73, 9, 9, 9, 9, 14, 76, 76, 119, 119, 89, 89, 9, 9, 89, 89, 103, 73, 89, 89, 89, 73, 19, 19, 19, 104, 163, 14, 163, 22, 64, 22, 19, 7, 163, 158, 76, 76, 76, 76, 76, 76, 76, 76, 7, 76, 76, 115, 46, 7, 46, 113, 7, 76, 120, 120, 19, 178, 178, 14, 117, 19, 19, 19, 19, 187, 187, 19, 108, 108, 19, 19, 2, 2, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 179, 179, 22, 83, 121, 83, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 29, 5, 5, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 80, 23, 18, 23, 23, 23, 134, 134, 134, 165, 165, 14, 93, 93, 93, 165, 134, 165, 165, 165, 165, 165, 165, 165, 165, 83, 39, 9, 9, 9, 85, 85, 85, 9, 92, 9, 28, 9, 9, 37, 169, 134, 134, 134, 134, 25, 25, 25, 25, 110, 9, 9, 9, 9, 99, 107, 107, 107, 107, 9, 107, 133, 9, 9, 31, 180, 180, 41, 160, 151, 134, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 24, 136, 24, 24, 24, 96, 9, -1, 20, 114, -1, -1, 22, -1, -1, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, -1, -1, 23, 134, 182, 182, -1, 134, 134, 134, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 17, 17, 82, 82, 17, 17, -1, 82, -1, 82, -1, 82, 82, 82, -1, 82, 17, -1, 82, 20, 20, -1, 20, 82, 17, -1, 17, 17, 20, -1, -1, -1, 17, 118, -1, 20, -1, 16, 16, 16, 16, -1, -1, -1, 17, -1, 118, -1, 20, 20, 20, 16, -1, -1, 118, 118, -1, -1, -1, 118, 118, 118, 118, 59, 59, 59, 59, -1, -1, -1, -1, -1, -1, -1, 16, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 16, 16, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -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);
18686 protected array $gotoBase = array(0, 0, -339, 0, 0, 174, -7, 339, 171, 10, 0, 0, -69, -36, -78, -186, 130, 81, 114, 66, 117, 0, 62, 160, 240, 468, 178, 225, 118, 112, 0, 45, 0, 0, 0, -195, 0, 119, 0, 122, 0, 44, -1, 226, 0, 227, -387, 0, -715, 182, 241, 0, 0, 0, 0, 0, 256, 0, 0, 570, 0, 0, 269, 0, 102, 3, -63, 0, 0, 0, 0, 0, 0, -5, 0, 0, -31, 0, 0, -120, 110, 53, 54, 120, -286, -33, -724, 0, 0, 40, 0, 0, 124, 129, 0, 0, 61, -488, 0, 67, 0, 0, 0, 294, 295, 0, 0, 453, 141, 0, 100, 0, 0, 83, -3, 82, 0, 86, 318, 38, 78, 107, 0, 0, 0, 0, 0, 16, 0, 0, 168, 20, 0, 108, 163, 0, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 43, 0, 0, 0, 0, 0, 193, 101, -38, 46, 0, 0, -166, 0, 195, 0, 0, 0, 92, 0, 0, 0, 0, 0, 0, 0, -60, 42, 157, 251, 243, 297, 0, 0, -97, 0, 1, 263, 0, 276, -101, 0, 0);
18687 protected array $gotoDefault = array(-32768, 526, 755, 7, 756, 951, 831, 840, 590, 544, 722, 356, 641, 432, 1352, 927, 1165, 610, 859, 1294, 1300, 468, 862, 340, 745, 939, 910, 911, 408, 395, 875, 406, 665, 642, 507, 895, 464, 887, 499, 890, 463, 899, 167, 428, 524, 903, 6, 906, 572, 937, 991, 396, 914, 397, 693, 916, 594, 918, 919, 403, 409, 410, 1170, 602, 638, 931, 261, 596, 932, 394, 933, 941, 399, 401, 703, 479, 518, 512, 421, 1132, 597, 625, 662, 457, 486, 636, 648, 635, 493, 444, 426, 339, 975, 983, 500, 477, 997, 358, 1005, 753, 1178, 656, 502, 1013, 657, 1020, 1023, 545, 546, 491, 1035, 271, 1038, 503, 1048, 26, 683, 1053, 1054, 684, 658, 1076, 659, 685, 660, 1078, 476, 592, 1179, 475, 1093, 1099, 465, 1102, 1340, 466, 1106, 270, 1109, 284, 427, 445, 1115, 1116, 12, 1122, 713, 714, 25, 280, 523, 1150, 704, -32768, -32768, -32768, -32768, 462, 1177, 461, 1249, 1251, 573, 504, 1269, 301, 1272, 696, 519, 1277, 458, 1343, 459, 547, 487, 325, 548, 1387, 315, 343, 322, 564, 302, 344, 549, 488, 1349, 1357, 341, 34, 1377, 1388, 607, 630);
18688 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, 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, 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, 112, 112, 112, 112, 110, 110, 110, 115, 115, 115, 115, 89, 89, 118, 118, 118, 119, 119, 116, 116, 120, 120, 122, 122, 123, 123, 117, 124, 124, 121, 125, 125, 125, 125, 113, 113, 82, 82, 82, 20, 20, 20, 128, 128, 128, 128, 129, 129, 129, 127, 126, 126, 131, 131, 131, 130, 130, 60, 132, 132, 133, 61, 135, 135, 136, 136, 137, 137, 86, 138, 138, 138, 138, 138, 138, 138, 143, 143, 144, 144, 145, 145, 145, 145, 145, 146, 147, 147, 142, 142, 139, 139, 141, 141, 149, 149, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 140, 150, 150, 152, 151, 151, 153, 153, 114, 154, 154, 156, 156, 156, 155, 155, 62, 104, 157, 157, 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, 42, 42, 164, 165, 165, 166, 158, 158, 163, 163, 167, 168, 168, 169, 170, 171, 171, 171, 171, 19, 19, 73, 73, 73, 73, 159, 159, 159, 159, 173, 173, 162, 162, 162, 160, 160, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 180, 180, 180, 108, 182, 182, 182, 182, 161, 161, 161, 161, 161, 161, 161, 161, 59, 59, 176, 176, 176, 176, 176, 183, 183, 172, 172, 172, 172, 184, 184, 184, 184, 184, 184, 74, 74, 66, 66, 66, 66, 134, 134, 134, 134, 187, 186, 175, 175, 175, 175, 175, 175, 175, 174, 174, 174, 185, 185, 185, 185, 107, 181, 189, 189, 188, 188, 190, 190, 190, 190, 190, 190, 190, 190, 178, 178, 178, 178, 177, 192, 191, 191, 191, 191, 191, 191, 191, 191, 193, 193, 193, 193);
18689 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, 1, 3, 4, 1, 1, 8, 7, 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, 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, 1, 1, 1, 1, 7, 9, 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, 2, 4, 4, 3, 3, 1, 3, 1, 1, 3, 2, 2, 3, 1, 1, 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, 1, 1, 1, 2, 1, 3, 1, 1, 3, 0, 2, 0, 5, 8, 1, 3, 3, 0, 2, 2, 2, 3, 1, 0, 1, 1, 3, 3, 3, 4, 4, 1, 1, 2, 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, 2, 1, 3, 2, 1, 2, 4, 2, 2, 8, 9, 8, 9, 9, 10, 9, 10, 8, 3, 2, 2, 1, 1, 0, 4, 2, 1, 3, 2, 1, 2, 2, 2, 4, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 0, 1, 1, 0, 1, 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, 1, 3, 1, 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);
18690 protected function initReduceCallbacks(): void
18691 {
18692 $this->reduceCallbacks = [0 => null, 1 => static function ($self, $stackPos) {
18693 $self->semValue = $self->handleNamespaces($self->semStack[$stackPos - (1 - 1)]);
18694 }, 2 => static function ($self, $stackPos) {
18695 if ($self->semStack[$stackPos - (2 - 2)] !== null) {
18696 $self->semStack[$stackPos - (2 - 1)][] = $self->semStack[$stackPos - (2 - 2)];
18697 }
18698 $self->semValue = $self->semStack[$stackPos - (2 - 1)];
18699 }, 3 => static function ($self, $stackPos) {
18700 $self->semValue = array();
18701 }, 4 => static function ($self, $stackPos) {
18702 $nop = $self->maybeCreateZeroLengthNop($self->tokenPos);
18703 if ($nop !== null) {
18704 $self->semStack[$stackPos - (1 - 1)][] = $nop;
18705 }
18706 $self->semValue = $self->semStack[$stackPos - (1 - 1)];
18707 }, 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 => static function ($self, $stackPos) {
18708 $self->semValue = $self->semStack[$stackPos - (1 - 1)];
18709 if ($self->semValue === "<?=") {
18710 $self->emitError(new Error('Cannot use "<?=" as an identifier', $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos])));
18711 }
18712 }, 77 => null, 78 => null, 79 => null, 80 => null, 81 => null, 82 => null, 83 => null, 84 => null, 85 => static function ($self, $stackPos) {
18713 $self->semValue = new Node\Identifier($self->semStack[$stackPos - (1 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
18714 }, 86 => static function ($self, $stackPos) {
18715 $self->semValue = new Node\Identifier($self->semStack[$stackPos - (1 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
18716 }, 87 => static function ($self, $stackPos) {
18717 $self->semValue = new Node\Identifier($self->semStack[$stackPos - (1 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
18718 }, 88 => static function ($self, $stackPos) {
18719 $self->semValue = new Node\Identifier($self->semStack[$stackPos - (1 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
18720 }, 89 => static function ($self, $stackPos) {
18721 $self->semValue = new Name($self->semStack[$stackPos - (1 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
18722 }, 90 => static function ($self, $stackPos) {
18723 $self->semValue = new Name($self->semStack[$stackPos - (1 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
18724 }, 91 => static function ($self, $stackPos) {
18725 $self->semValue = new Name($self->semStack[$stackPos - (1 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
18726 }, 92 => static function ($self, $stackPos) {
18727 $self->semValue = new Name($self->semStack[$stackPos - (1 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
18728 }, 93 => static function ($self, $stackPos) {
18729 $self->semValue = new Name($self->semStack[$stackPos - (1 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
18730 }, 94 => null, 95 => static function ($self, $stackPos) {
18731 $self->semValue = new Name(substr($self->semStack[$stackPos - (1 - 1)], 1), $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
18732 }, 96 => static function ($self, $stackPos) {
18733 $self->semValue = new Expr\Variable(substr($self->semStack[$stackPos - (1 - 1)], 1), $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
18734 }, 97 => static function ($self, $stackPos) {
18735 /* nothing */
18736 }, 98 => static function ($self, $stackPos) {
18737 /* nothing */
18738 }, 99 => static function ($self, $stackPos) {
18739 /* nothing */
18740 }, 100 => static function ($self, $stackPos) {
18741 $self->emitError(new Error('A trailing comma is not allowed here', $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos])));
18742 }, 101 => null, 102 => null, 103 => static function ($self, $stackPos) {
18743 $self->semValue = new Node\Attribute($self->semStack[$stackPos - (1 - 1)], [], $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
18744 }, 104 => static function ($self, $stackPos) {
18745 $self->semValue = new Node\Attribute($self->semStack[$stackPos - (2 - 1)], $self->semStack[$stackPos - (2 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
18746 }, 105 => static function ($self, $stackPos) {
18747 $self->semValue = array($self->semStack[$stackPos - (1 - 1)]);
18748 }, 106 => static function ($self, $stackPos) {
18749 $self->semStack[$stackPos - (3 - 1)][] = $self->semStack[$stackPos - (3 - 3)];
18750 $self->semValue = $self->semStack[$stackPos - (3 - 1)];
18751 }, 107 => static function ($self, $stackPos) {
18752 $self->semValue = new Node\AttributeGroup($self->semStack[$stackPos - (4 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]));
18753 }, 108 => static function ($self, $stackPos) {
18754 $self->semValue = array($self->semStack[$stackPos - (1 - 1)]);
18755 }, 109 => static function ($self, $stackPos) {
18756 $self->semStack[$stackPos - (2 - 1)][] = $self->semStack[$stackPos - (2 - 2)];
18757 $self->semValue = $self->semStack[$stackPos - (2 - 1)];
18758 }, 110 => static function ($self, $stackPos) {
18759 $self->semValue = [];
18760 }, 111 => null, 112 => null, 113 => null, 114 => null, 115 => static function ($self, $stackPos) {
18761 $self->semValue = new Stmt\HaltCompiler($self->handleHaltCompiler(), $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]));
18762 }, 116 => static function ($self, $stackPos) {
18763 $self->semValue = new Stmt\Namespace_($self->semStack[$stackPos - (3 - 2)], null, $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
18764 $self->semValue->setAttribute('kind', Stmt\Namespace_::KIND_SEMICOLON);
18765 $self->checkNamespace($self->semValue);
18766 }, 117 => static function ($self, $stackPos) {
18767 $self->semValue = new Stmt\Namespace_($self->semStack[$stackPos - (5 - 2)], $self->semStack[$stackPos - (5 - 4)], $self->getAttributes($self->tokenStartStack[$stackPos - (5 - 1)], $self->tokenEndStack[$stackPos]));
18768 $self->semValue->setAttribute('kind', Stmt\Namespace_::KIND_BRACED);
18769 $self->checkNamespace($self->semValue);
18770 }, 118 => static function ($self, $stackPos) {
18771 $self->semValue = new Stmt\Namespace_(null, $self->semStack[$stackPos - (4 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]));
18772 $self->semValue->setAttribute('kind', Stmt\Namespace_::KIND_BRACED);
18773 $self->checkNamespace($self->semValue);
18774 }, 119 => static function ($self, $stackPos) {
18775 $self->semValue = new Stmt\Use_($self->semStack[$stackPos - (3 - 2)], Stmt\Use_::TYPE_NORMAL, $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
18776 }, 120 => static function ($self, $stackPos) {
18777 $self->semValue = new Stmt\Use_($self->semStack[$stackPos - (4 - 3)], $self->semStack[$stackPos - (4 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]));
18778 }, 121 => null, 122 => static function ($self, $stackPos) {
18779 $self->semValue = new Stmt\Const_($self->semStack[$stackPos - (3 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]), []);
18780 }, 123 => static function ($self, $stackPos) {
18781 $self->semValue = new Stmt\Const_($self->semStack[$stackPos - (4 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]), $self->semStack[$stackPos - (4 - 1)]);
18782 $self->checkConstantAttributes($self->semValue);
18783 }, 124 => static function ($self, $stackPos) {
18784 $self->semValue = Stmt\Use_::TYPE_FUNCTION;
18785 }, 125 => static function ($self, $stackPos) {
18786 $self->semValue = Stmt\Use_::TYPE_CONSTANT;
18787 }, 126 => static function ($self, $stackPos) {
18788 $self->semValue = new Stmt\GroupUse($self->semStack[$stackPos - (8 - 3)], $self->semStack[$stackPos - (8 - 6)], $self->semStack[$stackPos - (8 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (8 - 1)], $self->tokenEndStack[$stackPos]));
18789 }, 127 => static function ($self, $stackPos) {
18790 $self->semValue = new Stmt\GroupUse($self->semStack[$stackPos - (7 - 2)], $self->semStack[$stackPos - (7 - 5)], Stmt\Use_::TYPE_UNKNOWN, $self->getAttributes($self->tokenStartStack[$stackPos - (7 - 1)], $self->tokenEndStack[$stackPos]));
18791 }, 128 => null, 129 => static function ($self, $stackPos) {
18792 $self->semStack[$stackPos - (3 - 1)][] = $self->semStack[$stackPos - (3 - 3)];
18793 $self->semValue = $self->semStack[$stackPos - (3 - 1)];
18794 }, 130 => static function ($self, $stackPos) {
18795 $self->semValue = array($self->semStack[$stackPos - (1 - 1)]);
18796 }, 131 => null, 132 => static function ($self, $stackPos) {
18797 $self->semStack[$stackPos - (3 - 1)][] = $self->semStack[$stackPos - (3 - 3)];
18798 $self->semValue = $self->semStack[$stackPos - (3 - 1)];
18799 }, 133 => static function ($self, $stackPos) {
18800 $self->semValue = array($self->semStack[$stackPos - (1 - 1)]);
18801 }, 134 => null, 135 => static function ($self, $stackPos) {
18802 $self->semStack[$stackPos - (3 - 1)][] = $self->semStack[$stackPos - (3 - 3)];
18803 $self->semValue = $self->semStack[$stackPos - (3 - 1)];
18804 }, 136 => static function ($self, $stackPos) {
18805 $self->semValue = array($self->semStack[$stackPos - (1 - 1)]);
18806 }, 137 => static function ($self, $stackPos) {
18807 $self->semValue = new Node\UseItem($self->semStack[$stackPos - (1 - 1)], null, Stmt\Use_::TYPE_UNKNOWN, $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
18808 $self->checkUseUse($self->semValue, $stackPos - (1 - 1));
18809 }, 138 => static function ($self, $stackPos) {
18810 $self->semValue = new Node\UseItem($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], Stmt\Use_::TYPE_UNKNOWN, $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
18811 $self->checkUseUse($self->semValue, $stackPos - (3 - 3));
18812 }, 139 => static function ($self, $stackPos) {
18813 $self->semValue = new Node\UseItem($self->semStack[$stackPos - (1 - 1)], null, Stmt\Use_::TYPE_UNKNOWN, $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
18814 $self->checkUseUse($self->semValue, $stackPos - (1 - 1));
18815 }, 140 => static function ($self, $stackPos) {
18816 $self->semValue = new Node\UseItem($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], Stmt\Use_::TYPE_UNKNOWN, $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
18817 $self->checkUseUse($self->semValue, $stackPos - (3 - 3));
18818 }, 141 => static function ($self, $stackPos) {
18819 $self->semValue = $self->semStack[$stackPos - (1 - 1)];
18820 $self->semValue->type = Stmt\Use_::TYPE_NORMAL;
18821 }, 142 => static function ($self, $stackPos) {
18822 $self->semValue = $self->semStack[$stackPos - (2 - 2)];
18823 $self->semValue->type = $self->semStack[$stackPos - (2 - 1)];
18824 }, 143 => null, 144 => static function ($self, $stackPos) {
18825 $self->semStack[$stackPos - (3 - 1)][] = $self->semStack[$stackPos - (3 - 3)];
18826 $self->semValue = $self->semStack[$stackPos - (3 - 1)];
18827 }, 145 => static function ($self, $stackPos) {
18828 $self->semValue = array($self->semStack[$stackPos - (1 - 1)]);
18829 }, 146 => static function ($self, $stackPos) {
18830 $self->semValue = new Node\Const_($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
18831 }, 147 => null, 148 => static function ($self, $stackPos) {
18832 $self->semStack[$stackPos - (3 - 1)][] = $self->semStack[$stackPos - (3 - 3)];
18833 $self->semValue = $self->semStack[$stackPos - (3 - 1)];
18834 }, 149 => static function ($self, $stackPos) {
18835 $self->semValue = array($self->semStack[$stackPos - (1 - 1)]);
18836 }, 150 => static function ($self, $stackPos) {
18837 $self->semValue = new Node\Const_(new Node\Identifier($self->semStack[$stackPos - (3 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos - (3 - 1)])), $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
18838 }, 151 => static function ($self, $stackPos) {
18839 $self->semValue = new Node\Const_(new Node\Identifier($self->semStack[$stackPos - (3 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos - (3 - 1)])), $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
18840 }, 152 => static function ($self, $stackPos) {
18841 if ($self->semStack[$stackPos - (2 - 2)] !== null) {
18842 $self->semStack[$stackPos - (2 - 1)][] = $self->semStack[$stackPos - (2 - 2)];
18843 }
18844 $self->semValue = $self->semStack[$stackPos - (2 - 1)];
18845 }, 153 => static function ($self, $stackPos) {
18846 $self->semValue = array();
18847 }, 154 => static function ($self, $stackPos) {
18848 $nop = $self->maybeCreateZeroLengthNop($self->tokenPos);
18849 if ($nop !== null) {
18850 $self->semStack[$stackPos - (1 - 1)][] = $nop;
18851 }
18852 $self->semValue = $self->semStack[$stackPos - (1 - 1)];
18853 }, 155 => null, 156 => null, 157 => null, 158 => static function ($self, $stackPos) {
18854 throw new Error('__HALT_COMPILER() can only be used from the outermost scope', $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
18855 }, 159 => static function ($self, $stackPos) {
18856 $self->semValue = new Stmt\Block($self->semStack[$stackPos - (3 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
18857 }, 160 => static function ($self, $stackPos) {
18858 $self->semValue = new Stmt\If_($self->semStack[$stackPos - (7 - 3)], ['stmts' => $self->semStack[$stackPos - (7 - 5)], 'elseifs' => $self->semStack[$stackPos - (7 - 6)], 'else' => $self->semStack[$stackPos - (7 - 7)]], $self->getAttributes($self->tokenStartStack[$stackPos - (7 - 1)], $self->tokenEndStack[$stackPos]));
18859 }, 161 => static function ($self, $stackPos) {
18860 $self->semValue = new Stmt\If_($self->semStack[$stackPos - (10 - 3)], ['stmts' => $self->semStack[$stackPos - (10 - 6)], 'elseifs' => $self->semStack[$stackPos - (10 - 7)], 'else' => $self->semStack[$stackPos - (10 - 8)]], $self->getAttributes($self->tokenStartStack[$stackPos - (10 - 1)], $self->tokenEndStack[$stackPos]));
18861 }, 162 => static function ($self, $stackPos) {
18862 $self->semValue = new Stmt\While_($self->semStack[$stackPos - (5 - 3)], $self->semStack[$stackPos - (5 - 5)], $self->getAttributes($self->tokenStartStack[$stackPos - (5 - 1)], $self->tokenEndStack[$stackPos]));
18863 }, 163 => static function ($self, $stackPos) {
18864 $self->semValue = new Stmt\Do_($self->semStack[$stackPos - (7 - 5)], $self->semStack[$stackPos - (7 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (7 - 1)], $self->tokenEndStack[$stackPos]));
18865 }, 164 => static function ($self, $stackPos) {
18866 $self->semValue = new Stmt\For_(['init' => $self->semStack[$stackPos - (9 - 3)], 'cond' => $self->semStack[$stackPos - (9 - 5)], 'loop' => $self->semStack[$stackPos - (9 - 7)], 'stmts' => $self->semStack[$stackPos - (9 - 9)]], $self->getAttributes($self->tokenStartStack[$stackPos - (9 - 1)], $self->tokenEndStack[$stackPos]));
18867 }, 165 => static function ($self, $stackPos) {
18868 $self->semValue = new Stmt\Switch_($self->semStack[$stackPos - (5 - 3)], $self->semStack[$stackPos - (5 - 5)], $self->getAttributes($self->tokenStartStack[$stackPos - (5 - 1)], $self->tokenEndStack[$stackPos]));
18869 }, 166 => static function ($self, $stackPos) {
18870 $self->semValue = new Stmt\Break_($self->semStack[$stackPos - (3 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
18871 }, 167 => static function ($self, $stackPos) {
18872 $self->semValue = new Stmt\Continue_($self->semStack[$stackPos - (3 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
18873 }, 168 => static function ($self, $stackPos) {
18874 $self->semValue = new Stmt\Return_($self->semStack[$stackPos - (3 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
18875 }, 169 => static function ($self, $stackPos) {
18876 $self->semValue = new Stmt\Global_($self->semStack[$stackPos - (3 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
18877 }, 170 => static function ($self, $stackPos) {
18878 $self->semValue = new Stmt\Static_($self->semStack[$stackPos - (3 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
18879 }, 171 => static function ($self, $stackPos) {
18880 $self->semValue = new Stmt\Echo_($self->semStack[$stackPos - (3 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
18881 }, 172 => static function ($self, $stackPos) {
18882 $self->semValue = new Stmt\InlineHTML($self->semStack[$stackPos - (1 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
18883 $self->semValue->setAttribute('hasLeadingNewline', $self->inlineHtmlHasLeadingNewline($stackPos - (1 - 1)));
18884 }, 173 => static function ($self, $stackPos) {
18885 $self->semValue = new Stmt\Expression($self->semStack[$stackPos - (2 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
18886 }, 174 => static function ($self, $stackPos) {
18887 $self->semValue = new Stmt\Unset_($self->semStack[$stackPos - (5 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (5 - 1)], $self->tokenEndStack[$stackPos]));
18888 }, 175 => static function ($self, $stackPos) {
18889 $self->semValue = new Stmt\Foreach_($self->semStack[$stackPos - (7 - 3)], $self->semStack[$stackPos - (7 - 5)][0], ['keyVar' => null, 'byRef' => $self->semStack[$stackPos - (7 - 5)][1], 'stmts' => $self->semStack[$stackPos - (7 - 7)]], $self->getAttributes($self->tokenStartStack[$stackPos - (7 - 1)], $self->tokenEndStack[$stackPos]));
18890 }, 176 => static function ($self, $stackPos) {
18891 $self->semValue = new Stmt\Foreach_($self->semStack[$stackPos - (9 - 3)], $self->semStack[$stackPos - (9 - 7)][0], ['keyVar' => $self->semStack[$stackPos - (9 - 5)], 'byRef' => $self->semStack[$stackPos - (9 - 7)][1], 'stmts' => $self->semStack[$stackPos - (9 - 9)]], $self->getAttributes($self->tokenStartStack[$stackPos - (9 - 1)], $self->tokenEndStack[$stackPos]));
18892 }, 177 => static function ($self, $stackPos) {
18893 $self->semValue = new Stmt\Foreach_($self->semStack[$stackPos - (6 - 3)], new Expr\Error($self->getAttributes($self->tokenStartStack[$stackPos - (6 - 4)], $self->tokenEndStack[$stackPos - (6 - 4)])), ['stmts' => $self->semStack[$stackPos - (6 - 6)]], $self->getAttributes($self->tokenStartStack[$stackPos - (6 - 1)], $self->tokenEndStack[$stackPos]));
18894 }, 178 => static function ($self, $stackPos) {
18895 $self->semValue = new Stmt\Declare_($self->semStack[$stackPos - (5 - 3)], $self->semStack[$stackPos - (5 - 5)], $self->getAttributes($self->tokenStartStack[$stackPos - (5 - 1)], $self->tokenEndStack[$stackPos]));
18896 }, 179 => static function ($self, $stackPos) {
18897 $self->semValue = new Stmt\TryCatch($self->semStack[$stackPos - (6 - 3)], $self->semStack[$stackPos - (6 - 5)], $self->semStack[$stackPos - (6 - 6)], $self->getAttributes($self->tokenStartStack[$stackPos - (6 - 1)], $self->tokenEndStack[$stackPos]));
18898 $self->checkTryCatch($self->semValue);
18899 }, 180 => static function ($self, $stackPos) {
18900 $self->semValue = new Stmt\Goto_($self->semStack[$stackPos - (3 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
18901 }, 181 => static function ($self, $stackPos) {
18902 $self->semValue = new Stmt\Label($self->semStack[$stackPos - (2 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
18903 }, 182 => static function ($self, $stackPos) {
18904 $self->semValue = null;
18905 /* means: no statement */
18906 }, 183 => null, 184 => static function ($self, $stackPos) {
18907 $self->semValue = $self->maybeCreateNop($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]);
18908 }, 185 => static function ($self, $stackPos) {
18909 if ($self->semStack[$stackPos - (1 - 1)] instanceof Stmt\Block) {
18910 $self->semValue = $self->semStack[$stackPos - (1 - 1)]->stmts;
18911 } else if ($self->semStack[$stackPos - (1 - 1)] === null) {
18912 $self->semValue = [];
18913 } else {
18914 $self->semValue = [$self->semStack[$stackPos - (1 - 1)]];
18915 }
18916 }, 186 => static function ($self, $stackPos) {
18917 $self->semValue = array();
18918 }, 187 => static function ($self, $stackPos) {
18919 $self->semStack[$stackPos - (2 - 1)][] = $self->semStack[$stackPos - (2 - 2)];
18920 $self->semValue = $self->semStack[$stackPos - (2 - 1)];
18921 }, 188 => static function ($self, $stackPos) {
18922 $self->semValue = array($self->semStack[$stackPos - (1 - 1)]);
18923 }, 189 => static function ($self, $stackPos) {
18924 $self->semStack[$stackPos - (3 - 1)][] = $self->semStack[$stackPos - (3 - 3)];
18925 $self->semValue = $self->semStack[$stackPos - (3 - 1)];
18926 }, 190 => static function ($self, $stackPos) {
18927 $self->semValue = new Stmt\Catch_($self->semStack[$stackPos - (8 - 3)], $self->semStack[$stackPos - (8 - 4)], $self->semStack[$stackPos - (8 - 7)], $self->getAttributes($self->tokenStartStack[$stackPos - (8 - 1)], $self->tokenEndStack[$stackPos]));
18928 }, 191 => static function ($self, $stackPos) {
18929 $self->semValue = null;
18930 }, 192 => static function ($self, $stackPos) {
18931 $self->semValue = new Stmt\Finally_($self->semStack[$stackPos - (4 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]));
18932 }, 193 => null, 194 => static function ($self, $stackPos) {
18933 $self->semValue = array($self->semStack[$stackPos - (1 - 1)]);
18934 }, 195 => static function ($self, $stackPos) {
18935 $self->semStack[$stackPos - (3 - 1)][] = $self->semStack[$stackPos - (3 - 3)];
18936 $self->semValue = $self->semStack[$stackPos - (3 - 1)];
18937 }, 196 => static function ($self, $stackPos) {
18938 $self->semValue = \false;
18939 }, 197 => static function ($self, $stackPos) {
18940 $self->semValue = \true;
18941 }, 198 => static function ($self, $stackPos) {
18942 $self->semValue = \false;
18943 }, 199 => static function ($self, $stackPos) {
18944 $self->semValue = \true;
18945 }, 200 => static function ($self, $stackPos) {
18946 $self->semValue = \false;
18947 }, 201 => static function ($self, $stackPos) {
18948 $self->semValue = \true;
18949 }, 202 => static function ($self, $stackPos) {
18950 $self->semValue = $self->semStack[$stackPos - (3 - 2)];
18951 }, 203 => static function ($self, $stackPos) {
18952 $self->semValue = [];
18953 }, 204 => null, 205 => static function ($self, $stackPos) {
18954 $self->semValue = new Node\Identifier($self->semStack[$stackPos - (1 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
18955 }, 206 => static function ($self, $stackPos) {
18956 $self->semValue = new Node\Identifier($self->semStack[$stackPos - (1 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
18957 }, 207 => static function ($self, $stackPos) {
18958 $self->semValue = new Node\Identifier($self->semStack[$stackPos - (1 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
18959 }, 208 => static function ($self, $stackPos) {
18960 $self->semValue = new Stmt\Function_($self->semStack[$stackPos - (8 - 3)], ['byRef' => $self->semStack[$stackPos - (8 - 2)], 'params' => $self->semStack[$stackPos - (8 - 5)], 'returnType' => $self->semStack[$stackPos - (8 - 7)], 'stmts' => $self->semStack[$stackPos - (8 - 8)], 'attrGroups' => []], $self->getAttributes($self->tokenStartStack[$stackPos - (8 - 1)], $self->tokenEndStack[$stackPos]));
18961 }, 209 => static function ($self, $stackPos) {
18962 $self->semValue = new Stmt\Function_($self->semStack[$stackPos - (9 - 4)], ['byRef' => $self->semStack[$stackPos - (9 - 3)], 'params' => $self->semStack[$stackPos - (9 - 6)], 'returnType' => $self->semStack[$stackPos - (9 - 8)], 'stmts' => $self->semStack[$stackPos - (9 - 9)], 'attrGroups' => $self->semStack[$stackPos - (9 - 1)]], $self->getAttributes($self->tokenStartStack[$stackPos - (9 - 1)], $self->tokenEndStack[$stackPos]));
18963 }, 210 => static function ($self, $stackPos) {
18964 $self->semValue = new Stmt\Class_($self->semStack[$stackPos - (7 - 2)], ['type' => $self->semStack[$stackPos - (7 - 1)], 'extends' => $self->semStack[$stackPos - (7 - 3)], 'implements' => $self->semStack[$stackPos - (7 - 4)], 'stmts' => $self->semStack[$stackPos - (7 - 6)], 'attrGroups' => []], $self->getAttributes($self->tokenStartStack[$stackPos - (7 - 1)], $self->tokenEndStack[$stackPos]));
18965 $self->checkClass($self->semValue, $stackPos - (7 - 2));
18966 }, 211 => static function ($self, $stackPos) {
18967 $self->semValue = new Stmt\Class_($self->semStack[$stackPos - (8 - 3)], ['type' => $self->semStack[$stackPos - (8 - 2)], 'extends' => $self->semStack[$stackPos - (8 - 4)], 'implements' => $self->semStack[$stackPos - (8 - 5)], 'stmts' => $self->semStack[$stackPos - (8 - 7)], 'attrGroups' => $self->semStack[$stackPos - (8 - 1)]], $self->getAttributes($self->tokenStartStack[$stackPos - (8 - 1)], $self->tokenEndStack[$stackPos]));
18968 $self->checkClass($self->semValue, $stackPos - (8 - 3));
18969 }, 212 => static function ($self, $stackPos) {
18970 $self->semValue = new Stmt\Interface_($self->semStack[$stackPos - (7 - 3)], ['extends' => $self->semStack[$stackPos - (7 - 4)], 'stmts' => $self->semStack[$stackPos - (7 - 6)], 'attrGroups' => $self->semStack[$stackPos - (7 - 1)]], $self->getAttributes($self->tokenStartStack[$stackPos - (7 - 1)], $self->tokenEndStack[$stackPos]));
18971 $self->checkInterface($self->semValue, $stackPos - (7 - 3));
18972 }, 213 => static function ($self, $stackPos) {
18973 $self->semValue = new Stmt\Trait_($self->semStack[$stackPos - (6 - 3)], ['stmts' => $self->semStack[$stackPos - (6 - 5)], 'attrGroups' => $self->semStack[$stackPos - (6 - 1)]], $self->getAttributes($self->tokenStartStack[$stackPos - (6 - 1)], $self->tokenEndStack[$stackPos]));
18974 }, 214 => static function ($self, $stackPos) {
18975 $self->semValue = new Stmt\Enum_($self->semStack[$stackPos - (8 - 3)], ['scalarType' => $self->semStack[$stackPos - (8 - 4)], 'implements' => $self->semStack[$stackPos - (8 - 5)], 'stmts' => $self->semStack[$stackPos - (8 - 7)], 'attrGroups' => $self->semStack[$stackPos - (8 - 1)]], $self->getAttributes($self->tokenStartStack[$stackPos - (8 - 1)], $self->tokenEndStack[$stackPos]));
18976 $self->checkEnum($self->semValue, $stackPos - (8 - 3));
18977 }, 215 => static function ($self, $stackPos) {
18978 $self->semValue = null;
18979 }, 216 => static function ($self, $stackPos) {
18980 $self->semValue = $self->semStack[$stackPos - (2 - 2)];
18981 }, 217 => static function ($self, $stackPos) {
18982 $self->semValue = null;
18983 }, 218 => static function ($self, $stackPos) {
18984 $self->semValue = $self->semStack[$stackPos - (2 - 2)];
18985 }, 219 => static function ($self, $stackPos) {
18986 $self->semValue = 0;
18987 }, 220 => null, 221 => null, 222 => static function ($self, $stackPos) {
18988 $self->checkClassModifier($self->semStack[$stackPos - (2 - 1)], $self->semStack[$stackPos - (2 - 2)], $stackPos - (2 - 2));
18989 $self->semValue = $self->semStack[$stackPos - (2 - 1)] | $self->semStack[$stackPos - (2 - 2)];
18990 }, 223 => static function ($self, $stackPos) {
18991 $self->semValue = Modifiers::ABSTRACT;
18992 }, 224 => static function ($self, $stackPos) {
18993 $self->semValue = Modifiers::FINAL;
18994 }, 225 => static function ($self, $stackPos) {
18995 $self->semValue = Modifiers::READONLY;
18996 }, 226 => static function ($self, $stackPos) {
18997 $self->semValue = null;
18998 }, 227 => static function ($self, $stackPos) {
18999 $self->semValue = $self->semStack[$stackPos - (2 - 2)];
19000 }, 228 => static function ($self, $stackPos) {
19001 $self->semValue = array();
19002 }, 229 => static function ($self, $stackPos) {
19003 $self->semValue = $self->semStack[$stackPos - (2 - 2)];
19004 }, 230 => static function ($self, $stackPos) {
19005 $self->semValue = array();
19006 }, 231 => static function ($self, $stackPos) {
19007 $self->semValue = $self->semStack[$stackPos - (2 - 2)];
19008 }, 232 => null, 233 => static function ($self, $stackPos) {
19009 $self->semValue = array($self->semStack[$stackPos - (1 - 1)]);
19010 }, 234 => static function ($self, $stackPos) {
19011 $self->semStack[$stackPos - (3 - 1)][] = $self->semStack[$stackPos - (3 - 3)];
19012 $self->semValue = $self->semStack[$stackPos - (3 - 1)];
19013 }, 235 => null, 236 => static function ($self, $stackPos) {
19014 $self->semValue = $self->semStack[$stackPos - (4 - 2)];
19015 }, 237 => null, 238 => static function ($self, $stackPos) {
19016 $self->semValue = $self->semStack[$stackPos - (4 - 2)];
19017 }, 239 => static function ($self, $stackPos) {
19018 if ($self->semStack[$stackPos - (1 - 1)] instanceof Stmt\Block) {
19019 $self->semValue = $self->semStack[$stackPos - (1 - 1)]->stmts;
19020 } else if ($self->semStack[$stackPos - (1 - 1)] === null) {
19021 $self->semValue = [];
19022 } else {
19023 $self->semValue = [$self->semStack[$stackPos - (1 - 1)]];
19024 }
19025 }, 240 => static function ($self, $stackPos) {
19026 $self->semValue = null;
19027 }, 241 => static function ($self, $stackPos) {
19028 $self->semValue = $self->semStack[$stackPos - (4 - 2)];
19029 }, 242 => null, 243 => static function ($self, $stackPos) {
19030 $self->semValue = array($self->semStack[$stackPos - (1 - 1)]);
19031 }, 244 => static function ($self, $stackPos) {
19032 $self->semStack[$stackPos - (3 - 1)][] = $self->semStack[$stackPos - (3 - 3)];
19033 $self->semValue = $self->semStack[$stackPos - (3 - 1)];
19034 }, 245 => static function ($self, $stackPos) {
19035 $self->semValue = new Node\DeclareItem($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
19036 }, 246 => static function ($self, $stackPos) {
19037 $self->semValue = $self->semStack[$stackPos - (3 - 2)];
19038 }, 247 => static function ($self, $stackPos) {
19039 $self->semValue = $self->semStack[$stackPos - (4 - 3)];
19040 }, 248 => static function ($self, $stackPos) {
19041 $self->semValue = $self->semStack[$stackPos - (4 - 2)];
19042 }, 249 => static function ($self, $stackPos) {
19043 $self->semValue = $self->semStack[$stackPos - (5 - 3)];
19044 }, 250 => static function ($self, $stackPos) {
19045 $self->semValue = array();
19046 }, 251 => static function ($self, $stackPos) {
19047 $self->semStack[$stackPos - (2 - 1)][] = $self->semStack[$stackPos - (2 - 2)];
19048 $self->semValue = $self->semStack[$stackPos - (2 - 1)];
19049 }, 252 => static function ($self, $stackPos) {
19050 $self->semValue = new Stmt\Case_($self->semStack[$stackPos - (4 - 2)], $self->semStack[$stackPos - (4 - 4)], $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]));
19051 }, 253 => static function ($self, $stackPos) {
19052 $self->semValue = new Stmt\Case_(null, $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
19053 }, 254 => null, 255 => null, 256 => static function ($self, $stackPos) {
19054 $self->semValue = new Expr\Match_($self->semStack[$stackPos - (7 - 3)], $self->semStack[$stackPos - (7 - 6)], $self->getAttributes($self->tokenStartStack[$stackPos - (7 - 1)], $self->tokenEndStack[$stackPos]));
19055 }, 257 => static function ($self, $stackPos) {
19056 $self->semValue = [];
19057 }, 258 => null, 259 => static function ($self, $stackPos) {
19058 $self->semValue = array($self->semStack[$stackPos - (1 - 1)]);
19059 }, 260 => static function ($self, $stackPos) {
19060 $self->semStack[$stackPos - (3 - 1)][] = $self->semStack[$stackPos - (3 - 3)];
19061 $self->semValue = $self->semStack[$stackPos - (3 - 1)];
19062 }, 261 => static function ($self, $stackPos) {
19063 $self->semValue = new Node\MatchArm($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
19064 }, 262 => static function ($self, $stackPos) {
19065 $self->semValue = new Node\MatchArm(null, $self->semStack[$stackPos - (4 - 4)], $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]));
19066 }, 263 => static function ($self, $stackPos) {
19067 $self->semValue = $self->semStack[$stackPos - (1 - 1)];
19068 }, 264 => static function ($self, $stackPos) {
19069 $self->semValue = $self->semStack[$stackPos - (4 - 2)];
19070 }, 265 => static function ($self, $stackPos) {
19071 $self->semValue = array();
19072 }, 266 => static function ($self, $stackPos) {
19073 $self->semStack[$stackPos - (2 - 1)][] = $self->semStack[$stackPos - (2 - 2)];
19074 $self->semValue = $self->semStack[$stackPos - (2 - 1)];
19075 }, 267 => static function ($self, $stackPos) {
19076 $self->semValue = new Stmt\ElseIf_($self->semStack[$stackPos - (5 - 3)], $self->semStack[$stackPos - (5 - 5)], $self->getAttributes($self->tokenStartStack[$stackPos - (5 - 1)], $self->tokenEndStack[$stackPos]));
19077 }, 268 => static function ($self, $stackPos) {
19078 $self->semValue = array();
19079 }, 269 => static function ($self, $stackPos) {
19080 $self->semStack[$stackPos - (2 - 1)][] = $self->semStack[$stackPos - (2 - 2)];
19081 $self->semValue = $self->semStack[$stackPos - (2 - 1)];
19082 }, 270 => static function ($self, $stackPos) {
19083 $self->semValue = new Stmt\ElseIf_($self->semStack[$stackPos - (6 - 3)], $self->semStack[$stackPos - (6 - 6)], $self->getAttributes($self->tokenStartStack[$stackPos - (6 - 1)], $self->tokenEndStack[$stackPos]));
19084 $self->fixupAlternativeElse($self->semValue);
19085 }, 271 => static function ($self, $stackPos) {
19086 $self->semValue = null;
19087 }, 272 => static function ($self, $stackPos) {
19088 $self->semValue = new Stmt\Else_($self->semStack[$stackPos - (2 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
19089 }, 273 => static function ($self, $stackPos) {
19090 $self->semValue = null;
19091 }, 274 => static function ($self, $stackPos) {
19092 $self->semValue = new Stmt\Else_($self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
19093 $self->fixupAlternativeElse($self->semValue);
19094 }, 275 => static function ($self, $stackPos) {
19095 $self->semValue = array($self->semStack[$stackPos - (1 - 1)], \false);
19096 }, 276 => static function ($self, $stackPos) {
19097 $self->semValue = array($self->semStack[$stackPos - (2 - 2)], \true);
19098 }, 277 => static function ($self, $stackPos) {
19099 $self->semValue = array($self->semStack[$stackPos - (1 - 1)], \false);
19100 }, 278 => static function ($self, $stackPos) {
19101 $self->semValue = array($self->fixupArrayDestructuring($self->semStack[$stackPos - (1 - 1)]), \false);
19102 }, 279 => null, 280 => static function ($self, $stackPos) {
19103 $self->semValue = array();
19104 }, 281 => static function ($self, $stackPos) {
19105 $self->semValue = array($self->semStack[$stackPos - (1 - 1)]);
19106 }, 282 => static function ($self, $stackPos) {
19107 $self->semStack[$stackPos - (3 - 1)][] = $self->semStack[$stackPos - (3 - 3)];
19108 $self->semValue = $self->semStack[$stackPos - (3 - 1)];
19109 }, 283 => static function ($self, $stackPos) {
19110 $self->semValue = 0;
19111 }, 284 => static function ($self, $stackPos) {
19112 $self->checkModifier($self->semStack[$stackPos - (2 - 1)], $self->semStack[$stackPos - (2 - 2)], $stackPos - (2 - 2));
19113 $self->semValue = $self->semStack[$stackPos - (2 - 1)] | $self->semStack[$stackPos - (2 - 2)];
19114 }, 285 => static function ($self, $stackPos) {
19115 $self->semValue = Modifiers::PUBLIC;
19116 }, 286 => static function ($self, $stackPos) {
19117 $self->semValue = Modifiers::PROTECTED;
19118 }, 287 => static function ($self, $stackPos) {
19119 $self->semValue = Modifiers::PRIVATE;
19120 }, 288 => static function ($self, $stackPos) {
19121 $self->semValue = Modifiers::PUBLIC_SET;
19122 }, 289 => static function ($self, $stackPos) {
19123 $self->semValue = Modifiers::PROTECTED_SET;
19124 }, 290 => static function ($self, $stackPos) {
19125 $self->semValue = Modifiers::PRIVATE_SET;
19126 }, 291 => static function ($self, $stackPos) {
19127 $self->semValue = Modifiers::READONLY;
19128 }, 292 => static function ($self, $stackPos) {
19129 $self->semValue = Modifiers::FINAL;
19130 }, 293 => static function ($self, $stackPos) {
19131 $self->semValue = new Node\Param($self->semStack[$stackPos - (7 - 6)], null, $self->semStack[$stackPos - (7 - 3)], $self->semStack[$stackPos - (7 - 4)], $self->semStack[$stackPos - (7 - 5)], $self->getAttributes($self->tokenStartStack[$stackPos - (7 - 1)], $self->tokenEndStack[$stackPos]), $self->semStack[$stackPos - (7 - 2)], $self->semStack[$stackPos - (7 - 1)], $self->semStack[$stackPos - (7 - 7)]);
19132 $self->checkParam($self->semValue);
19133 $self->addPropertyNameToHooks($self->semValue);
19134 }, 294 => static function ($self, $stackPos) {
19135 $self->semValue = new Node\Param($self->semStack[$stackPos - (9 - 6)], $self->semStack[$stackPos - (9 - 8)], $self->semStack[$stackPos - (9 - 3)], $self->semStack[$stackPos - (9 - 4)], $self->semStack[$stackPos - (9 - 5)], $self->getAttributes($self->tokenStartStack[$stackPos - (9 - 1)], $self->tokenEndStack[$stackPos]), $self->semStack[$stackPos - (9 - 2)], $self->semStack[$stackPos - (9 - 1)], $self->semStack[$stackPos - (9 - 9)]);
19136 $self->checkParam($self->semValue);
19137 $self->addPropertyNameToHooks($self->semValue);
19138 }, 295 => static function ($self, $stackPos) {
19139 $self->semValue = new Node\Param(new Expr\Error($self->getAttributes($self->tokenStartStack[$stackPos - (6 - 1)], $self->tokenEndStack[$stackPos])), null, $self->semStack[$stackPos - (6 - 3)], $self->semStack[$stackPos - (6 - 4)], $self->semStack[$stackPos - (6 - 5)], $self->getAttributes($self->tokenStartStack[$stackPos - (6 - 1)], $self->tokenEndStack[$stackPos]), $self->semStack[$stackPos - (6 - 2)], $self->semStack[$stackPos - (6 - 1)]);
19140 }, 296 => null, 297 => static function ($self, $stackPos) {
19141 $self->semValue = new Node\NullableType($self->semStack[$stackPos - (2 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
19142 }, 298 => static function ($self, $stackPos) {
19143 $self->semValue = new Node\UnionType($self->semStack[$stackPos - (1 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
19144 }, 299 => null, 300 => null, 301 => static function ($self, $stackPos) {
19145 $self->semValue = new Node\Name('static', $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
19146 }, 302 => static function ($self, $stackPos) {
19147 $self->semValue = $self->handleBuiltinTypes($self->semStack[$stackPos - (1 - 1)]);
19148 }, 303 => static function ($self, $stackPos) {
19149 $self->semValue = new Node\Identifier('array', $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
19150 }, 304 => static function ($self, $stackPos) {
19151 $self->semValue = new Node\Identifier('callable', $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
19152 }, 305 => null, 306 => static function ($self, $stackPos) {
19153 $self->semValue = $self->semStack[$stackPos - (3 - 2)];
19154 }, 307 => static function ($self, $stackPos) {
19155 $self->semValue = array($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)]);
19156 }, 308 => static function ($self, $stackPos) {
19157 $self->semStack[$stackPos - (3 - 1)][] = $self->semStack[$stackPos - (3 - 3)];
19158 $self->semValue = $self->semStack[$stackPos - (3 - 1)];
19159 }, 309 => null, 310 => static function ($self, $stackPos) {
19160 $self->semValue = $self->semStack[$stackPos - (3 - 2)];
19161 }, 311 => static function ($self, $stackPos) {
19162 $self->semValue = array($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)]);
19163 }, 312 => static function ($self, $stackPos) {
19164 $self->semStack[$stackPos - (3 - 1)][] = $self->semStack[$stackPos - (3 - 3)];
19165 $self->semValue = $self->semStack[$stackPos - (3 - 1)];
19166 }, 313 => static function ($self, $stackPos) {
19167 $self->semValue = array($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)]);
19168 }, 314 => static function ($self, $stackPos) {
19169 $self->semStack[$stackPos - (3 - 1)][] = $self->semStack[$stackPos - (3 - 3)];
19170 $self->semValue = $self->semStack[$stackPos - (3 - 1)];
19171 }, 315 => static function ($self, $stackPos) {
19172 $self->semValue = new Node\IntersectionType($self->semStack[$stackPos - (1 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
19173 }, 316 => static function ($self, $stackPos) {
19174 $self->semValue = array($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)]);
19175 }, 317 => static function ($self, $stackPos) {
19176 $self->semStack[$stackPos - (3 - 1)][] = $self->semStack[$stackPos - (3 - 3)];
19177 $self->semValue = $self->semStack[$stackPos - (3 - 1)];
19178 }, 318 => static function ($self, $stackPos) {
19179 $self->semValue = new Node\IntersectionType($self->semStack[$stackPos - (1 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
19180 }, 319 => null, 320 => static function ($self, $stackPos) {
19181 $self->semValue = new Node\NullableType($self->semStack[$stackPos - (2 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
19182 }, 321 => static function ($self, $stackPos) {
19183 $self->semValue = new Node\UnionType($self->semStack[$stackPos - (1 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
19184 }, 322 => null, 323 => static function ($self, $stackPos) {
19185 $self->semValue = null;
19186 }, 324 => null, 325 => static function ($self, $stackPos) {
19187 $self->semValue = null;
19188 }, 326 => static function ($self, $stackPos) {
19189 $self->semValue = $self->semStack[$stackPos - (2 - 2)];
19190 }, 327 => static function ($self, $stackPos) {
19191 $self->semValue = null;
19192 }, 328 => static function ($self, $stackPos) {
19193 $self->semValue = array();
19194 }, 329 => static function ($self, $stackPos) {
19195 $self->semValue = $self->semStack[$stackPos - (4 - 2)];
19196 }, 330 => static function ($self, $stackPos) {
19197 $self->semValue = array($self->semStack[$stackPos - (3 - 2)]);
19198 }, 331 => static function ($self, $stackPos) {
19199 $self->semValue = array();
19200 }, 332 => static function ($self, $stackPos) {
19201 $self->semValue = $self->semStack[$stackPos - (4 - 2)];
19202 }, 333 => static function ($self, $stackPos) {
19203 $self->semValue = array(new Node\Arg($self->semStack[$stackPos - (4 - 2)], \false, \false, $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos])));
19204 }, 334 => static function ($self, $stackPos) {
19205 $self->semValue = array($self->semStack[$stackPos - (3 - 2)]);
19206 }, 335 => static function ($self, $stackPos) {
19207 $self->semValue = array(new Node\Arg($self->semStack[$stackPos - (3 - 1)], \false, \false, $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos - (3 - 1)])), $self->semStack[$stackPos - (3 - 3)]);
19208 }, 336 => static function ($self, $stackPos) {
19209 $self->semValue = array($self->semStack[$stackPos - (1 - 1)]);
19210 }, 337 => static function ($self, $stackPos) {
19211 $self->semStack[$stackPos - (3 - 1)][] = $self->semStack[$stackPos - (3 - 3)];
19212 $self->semValue = $self->semStack[$stackPos - (3 - 1)];
19213 }, 338 => static function ($self, $stackPos) {
19214 $self->semValue = new Node\VariadicPlaceholder($self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
19215 }, 339 => static function ($self, $stackPos) {
19216 $self->semValue = array($self->semStack[$stackPos - (1 - 1)]);
19217 }, 340 => static function ($self, $stackPos) {
19218 $self->semStack[$stackPos - (3 - 1)][] = $self->semStack[$stackPos - (3 - 3)];
19219 $self->semValue = $self->semStack[$stackPos - (3 - 1)];
19220 }, 341 => static function ($self, $stackPos) {
19221 $self->semValue = new Node\Arg($self->semStack[$stackPos - (2 - 2)], \true, \false, $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
19222 }, 342 => static function ($self, $stackPos) {
19223 $self->semValue = new Node\Arg($self->semStack[$stackPos - (2 - 2)], \false, \true, $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
19224 }, 343 => static function ($self, $stackPos) {
19225 $self->semValue = new Node\Arg($self->semStack[$stackPos - (3 - 3)], \false, \false, $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]), $self->semStack[$stackPos - (3 - 1)]);
19226 }, 344 => static function ($self, $stackPos) {
19227 $self->semValue = new Node\Arg($self->semStack[$stackPos - (1 - 1)], \false, \false, $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
19228 }, 345 => static function ($self, $stackPos) {
19229 $self->semValue = $self->semStack[$stackPos - (1 - 1)];
19230 }, 346 => null, 347 => static function ($self, $stackPos) {
19231 $self->semStack[$stackPos - (3 - 1)][] = $self->semStack[$stackPos - (3 - 3)];
19232 $self->semValue = $self->semStack[$stackPos - (3 - 1)];
19233 }, 348 => static function ($self, $stackPos) {
19234 $self->semValue = array($self->semStack[$stackPos - (1 - 1)]);
19235 }, 349 => null, 350 => null, 351 => static function ($self, $stackPos) {
19236 $self->semStack[$stackPos - (3 - 1)][] = $self->semStack[$stackPos - (3 - 3)];
19237 $self->semValue = $self->semStack[$stackPos - (3 - 1)];
19238 }, 352 => static function ($self, $stackPos) {
19239 $self->semValue = array($self->semStack[$stackPos - (1 - 1)]);
19240 }, 353 => static function ($self, $stackPos) {
19241 $self->semValue = new Node\StaticVar($self->semStack[$stackPos - (1 - 1)], null, $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
19242 }, 354 => static function ($self, $stackPos) {
19243 $self->semValue = new Node\StaticVar($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
19244 }, 355 => static function ($self, $stackPos) {
19245 if ($self->semStack[$stackPos - (2 - 2)] !== null) {
19246 $self->semStack[$stackPos - (2 - 1)][] = $self->semStack[$stackPos - (2 - 2)];
19247 $self->semValue = $self->semStack[$stackPos - (2 - 1)];
19248 } else {
19249 $self->semValue = $self->semStack[$stackPos - (2 - 1)];
19250 }
19251 }, 356 => static function ($self, $stackPos) {
19252 $self->semValue = array();
19253 }, 357 => static function ($self, $stackPos) {
19254 $nop = $self->maybeCreateZeroLengthNop($self->tokenPos);
19255 if ($nop !== null) {
19256 $self->semStack[$stackPos - (1 - 1)][] = $nop;
19257 }
19258 $self->semValue = $self->semStack[$stackPos - (1 - 1)];
19259 }, 358 => static function ($self, $stackPos) {
19260 $self->semValue = new Stmt\Property($self->semStack[$stackPos - (5 - 2)], $self->semStack[$stackPos - (5 - 4)], $self->getAttributes($self->tokenStartStack[$stackPos - (5 - 1)], $self->tokenEndStack[$stackPos]), $self->semStack[$stackPos - (5 - 3)], $self->semStack[$stackPos - (5 - 1)]);
19261 }, 359 => static function ($self, $stackPos) {
19262 $self->semValue = new Stmt\ClassConst($self->semStack[$stackPos - (5 - 4)], $self->semStack[$stackPos - (5 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (5 - 1)], $self->tokenEndStack[$stackPos]), $self->semStack[$stackPos - (5 - 1)]);
19263 $self->checkClassConst($self->semValue, $stackPos - (5 - 2));
19264 }, 360 => static function ($self, $stackPos) {
19265 $self->semValue = new Stmt\ClassConst($self->semStack[$stackPos - (6 - 5)], $self->semStack[$stackPos - (6 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (6 - 1)], $self->tokenEndStack[$stackPos]), $self->semStack[$stackPos - (6 - 1)], $self->semStack[$stackPos - (6 - 4)]);
19266 $self->checkClassConst($self->semValue, $stackPos - (6 - 2));
19267 }, 361 => static function ($self, $stackPos) {
19268 $self->semValue = new Stmt\ClassMethod($self->semStack[$stackPos - (10 - 5)], ['type' => $self->semStack[$stackPos - (10 - 2)], 'byRef' => $self->semStack[$stackPos - (10 - 4)], 'params' => $self->semStack[$stackPos - (10 - 7)], 'returnType' => $self->semStack[$stackPos - (10 - 9)], 'stmts' => $self->semStack[$stackPos - (10 - 10)], 'attrGroups' => $self->semStack[$stackPos - (10 - 1)]], $self->getAttributes($self->tokenStartStack[$stackPos - (10 - 1)], $self->tokenEndStack[$stackPos]));
19269 $self->checkClassMethod($self->semValue, $stackPos - (10 - 2));
19270 }, 362 => static function ($self, $stackPos) {
19271 $self->semValue = new Stmt\TraitUse($self->semStack[$stackPos - (3 - 2)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
19272 }, 363 => static function ($self, $stackPos) {
19273 $self->semValue = new Stmt\EnumCase($self->semStack[$stackPos - (5 - 3)], $self->semStack[$stackPos - (5 - 4)], $self->semStack[$stackPos - (5 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (5 - 1)], $self->tokenEndStack[$stackPos]));
19274 }, 364 => static function ($self, $stackPos) {
19275 $self->semValue = null;
19276 /* will be skipped */
19277 }, 365 => static function ($self, $stackPos) {
19278 $self->semValue = array();
19279 }, 366 => static function ($self, $stackPos) {
19280 $self->semValue = $self->semStack[$stackPos - (3 - 2)];
19281 }, 367 => static function ($self, $stackPos) {
19282 $self->semValue = array();
19283 }, 368 => static function ($self, $stackPos) {
19284 $self->semStack[$stackPos - (2 - 1)][] = $self->semStack[$stackPos - (2 - 2)];
19285 $self->semValue = $self->semStack[$stackPos - (2 - 1)];
19286 }, 369 => static function ($self, $stackPos) {
19287 $self->semValue = new Stmt\TraitUseAdaptation\Precedence($self->semStack[$stackPos - (4 - 1)][0], $self->semStack[$stackPos - (4 - 1)][1], $self->semStack[$stackPos - (4 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]));
19288 }, 370 => static function ($self, $stackPos) {
19289 $self->semValue = new Stmt\TraitUseAdaptation\Alias($self->semStack[$stackPos - (5 - 1)][0], $self->semStack[$stackPos - (5 - 1)][1], $self->semStack[$stackPos - (5 - 3)], $self->semStack[$stackPos - (5 - 4)], $self->getAttributes($self->tokenStartStack[$stackPos - (5 - 1)], $self->tokenEndStack[$stackPos]));
19290 }, 371 => static function ($self, $stackPos) {
19291 $self->semValue = new Stmt\TraitUseAdaptation\Alias($self->semStack[$stackPos - (4 - 1)][0], $self->semStack[$stackPos - (4 - 1)][1], $self->semStack[$stackPos - (4 - 3)], null, $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]));
19292 }, 372 => static function ($self, $stackPos) {
19293 $self->semValue = new Stmt\TraitUseAdaptation\Alias($self->semStack[$stackPos - (4 - 1)][0], $self->semStack[$stackPos - (4 - 1)][1], null, $self->semStack[$stackPos - (4 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]));
19294 }, 373 => static function ($self, $stackPos) {
19295 $self->semValue = new Stmt\TraitUseAdaptation\Alias($self->semStack[$stackPos - (4 - 1)][0], $self->semStack[$stackPos - (4 - 1)][1], null, $self->semStack[$stackPos - (4 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]));
19296 }, 374 => static function ($self, $stackPos) {
19297 $self->semValue = array($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)]);
19298 }, 375 => null, 376 => static function ($self, $stackPos) {
19299 $self->semValue = array(null, $self->semStack[$stackPos - (1 - 1)]);
19300 }, 377 => static function ($self, $stackPos) {
19301 $self->semValue = null;
19302 }, 378 => null, 379 => null, 380 => static function ($self, $stackPos) {
19303 $self->semValue = 0;
19304 }, 381 => static function ($self, $stackPos) {
19305 $self->semValue = 0;
19306 }, 382 => null, 383 => null, 384 => static function ($self, $stackPos) {
19307 $self->checkModifier($self->semStack[$stackPos - (2 - 1)], $self->semStack[$stackPos - (2 - 2)], $stackPos - (2 - 2));
19308 $self->semValue = $self->semStack[$stackPos - (2 - 1)] | $self->semStack[$stackPos - (2 - 2)];
19309 }, 385 => static function ($self, $stackPos) {
19310 $self->semValue = Modifiers::PUBLIC;
19311 }, 386 => static function ($self, $stackPos) {
19312 $self->semValue = Modifiers::PROTECTED;
19313 }, 387 => static function ($self, $stackPos) {
19314 $self->semValue = Modifiers::PRIVATE;
19315 }, 388 => static function ($self, $stackPos) {
19316 $self->semValue = Modifiers::PUBLIC_SET;
19317 }, 389 => static function ($self, $stackPos) {
19318 $self->semValue = Modifiers::PROTECTED_SET;
19319 }, 390 => static function ($self, $stackPos) {
19320 $self->semValue = Modifiers::PRIVATE_SET;
19321 }, 391 => static function ($self, $stackPos) {
19322 $self->semValue = Modifiers::STATIC;
19323 }, 392 => static function ($self, $stackPos) {
19324 $self->semValue = Modifiers::ABSTRACT;
19325 }, 393 => static function ($self, $stackPos) {
19326 $self->semValue = Modifiers::FINAL;
19327 }, 394 => static function ($self, $stackPos) {
19328 $self->semValue = Modifiers::READONLY;
19329 }, 395 => null, 396 => static function ($self, $stackPos) {
19330 $self->semValue = array($self->semStack[$stackPos - (1 - 1)]);
19331 }, 397 => static function ($self, $stackPos) {
19332 $self->semStack[$stackPos - (3 - 1)][] = $self->semStack[$stackPos - (3 - 3)];
19333 $self->semValue = $self->semStack[$stackPos - (3 - 1)];
19334 }, 398 => static function ($self, $stackPos) {
19335 $self->semValue = new Node\VarLikeIdentifier(substr($self->semStack[$stackPos - (1 - 1)], 1), $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
19336 }, 399 => static function ($self, $stackPos) {
19337 $self->semValue = new Node\PropertyItem($self->semStack[$stackPos - (1 - 1)], null, $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
19338 }, 400 => static function ($self, $stackPos) {
19339 $self->semValue = new Node\PropertyItem($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
19340 }, 401 => static function ($self, $stackPos) {
19341 $self->semValue = [];
19342 }, 402 => static function ($self, $stackPos) {
19343 $self->semStack[$stackPos - (2 - 1)][] = $self->semStack[$stackPos - (2 - 2)];
19344 $self->semValue = $self->semStack[$stackPos - (2 - 1)];
19345 }, 403 => static function ($self, $stackPos) {
19346 $self->semValue = [];
19347 }, 404 => static function ($self, $stackPos) {
19348 $self->semValue = new Node\PropertyHook($self->semStack[$stackPos - (5 - 4)], $self->semStack[$stackPos - (5 - 5)], ['flags' => $self->semStack[$stackPos - (5 - 2)], 'byRef' => $self->semStack[$stackPos - (5 - 3)], 'params' => [], 'attrGroups' => $self->semStack[$stackPos - (5 - 1)]], $self->getAttributes($self->tokenStartStack[$stackPos - (5 - 1)], $self->tokenEndStack[$stackPos]));
19349 $self->checkPropertyHook($self->semValue, null);
19350 }, 405 => static function ($self, $stackPos) {
19351 $self->semValue = new Node\PropertyHook($self->semStack[$stackPos - (8 - 4)], $self->semStack[$stackPos - (8 - 8)], ['flags' => $self->semStack[$stackPos - (8 - 2)], 'byRef' => $self->semStack[$stackPos - (8 - 3)], 'params' => $self->semStack[$stackPos - (8 - 6)], 'attrGroups' => $self->semStack[$stackPos - (8 - 1)]], $self->getAttributes($self->tokenStartStack[$stackPos - (8 - 1)], $self->tokenEndStack[$stackPos]));
19352 $self->checkPropertyHook($self->semValue, $stackPos - (8 - 5));
19353 }, 406 => static function ($self, $stackPos) {
19354 $self->semValue = null;
19355 }, 407 => static function ($self, $stackPos) {
19356 $self->semValue = $self->semStack[$stackPos - (3 - 2)];
19357 }, 408 => static function ($self, $stackPos) {
19358 $self->semValue = $self->semStack[$stackPos - (3 - 2)];
19359 }, 409 => static function ($self, $stackPos) {
19360 $self->semValue = 0;
19361 }, 410 => static function ($self, $stackPos) {
19362 $self->checkPropertyHookModifiers($self->semStack[$stackPos - (2 - 1)], $self->semStack[$stackPos - (2 - 2)], $stackPos - (2 - 2));
19363 $self->semValue = $self->semStack[$stackPos - (2 - 1)] | $self->semStack[$stackPos - (2 - 2)];
19364 }, 411 => null, 412 => null, 413 => static function ($self, $stackPos) {
19365 $self->semStack[$stackPos - (3 - 1)][] = $self->semStack[$stackPos - (3 - 3)];
19366 $self->semValue = $self->semStack[$stackPos - (3 - 1)];
19367 }, 414 => static function ($self, $stackPos) {
19368 $self->semValue = array($self->semStack[$stackPos - (1 - 1)]);
19369 }, 415 => static function ($self, $stackPos) {
19370 $self->semValue = array();
19371 }, 416 => null, 417 => null, 418 => static function ($self, $stackPos) {
19372 $self->semValue = new Expr\Assign($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
19373 }, 419 => static function ($self, $stackPos) {
19374 $self->semValue = new Expr\Assign($self->fixupArrayDestructuring($self->semStack[$stackPos - (3 - 1)]), $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
19375 }, 420 => static function ($self, $stackPos) {
19376 $self->semValue = new Expr\Assign($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
19377 }, 421 => static function ($self, $stackPos) {
19378 $self->semValue = new Expr\AssignRef($self->semStack[$stackPos - (4 - 1)], $self->semStack[$stackPos - (4 - 4)], $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]));
19379 }, 422 => static function ($self, $stackPos) {
19380 $self->semValue = new Expr\AssignRef($self->semStack[$stackPos - (4 - 1)], $self->semStack[$stackPos - (4 - 4)], $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]));
19381 if (!$self->phpVersion->allowsAssignNewByReference()) {
19382 $self->emitError(new Error('Cannot assign new by reference', $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos])));
19383 }
19384 }, 423 => null, 424 => null, 425 => static function ($self, $stackPos) {
19385 $self->semValue = new Expr\FuncCall(new Node\Name($self->semStack[$stackPos - (2 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos - (2 - 1)])), $self->semStack[$stackPos - (2 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
19386 }, 426 => static function ($self, $stackPos) {
19387 $self->semValue = new Expr\Clone_($self->semStack[$stackPos - (2 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
19388 }, 427 => static function ($self, $stackPos) {
19389 $self->semValue = new Expr\AssignOp\Plus($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
19390 }, 428 => static function ($self, $stackPos) {
19391 $self->semValue = new Expr\AssignOp\Minus($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
19392 }, 429 => static function ($self, $stackPos) {
19393 $self->semValue = new Expr\AssignOp\Mul($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
19394 }, 430 => static function ($self, $stackPos) {
19395 $self->semValue = new Expr\AssignOp\Div($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
19396 }, 431 => static function ($self, $stackPos) {
19397 $self->semValue = new Expr\AssignOp\Concat($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
19398 }, 432 => static function ($self, $stackPos) {
19399 $self->semValue = new Expr\AssignOp\Mod($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
19400 }, 433 => static function ($self, $stackPos) {
19401 $self->semValue = new Expr\AssignOp\BitwiseAnd($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
19402 }, 434 => static function ($self, $stackPos) {
19403 $self->semValue = new Expr\AssignOp\BitwiseOr($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
19404 }, 435 => static function ($self, $stackPos) {
19405 $self->semValue = new Expr\AssignOp\BitwiseXor($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
19406 }, 436 => static function ($self, $stackPos) {
19407 $self->semValue = new Expr\AssignOp\ShiftLeft($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
19408 }, 437 => static function ($self, $stackPos) {
19409 $self->semValue = new Expr\AssignOp\ShiftRight($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
19410 }, 438 => static function ($self, $stackPos) {
19411 $self->semValue = new Expr\AssignOp\Pow($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
19412 }, 439 => static function ($self, $stackPos) {
19413 $self->semValue = new Expr\AssignOp\Coalesce($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
19414 }, 440 => static function ($self, $stackPos) {
19415 $self->semValue = new Expr\PostInc($self->semStack[$stackPos - (2 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
19416 }, 441 => static function ($self, $stackPos) {
19417 $self->semValue = new Expr\PreInc($self->semStack[$stackPos - (2 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
19418 }, 442 => static function ($self, $stackPos) {
19419 $self->semValue = new Expr\PostDec($self->semStack[$stackPos - (2 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
19420 }, 443 => static function ($self, $stackPos) {
19421 $self->semValue = new Expr\PreDec($self->semStack[$stackPos - (2 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
19422 }, 444 => static function ($self, $stackPos) {
19423 $self->semValue = new Expr\BinaryOp\BooleanOr($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
19424 }, 445 => static function ($self, $stackPos) {
19425 $self->semValue = new Expr\BinaryOp\BooleanAnd($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
19426 }, 446 => static function ($self, $stackPos) {
19427 $self->semValue = new Expr\BinaryOp\LogicalOr($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
19428 }, 447 => static function ($self, $stackPos) {
19429 $self->semValue = new Expr\BinaryOp\LogicalAnd($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
19430 }, 448 => static function ($self, $stackPos) {
19431 $self->semValue = new Expr\BinaryOp\LogicalXor($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
19432 }, 449 => static function ($self, $stackPos) {
19433 $self->semValue = new Expr\BinaryOp\BitwiseOr($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
19434 }, 450 => static function ($self, $stackPos) {
19435 $self->semValue = new Expr\BinaryOp\BitwiseAnd($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
19436 }, 451 => static function ($self, $stackPos) {
19437 $self->semValue = new Expr\BinaryOp\BitwiseAnd($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
19438 }, 452 => static function ($self, $stackPos) {
19439 $self->semValue = new Expr\BinaryOp\BitwiseXor($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
19440 }, 453 => static function ($self, $stackPos) {
19441 $self->semValue = new Expr\BinaryOp\Concat($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
19442 }, 454 => static function ($self, $stackPos) {
19443 $self->semValue = new Expr\BinaryOp\Plus($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
19444 }, 455 => static function ($self, $stackPos) {
19445 $self->semValue = new Expr\BinaryOp\Minus($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
19446 }, 456 => static function ($self, $stackPos) {
19447 $self->semValue = new Expr\BinaryOp\Mul($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
19448 }, 457 => static function ($self, $stackPos) {
19449 $self->semValue = new Expr\BinaryOp\Div($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
19450 }, 458 => static function ($self, $stackPos) {
19451 $self->semValue = new Expr\BinaryOp\Mod($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
19452 }, 459 => static function ($self, $stackPos) {
19453 $self->semValue = new Expr\BinaryOp\ShiftLeft($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
19454 }, 460 => static function ($self, $stackPos) {
19455 $self->semValue = new Expr\BinaryOp\ShiftRight($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
19456 }, 461 => static function ($self, $stackPos) {
19457 $self->semValue = new Expr\BinaryOp\Pow($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
19458 }, 462 => static function ($self, $stackPos) {
19459 $self->semValue = new Expr\UnaryPlus($self->semStack[$stackPos - (2 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
19460 }, 463 => static function ($self, $stackPos) {
19461 $self->semValue = new Expr\UnaryMinus($self->semStack[$stackPos - (2 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
19462 }, 464 => static function ($self, $stackPos) {
19463 $self->semValue = new Expr\BooleanNot($self->semStack[$stackPos - (2 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
19464 }, 465 => static function ($self, $stackPos) {
19465 $self->semValue = new Expr\BitwiseNot($self->semStack[$stackPos - (2 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
19466 }, 466 => static function ($self, $stackPos) {
19467 $self->semValue = new Expr\BinaryOp\Identical($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
19468 }, 467 => static function ($self, $stackPos) {
19469 $self->semValue = new Expr\BinaryOp\NotIdentical($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
19470 }, 468 => static function ($self, $stackPos) {
19471 $self->semValue = new Expr\BinaryOp\Equal($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
19472 }, 469 => static function ($self, $stackPos) {
19473 $self->semValue = new Expr\BinaryOp\NotEqual($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
19474 }, 470 => static function ($self, $stackPos) {
19475 $self->semValue = new Expr\BinaryOp\Spaceship($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
19476 }, 471 => static function ($self, $stackPos) {
19477 $self->semValue = new Expr\BinaryOp\Smaller($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
19478 }, 472 => static function ($self, $stackPos) {
19479 $self->semValue = new Expr\BinaryOp\SmallerOrEqual($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
19480 }, 473 => static function ($self, $stackPos) {
19481 $self->semValue = new Expr\BinaryOp\Greater($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
19482 }, 474 => static function ($self, $stackPos) {
19483 $self->semValue = new Expr\BinaryOp\GreaterOrEqual($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
19484 }, 475 => static function ($self, $stackPos) {
19485 $self->semValue = new Expr\Instanceof_($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
19486 }, 476 => static function ($self, $stackPos) {
19487 $self->semValue = $self->semStack[$stackPos - (3 - 2)];
19488 if ($self->semValue instanceof Expr\ArrowFunction) {
19489 $self->parenthesizedArrowFunctions->offsetSet($self->semValue);
19490 }
19491 }, 477 => static function ($self, $stackPos) {
19492 $self->semValue = new Expr\Ternary($self->semStack[$stackPos - (5 - 1)], $self->semStack[$stackPos - (5 - 3)], $self->semStack[$stackPos - (5 - 5)], $self->getAttributes($self->tokenStartStack[$stackPos - (5 - 1)], $self->tokenEndStack[$stackPos]));
19493 }, 478 => static function ($self, $stackPos) {
19494 $self->semValue = new Expr\Ternary($self->semStack[$stackPos - (4 - 1)], null, $self->semStack[$stackPos - (4 - 4)], $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]));
19495 }, 479 => static function ($self, $stackPos) {
19496 $self->semValue = new Expr\BinaryOp\Coalesce($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
19497 }, 480 => static function ($self, $stackPos) {
19498 $self->semValue = new Expr\Isset_($self->semStack[$stackPos - (4 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]));
19499 }, 481 => static function ($self, $stackPos) {
19500 $self->semValue = new Expr\Empty_($self->semStack[$stackPos - (4 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]));
19501 }, 482 => static function ($self, $stackPos) {
19502 $self->semValue = new Expr\Include_($self->semStack[$stackPos - (2 - 2)], Expr\Include_::TYPE_INCLUDE, $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
19503 }, 483 => static function ($self, $stackPos) {
19504 $self->semValue = new Expr\Include_($self->semStack[$stackPos - (2 - 2)], Expr\Include_::TYPE_INCLUDE_ONCE, $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
19505 }, 484 => static function ($self, $stackPos) {
19506 $self->semValue = new Expr\Eval_($self->semStack[$stackPos - (4 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]));
19507 }, 485 => static function ($self, $stackPos) {
19508 $self->semValue = new Expr\Include_($self->semStack[$stackPos - (2 - 2)], Expr\Include_::TYPE_REQUIRE, $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
19509 }, 486 => static function ($self, $stackPos) {
19510 $self->semValue = new Expr\Include_($self->semStack[$stackPos - (2 - 2)], Expr\Include_::TYPE_REQUIRE_ONCE, $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
19511 }, 487 => static function ($self, $stackPos) {
19512 $attrs = $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]);
19513 $attrs['kind'] = $self->getIntCastKind($self->semStack[$stackPos - (2 - 1)]);
19514 $self->semValue = new Expr\Cast\Int_($self->semStack[$stackPos - (2 - 2)], $attrs);
19515 }, 488 => static function ($self, $stackPos) {
19516 $attrs = $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]);
19517 $attrs['kind'] = $self->getFloatCastKind($self->semStack[$stackPos - (2 - 1)]);
19518 $self->semValue = new Expr\Cast\Double($self->semStack[$stackPos - (2 - 2)], $attrs);
19519 }, 489 => static function ($self, $stackPos) {
19520 $attrs = $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]);
19521 $attrs['kind'] = $self->getStringCastKind($self->semStack[$stackPos - (2 - 1)]);
19522 $self->semValue = new Expr\Cast\String_($self->semStack[$stackPos - (2 - 2)], $attrs);
19523 }, 490 => static function ($self, $stackPos) {
19524 $self->semValue = new Expr\Cast\Array_($self->semStack[$stackPos - (2 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
19525 }, 491 => static function ($self, $stackPos) {
19526 $self->semValue = new Expr\Cast\Object_($self->semStack[$stackPos - (2 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
19527 }, 492 => static function ($self, $stackPos) {
19528 $attrs = $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]);
19529 $attrs['kind'] = $self->getBoolCastKind($self->semStack[$stackPos - (2 - 1)]);
19530 $self->semValue = new Expr\Cast\Bool_($self->semStack[$stackPos - (2 - 2)], $attrs);
19531 }, 493 => static function ($self, $stackPos) {
19532 $self->semValue = new Expr\Cast\Unset_($self->semStack[$stackPos - (2 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
19533 }, 494 => static function ($self, $stackPos) {
19534 $self->semValue = new Expr\Cast\Void_($self->semStack[$stackPos - (2 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
19535 }, 495 => static function ($self, $stackPos) {
19536 $self->semValue = $self->createExitExpr($self->semStack[$stackPos - (2 - 1)], $stackPos - (2 - 1), $self->semStack[$stackPos - (2 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
19537 }, 496 => static function ($self, $stackPos) {
19538 $self->semValue = new Expr\ErrorSuppress($self->semStack[$stackPos - (2 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
19539 }, 497 => null, 498 => static function ($self, $stackPos) {
19540 $self->semValue = new Expr\ShellExec($self->semStack[$stackPos - (3 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
19541 }, 499 => static function ($self, $stackPos) {
19542 $self->semValue = new Expr\Print_($self->semStack[$stackPos - (2 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
19543 }, 500 => static function ($self, $stackPos) {
19544 $self->semValue = new Expr\Yield_(null, null, $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
19545 }, 501 => static function ($self, $stackPos) {
19546 $self->semValue = new Expr\Yield_($self->semStack[$stackPos - (2 - 2)], null, $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
19547 }, 502 => static function ($self, $stackPos) {
19548 $self->semValue = new Expr\Yield_($self->semStack[$stackPos - (4 - 4)], $self->semStack[$stackPos - (4 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]));
19549 }, 503 => static function ($self, $stackPos) {
19550 $self->semValue = new Expr\YieldFrom($self->semStack[$stackPos - (2 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
19551 }, 504 => static function ($self, $stackPos) {
19552 $self->semValue = new Expr\Throw_($self->semStack[$stackPos - (2 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
19553 }, 505 => static function ($self, $stackPos) {
19554 $self->semValue = new Expr\ArrowFunction(['static' => \false, 'byRef' => $self->semStack[$stackPos - (8 - 2)], 'params' => $self->semStack[$stackPos - (8 - 4)], 'returnType' => $self->semStack[$stackPos - (8 - 6)], 'expr' => $self->semStack[$stackPos - (8 - 8)], 'attrGroups' => []], $self->getAttributes($self->tokenStartStack[$stackPos - (8 - 1)], $self->tokenEndStack[$stackPos]));
19555 }, 506 => static function ($self, $stackPos) {
19556 $self->semValue = new Expr\ArrowFunction(['static' => \true, 'byRef' => $self->semStack[$stackPos - (9 - 3)], 'params' => $self->semStack[$stackPos - (9 - 5)], 'returnType' => $self->semStack[$stackPos - (9 - 7)], 'expr' => $self->semStack[$stackPos - (9 - 9)], 'attrGroups' => []], $self->getAttributes($self->tokenStartStack[$stackPos - (9 - 1)], $self->tokenEndStack[$stackPos]));
19557 }, 507 => static function ($self, $stackPos) {
19558 $self->semValue = new Expr\Closure(['static' => \false, 'byRef' => $self->semStack[$stackPos - (8 - 2)], 'params' => $self->semStack[$stackPos - (8 - 4)], 'uses' => $self->semStack[$stackPos - (8 - 6)], 'returnType' => $self->semStack[$stackPos - (8 - 7)], 'stmts' => $self->semStack[$stackPos - (8 - 8)], 'attrGroups' => []], $self->getAttributes($self->tokenStartStack[$stackPos - (8 - 1)], $self->tokenEndStack[$stackPos]));
19559 }, 508 => static function ($self, $stackPos) {
19560 $self->semValue = new Expr\Closure(['static' => \true, 'byRef' => $self->semStack[$stackPos - (9 - 3)], 'params' => $self->semStack[$stackPos - (9 - 5)], 'uses' => $self->semStack[$stackPos - (9 - 7)], 'returnType' => $self->semStack[$stackPos - (9 - 8)], 'stmts' => $self->semStack[$stackPos - (9 - 9)], 'attrGroups' => []], $self->getAttributes($self->tokenStartStack[$stackPos - (9 - 1)], $self->tokenEndStack[$stackPos]));
19561 }, 509 => static function ($self, $stackPos) {
19562 $self->semValue = new Expr\ArrowFunction(['static' => \false, 'byRef' => $self->semStack[$stackPos - (9 - 3)], 'params' => $self->semStack[$stackPos - (9 - 5)], 'returnType' => $self->semStack[$stackPos - (9 - 7)], 'expr' => $self->semStack[$stackPos - (9 - 9)], 'attrGroups' => $self->semStack[$stackPos - (9 - 1)]], $self->getAttributes($self->tokenStartStack[$stackPos - (9 - 1)], $self->tokenEndStack[$stackPos]));
19563 }, 510 => static function ($self, $stackPos) {
19564 $self->semValue = new Expr\ArrowFunction(['static' => \true, 'byRef' => $self->semStack[$stackPos - (10 - 4)], 'params' => $self->semStack[$stackPos - (10 - 6)], 'returnType' => $self->semStack[$stackPos - (10 - 8)], 'expr' => $self->semStack[$stackPos - (10 - 10)], 'attrGroups' => $self->semStack[$stackPos - (10 - 1)]], $self->getAttributes($self->tokenStartStack[$stackPos - (10 - 1)], $self->tokenEndStack[$stackPos]));
19565 }, 511 => static function ($self, $stackPos) {
19566 $self->semValue = new Expr\Closure(['static' => \false, 'byRef' => $self->semStack[$stackPos - (9 - 3)], 'params' => $self->semStack[$stackPos - (9 - 5)], 'uses' => $self->semStack[$stackPos - (9 - 7)], 'returnType' => $self->semStack[$stackPos - (9 - 8)], 'stmts' => $self->semStack[$stackPos - (9 - 9)], 'attrGroups' => $self->semStack[$stackPos - (9 - 1)]], $self->getAttributes($self->tokenStartStack[$stackPos - (9 - 1)], $self->tokenEndStack[$stackPos]));
19567 }, 512 => static function ($self, $stackPos) {
19568 $self->semValue = new Expr\Closure(['static' => \true, 'byRef' => $self->semStack[$stackPos - (10 - 4)], 'params' => $self->semStack[$stackPos - (10 - 6)], 'uses' => $self->semStack[$stackPos - (10 - 8)], 'returnType' => $self->semStack[$stackPos - (10 - 9)], 'stmts' => $self->semStack[$stackPos - (10 - 10)], 'attrGroups' => $self->semStack[$stackPos - (10 - 1)]], $self->getAttributes($self->tokenStartStack[$stackPos - (10 - 1)], $self->tokenEndStack[$stackPos]));
19569 }, 513 => static function ($self, $stackPos) {
19570 $self->semValue = array(new Stmt\Class_(null, ['type' => $self->semStack[$stackPos - (8 - 2)], 'extends' => $self->semStack[$stackPos - (8 - 4)], 'implements' => $self->semStack[$stackPos - (8 - 5)], 'stmts' => $self->semStack[$stackPos - (8 - 7)], 'attrGroups' => $self->semStack[$stackPos - (8 - 1)]], $self->getAttributes($self->tokenStartStack[$stackPos - (8 - 1)], $self->tokenEndStack[$stackPos])), $self->semStack[$stackPos - (8 - 3)]);
19571 $self->checkClass($self->semValue[0], -1);
19572 }, 514 => static function ($self, $stackPos) {
19573 $self->semValue = new Expr\New_($self->semStack[$stackPos - (3 - 2)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
19574 }, 515 => static function ($self, $stackPos) {
19575 list($class, $ctorArgs) = $self->semStack[$stackPos - (2 - 2)];
19576 $self->semValue = new Expr\New_($class, $ctorArgs, $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
19577 }, 516 => static function ($self, $stackPos) {
19578 $self->semValue = new Expr\New_($self->semStack[$stackPos - (2 - 2)], [], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
19579 }, 517 => null, 518 => null, 519 => static function ($self, $stackPos) {
19580 $self->semValue = array();
19581 }, 520 => static function ($self, $stackPos) {
19582 $self->semValue = $self->semStack[$stackPos - (4 - 3)];
19583 }, 521 => null, 522 => static function ($self, $stackPos) {
19584 $self->semValue = array($self->semStack[$stackPos - (1 - 1)]);
19585 }, 523 => static function ($self, $stackPos) {
19586 $self->semStack[$stackPos - (3 - 1)][] = $self->semStack[$stackPos - (3 - 3)];
19587 $self->semValue = $self->semStack[$stackPos - (3 - 1)];
19588 }, 524 => static function ($self, $stackPos) {
19589 $self->semValue = new Node\ClosureUse($self->semStack[$stackPos - (2 - 2)], $self->semStack[$stackPos - (2 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
19590 }, 525 => static function ($self, $stackPos) {
19591 $self->semValue = new Name($self->semStack[$stackPos - (1 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
19592 }, 526 => static function ($self, $stackPos) {
19593 $self->semValue = new Expr\FuncCall($self->semStack[$stackPos - (2 - 1)], $self->semStack[$stackPos - (2 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
19594 }, 527 => static function ($self, $stackPos) {
19595 $self->semValue = new Expr\FuncCall($self->semStack[$stackPos - (2 - 1)], $self->semStack[$stackPos - (2 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
19596 }, 528 => static function ($self, $stackPos) {
19597 $self->semValue = new Expr\FuncCall($self->semStack[$stackPos - (2 - 1)], $self->semStack[$stackPos - (2 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
19598 }, 529 => static function ($self, $stackPos) {
19599 $self->semValue = new Expr\StaticCall($self->semStack[$stackPos - (4 - 1)], $self->semStack[$stackPos - (4 - 3)], $self->semStack[$stackPos - (4 - 4)], $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]));
19600 }, 530 => static function ($self, $stackPos) {
19601 $self->semValue = new Name($self->semStack[$stackPos - (1 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
19602 }, 531 => null, 532 => static function ($self, $stackPos) {
19603 $self->semValue = new Name($self->semStack[$stackPos - (1 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
19604 }, 533 => static function ($self, $stackPos) {
19605 $self->semValue = new Name($self->semStack[$stackPos - (1 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
19606 }, 534 => static function ($self, $stackPos) {
19607 $self->semValue = new Name\FullyQualified(substr($self->semStack[$stackPos - (1 - 1)], 1), $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
19608 }, 535 => static function ($self, $stackPos) {
19609 $self->semValue = new Name\Relative(substr($self->semStack[$stackPos - (1 - 1)], 10), $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
19610 }, 536 => null, 537 => null, 538 => static function ($self, $stackPos) {
19611 $self->semValue = $self->semStack[$stackPos - (3 - 2)];
19612 }, 539 => static function ($self, $stackPos) {
19613 $self->semValue = new Expr\Error($self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
19614 $self->errorState = 2;
19615 }, 540 => null, 541 => null, 542 => static function ($self, $stackPos) {
19616 $self->semValue = array();
19617 }, 543 => static function ($self, $stackPos) {
19618 $self->semValue = array($self->semStack[$stackPos - (1 - 1)]);
19619 foreach ($self->semValue as $s) {
19620 if ($s instanceof Node\InterpolatedStringPart) {
19621 $s->value = Node\Scalar\String_::parseEscapeSequences($s->value, '`', $self->phpVersion->supportsUnicodeEscapes());
19622 }
19623 }
19624 }, 544 => static function ($self, $stackPos) {
19625 foreach ($self->semStack[$stackPos - (1 - 1)] as $s) {
19626 if ($s instanceof Node\InterpolatedStringPart) {
19627 $s->value = Node\Scalar\String_::parseEscapeSequences($s->value, '`', $self->phpVersion->supportsUnicodeEscapes());
19628 }
19629 }
19630 $self->semValue = $self->semStack[$stackPos - (1 - 1)];
19631 }, 545 => static function ($self, $stackPos) {
19632 $self->semValue = array();
19633 }, 546 => null, 547 => static function ($self, $stackPos) {
19634 $self->semValue = new Expr\ConstFetch($self->semStack[$stackPos - (1 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
19635 }, 548 => static function ($self, $stackPos) {
19636 $self->semValue = new Scalar\MagicConst\Line($self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
19637 }, 549 => static function ($self, $stackPos) {
19638 $self->semValue = new Scalar\MagicConst\File($self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
19639 }, 550 => static function ($self, $stackPos) {
19640 $self->semValue = new Scalar\MagicConst\Dir($self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
19641 }, 551 => static function ($self, $stackPos) {
19642 $self->semValue = new Scalar\MagicConst\Class_($self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
19643 }, 552 => static function ($self, $stackPos) {
19644 $self->semValue = new Scalar\MagicConst\Trait_($self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
19645 }, 553 => static function ($self, $stackPos) {
19646 $self->semValue = new Scalar\MagicConst\Method($self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
19647 }, 554 => static function ($self, $stackPos) {
19648 $self->semValue = new Scalar\MagicConst\Function_($self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
19649 }, 555 => static function ($self, $stackPos) {
19650 $self->semValue = new Scalar\MagicConst\Namespace_($self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
19651 }, 556 => static function ($self, $stackPos) {
19652 $self->semValue = new Scalar\MagicConst\Property($self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
19653 }, 557 => static function ($self, $stackPos) {
19654 $self->semValue = new Expr\ClassConstFetch($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
19655 }, 558 => static function ($self, $stackPos) {
19656 $self->semValue = new Expr\ClassConstFetch($self->semStack[$stackPos - (5 - 1)], $self->semStack[$stackPos - (5 - 4)], $self->getAttributes($self->tokenStartStack[$stackPos - (5 - 1)], $self->tokenEndStack[$stackPos]));
19657 }, 559 => static function ($self, $stackPos) {
19658 $self->semValue = new Expr\ClassConstFetch($self->semStack[$stackPos - (3 - 1)], new Expr\Error($self->getAttributes($self->tokenStartStack[$stackPos - (3 - 3)], $self->tokenEndStack[$stackPos - (3 - 3)])), $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
19659 $self->errorState = 2;
19660 }, 560 => static function ($self, $stackPos) {
19661 $attrs = $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]);
19662 $attrs['kind'] = Expr\Array_::KIND_SHORT;
19663 $self->semValue = new Expr\Array_($self->semStack[$stackPos - (3 - 2)], $attrs);
19664 }, 561 => static function ($self, $stackPos) {
19665 $attrs = $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]);
19666 $attrs['kind'] = Expr\Array_::KIND_LONG;
19667 $self->semValue = new Expr\Array_($self->semStack[$stackPos - (4 - 3)], $attrs);
19668 $self->createdArrays->offsetSet($self->semValue);
19669 }, 562 => static function ($self, $stackPos) {
19670 $self->semValue = $self->semStack[$stackPos - (1 - 1)];
19671 $self->createdArrays->offsetSet($self->semValue);
19672 }, 563 => static function ($self, $stackPos) {
19673 $self->semValue = Scalar\String_::fromString($self->semStack[$stackPos - (1 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]), $self->phpVersion->supportsUnicodeEscapes());
19674 }, 564 => static function ($self, $stackPos) {
19675 $attrs = $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]);
19676 $attrs['kind'] = Scalar\String_::KIND_DOUBLE_QUOTED;
19677 foreach ($self->semStack[$stackPos - (3 - 2)] as $s) {
19678 if ($s instanceof Node\InterpolatedStringPart) {
19679 $s->value = Node\Scalar\String_::parseEscapeSequences($s->value, '"', $self->phpVersion->supportsUnicodeEscapes());
19680 }
19681 }
19682 $self->semValue = new Scalar\InterpolatedString($self->semStack[$stackPos - (3 - 2)], $attrs);
19683 }, 565 => static function ($self, $stackPos) {
19684 $self->semValue = $self->parseLNumber($self->semStack[$stackPos - (1 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]), $self->phpVersion->allowsInvalidOctals());
19685 }, 566 => static function ($self, $stackPos) {
19686 $self->semValue = Scalar\Float_::fromString($self->semStack[$stackPos - (1 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
19687 }, 567 => null, 568 => null, 569 => null, 570 => static function ($self, $stackPos) {
19688 $self->semValue = $self->parseDocString($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 2)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]), $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 3)], $self->tokenEndStack[$stackPos - (3 - 3)]), \true);
19689 }, 571 => static function ($self, $stackPos) {
19690 $self->semValue = $self->parseDocString($self->semStack[$stackPos - (2 - 1)], '', $self->semStack[$stackPos - (2 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]), $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 2)], $self->tokenEndStack[$stackPos - (2 - 2)]), \true);
19691 }, 572 => static function ($self, $stackPos) {
19692 $self->semValue = $self->parseDocString($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 2)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]), $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 3)], $self->tokenEndStack[$stackPos - (3 - 3)]), \true);
19693 }, 573 => static function ($self, $stackPos) {
19694 $self->semValue = null;
19695 }, 574 => null, 575 => null, 576 => static function ($self, $stackPos) {
19696 $self->semValue = $self->semStack[$stackPos - (3 - 2)];
19697 }, 577 => null, 578 => null, 579 => null, 580 => null, 581 => null, 582 => null, 583 => static function ($self, $stackPos) {
19698 $self->semValue = $self->semStack[$stackPos - (3 - 2)];
19699 }, 584 => null, 585 => null, 586 => null, 587 => static function ($self, $stackPos) {
19700 $self->semValue = new Expr\ArrayDimFetch($self->semStack[$stackPos - (4 - 1)], $self->semStack[$stackPos - (4 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]));
19701 }, 588 => static function ($self, $stackPos) {
19702 $self->semValue = new Expr\ArrayDimFetch($self->semStack[$stackPos - (4 - 1)], $self->semStack[$stackPos - (4 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]));
19703 }, 589 => null, 590 => static function ($self, $stackPos) {
19704 $self->semValue = new Expr\MethodCall($self->semStack[$stackPos - (4 - 1)], $self->semStack[$stackPos - (4 - 3)], $self->semStack[$stackPos - (4 - 4)], $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]));
19705 }, 591 => static function ($self, $stackPos) {
19706 $self->semValue = new Expr\NullsafeMethodCall($self->semStack[$stackPos - (4 - 1)], $self->semStack[$stackPos - (4 - 3)], $self->semStack[$stackPos - (4 - 4)], $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]));
19707 }, 592 => static function ($self, $stackPos) {
19708 $self->semValue = null;
19709 }, 593 => null, 594 => null, 595 => null, 596 => static function ($self, $stackPos) {
19710 $self->semValue = new Expr\PropertyFetch($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
19711 }, 597 => static function ($self, $stackPos) {
19712 $self->semValue = new Expr\NullsafePropertyFetch($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
19713 }, 598 => null, 599 => static function ($self, $stackPos) {
19714 $self->semValue = new Expr\Variable($self->semStack[$stackPos - (4 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]));
19715 }, 600 => static function ($self, $stackPos) {
19716 $self->semValue = new Expr\Variable($self->semStack[$stackPos - (2 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
19717 }, 601 => static function ($self, $stackPos) {
19718 $self->semValue = new Expr\Variable(new Expr\Error($self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos])), $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
19719 $self->errorState = 2;
19720 }, 602 => static function ($self, $stackPos) {
19721 $var = $self->semStack[$stackPos - (1 - 1)]->name;
19722 $self->semValue = \is_string($var) ? new Node\VarLikeIdentifier($var, $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos])) : $var;
19723 }, 603 => static function ($self, $stackPos) {
19724 $self->semValue = new Expr\StaticPropertyFetch($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
19725 }, 604 => null, 605 => static function ($self, $stackPos) {
19726 $self->semValue = new Expr\ArrayDimFetch($self->semStack[$stackPos - (4 - 1)], $self->semStack[$stackPos - (4 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]));
19727 }, 606 => static function ($self, $stackPos) {
19728 $self->semValue = new Expr\ArrayDimFetch($self->semStack[$stackPos - (4 - 1)], $self->semStack[$stackPos - (4 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]));
19729 }, 607 => static function ($self, $stackPos) {
19730 $self->semValue = new Expr\PropertyFetch($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
19731 }, 608 => static function ($self, $stackPos) {
19732 $self->semValue = new Expr\NullsafePropertyFetch($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
19733 }, 609 => static function ($self, $stackPos) {
19734 $self->semValue = new Expr\StaticPropertyFetch($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
19735 }, 610 => static function ($self, $stackPos) {
19736 $self->semValue = new Expr\StaticPropertyFetch($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
19737 }, 611 => null, 612 => static function ($self, $stackPos) {
19738 $self->semValue = $self->semStack[$stackPos - (3 - 2)];
19739 }, 613 => null, 614 => null, 615 => static function ($self, $stackPos) {
19740 $self->semValue = $self->semStack[$stackPos - (3 - 2)];
19741 }, 616 => null, 617 => static function ($self, $stackPos) {
19742 $self->semValue = new Expr\Error($self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
19743 $self->errorState = 2;
19744 }, 618 => static function ($self, $stackPos) {
19745 $self->semValue = new Expr\List_($self->semStack[$stackPos - (4 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]));
19746 $self->semValue->setAttribute('kind', Expr\List_::KIND_LIST);
19747 $self->postprocessList($self->semValue);
19748 }, 619 => static function ($self, $stackPos) {
19749 $self->semValue = $self->semStack[$stackPos - (1 - 1)];
19750 $end = count($self->semValue) - 1;
19751 if ($self->semValue[$end]->value instanceof Expr\Error) {
19752 array_pop($self->semValue);
19753 }
19754 }, 620 => null, 621 => static function ($self, $stackPos) {
19755 /* do nothing -- prevent default action of $$=$self->semStack[$1]. See $551. */
19756 }, 622 => static function ($self, $stackPos) {
19757 $self->semStack[$stackPos - (3 - 1)][] = $self->semStack[$stackPos - (3 - 3)];
19758 $self->semValue = $self->semStack[$stackPos - (3 - 1)];
19759 }, 623 => static function ($self, $stackPos) {
19760 $self->semValue = array($self->semStack[$stackPos - (1 - 1)]);
19761 }, 624 => static function ($self, $stackPos) {
19762 $self->semValue = new Node\ArrayItem($self->semStack[$stackPos - (1 - 1)], null, \false, $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
19763 }, 625 => static function ($self, $stackPos) {
19764 $self->semValue = new Node\ArrayItem($self->semStack[$stackPos - (2 - 2)], null, \true, $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
19765 }, 626 => static function ($self, $stackPos) {
19766 $self->semValue = new Node\ArrayItem($self->semStack[$stackPos - (1 - 1)], null, \false, $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
19767 }, 627 => static function ($self, $stackPos) {
19768 $self->semValue = new Node\ArrayItem($self->semStack[$stackPos - (3 - 3)], $self->semStack[$stackPos - (3 - 1)], \false, $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
19769 }, 628 => static function ($self, $stackPos) {
19770 $self->semValue = new Node\ArrayItem($self->semStack[$stackPos - (4 - 4)], $self->semStack[$stackPos - (4 - 1)], \true, $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]));
19771 }, 629 => static function ($self, $stackPos) {
19772 $self->semValue = new Node\ArrayItem($self->semStack[$stackPos - (3 - 3)], $self->semStack[$stackPos - (3 - 1)], \false, $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
19773 }, 630 => static function ($self, $stackPos) {
19774 $self->semValue = new Node\ArrayItem($self->semStack[$stackPos - (2 - 2)], null, \false, $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]), \true);
19775 }, 631 => static function ($self, $stackPos) {
19776 /* Create an Error node now to remember the position. We'll later either report an error,
19777 or convert this into a null element, depending on whether this is a creation or destructuring context. */
19778 $attrs = $self->createEmptyElemAttributes($self->tokenPos);
19779 $self->semValue = new Node\ArrayItem(new Expr\Error($attrs), null, \false, $attrs);
19780 }, 632 => static function ($self, $stackPos) {
19781 $self->semStack[$stackPos - (2 - 1)][] = $self->semStack[$stackPos - (2 - 2)];
19782 $self->semValue = $self->semStack[$stackPos - (2 - 1)];
19783 }, 633 => static function ($self, $stackPos) {
19784 $self->semStack[$stackPos - (2 - 1)][] = $self->semStack[$stackPos - (2 - 2)];
19785 $self->semValue = $self->semStack[$stackPos - (2 - 1)];
19786 }, 634 => static function ($self, $stackPos) {
19787 $self->semValue = array($self->semStack[$stackPos - (1 - 1)]);
19788 }, 635 => static function ($self, $stackPos) {
19789 $self->semValue = array($self->semStack[$stackPos - (2 - 1)], $self->semStack[$stackPos - (2 - 2)]);
19790 }, 636 => static function ($self, $stackPos) {
19791 $attrs = $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]);
19792 $attrs['rawValue'] = $self->semStack[$stackPos - (1 - 1)];
19793 $self->semValue = new Node\InterpolatedStringPart($self->semStack[$stackPos - (1 - 1)], $attrs);
19794 }, 637 => static function ($self, $stackPos) {
19795 $self->semValue = new Expr\Variable($self->semStack[$stackPos - (1 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
19796 }, 638 => null, 639 => static function ($self, $stackPos) {
19797 $self->semValue = new Expr\ArrayDimFetch($self->semStack[$stackPos - (4 - 1)], $self->semStack[$stackPos - (4 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]));
19798 }, 640 => static function ($self, $stackPos) {
19799 $self->semValue = new Expr\PropertyFetch($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
19800 }, 641 => static function ($self, $stackPos) {
19801 $self->semValue = new Expr\NullsafePropertyFetch($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
19802 }, 642 => static function ($self, $stackPos) {
19803 $self->semValue = new Expr\Variable($self->semStack[$stackPos - (3 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
19804 }, 643 => static function ($self, $stackPos) {
19805 $self->semValue = new Expr\Variable($self->semStack[$stackPos - (3 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
19806 }, 644 => static function ($self, $stackPos) {
19807 $self->semValue = new Expr\ArrayDimFetch($self->semStack[$stackPos - (6 - 2)], $self->semStack[$stackPos - (6 - 4)], $self->getAttributes($self->tokenStartStack[$stackPos - (6 - 1)], $self->tokenEndStack[$stackPos]));
19808 }, 645 => static function ($self, $stackPos) {
19809 $self->semValue = $self->semStack[$stackPos - (3 - 2)];
19810 }, 646 => static function ($self, $stackPos) {
19811 $self->semValue = new Scalar\String_($self->semStack[$stackPos - (1 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
19812 }, 647 => static function ($self, $stackPos) {
19813 $self->semValue = $self->parseNumString($self->semStack[$stackPos - (1 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
19814 }, 648 => static function ($self, $stackPos) {
19815 $self->semValue = $self->parseNumString('-' . $self->semStack[$stackPos - (2 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
19816 }, 649 => null];
19817 }
19818 }
19819 <?php
19820
19821 declare (strict_types=1);
19822 namespace PHPUnitPHAR\PhpParser\Parser;
19823
19824 use PHPUnitPHAR\PhpParser\Error;
19825 use PHPUnitPHAR\PhpParser\Modifiers;
19826 use PHPUnitPHAR\PhpParser\Node;
19827 use PHPUnitPHAR\PhpParser\Node\Expr;
19828 use PHPUnitPHAR\PhpParser\Node\Name;
19829 use PHPUnitPHAR\PhpParser\Node\Scalar;
19830 use PHPUnitPHAR\PhpParser\Node\Stmt;
19831 /* This is an automatically GENERATED file, which should not be manually edited.
19832 * Instead edit one of the following:
19833 * * the grammar file grammar/php.y
19834 * * the skeleton file grammar/parser.template
19835 * * the preprocessing script grammar/rebuildParsers.php
19836 */
19837 class Php8 extends \PHPUnitPHAR\PhpParser\ParserAbstract
19838 {
19839 public const YYERRTOK = 256;
19840 public const T_VOID_CAST = 257;
19841 public const T_THROW = 258;
19842 public const T_INCLUDE = 259;
19843 public const T_INCLUDE_ONCE = 260;
19844 public const T_EVAL = 261;
19845 public const T_REQUIRE = 262;
19846 public const T_REQUIRE_ONCE = 263;
19847 public const T_LOGICAL_OR = 264;
19848 public const T_LOGICAL_XOR = 265;
19849 public const T_LOGICAL_AND = 266;
19850 public const T_PRINT = 267;
19851 public const T_YIELD = 268;
19852 public const T_DOUBLE_ARROW = 269;
19853 public const T_YIELD_FROM = 270;
19854 public const T_PLUS_EQUAL = 271;
19855 public const T_MINUS_EQUAL = 272;
19856 public const T_MUL_EQUAL = 273;
19857 public const T_DIV_EQUAL = 274;
19858 public const T_CONCAT_EQUAL = 275;
19859 public const T_MOD_EQUAL = 276;
19860 public const T_AND_EQUAL = 277;
19861 public const T_OR_EQUAL = 278;
19862 public const T_XOR_EQUAL = 279;
19863 public const T_SL_EQUAL = 280;
19864 public const T_SR_EQUAL = 281;
19865 public const T_POW_EQUAL = 282;
19866 public const T_COALESCE_EQUAL = 283;
19867 public const T_COALESCE = 284;
19868 public const T_BOOLEAN_OR = 285;
19869 public const T_BOOLEAN_AND = 286;
19870 public const T_AMPERSAND_NOT_FOLLOWED_BY_VAR_OR_VARARG = 287;
19871 public const T_AMPERSAND_FOLLOWED_BY_VAR_OR_VARARG = 288;
19872 public const T_IS_EQUAL = 289;
19873 public const T_IS_NOT_EQUAL = 290;
19874 public const T_IS_IDENTICAL = 291;
19875 public const T_IS_NOT_IDENTICAL = 292;
19876 public const T_SPACESHIP = 293;
19877 public const T_IS_SMALLER_OR_EQUAL = 294;
19878 public const T_IS_GREATER_OR_EQUAL = 295;
19879 public const T_PIPE = 296;
19880 public const T_SL = 297;
19881 public const T_SR = 298;
19882 public const T_INSTANCEOF = 299;
19883 public const T_INC = 300;
19884 public const T_DEC = 301;
19885 public const T_INT_CAST = 302;
19886 public const T_DOUBLE_CAST = 303;
19887 public const T_STRING_CAST = 304;
19888 public const T_ARRAY_CAST = 305;
19889 public const T_OBJECT_CAST = 306;
19890 public const T_BOOL_CAST = 307;
19891 public const T_UNSET_CAST = 308;
19892 public const T_POW = 309;
19893 public const T_NEW = 310;
19894 public const T_CLONE = 311;
19895 public const T_EXIT = 312;
19896 public const T_IF = 313;
19897 public const T_ELSEIF = 314;
19898 public const T_ELSE = 315;
19899 public const T_ENDIF = 316;
19900 public const T_LNUMBER = 317;
19901 public const T_DNUMBER = 318;
19902 public const T_STRING = 319;
19903 public const T_STRING_VARNAME = 320;
19904 public const T_VARIABLE = 321;
19905 public const T_NUM_STRING = 322;
19906 public const T_INLINE_HTML = 323;
19907 public const T_ENCAPSED_AND_WHITESPACE = 324;
19908 public const T_CONSTANT_ENCAPSED_STRING = 325;
19909 public const T_ECHO = 326;
19910 public const T_DO = 327;
19911 public const T_WHILE = 328;
19912 public const T_ENDWHILE = 329;
19913 public const T_FOR = 330;
19914 public const T_ENDFOR = 331;
19915 public const T_FOREACH = 332;
19916 public const T_ENDFOREACH = 333;
19917 public const T_DECLARE = 334;
19918 public const T_ENDDECLARE = 335;
19919 public const T_AS = 336;
19920 public const T_SWITCH = 337;
19921 public const T_MATCH = 338;
19922 public const T_ENDSWITCH = 339;
19923 public const T_CASE = 340;
19924 public const T_DEFAULT = 341;
19925 public const T_BREAK = 342;
19926 public const T_CONTINUE = 343;
19927 public const T_GOTO = 344;
19928 public const T_FUNCTION = 345;
19929 public const T_FN = 346;
19930 public const T_CONST = 347;
19931 public const T_RETURN = 348;
19932 public const T_TRY = 349;
19933 public const T_CATCH = 350;
19934 public const T_FINALLY = 351;
19935 public const T_USE = 352;
19936 public const T_INSTEADOF = 353;
19937 public const T_GLOBAL = 354;
19938 public const T_STATIC = 355;
19939 public const T_ABSTRACT = 356;
19940 public const T_FINAL = 357;
19941 public const T_PRIVATE = 358;
19942 public const T_PROTECTED = 359;
19943 public const T_PUBLIC = 360;
19944 public const T_READONLY = 361;
19945 public const T_PUBLIC_SET = 362;
19946 public const T_PROTECTED_SET = 363;
19947 public const T_PRIVATE_SET = 364;
19948 public const T_VAR = 365;
19949 public const T_UNSET = 366;
19950 public const T_ISSET = 367;
19951 public const T_EMPTY = 368;
19952 public const T_HALT_COMPILER = 369;
19953 public const T_CLASS = 370;
19954 public const T_TRAIT = 371;
19955 public const T_INTERFACE = 372;
19956 public const T_ENUM = 373;
19957 public const T_EXTENDS = 374;
19958 public const T_IMPLEMENTS = 375;
19959 public const T_OBJECT_OPERATOR = 376;
19960 public const T_NULLSAFE_OBJECT_OPERATOR = 377;
19961 public const T_LIST = 378;
19962 public const T_ARRAY = 379;
19963 public const T_CALLABLE = 380;
19964 public const T_CLASS_C = 381;
19965 public const T_TRAIT_C = 382;
19966 public const T_METHOD_C = 383;
19967 public const T_FUNC_C = 384;
19968 public const T_PROPERTY_C = 385;
19969 public const T_LINE = 386;
19970 public const T_FILE = 387;
19971 public const T_START_HEREDOC = 388;
19972 public const T_END_HEREDOC = 389;
19973 public const T_DOLLAR_OPEN_CURLY_BRACES = 390;
19974 public const T_CURLY_OPEN = 391;
19975 public const T_PAAMAYIM_NEKUDOTAYIM = 392;
19976 public const T_NAMESPACE = 393;
19977 public const T_NS_C = 394;
19978 public const T_DIR = 395;
19979 public const T_NS_SEPARATOR = 396;
19980 public const T_ELLIPSIS = 397;
19981 public const T_NAME_FULLY_QUALIFIED = 398;
19982 public const T_NAME_QUALIFIED = 399;
19983 public const T_NAME_RELATIVE = 400;
19984 public const T_ATTRIBUTE = 401;
19985 protected int $tokenToSymbolMapSize = 402;
19986 protected int $actionTableSize = 1537;
19987 protected int $gotoTableSize = 642;
19988 protected int $invalidSymbol = 174;
19989 protected int $errorSymbol = 1;
19990 protected int $defaultAction = -32766;
19991 protected int $unexpectedTokenRule = 32767;
19992 protected int $YY2TBLSTATE = 452;
19993 protected int $numNonLeafStates = 767;
19994 protected array $symbolToName = array("EOF", "error", "T_VOID_CAST", "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_PIPE", "'.'", "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_PUBLIC_SET", "T_PROTECTED_SET", "T_PRIVATE_SET", "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_PROPERTY_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", "';'", "']'", "'('", "')'", "'{'", "'}'", "'`'", "'\"'", "'\$'");
19995 protected array $tokenToSymbol = array(0, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 58, 172, 174, 173, 57, 174, 174, 167, 168, 55, 53, 9, 54, 50, 56, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 32, 165, 45, 17, 47, 31, 70, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 72, 174, 166, 37, 174, 171, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 169, 36, 170, 60, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 12, 13, 14, 15, 16, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 33, 34, 35, 38, 39, 40, 41, 42, 43, 44, 46, 48, 49, 51, 52, 59, 61, 62, 63, 64, 65, 66, 67, 68, 69, 71, 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, 159, 160, 161, 162, 163, 164);
19996 protected array $action = array(132, 133, 134, 582, 135, 136, 162, 779, 780, 781, 137, 41, 863, -32766, 970, 1404, -584, 974, 973, 1302, 0, 395, 396, 455, 246, 854, -32766, -32766, -32766, -32766, -32766, 440, -32766, 27, -32766, 773, 772, -32766, -32766, -32766, -32766, 508, -32766, -32766, -32766, -32766, -32766, -32766, -32766, -32766, 131, -32766, -32766, -32766, -32766, 437, 782, 859, 1148, -32766, 949, -32766, -32766, -32766, -32766, -32766, -32766, 972, 1385, 300, 271, 53, 398, 786, 787, 788, 789, 305, 865, 441, -341, 39, 254, -584, -584, -195, 843, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 819, 583, 820, 821, 822, 823, 811, 812, 353, 354, 814, 815, 800, 801, 802, 804, 805, 806, 368, 846, 847, 848, 849, 850, 584, 1062, -194, 856, 807, 808, 585, 586, 3, 831, 829, 830, 842, 826, 827, 4, 860, 587, 588, 825, 589, 590, 591, 592, 939, 593, 594, 5, 854, -32766, -32766, -32766, 828, 595, 596, -32766, 138, 764, 132, 133, 134, 582, 135, 136, 1098, 779, 780, 781, 137, 41, -32766, -32766, -32766, -32766, -32766, -32766, -275, 1302, 613, 153, 1071, 749, 990, 991, -32766, -32766, -32766, 992, -32766, 891, -32766, 892, -32766, 773, 772, -32766, 986, 1309, 397, 396, -32766, -32766, -32766, 858, 299, 630, -32766, -32766, 440, 502, 736, -32766, -32766, 437, 782, -32767, -32767, -32767, -32767, 106, 107, 108, 109, 951, -32766, 1021, 29, 734, 271, 53, 398, 786, 787, 788, 789, 144, 1071, 441, -341, 332, 38, 864, 862, -195, 843, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 819, 583, 820, 821, 822, 823, 811, 812, 353, 354, 814, 815, 800, 801, 802, 804, 805, 806, 368, 846, 847, 848, 849, 850, 584, 863, -194, 139, 807, 808, 585, 586, 323, 831, 829, 830, 842, 826, 827, 1370, 148, 587, 588, 825, 589, 590, 591, 592, 245, 593, 594, 395, 396, -32766, -32766, -32766, 828, 595, 596, -85, 138, 440, 132, 133, 134, 582, 135, 136, 1095, 779, 780, 781, 137, 41, -32766, -32766, -32766, -32766, -32766, 51, 578, 1302, 257, -32766, 636, 107, 108, 109, -32766, -32766, -32766, 503, -32766, 316, -32766, -32766, -32766, 773, 772, -32766, -383, 166, -383, 1022, -32766, -32766, -32766, 305, 79, 1133, -32766, -32766, 1414, 762, 332, 1415, -32766, 437, 782, -32766, 1071, 110, 111, 112, 113, 114, -85, 283, -32766, 477, 478, 479, 271, 53, 398, 786, 787, 788, 789, 115, 407, 441, 10, -32766, 299, 1341, 306, 307, 843, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 819, 583, 820, 821, 822, 823, 811, 812, 353, 354, 814, 815, 800, 801, 802, 804, 805, 806, 368, 846, 847, 848, 849, 850, 584, 320, 1068, -582, 807, 808, 585, 586, 1389, 831, 829, 830, 842, 826, 827, 329, 1388, 587, 588, 825, 589, 590, 591, 592, 86, 593, 594, 1071, 332, -32766, -32766, -32766, 828, 595, 596, 349, 151, -581, 132, 133, 134, 582, 135, 136, 1100, 779, 780, 781, 137, 41, -32766, 290, -32766, -32766, -32766, -32766, -32766, -32766, -32766, -32767, -32767, -32767, -32767, -32767, -32766, -32766, -32766, 891, 1175, 892, -582, -582, 754, 773, 772, 1159, 1160, 1161, 1155, 1154, 1153, 1162, 1156, 1157, 1158, -32766, -582, -32766, -32766, -32766, -32766, -32766, -32766, -32766, 782, -32766, -32766, -32766, -588, -78, -32766, -32766, -32766, 350, -581, -581, -32766, -32766, 271, 53, 398, 786, 787, 788, 789, 383, -32766, 441, -32766, -32766, -581, -32766, 773, 772, 843, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 819, 583, 820, 821, 822, 823, 811, 812, 353, 354, 814, 815, 800, 801, 802, 804, 805, 806, 368, 846, 847, 848, 849, 850, 584, -620, 1068, -620, 807, 808, 585, 586, 389, 831, 829, 830, 842, 826, 827, 441, 405, 587, 588, 825, 589, 590, 591, 592, 333, 593, 594, 1071, 87, 88, 89, 459, 828, 595, 596, 460, 151, 803, 774, 775, 776, 777, 778, 854, 779, 780, 781, 816, 817, 40, 461, 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, 462, 283, 1329, 1159, 1160, 1161, 1155, 1154, 1153, 1162, 1156, 1157, 1158, 115, 869, 488, 489, 782, 1304, 1303, 1305, 108, 109, 1132, 154, -32766, -32766, 1134, 679, 23, 156, 783, 784, 785, 786, 787, 788, 789, 698, 699, 852, 152, 423, -580, 393, 394, 157, 843, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 819, 841, 820, 821, 822, 823, 811, 812, 813, 840, 814, 815, 800, 801, 802, 804, 805, 806, 845, 846, 847, 848, 849, 850, 851, 1094, -578, 863, 807, 808, 809, 810, -58, 831, 829, 830, 842, 826, 827, 399, 400, 818, 824, 825, 832, 833, 835, 834, 294, 836, 837, 158, -580, -580, 160, 294, 828, 839, 838, 54, 55, 56, 57, 534, 58, 59, 36, -110, -580, -57, 60, 61, -110, 62, -110, 670, 671, 129, 130, 312, -587, 140, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -578, -578, 141, 147, 949, 161, 712, -87, 163, 164, 165, -84, 949, -78, -73, -72, -578, 63, 64, 143, -309, -71, 65, 332, 66, 251, 252, 67, 68, 69, 70, 71, 72, 73, 74, 739, 31, 276, 47, 457, 535, -357, 713, 740, 1335, 1336, 536, -70, 863, 1068, -69, -68, 1333, 45, 22, 537, 949, 538, -67, 539, -66, 540, 52, -65, 541, 542, 714, 715, -46, 48, 49, 463, 392, 391, 1071, 50, 543, -18, 145, 281, 1302, 381, 348, 291, 750, 1304, 1303, 1305, 1295, 939, 753, 290, 948, 545, 546, 547, 150, 939, 290, -305, 295, 288, 289, 292, 293, 549, 550, 338, 1321, 1322, 1323, 1324, 1326, 1318, 1319, 304, 1300, 296, 301, 302, 283, 1325, 1320, 773, 772, 1304, 1303, 1305, 305, 308, 309, 75, -154, -154, -154, 327, 328, 332, 966, 854, 1070, 939, 149, 115, 1416, 388, 680, -154, 708, -154, 725, -154, 13, -154, 668, 723, 313, 31, 277, 1304, 1303, 1305, 863, 390, -32766, 600, 1166, 987, 951, 863, 310, 701, 734, 1333, 990, 991, 951, -32766, 686, 544, 734, 949, 685, 606, 1340, 485, 513, 925, 986, -110, -110, -110, 35, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 702, 949, 634, 1295, 773, 772, 741, -579, 305, -614, 1334, 0, 0, 0, 951, 311, 949, 0, 734, -154, 549, 550, 319, 1321, 1322, 1323, 1324, 1326, 1318, 1319, 1209, 1211, 744, 0, 1342, 0, 1325, 1320, -544, -534, 0, -578, -32766, -4, 949, 11, 77, 751, 1302, 30, 387, 328, 332, 862, 43, -32766, -32766, -32766, -613, -32766, 939, -32766, 968, -32766, 44, 759, -32766, 1330, 773, 772, 760, -32766, -32766, -32766, -579, -579, 882, -32766, -32766, 930, 1031, 1008, 1015, -32766, 437, 1005, 939, 1016, 928, 1003, -579, 1137, 1140, 1141, 1138, -32766, 1177, 1139, 1145, 37, 874, 939, -586, 1357, 1374, 1407, -32766, 673, -578, -578, -612, -588, 1302, -587, -586, -585, 31, 276, -528, -32766, -32766, -32766, 1, -32766, -578, -32766, 78, -32766, 863, 939, -32766, 32, 1333, -278, 33, -32766, -32766, -32766, 42, 1007, 46, -32766, -32766, 734, 76, 80, 81, -32766, 437, 82, 83, 390, 84, 453, 31, 277, 85, 146, 303, -32766, 155, 159, 990, 991, 249, 951, 863, 544, 1295, 734, 1333, 334, 369, 370, 371, 548, 986, -110, -110, -110, 951, 372, 326, 373, 734, 374, 550, 375, 1321, 1322, 1323, 1324, 1326, 1318, 1319, 376, 377, 422, 378, 21, -50, 1325, 1320, 379, 382, 454, 1295, 577, 951, 380, 384, 77, 734, -4, -276, -275, 328, 332, 15, 16, 17, 18, 20, 363, 550, 421, 1321, 1322, 1323, 1324, 1326, 1318, 1319, 142, 504, 505, 512, 515, 516, 1325, 1320, 949, 517, 518, -32766, 522, 523, 524, 531, 77, 1302, 611, 718, 1101, 328, 332, 1097, -32766, -32766, -32766, 1250, -32766, 1331, -32766, 949, -32766, 1099, 1096, -32766, 1077, 1290, 1309, 1073, -32766, -32766, -32766, -280, -32766, -102, -32766, -32766, 14, 19, 1302, 24, -32766, 437, 323, 420, 625, -32766, -32766, -32766, 631, -32766, 659, -32766, -32766, -32766, 724, 1254, -32766, -16, 1308, 1251, 1386, -32766, -32766, -32766, 735, -32766, 738, -32766, -32766, 742, 743, 1302, 745, -32766, 437, 746, 747, 748, -32766, -32766, -32766, 939, -32766, 300, -32766, -32766, -32766, 752, 1309, -32766, 764, 737, 332, 765, -32766, -32766, -32766, -253, -253, -253, -32766, -32766, 426, 390, 939, 756, -32766, 437, 926, 863, 1411, 1413, 885, 884, 990, 991, 980, 1023, -32766, 544, -252, -252, -252, 1412, 979, 977, 390, 925, 986, -110, -110, -110, 978, 981, 1283, 959, 969, 990, 991, 957, 1176, 1172, 544, 1126, -110, -110, 1013, 1014, 657, -110, 925, 986, -110, -110, -110, 1410, 2, 1368, -110, 1268, 951, 1383, 0, 0, 734, -253, 0, -32766, 0, 0, -32766, 863, 1059, 1054, 1053, 1052, 1058, 1055, 1056, 1057, 0, 0, 0, 951, 0, 0, 0, 734, -252, 305, 0, 0, 79, 0, 0, 1071, 0, 0, 332, 0, 0, 0, 0, 0, 0, 0, -110, -110, 0, 0, 0, -110, 0, 0, 0, 0, 0, 0, 0, 299, -110, 0, 0, 0, 0, 0, 0, 0, 0, -32766, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 305, 0, 0, 79, 0, 0, 0, 0, 0, 332);
19997 protected array $actionCheck = array(3, 4, 5, 6, 7, 8, 17, 10, 11, 12, 13, 14, 84, 76, 1, 87, 72, 74, 75, 82, 0, 108, 109, 110, 15, 82, 89, 90, 91, 10, 93, 118, 95, 103, 97, 38, 39, 100, 10, 11, 12, 104, 105, 106, 107, 10, 11, 12, 111, 112, 15, 10, 11, 12, 117, 118, 59, 82, 128, 31, 1, 33, 34, 35, 36, 37, 129, 124, 1, 31, 73, 74, 75, 76, 77, 78, 79, 164, 1, 82, 9, 153, 154, 139, 140, 9, 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, 1, 9, 82, 128, 129, 130, 131, 9, 133, 134, 135, 136, 137, 138, 9, 162, 141, 142, 143, 144, 145, 146, 147, 86, 149, 150, 9, 82, 10, 11, 12, 156, 157, 158, 118, 160, 169, 3, 4, 5, 6, 7, 8, 168, 10, 11, 12, 13, 14, 31, 76, 33, 34, 35, 36, 168, 82, 83, 15, 143, 169, 119, 120, 89, 90, 91, 124, 93, 108, 95, 110, 97, 38, 39, 100, 133, 1, 108, 109, 105, 106, 107, 162, 167, 1, 111, 112, 118, 32, 169, 118, 117, 118, 59, 45, 46, 47, 48, 49, 50, 51, 52, 165, 129, 32, 9, 169, 73, 74, 75, 76, 77, 78, 79, 169, 143, 82, 168, 173, 9, 165, 161, 168, 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, 84, 168, 9, 128, 129, 130, 131, 168, 133, 134, 135, 136, 137, 138, 1, 9, 141, 142, 143, 144, 145, 146, 147, 99, 149, 150, 108, 109, 10, 11, 12, 156, 157, 158, 32, 160, 118, 3, 4, 5, 6, 7, 8, 168, 10, 11, 12, 13, 14, 31, 76, 33, 34, 35, 72, 87, 82, 9, 142, 54, 50, 51, 52, 89, 90, 91, 169, 93, 9, 95, 118, 97, 38, 39, 100, 108, 15, 110, 165, 105, 106, 107, 164, 167, 165, 111, 112, 82, 169, 173, 85, 117, 118, 59, 118, 143, 53, 54, 55, 56, 57, 99, 59, 129, 134, 135, 136, 73, 74, 75, 76, 77, 78, 79, 71, 108, 82, 110, 142, 167, 152, 139, 140, 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, 9, 118, 72, 128, 129, 130, 131, 1, 133, 134, 135, 136, 137, 138, 9, 9, 141, 142, 143, 144, 145, 146, 147, 169, 149, 150, 143, 173, 10, 11, 12, 156, 157, 158, 9, 160, 72, 3, 4, 5, 6, 7, 8, 168, 10, 11, 12, 13, 14, 31, 167, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 10, 11, 12, 108, 165, 110, 139, 140, 169, 38, 39, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 31, 155, 33, 34, 35, 36, 37, 38, 39, 59, 10, 11, 12, 167, 17, 10, 11, 12, 9, 139, 140, 10, 11, 73, 74, 75, 76, 77, 78, 79, 9, 31, 82, 33, 34, 155, 31, 38, 39, 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, 166, 118, 168, 128, 129, 130, 131, 9, 133, 134, 135, 136, 137, 138, 82, 9, 141, 142, 143, 144, 145, 146, 147, 72, 149, 150, 143, 10, 11, 12, 9, 156, 157, 158, 9, 160, 3, 4, 5, 6, 7, 8, 82, 10, 11, 12, 13, 14, 31, 9, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 9, 59, 1, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 71, 9, 139, 140, 59, 161, 162, 163, 51, 52, 1, 15, 53, 54, 170, 77, 78, 15, 73, 74, 75, 76, 77, 78, 79, 77, 78, 82, 103, 104, 72, 108, 109, 15, 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, 1, 72, 84, 128, 129, 130, 131, 17, 133, 134, 135, 136, 137, 138, 108, 109, 141, 142, 143, 144, 145, 146, 147, 31, 149, 150, 15, 139, 140, 15, 31, 156, 157, 158, 2, 3, 4, 5, 6, 7, 8, 15, 103, 155, 17, 13, 14, 108, 16, 110, 113, 114, 17, 17, 115, 167, 17, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 139, 140, 17, 17, 1, 17, 82, 32, 17, 17, 17, 32, 1, 32, 32, 32, 155, 53, 54, 169, 36, 32, 58, 173, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 32, 72, 73, 74, 75, 76, 170, 118, 32, 80, 81, 82, 32, 84, 118, 32, 32, 88, 89, 90, 91, 1, 93, 32, 95, 32, 97, 72, 32, 100, 101, 142, 143, 32, 105, 106, 107, 108, 109, 143, 111, 112, 32, 32, 32, 82, 117, 118, 32, 32, 161, 162, 163, 124, 86, 32, 167, 32, 129, 130, 131, 32, 86, 167, 36, 38, 36, 36, 36, 36, 141, 142, 36, 144, 145, 146, 147, 148, 149, 150, 151, 118, 38, 38, 38, 59, 157, 158, 38, 39, 161, 162, 163, 164, 139, 140, 167, 77, 78, 79, 171, 172, 173, 39, 82, 142, 86, 72, 71, 85, 155, 92, 92, 79, 94, 94, 96, 99, 98, 115, 82, 116, 72, 73, 161, 162, 163, 84, 108, 87, 91, 84, 133, 165, 84, 137, 96, 169, 88, 119, 120, 165, 142, 102, 124, 169, 1, 98, 159, 152, 99, 99, 132, 133, 134, 135, 136, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 102, 1, 159, 124, 38, 39, 32, 72, 164, 167, 172, -1, -1, -1, 165, 138, 1, -1, 169, 170, 141, 142, 137, 144, 145, 146, 147, 148, 149, 150, 61, 62, 32, -1, 152, -1, 157, 158, 155, 155, -1, 72, 76, 0, 1, 155, 167, 32, 82, 155, 155, 172, 173, 161, 165, 89, 90, 91, 167, 93, 86, 95, 160, 97, 165, 165, 100, 166, 38, 39, 165, 105, 106, 107, 139, 140, 165, 111, 112, 165, 165, 165, 165, 117, 118, 165, 86, 165, 165, 165, 155, 165, 165, 165, 165, 129, 165, 165, 165, 169, 166, 86, 167, 166, 166, 166, 76, 166, 139, 140, 167, 167, 82, 167, 167, 167, 72, 73, 167, 89, 90, 91, 167, 93, 155, 95, 160, 97, 84, 86, 100, 167, 88, 168, 167, 105, 106, 107, 167, 165, 167, 111, 112, 169, 167, 167, 167, 117, 118, 167, 167, 108, 167, 110, 72, 73, 167, 167, 115, 129, 167, 167, 119, 120, 167, 165, 84, 124, 124, 169, 88, 167, 167, 167, 167, 132, 133, 134, 135, 136, 165, 167, 169, 167, 169, 167, 142, 167, 144, 145, 146, 147, 148, 149, 150, 167, 167, 170, 167, 156, 32, 157, 158, 167, 167, 167, 124, 167, 165, 167, 169, 167, 169, 170, 168, 168, 172, 173, 168, 168, 168, 168, 168, 168, 142, 168, 144, 145, 146, 147, 148, 149, 150, 32, 168, 168, 168, 168, 168, 157, 158, 1, 168, 168, 76, 168, 168, 168, 168, 167, 82, 168, 168, 168, 172, 173, 168, 89, 90, 91, 168, 93, 168, 95, 1, 97, 168, 168, 100, 168, 168, 1, 168, 105, 106, 107, 168, 76, 168, 111, 112, 168, 168, 82, 168, 117, 118, 168, 168, 168, 89, 90, 91, 168, 93, 168, 95, 129, 97, 168, 168, 100, 32, 168, 168, 168, 105, 106, 107, 169, 76, 169, 111, 112, 169, 169, 82, 169, 117, 118, 169, 169, 169, 89, 90, 91, 86, 93, 31, 95, 129, 97, 169, 1, 100, 169, 169, 173, 169, 105, 106, 107, 102, 103, 104, 111, 112, 170, 108, 86, 170, 117, 118, 170, 84, 170, 170, 170, 170, 119, 120, 170, 170, 129, 124, 102, 103, 104, 170, 170, 170, 108, 132, 133, 134, 135, 136, 170, 170, 170, 170, 170, 119, 120, 170, 170, 170, 124, 170, 119, 120, 170, 170, 170, 124, 132, 133, 134, 135, 136, 170, 167, 170, 133, 171, 165, 170, -1, -1, 169, 170, -1, 142, -1, -1, 118, 84, 120, 121, 122, 123, 124, 125, 126, 127, -1, -1, -1, 165, -1, -1, -1, 169, 170, 164, -1, -1, 167, -1, -1, 143, -1, -1, 173, -1, -1, -1, -1, -1, -1, -1, 119, 120, -1, -1, -1, 124, -1, -1, -1, -1, -1, -1, -1, 167, 133, -1, -1, -1, -1, -1, -1, -1, -1, 142, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 164, -1, -1, 167, -1, -1, -1, -1, -1, 173);
19998 protected array $actionBase = array(0, 156, -3, 315, 474, 474, 880, 1074, 1271, 1294, 749, 675, 531, 559, 836, 1031, 1031, 1046, 1031, 828, 1005, 42, 59, 59, 59, 963, 898, 632, 632, 898, 632, 997, 997, 997, 997, 1061, 1061, -63, -63, 96, 1232, 1199, 255, 255, 255, 255, 255, 1265, 255, 255, 255, 255, 255, 1265, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 77, 194, 120, 205, 1197, 783, 1150, 1163, 1152, 1166, 1145, 1144, 1151, 1156, 1167, 1261, 1263, 889, 1254, 1267, 1158, 972, 1147, 1162, 962, 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 19, 35, 535, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 529, 529, 529, 910, 910, 524, 299, 1113, 1075, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 140, 28, 1000, 493, 493, 458, 458, 458, 458, 458, 696, 1328, 1301, 171, 171, 171, 171, 1363, 1363, -70, 523, 248, 756, 291, 197, -87, 644, 38, 199, 323, 323, 482, 482, 233, 233, 482, 482, 482, 324, 324, 94, 94, 94, 94, 82, 249, 860, 67, 67, 67, 67, 860, 860, 860, 860, 913, 869, 860, 1036, 1049, 860, 860, 370, 645, 966, 646, 646, 398, -72, -72, 398, 64, -72, 294, 286, 257, 859, 91, 433, 257, 1073, 404, 686, 686, 815, 686, 686, 686, 923, 610, 923, 1141, 902, 902, 861, 807, 964, 1198, 1168, 901, 1252, 929, 1253, 1200, 342, 251, -56, 263, 550, 806, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1195, 523, 1141, -25, 1247, 1249, 1195, 1195, 1195, 523, 523, 523, 523, 523, 523, 523, 523, 870, 523, 523, 694, -25, 625, 635, -25, 896, 523, 915, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 178, 77, 77, 194, 13, 13, 77, 200, 121, 13, 13, 13, -11, 13, 77, 77, 77, 610, 886, 849, 663, 283, 874, 114, 886, 886, 886, 71, 9, 76, 809, 888, 288, 882, 882, 882, 907, 986, 986, 882, 903, 882, 907, 882, 882, 986, 986, 875, 986, 274, 620, 465, 597, 624, 986, 340, 882, 882, 882, 882, 916, 986, 127, 139, 639, 882, 329, 287, 882, 882, 916, 858, 876, 908, 986, 986, 986, 916, 545, 908, 908, 908, 931, 936, 864, 872, 445, 431, 679, 232, 924, 872, 872, 882, 605, 864, 872, 864, 872, 933, 872, 872, 872, 864, 872, 903, 533, 872, 813, 665, 218, 872, 882, 20, 1008, 1009, 800, 1010, 1002, 1013, 1069, 1014, 1016, 1171, 982, 1028, 1004, 1020, 1071, 998, 995, 885, 792, 793, 921, 914, 979, 897, 897, 897, 975, 977, 897, 897, 897, 897, 897, 897, 897, 897, 792, 932, 926, 899, 1037, 796, 810, 1114, 857, 1214, 1264, 1036, 1008, 1016, 804, 1004, 1020, 998, 995, 856, 853, 844, 851, 843, 840, 808, 814, 871, 1116, 1119, 1021, 920, 811, 1085, 1038, 1211, 1044, 1045, 1047, 1088, 1123, 942, 1125, 1216, 895, 1217, 1218, 965, 1051, 1173, 897, 974, 873, 968, 1049, 978, 792, 969, 1129, 1130, 1081, 961, 1097, 1098, 1072, 911, 884, 970, 1219, 1059, 1060, 1062, 1176, 1177, 930, 1082, 996, 1099, 912, 1058, 1100, 1101, 1105, 1106, 1179, 1222, 1182, 922, 1183, 945, 879, 1077, 909, 1223, 165, 892, 893, 906, 1068, 683, 1035, 1184, 1208, 1229, 1108, 1109, 1110, 1230, 1231, 1024, 946, 1083, 900, 1084, 1078, 947, 948, 689, 905, 1132, 890, 891, 904, 705, 768, 1238, 1239, 1240, 1025, 877, 894, 951, 953, 1133, 887, 1135, 1241, 771, 954, 1242, 1115, 816, 817, 521, 784, 747, 818, 881, 1194, 925, 865, 878, 1067, 817, 883, 955, 1245, 957, 958, 959, 1111, 960, 1086, 1246, 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, 789, 789, 789, 789, 789, 789, 789, 789, 789, 632, 632, 632, 632, 789, 789, 789, 789, 789, 789, 789, 632, 789, 789, 789, 632, 632, 0, 0, 632, 0, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 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, 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 823, 823, 616, 616, 823, 823, 823, 823, 823, 823, 823, 823, 823, 823, 616, 616, 0, 616, 616, 616, 616, 616, 616, 616, 875, 823, 823, 324, 324, 324, 324, 823, 823, 396, 396, 396, 823, 324, 823, 64, 324, 823, 64, 823, 823, 823, 823, 823, 823, 823, 823, 823, 0, 0, 823, 823, 823, 823, -25, -72, 823, 903, 903, 903, 903, 823, 823, 823, 823, -72, -72, 823, -57, -57, 823, 823, 0, 0, 0, 324, 324, -25, 0, 0, -25, 0, 0, 903, 903, 823, 64, 875, 446, 823, 342, 0, 0, 0, 0, 0, 0, 0, -25, 903, -25, 523, -72, -72, 523, 523, 13, 77, 446, 612, 612, 612, 612, 77, 0, 0, 0, 0, 0, 610, 875, 875, 875, 875, 875, 875, 875, 875, 875, 875, 875, 875, 903, 0, 875, 0, 875, 875, 903, 903, 903, 0, 0, 0, 0, 0, 0, 0, 0, 986, 0, 0, 0, 0, 0, 0, 0, 903, 0, 986, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 903, 0, 0, 0, 0, 0, 0, 0, 0, 0, 897, 911, 0, 0, 911, 0, 897, 897, 897, 0, 0, 0, 905, 887);
19999 protected array $actionDefault = array(3, 32767, 32767, 32767, 102, 102, 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, 632, 632, 632, 632, 32767, 32767, 257, 102, 32767, 32767, 503, 417, 417, 417, 32767, 32767, 32767, 576, 576, 576, 576, 576, 17, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 503, 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, 36, 7, 8, 10, 11, 49, 338, 100, 32767, 32767, 32767, 32767, 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, 32767, 404, 625, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 497, 507, 485, 486, 488, 489, 416, 577, 631, 344, 628, 342, 415, 146, 354, 343, 245, 261, 508, 262, 509, 512, 513, 218, 401, 150, 151, 448, 504, 450, 502, 506, 449, 422, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 420, 421, 505, 482, 481, 480, 32767, 32767, 446, 447, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 102, 32767, 451, 454, 419, 452, 453, 470, 471, 468, 469, 472, 32767, 323, 32767, 473, 474, 475, 476, 32767, 32767, 382, 196, 380, 32767, 477, 32767, 111, 455, 323, 111, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 461, 462, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 102, 32767, 32767, 32767, 100, 520, 570, 479, 456, 457, 32767, 545, 32767, 102, 32767, 547, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 572, 443, 445, 540, 626, 423, 629, 32767, 533, 100, 196, 32767, 546, 196, 196, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 571, 32767, 639, 533, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 32767, 196, 110, 32767, 110, 110, 32767, 32767, 100, 196, 196, 196, 196, 196, 196, 196, 196, 548, 196, 196, 191, 32767, 271, 273, 102, 594, 196, 550, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 404, 32767, 32767, 32767, 32767, 533, 466, 139, 32767, 535, 139, 578, 458, 459, 460, 578, 578, 578, 319, 296, 32767, 32767, 32767, 32767, 32767, 548, 548, 100, 100, 100, 100, 32767, 32767, 32767, 32767, 111, 519, 99, 99, 99, 99, 99, 103, 101, 32767, 32767, 32767, 32767, 226, 32767, 101, 101, 99, 32767, 101, 101, 32767, 32767, 226, 228, 215, 230, 32767, 598, 599, 226, 101, 230, 230, 230, 250, 250, 522, 325, 101, 99, 101, 101, 198, 325, 325, 32767, 101, 522, 325, 522, 325, 200, 325, 325, 325, 522, 325, 32767, 101, 325, 217, 99, 99, 325, 32767, 32767, 32767, 32767, 535, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 225, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 565, 32767, 583, 596, 464, 465, 467, 582, 580, 490, 491, 492, 493, 494, 495, 496, 499, 627, 32767, 539, 32767, 32767, 32767, 353, 32767, 637, 32767, 32767, 32767, 9, 74, 528, 42, 43, 51, 57, 554, 555, 556, 557, 551, 552, 558, 553, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 638, 32767, 578, 32767, 32767, 32767, 32767, 463, 560, 604, 32767, 32767, 579, 630, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 139, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 565, 32767, 137, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 561, 32767, 32767, 32767, 578, 32767, 32767, 32767, 32767, 321, 318, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 578, 32767, 32767, 32767, 32767, 32767, 298, 32767, 315, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 400, 535, 301, 303, 304, 32767, 32767, 32767, 32767, 376, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 153, 153, 3, 3, 356, 153, 153, 153, 356, 356, 153, 356, 356, 356, 153, 153, 153, 153, 153, 153, 153, 283, 186, 265, 268, 250, 250, 153, 368, 153, 402, 402, 411);
20000 protected array $goto = array(201, 169, 201, 201, 201, 1069, 598, 719, 448, 684, 644, 681, 443, 345, 341, 342, 344, 615, 447, 346, 449, 661, 481, 728, 570, 570, 570, 570, 1245, 626, 172, 172, 172, 172, 225, 202, 198, 198, 182, 184, 220, 198, 198, 198, 198, 198, 1195, 199, 199, 199, 199, 199, 1195, 192, 193, 194, 195, 196, 197, 222, 220, 223, 557, 558, 438, 559, 562, 563, 564, 565, 566, 567, 568, 569, 173, 174, 175, 200, 176, 177, 178, 170, 179, 180, 181, 183, 219, 221, 224, 242, 247, 248, 259, 260, 262, 263, 264, 265, 266, 267, 268, 272, 273, 274, 275, 282, 285, 297, 298, 324, 325, 444, 445, 446, 620, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 193, 194, 195, 196, 197, 222, 203, 204, 205, 206, 243, 185, 186, 207, 187, 208, 204, 188, 244, 203, 168, 209, 210, 189, 211, 212, 213, 190, 214, 215, 171, 216, 217, 218, 191, 287, 284, 287, 287, 883, 255, 255, 255, 255, 255, 1125, 605, 487, 487, 622, 758, 660, 662, 1103, 359, 682, 487, 1075, 1074, 706, 709, 1041, 717, 726, 1037, 733, 922, 879, 922, 922, 253, 253, 253, 253, 250, 256, 646, 646, 1078, 1079, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 880, 351, 938, 933, 934, 947, 889, 935, 886, 936, 937, 887, 890, 476, 941, 894, 476, 1044, 1044, 893, 364, 364, 364, 364, 352, 351, 532, 1131, 1127, 1128, 1351, 1351, 331, 315, 1351, 1351, 1351, 1351, 1351, 1351, 1351, 1351, 1351, 1351, 1069, 1301, 1072, 1072, 704, 983, 1301, 1301, 1064, 1080, 1081, 1069, 942, 1301, 943, 458, 1069, 881, 1069, 1069, 1069, 1069, 1069, 1069, 1069, 1069, 1069, 897, 855, 1069, 1069, 1069, 1069, 677, 678, 1301, 695, 696, 697, 1006, 1301, 1301, 1301, 1301, 450, 909, 1301, 436, 896, 1301, 1301, 1382, 1382, 1382, 1382, 915, 581, 574, 499, 612, 450, 367, 971, 971, 955, 501, 1076, 1076, 956, 1400, 1400, 367, 367, 688, 1087, 1083, 1084, 572, 411, 414, 623, 627, 572, 572, 367, 367, 1400, 357, 367, 572, 1417, 1377, 1378, 317, 574, 581, 607, 608, 318, 618, 624, 1390, 640, 641, 1027, 576, 1403, 1403, 367, 367, 28, 474, 520, 442, 521, 635, 1000, 1000, 1000, 1000, 527, 409, 474, 1348, 1348, 994, 1001, 1348, 1348, 1348, 1348, 1348, 1348, 1348, 1348, 1348, 1348, 633, 647, 650, 651, 652, 653, 674, 675, 676, 730, 732, 561, 561, 258, 258, 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, 610, 1362, 467, 683, 467, 876, 616, 638, 876, 467, 467, 1191, 861, 1373, 360, 361, 1093, 456, 1373, 1373, 560, 560, 705, 432, 560, 1373, 560, 560, 560, 560, 560, 560, 560, 560, 1277, 975, 575, 602, 575, 1278, 1281, 976, 575, 1282, 602, 689, 412, 480, 1384, 1384, 1384, 1384, 347, 873, 716, 576, 861, 876, 861, 490, 619, 491, 492, 639, 8, 857, 9, 902, 907, 989, 716, 1408, 1409, 716, 1369, 418, 1296, 278, 899, 330, 1174, 424, 425, 1292, 330, 330, 693, 1049, 694, 1114, 429, 430, 431, 761, 707, 1060, 905, 433, 1102, 1104, 1107, 355, 467, 467, 467, 467, 467, 467, 467, 467, 467, 467, 467, 467, 419, 339, 467, 911, 467, 467, 1294, 628, 629, 1116, 497, 960, 1181, 621, 1144, 1371, 1371, 1116, 1118, 1297, 1298, 1011, 1284, 1046, 1151, 1179, 1152, 731, 871, 528, 722, 901, 1142, 687, 1025, 1284, 496, 1375, 1376, 895, 910, 898, 1113, 1117, 998, 427, 727, 1165, 1299, 1359, 1360, 1291, 1030, 386, 1009, 1002, 0, 757, 0, 0, 573, 1039, 1034, 654, 656, 658, 0, 0, 0, 0, 0, 0, 0, 0, 876, 0, 0, 999, 0, 766, 766, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1163, 914);
20001 protected array $gotoCheck = array(42, 42, 42, 42, 42, 73, 127, 73, 66, 66, 56, 56, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 159, 9, 107, 107, 107, 107, 159, 107, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 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, 5, 5, 5, 5, 5, 15, 48, 157, 157, 134, 48, 48, 48, 131, 97, 48, 157, 119, 119, 48, 48, 48, 48, 48, 48, 48, 25, 25, 25, 25, 5, 5, 5, 5, 5, 5, 108, 108, 120, 120, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 26, 177, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 83, 15, 15, 83, 107, 107, 15, 24, 24, 24, 24, 177, 177, 76, 15, 15, 15, 179, 179, 178, 178, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 73, 73, 89, 89, 89, 89, 73, 73, 89, 89, 89, 73, 65, 73, 65, 83, 73, 27, 73, 73, 73, 73, 73, 73, 73, 73, 73, 35, 6, 73, 73, 73, 73, 86, 86, 73, 86, 86, 86, 49, 73, 73, 73, 73, 118, 35, 73, 43, 35, 73, 73, 9, 9, 9, 9, 45, 76, 76, 84, 181, 118, 14, 9, 9, 73, 84, 118, 118, 73, 191, 191, 14, 14, 118, 118, 118, 118, 19, 59, 59, 59, 59, 19, 19, 14, 14, 191, 188, 14, 19, 14, 187, 187, 76, 76, 76, 76, 76, 76, 76, 76, 190, 76, 76, 103, 14, 191, 191, 14, 14, 76, 19, 163, 13, 163, 13, 19, 19, 19, 19, 163, 62, 19, 180, 180, 19, 19, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 182, 182, 5, 5, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 104, 14, 23, 64, 23, 22, 2, 2, 22, 23, 23, 158, 12, 134, 97, 97, 115, 113, 134, 134, 165, 165, 117, 14, 165, 134, 165, 165, 165, 165, 165, 165, 165, 165, 79, 79, 9, 9, 9, 79, 79, 79, 9, 79, 9, 121, 9, 9, 134, 134, 134, 134, 29, 18, 7, 14, 12, 22, 12, 9, 9, 9, 9, 80, 46, 7, 46, 39, 9, 92, 7, 9, 9, 7, 134, 28, 20, 24, 37, 24, 156, 82, 82, 169, 24, 24, 82, 110, 82, 133, 82, 82, 82, 99, 82, 114, 9, 82, 130, 130, 130, 82, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 31, 9, 23, 41, 23, 23, 14, 17, 17, 134, 160, 17, 17, 8, 8, 134, 134, 134, 136, 20, 20, 96, 20, 17, 149, 149, 149, 8, 20, 8, 8, 17, 8, 17, 17, 20, 185, 185, 185, 17, 16, 16, 16, 16, 93, 93, 93, 152, 20, 20, 20, 17, 50, 141, 16, 50, -1, 50, -1, -1, 50, 50, 50, 85, 85, 85, -1, -1, -1, -1, -1, -1, -1, -1, 22, -1, -1, 16, -1, 24, 24, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 16, 16);
20002 protected array $gotoBase = array(0, 0, -303, 0, 0, 170, 280, 471, 543, 10, 0, 0, 136, 31, 22, -186, 111, 66, 164, 71, 95, 0, 148, 160, 235, 191, 214, 275, 155, 176, 0, 86, 0, 0, 0, -92, 0, 156, 0, 165, 0, 85, -1, 286, 0, 291, -270, 0, -558, 284, 579, 0, 0, 0, 0, 0, -33, 0, 0, 294, 0, 0, 341, 0, 184, 261, -237, 0, 0, 0, 0, 0, 0, -5, 0, 0, -32, 0, 0, 37, 172, 32, -3, -50, -167, 105, -444, 0, 0, -21, 0, 0, 161, 274, 0, 0, 101, -318, 0, 97, 0, 0, 0, 331, 381, 0, 0, -7, -38, 0, 131, 0, 0, 158, 90, 162, 0, 159, 39, -100, -83, 173, 0, 0, 0, 0, 0, 4, 0, 0, 522, 182, 0, 127, 169, 0, 99, 0, 0, 0, 0, -171, 0, 0, 0, 0, 0, 0, 0, 287, 0, 0, 126, 0, 0, 0, 144, 141, 188, -255, 93, 0, 0, -138, 0, 202, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, -82, -74, 6, 143, 292, 168, 0, 0, 270, 0, -31, 319, 0, 332, 20, 0, 0);
20003 protected array $gotoDefault = array(-32768, 533, 768, 7, 769, 964, 844, 853, 597, 551, 729, 356, 648, 439, 1367, 940, 1180, 617, 872, 1310, 1316, 475, 875, 336, 755, 952, 923, 924, 415, 402, 888, 413, 672, 649, 514, 908, 471, 900, 506, 903, 470, 912, 167, 435, 530, 916, 6, 919, 579, 950, 1004, 403, 927, 404, 700, 929, 601, 931, 932, 410, 416, 417, 1185, 609, 645, 944, 261, 603, 945, 401, 946, 954, 406, 408, 710, 486, 525, 519, 428, 1146, 604, 632, 669, 464, 493, 643, 655, 642, 500, 451, 434, 335, 988, 996, 507, 484, 1010, 358, 1018, 763, 1193, 663, 509, 1026, 664, 1033, 1036, 552, 553, 498, 1048, 270, 1051, 510, 1061, 26, 690, 1066, 1067, 691, 665, 1089, 666, 692, 667, 1091, 483, 599, 1194, 482, 1106, 1112, 472, 1115, 1356, 473, 1119, 269, 1122, 286, 362, 385, 452, 1129, 1130, 12, 1136, 720, 721, 25, 280, 529, 1164, 711, 1170, 279, 1173, 469, 1192, 468, 1265, 1267, 580, 511, 1285, 321, 1288, 703, 526, 1293, 465, 1358, 466, 554, 494, 343, 555, 1401, 314, 365, 340, 571, 322, 366, 556, 495, 1364, 1372, 337, 34, 1391, 1402, 614, 637);
20004 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, 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, 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, 112, 112, 112, 112, 110, 110, 110, 115, 115, 115, 115, 89, 89, 118, 118, 118, 119, 119, 116, 116, 120, 120, 122, 122, 123, 123, 117, 124, 124, 121, 125, 125, 125, 125, 113, 113, 82, 82, 82, 20, 20, 20, 128, 128, 128, 128, 129, 129, 129, 127, 126, 126, 131, 131, 131, 130, 130, 60, 132, 132, 133, 61, 135, 135, 136, 136, 137, 137, 86, 138, 138, 138, 138, 138, 138, 138, 138, 144, 144, 145, 145, 146, 146, 146, 146, 146, 147, 148, 148, 143, 143, 139, 139, 142, 142, 150, 150, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 140, 151, 151, 153, 152, 152, 141, 141, 114, 114, 154, 154, 156, 156, 156, 155, 155, 62, 104, 157, 157, 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, 42, 42, 42, 164, 165, 165, 166, 158, 158, 163, 163, 167, 168, 168, 169, 170, 171, 171, 171, 171, 19, 19, 73, 73, 73, 73, 159, 159, 159, 159, 173, 173, 162, 162, 162, 160, 160, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 180, 180, 180, 108, 182, 182, 182, 182, 161, 161, 161, 161, 161, 161, 161, 161, 59, 59, 176, 176, 176, 176, 176, 183, 183, 172, 172, 172, 172, 184, 184, 184, 184, 184, 74, 74, 66, 66, 66, 66, 134, 134, 134, 134, 187, 186, 175, 175, 175, 175, 175, 175, 174, 174, 174, 185, 185, 185, 185, 107, 181, 189, 189, 188, 188, 190, 190, 190, 190, 190, 190, 190, 190, 178, 178, 178, 178, 177, 192, 191, 191, 191, 191, 191, 191, 191, 191, 193, 193, 193, 193);
20005 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, 1, 3, 4, 1, 1, 8, 7, 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, 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, 1, 1, 1, 1, 7, 9, 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, 2, 4, 4, 3, 3, 1, 3, 1, 1, 3, 2, 2, 3, 1, 1, 2, 3, 1, 1, 2, 3, 1, 1, 3, 2, 0, 1, 5, 7, 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, 1, 1, 1, 2, 1, 3, 1, 1, 3, 0, 2, 0, 3, 5, 8, 1, 3, 3, 0, 2, 2, 2, 3, 1, 0, 1, 1, 3, 3, 3, 4, 4, 1, 1, 2, 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, 3, 5, 4, 3, 4, 4, 2, 2, 4, 2, 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, 2, 1, 1, 0, 4, 2, 1, 3, 2, 1, 2, 2, 2, 4, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 0, 1, 1, 0, 1, 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, 1, 3, 1, 1, 1, 4, 1, 4, 4, 0, 1, 1, 1, 3, 3, 1, 4, 2, 2, 1, 3, 1, 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);
20006 protected function initReduceCallbacks(): void
20007 {
20008 $this->reduceCallbacks = [0 => null, 1 => static function ($self, $stackPos) {
20009 $self->semValue = $self->handleNamespaces($self->semStack[$stackPos - (1 - 1)]);
20010 }, 2 => static function ($self, $stackPos) {
20011 if ($self->semStack[$stackPos - (2 - 2)] !== null) {
20012 $self->semStack[$stackPos - (2 - 1)][] = $self->semStack[$stackPos - (2 - 2)];
20013 }
20014 $self->semValue = $self->semStack[$stackPos - (2 - 1)];
20015 }, 3 => static function ($self, $stackPos) {
20016 $self->semValue = array();
20017 }, 4 => static function ($self, $stackPos) {
20018 $nop = $self->maybeCreateZeroLengthNop($self->tokenPos);
20019 if ($nop !== null) {
20020 $self->semStack[$stackPos - (1 - 1)][] = $nop;
20021 }
20022 $self->semValue = $self->semStack[$stackPos - (1 - 1)];
20023 }, 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 => static function ($self, $stackPos) {
20024 $self->semValue = $self->semStack[$stackPos - (1 - 1)];
20025 if ($self->semValue === "<?=") {
20026 $self->emitError(new Error('Cannot use "<?=" as an identifier', $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos])));
20027 }
20028 }, 77 => null, 78 => null, 79 => null, 80 => null, 81 => null, 82 => null, 83 => null, 84 => null, 85 => static function ($self, $stackPos) {
20029 $self->semValue = new Node\Identifier($self->semStack[$stackPos - (1 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
20030 }, 86 => static function ($self, $stackPos) {
20031 $self->semValue = new Node\Identifier($self->semStack[$stackPos - (1 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
20032 }, 87 => static function ($self, $stackPos) {
20033 $self->semValue = new Node\Identifier($self->semStack[$stackPos - (1 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
20034 }, 88 => static function ($self, $stackPos) {
20035 $self->semValue = new Node\Identifier($self->semStack[$stackPos - (1 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
20036 }, 89 => static function ($self, $stackPos) {
20037 $self->semValue = new Name($self->semStack[$stackPos - (1 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
20038 }, 90 => static function ($self, $stackPos) {
20039 $self->semValue = new Name($self->semStack[$stackPos - (1 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
20040 }, 91 => static function ($self, $stackPos) {
20041 $self->semValue = new Name($self->semStack[$stackPos - (1 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
20042 }, 92 => static function ($self, $stackPos) {
20043 $self->semValue = new Name($self->semStack[$stackPos - (1 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
20044 }, 93 => static function ($self, $stackPos) {
20045 $self->semValue = new Name($self->semStack[$stackPos - (1 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
20046 }, 94 => null, 95 => static function ($self, $stackPos) {
20047 $self->semValue = new Name(substr($self->semStack[$stackPos - (1 - 1)], 1), $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
20048 }, 96 => static function ($self, $stackPos) {
20049 $self->semValue = new Expr\Variable(substr($self->semStack[$stackPos - (1 - 1)], 1), $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
20050 }, 97 => static function ($self, $stackPos) {
20051 /* nothing */
20052 }, 98 => static function ($self, $stackPos) {
20053 /* nothing */
20054 }, 99 => static function ($self, $stackPos) {
20055 /* nothing */
20056 }, 100 => static function ($self, $stackPos) {
20057 $self->emitError(new Error('A trailing comma is not allowed here', $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos])));
20058 }, 101 => null, 102 => null, 103 => static function ($self, $stackPos) {
20059 $self->semValue = new Node\Attribute($self->semStack[$stackPos - (1 - 1)], [], $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
20060 }, 104 => static function ($self, $stackPos) {
20061 $self->semValue = new Node\Attribute($self->semStack[$stackPos - (2 - 1)], $self->semStack[$stackPos - (2 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
20062 }, 105 => static function ($self, $stackPos) {
20063 $self->semValue = array($self->semStack[$stackPos - (1 - 1)]);
20064 }, 106 => static function ($self, $stackPos) {
20065 $self->semStack[$stackPos - (3 - 1)][] = $self->semStack[$stackPos - (3 - 3)];
20066 $self->semValue = $self->semStack[$stackPos - (3 - 1)];
20067 }, 107 => static function ($self, $stackPos) {
20068 $self->semValue = new Node\AttributeGroup($self->semStack[$stackPos - (4 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]));
20069 }, 108 => static function ($self, $stackPos) {
20070 $self->semValue = array($self->semStack[$stackPos - (1 - 1)]);
20071 }, 109 => static function ($self, $stackPos) {
20072 $self->semStack[$stackPos - (2 - 1)][] = $self->semStack[$stackPos - (2 - 2)];
20073 $self->semValue = $self->semStack[$stackPos - (2 - 1)];
20074 }, 110 => static function ($self, $stackPos) {
20075 $self->semValue = [];
20076 }, 111 => null, 112 => null, 113 => null, 114 => null, 115 => static function ($self, $stackPos) {
20077 $self->semValue = new Stmt\HaltCompiler($self->handleHaltCompiler(), $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]));
20078 }, 116 => static function ($self, $stackPos) {
20079 $self->semValue = new Stmt\Namespace_($self->semStack[$stackPos - (3 - 2)], null, $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
20080 $self->semValue->setAttribute('kind', Stmt\Namespace_::KIND_SEMICOLON);
20081 $self->checkNamespace($self->semValue);
20082 }, 117 => static function ($self, $stackPos) {
20083 $self->semValue = new Stmt\Namespace_($self->semStack[$stackPos - (5 - 2)], $self->semStack[$stackPos - (5 - 4)], $self->getAttributes($self->tokenStartStack[$stackPos - (5 - 1)], $self->tokenEndStack[$stackPos]));
20084 $self->semValue->setAttribute('kind', Stmt\Namespace_::KIND_BRACED);
20085 $self->checkNamespace($self->semValue);
20086 }, 118 => static function ($self, $stackPos) {
20087 $self->semValue = new Stmt\Namespace_(null, $self->semStack[$stackPos - (4 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]));
20088 $self->semValue->setAttribute('kind', Stmt\Namespace_::KIND_BRACED);
20089 $self->checkNamespace($self->semValue);
20090 }, 119 => static function ($self, $stackPos) {
20091 $self->semValue = new Stmt\Use_($self->semStack[$stackPos - (3 - 2)], Stmt\Use_::TYPE_NORMAL, $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
20092 }, 120 => static function ($self, $stackPos) {
20093 $self->semValue = new Stmt\Use_($self->semStack[$stackPos - (4 - 3)], $self->semStack[$stackPos - (4 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]));
20094 }, 121 => null, 122 => static function ($self, $stackPos) {
20095 $self->semValue = new Stmt\Const_($self->semStack[$stackPos - (3 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]), []);
20096 }, 123 => static function ($self, $stackPos) {
20097 $self->semValue = new Stmt\Const_($self->semStack[$stackPos - (4 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]), $self->semStack[$stackPos - (4 - 1)]);
20098 $self->checkConstantAttributes($self->semValue);
20099 }, 124 => static function ($self, $stackPos) {
20100 $self->semValue = Stmt\Use_::TYPE_FUNCTION;
20101 }, 125 => static function ($self, $stackPos) {
20102 $self->semValue = Stmt\Use_::TYPE_CONSTANT;
20103 }, 126 => static function ($self, $stackPos) {
20104 $self->semValue = new Stmt\GroupUse($self->semStack[$stackPos - (8 - 3)], $self->semStack[$stackPos - (8 - 6)], $self->semStack[$stackPos - (8 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (8 - 1)], $self->tokenEndStack[$stackPos]));
20105 }, 127 => static function ($self, $stackPos) {
20106 $self->semValue = new Stmt\GroupUse($self->semStack[$stackPos - (7 - 2)], $self->semStack[$stackPos - (7 - 5)], Stmt\Use_::TYPE_UNKNOWN, $self->getAttributes($self->tokenStartStack[$stackPos - (7 - 1)], $self->tokenEndStack[$stackPos]));
20107 }, 128 => null, 129 => static function ($self, $stackPos) {
20108 $self->semStack[$stackPos - (3 - 1)][] = $self->semStack[$stackPos - (3 - 3)];
20109 $self->semValue = $self->semStack[$stackPos - (3 - 1)];
20110 }, 130 => static function ($self, $stackPos) {
20111 $self->semValue = array($self->semStack[$stackPos - (1 - 1)]);
20112 }, 131 => null, 132 => static function ($self, $stackPos) {
20113 $self->semStack[$stackPos - (3 - 1)][] = $self->semStack[$stackPos - (3 - 3)];
20114 $self->semValue = $self->semStack[$stackPos - (3 - 1)];
20115 }, 133 => static function ($self, $stackPos) {
20116 $self->semValue = array($self->semStack[$stackPos - (1 - 1)]);
20117 }, 134 => null, 135 => static function ($self, $stackPos) {
20118 $self->semStack[$stackPos - (3 - 1)][] = $self->semStack[$stackPos - (3 - 3)];
20119 $self->semValue = $self->semStack[$stackPos - (3 - 1)];
20120 }, 136 => static function ($self, $stackPos) {
20121 $self->semValue = array($self->semStack[$stackPos - (1 - 1)]);
20122 }, 137 => static function ($self, $stackPos) {
20123 $self->semValue = new Node\UseItem($self->semStack[$stackPos - (1 - 1)], null, Stmt\Use_::TYPE_UNKNOWN, $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
20124 $self->checkUseUse($self->semValue, $stackPos - (1 - 1));
20125 }, 138 => static function ($self, $stackPos) {
20126 $self->semValue = new Node\UseItem($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], Stmt\Use_::TYPE_UNKNOWN, $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
20127 $self->checkUseUse($self->semValue, $stackPos - (3 - 3));
20128 }, 139 => static function ($self, $stackPos) {
20129 $self->semValue = new Node\UseItem($self->semStack[$stackPos - (1 - 1)], null, Stmt\Use_::TYPE_UNKNOWN, $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
20130 $self->checkUseUse($self->semValue, $stackPos - (1 - 1));
20131 }, 140 => static function ($self, $stackPos) {
20132 $self->semValue = new Node\UseItem($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], Stmt\Use_::TYPE_UNKNOWN, $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
20133 $self->checkUseUse($self->semValue, $stackPos - (3 - 3));
20134 }, 141 => static function ($self, $stackPos) {
20135 $self->semValue = $self->semStack[$stackPos - (1 - 1)];
20136 $self->semValue->type = Stmt\Use_::TYPE_NORMAL;
20137 }, 142 => static function ($self, $stackPos) {
20138 $self->semValue = $self->semStack[$stackPos - (2 - 2)];
20139 $self->semValue->type = $self->semStack[$stackPos - (2 - 1)];
20140 }, 143 => null, 144 => static function ($self, $stackPos) {
20141 $self->semStack[$stackPos - (3 - 1)][] = $self->semStack[$stackPos - (3 - 3)];
20142 $self->semValue = $self->semStack[$stackPos - (3 - 1)];
20143 }, 145 => static function ($self, $stackPos) {
20144 $self->semValue = array($self->semStack[$stackPos - (1 - 1)]);
20145 }, 146 => static function ($self, $stackPos) {
20146 $self->semValue = new Node\Const_($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
20147 }, 147 => null, 148 => static function ($self, $stackPos) {
20148 $self->semStack[$stackPos - (3 - 1)][] = $self->semStack[$stackPos - (3 - 3)];
20149 $self->semValue = $self->semStack[$stackPos - (3 - 1)];
20150 }, 149 => static function ($self, $stackPos) {
20151 $self->semValue = array($self->semStack[$stackPos - (1 - 1)]);
20152 }, 150 => static function ($self, $stackPos) {
20153 $self->semValue = new Node\Const_(new Node\Identifier($self->semStack[$stackPos - (3 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos - (3 - 1)])), $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
20154 }, 151 => static function ($self, $stackPos) {
20155 $self->semValue = new Node\Const_(new Node\Identifier($self->semStack[$stackPos - (3 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos - (3 - 1)])), $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
20156 }, 152 => static function ($self, $stackPos) {
20157 if ($self->semStack[$stackPos - (2 - 2)] !== null) {
20158 $self->semStack[$stackPos - (2 - 1)][] = $self->semStack[$stackPos - (2 - 2)];
20159 }
20160 $self->semValue = $self->semStack[$stackPos - (2 - 1)];
20161 }, 153 => static function ($self, $stackPos) {
20162 $self->semValue = array();
20163 }, 154 => static function ($self, $stackPos) {
20164 $nop = $self->maybeCreateZeroLengthNop($self->tokenPos);
20165 if ($nop !== null) {
20166 $self->semStack[$stackPos - (1 - 1)][] = $nop;
20167 }
20168 $self->semValue = $self->semStack[$stackPos - (1 - 1)];
20169 }, 155 => null, 156 => null, 157 => null, 158 => static function ($self, $stackPos) {
20170 throw new Error('__HALT_COMPILER() can only be used from the outermost scope', $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
20171 }, 159 => static function ($self, $stackPos) {
20172 $self->semValue = new Stmt\Block($self->semStack[$stackPos - (3 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
20173 }, 160 => static function ($self, $stackPos) {
20174 $self->semValue = new Stmt\If_($self->semStack[$stackPos - (7 - 3)], ['stmts' => $self->semStack[$stackPos - (7 - 5)], 'elseifs' => $self->semStack[$stackPos - (7 - 6)], 'else' => $self->semStack[$stackPos - (7 - 7)]], $self->getAttributes($self->tokenStartStack[$stackPos - (7 - 1)], $self->tokenEndStack[$stackPos]));
20175 }, 161 => static function ($self, $stackPos) {
20176 $self->semValue = new Stmt\If_($self->semStack[$stackPos - (10 - 3)], ['stmts' => $self->semStack[$stackPos - (10 - 6)], 'elseifs' => $self->semStack[$stackPos - (10 - 7)], 'else' => $self->semStack[$stackPos - (10 - 8)]], $self->getAttributes($self->tokenStartStack[$stackPos - (10 - 1)], $self->tokenEndStack[$stackPos]));
20177 }, 162 => static function ($self, $stackPos) {
20178 $self->semValue = new Stmt\While_($self->semStack[$stackPos - (5 - 3)], $self->semStack[$stackPos - (5 - 5)], $self->getAttributes($self->tokenStartStack[$stackPos - (5 - 1)], $self->tokenEndStack[$stackPos]));
20179 }, 163 => static function ($self, $stackPos) {
20180 $self->semValue = new Stmt\Do_($self->semStack[$stackPos - (7 - 5)], $self->semStack[$stackPos - (7 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (7 - 1)], $self->tokenEndStack[$stackPos]));
20181 }, 164 => static function ($self, $stackPos) {
20182 $self->semValue = new Stmt\For_(['init' => $self->semStack[$stackPos - (9 - 3)], 'cond' => $self->semStack[$stackPos - (9 - 5)], 'loop' => $self->semStack[$stackPos - (9 - 7)], 'stmts' => $self->semStack[$stackPos - (9 - 9)]], $self->getAttributes($self->tokenStartStack[$stackPos - (9 - 1)], $self->tokenEndStack[$stackPos]));
20183 }, 165 => static function ($self, $stackPos) {
20184 $self->semValue = new Stmt\Switch_($self->semStack[$stackPos - (5 - 3)], $self->semStack[$stackPos - (5 - 5)], $self->getAttributes($self->tokenStartStack[$stackPos - (5 - 1)], $self->tokenEndStack[$stackPos]));
20185 }, 166 => static function ($self, $stackPos) {
20186 $self->semValue = new Stmt\Break_($self->semStack[$stackPos - (3 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
20187 }, 167 => static function ($self, $stackPos) {
20188 $self->semValue = new Stmt\Continue_($self->semStack[$stackPos - (3 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
20189 }, 168 => static function ($self, $stackPos) {
20190 $self->semValue = new Stmt\Return_($self->semStack[$stackPos - (3 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
20191 }, 169 => static function ($self, $stackPos) {
20192 $self->semValue = new Stmt\Global_($self->semStack[$stackPos - (3 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
20193 }, 170 => static function ($self, $stackPos) {
20194 $self->semValue = new Stmt\Static_($self->semStack[$stackPos - (3 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
20195 }, 171 => static function ($self, $stackPos) {
20196 $self->semValue = new Stmt\Echo_($self->semStack[$stackPos - (3 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
20197 }, 172 => static function ($self, $stackPos) {
20198 $self->semValue = new Stmt\InlineHTML($self->semStack[$stackPos - (1 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
20199 $self->semValue->setAttribute('hasLeadingNewline', $self->inlineHtmlHasLeadingNewline($stackPos - (1 - 1)));
20200 }, 173 => static function ($self, $stackPos) {
20201 $self->semValue = new Stmt\Expression($self->semStack[$stackPos - (2 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
20202 }, 174 => static function ($self, $stackPos) {
20203 $self->semValue = new Stmt\Unset_($self->semStack[$stackPos - (5 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (5 - 1)], $self->tokenEndStack[$stackPos]));
20204 }, 175 => static function ($self, $stackPos) {
20205 $self->semValue = new Stmt\Foreach_($self->semStack[$stackPos - (7 - 3)], $self->semStack[$stackPos - (7 - 5)][0], ['keyVar' => null, 'byRef' => $self->semStack[$stackPos - (7 - 5)][1], 'stmts' => $self->semStack[$stackPos - (7 - 7)]], $self->getAttributes($self->tokenStartStack[$stackPos - (7 - 1)], $self->tokenEndStack[$stackPos]));
20206 }, 176 => static function ($self, $stackPos) {
20207 $self->semValue = new Stmt\Foreach_($self->semStack[$stackPos - (9 - 3)], $self->semStack[$stackPos - (9 - 7)][0], ['keyVar' => $self->semStack[$stackPos - (9 - 5)], 'byRef' => $self->semStack[$stackPos - (9 - 7)][1], 'stmts' => $self->semStack[$stackPos - (9 - 9)]], $self->getAttributes($self->tokenStartStack[$stackPos - (9 - 1)], $self->tokenEndStack[$stackPos]));
20208 }, 177 => static function ($self, $stackPos) {
20209 $self->semValue = new Stmt\Foreach_($self->semStack[$stackPos - (6 - 3)], new Expr\Error($self->getAttributes($self->tokenStartStack[$stackPos - (6 - 4)], $self->tokenEndStack[$stackPos - (6 - 4)])), ['stmts' => $self->semStack[$stackPos - (6 - 6)]], $self->getAttributes($self->tokenStartStack[$stackPos - (6 - 1)], $self->tokenEndStack[$stackPos]));
20210 }, 178 => static function ($self, $stackPos) {
20211 $self->semValue = new Stmt\Declare_($self->semStack[$stackPos - (5 - 3)], $self->semStack[$stackPos - (5 - 5)], $self->getAttributes($self->tokenStartStack[$stackPos - (5 - 1)], $self->tokenEndStack[$stackPos]));
20212 }, 179 => static function ($self, $stackPos) {
20213 $self->semValue = new Stmt\TryCatch($self->semStack[$stackPos - (6 - 3)], $self->semStack[$stackPos - (6 - 5)], $self->semStack[$stackPos - (6 - 6)], $self->getAttributes($self->tokenStartStack[$stackPos - (6 - 1)], $self->tokenEndStack[$stackPos]));
20214 $self->checkTryCatch($self->semValue);
20215 }, 180 => static function ($self, $stackPos) {
20216 $self->semValue = new Stmt\Goto_($self->semStack[$stackPos - (3 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
20217 }, 181 => static function ($self, $stackPos) {
20218 $self->semValue = new Stmt\Label($self->semStack[$stackPos - (2 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
20219 }, 182 => static function ($self, $stackPos) {
20220 $self->semValue = null;
20221 /* means: no statement */
20222 }, 183 => null, 184 => static function ($self, $stackPos) {
20223 $self->semValue = $self->maybeCreateNop($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]);
20224 }, 185 => static function ($self, $stackPos) {
20225 if ($self->semStack[$stackPos - (1 - 1)] instanceof Stmt\Block) {
20226 $self->semValue = $self->semStack[$stackPos - (1 - 1)]->stmts;
20227 } else if ($self->semStack[$stackPos - (1 - 1)] === null) {
20228 $self->semValue = [];
20229 } else {
20230 $self->semValue = [$self->semStack[$stackPos - (1 - 1)]];
20231 }
20232 }, 186 => static function ($self, $stackPos) {
20233 $self->semValue = array();
20234 }, 187 => static function ($self, $stackPos) {
20235 $self->semStack[$stackPos - (2 - 1)][] = $self->semStack[$stackPos - (2 - 2)];
20236 $self->semValue = $self->semStack[$stackPos - (2 - 1)];
20237 }, 188 => static function ($self, $stackPos) {
20238 $self->semValue = array($self->semStack[$stackPos - (1 - 1)]);
20239 }, 189 => static function ($self, $stackPos) {
20240 $self->semStack[$stackPos - (3 - 1)][] = $self->semStack[$stackPos - (3 - 3)];
20241 $self->semValue = $self->semStack[$stackPos - (3 - 1)];
20242 }, 190 => static function ($self, $stackPos) {
20243 $self->semValue = new Stmt\Catch_($self->semStack[$stackPos - (8 - 3)], $self->semStack[$stackPos - (8 - 4)], $self->semStack[$stackPos - (8 - 7)], $self->getAttributes($self->tokenStartStack[$stackPos - (8 - 1)], $self->tokenEndStack[$stackPos]));
20244 }, 191 => static function ($self, $stackPos) {
20245 $self->semValue = null;
20246 }, 192 => static function ($self, $stackPos) {
20247 $self->semValue = new Stmt\Finally_($self->semStack[$stackPos - (4 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]));
20248 }, 193 => null, 194 => static function ($self, $stackPos) {
20249 $self->semValue = array($self->semStack[$stackPos - (1 - 1)]);
20250 }, 195 => static function ($self, $stackPos) {
20251 $self->semStack[$stackPos - (3 - 1)][] = $self->semStack[$stackPos - (3 - 3)];
20252 $self->semValue = $self->semStack[$stackPos - (3 - 1)];
20253 }, 196 => static function ($self, $stackPos) {
20254 $self->semValue = \false;
20255 }, 197 => static function ($self, $stackPos) {
20256 $self->semValue = \true;
20257 }, 198 => static function ($self, $stackPos) {
20258 $self->semValue = \false;
20259 }, 199 => static function ($self, $stackPos) {
20260 $self->semValue = \true;
20261 }, 200 => static function ($self, $stackPos) {
20262 $self->semValue = \false;
20263 }, 201 => static function ($self, $stackPos) {
20264 $self->semValue = \true;
20265 }, 202 => static function ($self, $stackPos) {
20266 $self->semValue = $self->semStack[$stackPos - (3 - 2)];
20267 }, 203 => static function ($self, $stackPos) {
20268 $self->semValue = [];
20269 }, 204 => null, 205 => static function ($self, $stackPos) {
20270 $self->semValue = new Node\Identifier($self->semStack[$stackPos - (1 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
20271 }, 206 => static function ($self, $stackPos) {
20272 $self->semValue = new Node\Identifier($self->semStack[$stackPos - (1 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
20273 }, 207 => static function ($self, $stackPos) {
20274 $self->semValue = new Node\Identifier($self->semStack[$stackPos - (1 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
20275 }, 208 => static function ($self, $stackPos) {
20276 $self->semValue = new Stmt\Function_($self->semStack[$stackPos - (8 - 3)], ['byRef' => $self->semStack[$stackPos - (8 - 2)], 'params' => $self->semStack[$stackPos - (8 - 5)], 'returnType' => $self->semStack[$stackPos - (8 - 7)], 'stmts' => $self->semStack[$stackPos - (8 - 8)], 'attrGroups' => []], $self->getAttributes($self->tokenStartStack[$stackPos - (8 - 1)], $self->tokenEndStack[$stackPos]));
20277 }, 209 => static function ($self, $stackPos) {
20278 $self->semValue = new Stmt\Function_($self->semStack[$stackPos - (9 - 4)], ['byRef' => $self->semStack[$stackPos - (9 - 3)], 'params' => $self->semStack[$stackPos - (9 - 6)], 'returnType' => $self->semStack[$stackPos - (9 - 8)], 'stmts' => $self->semStack[$stackPos - (9 - 9)], 'attrGroups' => $self->semStack[$stackPos - (9 - 1)]], $self->getAttributes($self->tokenStartStack[$stackPos - (9 - 1)], $self->tokenEndStack[$stackPos]));
20279 }, 210 => static function ($self, $stackPos) {
20280 $self->semValue = new Stmt\Class_($self->semStack[$stackPos - (7 - 2)], ['type' => $self->semStack[$stackPos - (7 - 1)], 'extends' => $self->semStack[$stackPos - (7 - 3)], 'implements' => $self->semStack[$stackPos - (7 - 4)], 'stmts' => $self->semStack[$stackPos - (7 - 6)], 'attrGroups' => []], $self->getAttributes($self->tokenStartStack[$stackPos - (7 - 1)], $self->tokenEndStack[$stackPos]));
20281 $self->checkClass($self->semValue, $stackPos - (7 - 2));
20282 }, 211 => static function ($self, $stackPos) {
20283 $self->semValue = new Stmt\Class_($self->semStack[$stackPos - (8 - 3)], ['type' => $self->semStack[$stackPos - (8 - 2)], 'extends' => $self->semStack[$stackPos - (8 - 4)], 'implements' => $self->semStack[$stackPos - (8 - 5)], 'stmts' => $self->semStack[$stackPos - (8 - 7)], 'attrGroups' => $self->semStack[$stackPos - (8 - 1)]], $self->getAttributes($self->tokenStartStack[$stackPos - (8 - 1)], $self->tokenEndStack[$stackPos]));
20284 $self->checkClass($self->semValue, $stackPos - (8 - 3));
20285 }, 212 => static function ($self, $stackPos) {
20286 $self->semValue = new Stmt\Interface_($self->semStack[$stackPos - (7 - 3)], ['extends' => $self->semStack[$stackPos - (7 - 4)], 'stmts' => $self->semStack[$stackPos - (7 - 6)], 'attrGroups' => $self->semStack[$stackPos - (7 - 1)]], $self->getAttributes($self->tokenStartStack[$stackPos - (7 - 1)], $self->tokenEndStack[$stackPos]));
20287 $self->checkInterface($self->semValue, $stackPos - (7 - 3));
20288 }, 213 => static function ($self, $stackPos) {
20289 $self->semValue = new Stmt\Trait_($self->semStack[$stackPos - (6 - 3)], ['stmts' => $self->semStack[$stackPos - (6 - 5)], 'attrGroups' => $self->semStack[$stackPos - (6 - 1)]], $self->getAttributes($self->tokenStartStack[$stackPos - (6 - 1)], $self->tokenEndStack[$stackPos]));
20290 }, 214 => static function ($self, $stackPos) {
20291 $self->semValue = new Stmt\Enum_($self->semStack[$stackPos - (8 - 3)], ['scalarType' => $self->semStack[$stackPos - (8 - 4)], 'implements' => $self->semStack[$stackPos - (8 - 5)], 'stmts' => $self->semStack[$stackPos - (8 - 7)], 'attrGroups' => $self->semStack[$stackPos - (8 - 1)]], $self->getAttributes($self->tokenStartStack[$stackPos - (8 - 1)], $self->tokenEndStack[$stackPos]));
20292 $self->checkEnum($self->semValue, $stackPos - (8 - 3));
20293 }, 215 => static function ($self, $stackPos) {
20294 $self->semValue = null;
20295 }, 216 => static function ($self, $stackPos) {
20296 $self->semValue = $self->semStack[$stackPos - (2 - 2)];
20297 }, 217 => static function ($self, $stackPos) {
20298 $self->semValue = null;
20299 }, 218 => static function ($self, $stackPos) {
20300 $self->semValue = $self->semStack[$stackPos - (2 - 2)];
20301 }, 219 => static function ($self, $stackPos) {
20302 $self->semValue = 0;
20303 }, 220 => null, 221 => null, 222 => static function ($self, $stackPos) {
20304 $self->checkClassModifier($self->semStack[$stackPos - (2 - 1)], $self->semStack[$stackPos - (2 - 2)], $stackPos - (2 - 2));
20305 $self->semValue = $self->semStack[$stackPos - (2 - 1)] | $self->semStack[$stackPos - (2 - 2)];
20306 }, 223 => static function ($self, $stackPos) {
20307 $self->semValue = Modifiers::ABSTRACT;
20308 }, 224 => static function ($self, $stackPos) {
20309 $self->semValue = Modifiers::FINAL;
20310 }, 225 => static function ($self, $stackPos) {
20311 $self->semValue = Modifiers::READONLY;
20312 }, 226 => static function ($self, $stackPos) {
20313 $self->semValue = null;
20314 }, 227 => static function ($self, $stackPos) {
20315 $self->semValue = $self->semStack[$stackPos - (2 - 2)];
20316 }, 228 => static function ($self, $stackPos) {
20317 $self->semValue = array();
20318 }, 229 => static function ($self, $stackPos) {
20319 $self->semValue = $self->semStack[$stackPos - (2 - 2)];
20320 }, 230 => static function ($self, $stackPos) {
20321 $self->semValue = array();
20322 }, 231 => static function ($self, $stackPos) {
20323 $self->semValue = $self->semStack[$stackPos - (2 - 2)];
20324 }, 232 => null, 233 => static function ($self, $stackPos) {
20325 $self->semValue = array($self->semStack[$stackPos - (1 - 1)]);
20326 }, 234 => static function ($self, $stackPos) {
20327 $self->semStack[$stackPos - (3 - 1)][] = $self->semStack[$stackPos - (3 - 3)];
20328 $self->semValue = $self->semStack[$stackPos - (3 - 1)];
20329 }, 235 => null, 236 => static function ($self, $stackPos) {
20330 $self->semValue = $self->semStack[$stackPos - (4 - 2)];
20331 }, 237 => null, 238 => static function ($self, $stackPos) {
20332 $self->semValue = $self->semStack[$stackPos - (4 - 2)];
20333 }, 239 => static function ($self, $stackPos) {
20334 if ($self->semStack[$stackPos - (1 - 1)] instanceof Stmt\Block) {
20335 $self->semValue = $self->semStack[$stackPos - (1 - 1)]->stmts;
20336 } else if ($self->semStack[$stackPos - (1 - 1)] === null) {
20337 $self->semValue = [];
20338 } else {
20339 $self->semValue = [$self->semStack[$stackPos - (1 - 1)]];
20340 }
20341 }, 240 => static function ($self, $stackPos) {
20342 $self->semValue = null;
20343 }, 241 => static function ($self, $stackPos) {
20344 $self->semValue = $self->semStack[$stackPos - (4 - 2)];
20345 }, 242 => null, 243 => static function ($self, $stackPos) {
20346 $self->semValue = array($self->semStack[$stackPos - (1 - 1)]);
20347 }, 244 => static function ($self, $stackPos) {
20348 $self->semStack[$stackPos - (3 - 1)][] = $self->semStack[$stackPos - (3 - 3)];
20349 $self->semValue = $self->semStack[$stackPos - (3 - 1)];
20350 }, 245 => static function ($self, $stackPos) {
20351 $self->semValue = new Node\DeclareItem($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
20352 }, 246 => static function ($self, $stackPos) {
20353 $self->semValue = $self->semStack[$stackPos - (3 - 2)];
20354 }, 247 => static function ($self, $stackPos) {
20355 $self->semValue = $self->semStack[$stackPos - (4 - 3)];
20356 }, 248 => static function ($self, $stackPos) {
20357 $self->semValue = $self->semStack[$stackPos - (4 - 2)];
20358 }, 249 => static function ($self, $stackPos) {
20359 $self->semValue = $self->semStack[$stackPos - (5 - 3)];
20360 }, 250 => static function ($self, $stackPos) {
20361 $self->semValue = array();
20362 }, 251 => static function ($self, $stackPos) {
20363 $self->semStack[$stackPos - (2 - 1)][] = $self->semStack[$stackPos - (2 - 2)];
20364 $self->semValue = $self->semStack[$stackPos - (2 - 1)];
20365 }, 252 => static function ($self, $stackPos) {
20366 $self->semValue = new Stmt\Case_($self->semStack[$stackPos - (4 - 2)], $self->semStack[$stackPos - (4 - 4)], $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]));
20367 }, 253 => static function ($self, $stackPos) {
20368 $self->semValue = new Stmt\Case_(null, $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
20369 }, 254 => null, 255 => null, 256 => static function ($self, $stackPos) {
20370 $self->semValue = new Expr\Match_($self->semStack[$stackPos - (7 - 3)], $self->semStack[$stackPos - (7 - 6)], $self->getAttributes($self->tokenStartStack[$stackPos - (7 - 1)], $self->tokenEndStack[$stackPos]));
20371 }, 257 => static function ($self, $stackPos) {
20372 $self->semValue = [];
20373 }, 258 => null, 259 => static function ($self, $stackPos) {
20374 $self->semValue = array($self->semStack[$stackPos - (1 - 1)]);
20375 }, 260 => static function ($self, $stackPos) {
20376 $self->semStack[$stackPos - (3 - 1)][] = $self->semStack[$stackPos - (3 - 3)];
20377 $self->semValue = $self->semStack[$stackPos - (3 - 1)];
20378 }, 261 => static function ($self, $stackPos) {
20379 $self->semValue = new Node\MatchArm($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
20380 }, 262 => static function ($self, $stackPos) {
20381 $self->semValue = new Node\MatchArm(null, $self->semStack[$stackPos - (4 - 4)], $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]));
20382 }, 263 => static function ($self, $stackPos) {
20383 $self->semValue = $self->semStack[$stackPos - (1 - 1)];
20384 }, 264 => static function ($self, $stackPos) {
20385 $self->semValue = $self->semStack[$stackPos - (4 - 2)];
20386 }, 265 => static function ($self, $stackPos) {
20387 $self->semValue = array();
20388 }, 266 => static function ($self, $stackPos) {
20389 $self->semStack[$stackPos - (2 - 1)][] = $self->semStack[$stackPos - (2 - 2)];
20390 $self->semValue = $self->semStack[$stackPos - (2 - 1)];
20391 }, 267 => static function ($self, $stackPos) {
20392 $self->semValue = new Stmt\ElseIf_($self->semStack[$stackPos - (5 - 3)], $self->semStack[$stackPos - (5 - 5)], $self->getAttributes($self->tokenStartStack[$stackPos - (5 - 1)], $self->tokenEndStack[$stackPos]));
20393 }, 268 => static function ($self, $stackPos) {
20394 $self->semValue = array();
20395 }, 269 => static function ($self, $stackPos) {
20396 $self->semStack[$stackPos - (2 - 1)][] = $self->semStack[$stackPos - (2 - 2)];
20397 $self->semValue = $self->semStack[$stackPos - (2 - 1)];
20398 }, 270 => static function ($self, $stackPos) {
20399 $self->semValue = new Stmt\ElseIf_($self->semStack[$stackPos - (6 - 3)], $self->semStack[$stackPos - (6 - 6)], $self->getAttributes($self->tokenStartStack[$stackPos - (6 - 1)], $self->tokenEndStack[$stackPos]));
20400 $self->fixupAlternativeElse($self->semValue);
20401 }, 271 => static function ($self, $stackPos) {
20402 $self->semValue = null;
20403 }, 272 => static function ($self, $stackPos) {
20404 $self->semValue = new Stmt\Else_($self->semStack[$stackPos - (2 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
20405 }, 273 => static function ($self, $stackPos) {
20406 $self->semValue = null;
20407 }, 274 => static function ($self, $stackPos) {
20408 $self->semValue = new Stmt\Else_($self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
20409 $self->fixupAlternativeElse($self->semValue);
20410 }, 275 => static function ($self, $stackPos) {
20411 $self->semValue = array($self->semStack[$stackPos - (1 - 1)], \false);
20412 }, 276 => static function ($self, $stackPos) {
20413 $self->semValue = array($self->semStack[$stackPos - (2 - 2)], \true);
20414 }, 277 => static function ($self, $stackPos) {
20415 $self->semValue = array($self->semStack[$stackPos - (1 - 1)], \false);
20416 }, 278 => static function ($self, $stackPos) {
20417 $self->semValue = array($self->fixupArrayDestructuring($self->semStack[$stackPos - (1 - 1)]), \false);
20418 }, 279 => null, 280 => static function ($self, $stackPos) {
20419 $self->semValue = array();
20420 }, 281 => static function ($self, $stackPos) {
20421 $self->semValue = array($self->semStack[$stackPos - (1 - 1)]);
20422 }, 282 => static function ($self, $stackPos) {
20423 $self->semStack[$stackPos - (3 - 1)][] = $self->semStack[$stackPos - (3 - 3)];
20424 $self->semValue = $self->semStack[$stackPos - (3 - 1)];
20425 }, 283 => static function ($self, $stackPos) {
20426 $self->semValue = 0;
20427 }, 284 => static function ($self, $stackPos) {
20428 $self->checkModifier($self->semStack[$stackPos - (2 - 1)], $self->semStack[$stackPos - (2 - 2)], $stackPos - (2 - 2));
20429 $self->semValue = $self->semStack[$stackPos - (2 - 1)] | $self->semStack[$stackPos - (2 - 2)];
20430 }, 285 => static function ($self, $stackPos) {
20431 $self->semValue = Modifiers::PUBLIC;
20432 }, 286 => static function ($self, $stackPos) {
20433 $self->semValue = Modifiers::PROTECTED;
20434 }, 287 => static function ($self, $stackPos) {
20435 $self->semValue = Modifiers::PRIVATE;
20436 }, 288 => static function ($self, $stackPos) {
20437 $self->semValue = Modifiers::PUBLIC_SET;
20438 }, 289 => static function ($self, $stackPos) {
20439 $self->semValue = Modifiers::PROTECTED_SET;
20440 }, 290 => static function ($self, $stackPos) {
20441 $self->semValue = Modifiers::PRIVATE_SET;
20442 }, 291 => static function ($self, $stackPos) {
20443 $self->semValue = Modifiers::READONLY;
20444 }, 292 => static function ($self, $stackPos) {
20445 $self->semValue = Modifiers::FINAL;
20446 }, 293 => static function ($self, $stackPos) {
20447 $self->semValue = new Node\Param($self->semStack[$stackPos - (7 - 6)], null, $self->semStack[$stackPos - (7 - 3)], $self->semStack[$stackPos - (7 - 4)], $self->semStack[$stackPos - (7 - 5)], $self->getAttributes($self->tokenStartStack[$stackPos - (7 - 1)], $self->tokenEndStack[$stackPos]), $self->semStack[$stackPos - (7 - 2)], $self->semStack[$stackPos - (7 - 1)], $self->semStack[$stackPos - (7 - 7)]);
20448 $self->checkParam($self->semValue);
20449 $self->addPropertyNameToHooks($self->semValue);
20450 }, 294 => static function ($self, $stackPos) {
20451 $self->semValue = new Node\Param($self->semStack[$stackPos - (9 - 6)], $self->semStack[$stackPos - (9 - 8)], $self->semStack[$stackPos - (9 - 3)], $self->semStack[$stackPos - (9 - 4)], $self->semStack[$stackPos - (9 - 5)], $self->getAttributes($self->tokenStartStack[$stackPos - (9 - 1)], $self->tokenEndStack[$stackPos]), $self->semStack[$stackPos - (9 - 2)], $self->semStack[$stackPos - (9 - 1)], $self->semStack[$stackPos - (9 - 9)]);
20452 $self->checkParam($self->semValue);
20453 $self->addPropertyNameToHooks($self->semValue);
20454 }, 295 => static function ($self, $stackPos) {
20455 $self->semValue = new Node\Param(new Expr\Error($self->getAttributes($self->tokenStartStack[$stackPos - (6 - 1)], $self->tokenEndStack[$stackPos])), null, $self->semStack[$stackPos - (6 - 3)], $self->semStack[$stackPos - (6 - 4)], $self->semStack[$stackPos - (6 - 5)], $self->getAttributes($self->tokenStartStack[$stackPos - (6 - 1)], $self->tokenEndStack[$stackPos]), $self->semStack[$stackPos - (6 - 2)], $self->semStack[$stackPos - (6 - 1)]);
20456 }, 296 => null, 297 => static function ($self, $stackPos) {
20457 $self->semValue = new Node\NullableType($self->semStack[$stackPos - (2 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
20458 }, 298 => static function ($self, $stackPos) {
20459 $self->semValue = new Node\UnionType($self->semStack[$stackPos - (1 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
20460 }, 299 => null, 300 => null, 301 => static function ($self, $stackPos) {
20461 $self->semValue = new Node\Name('static', $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
20462 }, 302 => static function ($self, $stackPos) {
20463 $self->semValue = $self->handleBuiltinTypes($self->semStack[$stackPos - (1 - 1)]);
20464 }, 303 => static function ($self, $stackPos) {
20465 $self->semValue = new Node\Identifier('array', $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
20466 }, 304 => static function ($self, $stackPos) {
20467 $self->semValue = new Node\Identifier('callable', $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
20468 }, 305 => null, 306 => static function ($self, $stackPos) {
20469 $self->semValue = $self->semStack[$stackPos - (3 - 2)];
20470 }, 307 => static function ($self, $stackPos) {
20471 $self->semValue = array($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)]);
20472 }, 308 => static function ($self, $stackPos) {
20473 $self->semStack[$stackPos - (3 - 1)][] = $self->semStack[$stackPos - (3 - 3)];
20474 $self->semValue = $self->semStack[$stackPos - (3 - 1)];
20475 }, 309 => null, 310 => static function ($self, $stackPos) {
20476 $self->semValue = $self->semStack[$stackPos - (3 - 2)];
20477 }, 311 => static function ($self, $stackPos) {
20478 $self->semValue = array($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)]);
20479 }, 312 => static function ($self, $stackPos) {
20480 $self->semStack[$stackPos - (3 - 1)][] = $self->semStack[$stackPos - (3 - 3)];
20481 $self->semValue = $self->semStack[$stackPos - (3 - 1)];
20482 }, 313 => static function ($self, $stackPos) {
20483 $self->semValue = array($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)]);
20484 }, 314 => static function ($self, $stackPos) {
20485 $self->semStack[$stackPos - (3 - 1)][] = $self->semStack[$stackPos - (3 - 3)];
20486 $self->semValue = $self->semStack[$stackPos - (3 - 1)];
20487 }, 315 => static function ($self, $stackPos) {
20488 $self->semValue = new Node\IntersectionType($self->semStack[$stackPos - (1 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
20489 }, 316 => static function ($self, $stackPos) {
20490 $self->semValue = array($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)]);
20491 }, 317 => static function ($self, $stackPos) {
20492 $self->semStack[$stackPos - (3 - 1)][] = $self->semStack[$stackPos - (3 - 3)];
20493 $self->semValue = $self->semStack[$stackPos - (3 - 1)];
20494 }, 318 => static function ($self, $stackPos) {
20495 $self->semValue = new Node\IntersectionType($self->semStack[$stackPos - (1 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
20496 }, 319 => null, 320 => static function ($self, $stackPos) {
20497 $self->semValue = new Node\NullableType($self->semStack[$stackPos - (2 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
20498 }, 321 => static function ($self, $stackPos) {
20499 $self->semValue = new Node\UnionType($self->semStack[$stackPos - (1 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
20500 }, 322 => null, 323 => static function ($self, $stackPos) {
20501 $self->semValue = null;
20502 }, 324 => null, 325 => static function ($self, $stackPos) {
20503 $self->semValue = null;
20504 }, 326 => static function ($self, $stackPos) {
20505 $self->semValue = $self->semStack[$stackPos - (2 - 2)];
20506 }, 327 => static function ($self, $stackPos) {
20507 $self->semValue = null;
20508 }, 328 => static function ($self, $stackPos) {
20509 $self->semValue = array();
20510 }, 329 => static function ($self, $stackPos) {
20511 $self->semValue = $self->semStack[$stackPos - (4 - 2)];
20512 }, 330 => static function ($self, $stackPos) {
20513 $self->semValue = array($self->semStack[$stackPos - (3 - 2)]);
20514 }, 331 => static function ($self, $stackPos) {
20515 $self->semValue = array();
20516 }, 332 => static function ($self, $stackPos) {
20517 $self->semValue = $self->semStack[$stackPos - (4 - 2)];
20518 }, 333 => static function ($self, $stackPos) {
20519 $self->semValue = array(new Node\Arg($self->semStack[$stackPos - (4 - 2)], \false, \false, $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos])));
20520 }, 334 => static function ($self, $stackPos) {
20521 $self->semValue = array($self->semStack[$stackPos - (3 - 2)]);
20522 }, 335 => static function ($self, $stackPos) {
20523 $self->semValue = array(new Node\Arg($self->semStack[$stackPos - (3 - 1)], \false, \false, $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos - (3 - 1)])), $self->semStack[$stackPos - (3 - 3)]);
20524 }, 336 => static function ($self, $stackPos) {
20525 $self->semValue = array($self->semStack[$stackPos - (1 - 1)]);
20526 }, 337 => static function ($self, $stackPos) {
20527 $self->semStack[$stackPos - (3 - 1)][] = $self->semStack[$stackPos - (3 - 3)];
20528 $self->semValue = $self->semStack[$stackPos - (3 - 1)];
20529 }, 338 => static function ($self, $stackPos) {
20530 $self->semValue = new Node\VariadicPlaceholder($self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
20531 }, 339 => static function ($self, $stackPos) {
20532 $self->semValue = array($self->semStack[$stackPos - (1 - 1)]);
20533 }, 340 => static function ($self, $stackPos) {
20534 $self->semStack[$stackPos - (3 - 1)][] = $self->semStack[$stackPos - (3 - 3)];
20535 $self->semValue = $self->semStack[$stackPos - (3 - 1)];
20536 }, 341 => static function ($self, $stackPos) {
20537 $self->semValue = new Node\Arg($self->semStack[$stackPos - (2 - 2)], \true, \false, $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
20538 }, 342 => static function ($self, $stackPos) {
20539 $self->semValue = new Node\Arg($self->semStack[$stackPos - (2 - 2)], \false, \true, $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
20540 }, 343 => static function ($self, $stackPos) {
20541 $self->semValue = new Node\Arg($self->semStack[$stackPos - (3 - 3)], \false, \false, $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]), $self->semStack[$stackPos - (3 - 1)]);
20542 }, 344 => static function ($self, $stackPos) {
20543 $self->semValue = new Node\Arg($self->semStack[$stackPos - (1 - 1)], \false, \false, $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
20544 }, 345 => static function ($self, $stackPos) {
20545 $self->semValue = $self->semStack[$stackPos - (1 - 1)];
20546 }, 346 => null, 347 => static function ($self, $stackPos) {
20547 $self->semStack[$stackPos - (3 - 1)][] = $self->semStack[$stackPos - (3 - 3)];
20548 $self->semValue = $self->semStack[$stackPos - (3 - 1)];
20549 }, 348 => static function ($self, $stackPos) {
20550 $self->semValue = array($self->semStack[$stackPos - (1 - 1)]);
20551 }, 349 => null, 350 => null, 351 => static function ($self, $stackPos) {
20552 $self->semStack[$stackPos - (3 - 1)][] = $self->semStack[$stackPos - (3 - 3)];
20553 $self->semValue = $self->semStack[$stackPos - (3 - 1)];
20554 }, 352 => static function ($self, $stackPos) {
20555 $self->semValue = array($self->semStack[$stackPos - (1 - 1)]);
20556 }, 353 => static function ($self, $stackPos) {
20557 $self->semValue = new Node\StaticVar($self->semStack[$stackPos - (1 - 1)], null, $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
20558 }, 354 => static function ($self, $stackPos) {
20559 $self->semValue = new Node\StaticVar($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
20560 }, 355 => static function ($self, $stackPos) {
20561 if ($self->semStack[$stackPos - (2 - 2)] !== null) {
20562 $self->semStack[$stackPos - (2 - 1)][] = $self->semStack[$stackPos - (2 - 2)];
20563 $self->semValue = $self->semStack[$stackPos - (2 - 1)];
20564 } else {
20565 $self->semValue = $self->semStack[$stackPos - (2 - 1)];
20566 }
20567 }, 356 => static function ($self, $stackPos) {
20568 $self->semValue = array();
20569 }, 357 => static function ($self, $stackPos) {
20570 $nop = $self->maybeCreateZeroLengthNop($self->tokenPos);
20571 if ($nop !== null) {
20572 $self->semStack[$stackPos - (1 - 1)][] = $nop;
20573 }
20574 $self->semValue = $self->semStack[$stackPos - (1 - 1)];
20575 }, 358 => static function ($self, $stackPos) {
20576 $self->semValue = new Stmt\Property($self->semStack[$stackPos - (5 - 2)], $self->semStack[$stackPos - (5 - 4)], $self->getAttributes($self->tokenStartStack[$stackPos - (5 - 1)], $self->tokenEndStack[$stackPos]), $self->semStack[$stackPos - (5 - 3)], $self->semStack[$stackPos - (5 - 1)]);
20577 }, 359 => static function ($self, $stackPos) {
20578 $self->semValue = new Stmt\Property($self->semStack[$stackPos - (7 - 2)], $self->semStack[$stackPos - (7 - 4)], $self->getAttributes($self->tokenStartStack[$stackPos - (7 - 1)], $self->tokenEndStack[$stackPos]), $self->semStack[$stackPos - (7 - 3)], $self->semStack[$stackPos - (7 - 1)], $self->semStack[$stackPos - (7 - 6)]);
20579 $self->checkPropertyHooksForMultiProperty($self->semValue, $stackPos - (7 - 5));
20580 $self->checkEmptyPropertyHookList($self->semStack[$stackPos - (7 - 6)], $stackPos - (7 - 5));
20581 $self->addPropertyNameToHooks($self->semValue);
20582 }, 360 => static function ($self, $stackPos) {
20583 $self->semValue = new Stmt\ClassConst($self->semStack[$stackPos - (5 - 4)], $self->semStack[$stackPos - (5 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (5 - 1)], $self->tokenEndStack[$stackPos]), $self->semStack[$stackPos - (5 - 1)]);
20584 $self->checkClassConst($self->semValue, $stackPos - (5 - 2));
20585 }, 361 => static function ($self, $stackPos) {
20586 $self->semValue = new Stmt\ClassConst($self->semStack[$stackPos - (6 - 5)], $self->semStack[$stackPos - (6 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (6 - 1)], $self->tokenEndStack[$stackPos]), $self->semStack[$stackPos - (6 - 1)], $self->semStack[$stackPos - (6 - 4)]);
20587 $self->checkClassConst($self->semValue, $stackPos - (6 - 2));
20588 }, 362 => static function ($self, $stackPos) {
20589 $self->semValue = new Stmt\ClassMethod($self->semStack[$stackPos - (10 - 5)], ['type' => $self->semStack[$stackPos - (10 - 2)], 'byRef' => $self->semStack[$stackPos - (10 - 4)], 'params' => $self->semStack[$stackPos - (10 - 7)], 'returnType' => $self->semStack[$stackPos - (10 - 9)], 'stmts' => $self->semStack[$stackPos - (10 - 10)], 'attrGroups' => $self->semStack[$stackPos - (10 - 1)]], $self->getAttributes($self->tokenStartStack[$stackPos - (10 - 1)], $self->tokenEndStack[$stackPos]));
20590 $self->checkClassMethod($self->semValue, $stackPos - (10 - 2));
20591 }, 363 => static function ($self, $stackPos) {
20592 $self->semValue = new Stmt\TraitUse($self->semStack[$stackPos - (3 - 2)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
20593 }, 364 => static function ($self, $stackPos) {
20594 $self->semValue = new Stmt\EnumCase($self->semStack[$stackPos - (5 - 3)], $self->semStack[$stackPos - (5 - 4)], $self->semStack[$stackPos - (5 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (5 - 1)], $self->tokenEndStack[$stackPos]));
20595 }, 365 => static function ($self, $stackPos) {
20596 $self->semValue = null;
20597 /* will be skipped */
20598 }, 366 => static function ($self, $stackPos) {
20599 $self->semValue = array();
20600 }, 367 => static function ($self, $stackPos) {
20601 $self->semValue = $self->semStack[$stackPos - (3 - 2)];
20602 }, 368 => static function ($self, $stackPos) {
20603 $self->semValue = array();
20604 }, 369 => static function ($self, $stackPos) {
20605 $self->semStack[$stackPos - (2 - 1)][] = $self->semStack[$stackPos - (2 - 2)];
20606 $self->semValue = $self->semStack[$stackPos - (2 - 1)];
20607 }, 370 => static function ($self, $stackPos) {
20608 $self->semValue = new Stmt\TraitUseAdaptation\Precedence($self->semStack[$stackPos - (4 - 1)][0], $self->semStack[$stackPos - (4 - 1)][1], $self->semStack[$stackPos - (4 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]));
20609 }, 371 => static function ($self, $stackPos) {
20610 $self->semValue = new Stmt\TraitUseAdaptation\Alias($self->semStack[$stackPos - (5 - 1)][0], $self->semStack[$stackPos - (5 - 1)][1], $self->semStack[$stackPos - (5 - 3)], $self->semStack[$stackPos - (5 - 4)], $self->getAttributes($self->tokenStartStack[$stackPos - (5 - 1)], $self->tokenEndStack[$stackPos]));
20611 }, 372 => static function ($self, $stackPos) {
20612 $self->semValue = new Stmt\TraitUseAdaptation\Alias($self->semStack[$stackPos - (4 - 1)][0], $self->semStack[$stackPos - (4 - 1)][1], $self->semStack[$stackPos - (4 - 3)], null, $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]));
20613 }, 373 => static function ($self, $stackPos) {
20614 $self->semValue = new Stmt\TraitUseAdaptation\Alias($self->semStack[$stackPos - (4 - 1)][0], $self->semStack[$stackPos - (4 - 1)][1], null, $self->semStack[$stackPos - (4 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]));
20615 }, 374 => static function ($self, $stackPos) {
20616 $self->semValue = new Stmt\TraitUseAdaptation\Alias($self->semStack[$stackPos - (4 - 1)][0], $self->semStack[$stackPos - (4 - 1)][1], null, $self->semStack[$stackPos - (4 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]));
20617 }, 375 => static function ($self, $stackPos) {
20618 $self->semValue = array($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)]);
20619 }, 376 => null, 377 => static function ($self, $stackPos) {
20620 $self->semValue = array(null, $self->semStack[$stackPos - (1 - 1)]);
20621 }, 378 => static function ($self, $stackPos) {
20622 $self->semValue = null;
20623 }, 379 => null, 380 => null, 381 => static function ($self, $stackPos) {
20624 $self->semValue = 0;
20625 }, 382 => static function ($self, $stackPos) {
20626 $self->semValue = 0;
20627 }, 383 => null, 384 => null, 385 => static function ($self, $stackPos) {
20628 $self->checkModifier($self->semStack[$stackPos - (2 - 1)], $self->semStack[$stackPos - (2 - 2)], $stackPos - (2 - 2));
20629 $self->semValue = $self->semStack[$stackPos - (2 - 1)] | $self->semStack[$stackPos - (2 - 2)];
20630 }, 386 => static function ($self, $stackPos) {
20631 $self->semValue = Modifiers::PUBLIC;
20632 }, 387 => static function ($self, $stackPos) {
20633 $self->semValue = Modifiers::PROTECTED;
20634 }, 388 => static function ($self, $stackPos) {
20635 $self->semValue = Modifiers::PRIVATE;
20636 }, 389 => static function ($self, $stackPos) {
20637 $self->semValue = Modifiers::PUBLIC_SET;
20638 }, 390 => static function ($self, $stackPos) {
20639 $self->semValue = Modifiers::PROTECTED_SET;
20640 }, 391 => static function ($self, $stackPos) {
20641 $self->semValue = Modifiers::PRIVATE_SET;
20642 }, 392 => static function ($self, $stackPos) {
20643 $self->semValue = Modifiers::STATIC;
20644 }, 393 => static function ($self, $stackPos) {
20645 $self->semValue = Modifiers::ABSTRACT;
20646 }, 394 => static function ($self, $stackPos) {
20647 $self->semValue = Modifiers::FINAL;
20648 }, 395 => static function ($self, $stackPos) {
20649 $self->semValue = Modifiers::READONLY;
20650 }, 396 => null, 397 => static function ($self, $stackPos) {
20651 $self->semValue = array($self->semStack[$stackPos - (1 - 1)]);
20652 }, 398 => static function ($self, $stackPos) {
20653 $self->semStack[$stackPos - (3 - 1)][] = $self->semStack[$stackPos - (3 - 3)];
20654 $self->semValue = $self->semStack[$stackPos - (3 - 1)];
20655 }, 399 => static function ($self, $stackPos) {
20656 $self->semValue = new Node\VarLikeIdentifier(substr($self->semStack[$stackPos - (1 - 1)], 1), $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
20657 }, 400 => static function ($self, $stackPos) {
20658 $self->semValue = new Node\PropertyItem($self->semStack[$stackPos - (1 - 1)], null, $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
20659 }, 401 => static function ($self, $stackPos) {
20660 $self->semValue = new Node\PropertyItem($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
20661 }, 402 => static function ($self, $stackPos) {
20662 $self->semValue = [];
20663 }, 403 => static function ($self, $stackPos) {
20664 $self->semStack[$stackPos - (2 - 1)][] = $self->semStack[$stackPos - (2 - 2)];
20665 $self->semValue = $self->semStack[$stackPos - (2 - 1)];
20666 }, 404 => static function ($self, $stackPos) {
20667 $self->semValue = [];
20668 }, 405 => static function ($self, $stackPos) {
20669 $self->semValue = $self->semStack[$stackPos - (3 - 2)];
20670 $self->checkEmptyPropertyHookList($self->semStack[$stackPos - (3 - 2)], $stackPos - (3 - 1));
20671 }, 406 => static function ($self, $stackPos) {
20672 $self->semValue = new Node\PropertyHook($self->semStack[$stackPos - (5 - 4)], $self->semStack[$stackPos - (5 - 5)], ['flags' => $self->semStack[$stackPos - (5 - 2)], 'byRef' => $self->semStack[$stackPos - (5 - 3)], 'params' => [], 'attrGroups' => $self->semStack[$stackPos - (5 - 1)]], $self->getAttributes($self->tokenStartStack[$stackPos - (5 - 1)], $self->tokenEndStack[$stackPos]));
20673 $self->checkPropertyHook($self->semValue, null);
20674 }, 407 => static function ($self, $stackPos) {
20675 $self->semValue = new Node\PropertyHook($self->semStack[$stackPos - (8 - 4)], $self->semStack[$stackPos - (8 - 8)], ['flags' => $self->semStack[$stackPos - (8 - 2)], 'byRef' => $self->semStack[$stackPos - (8 - 3)], 'params' => $self->semStack[$stackPos - (8 - 6)], 'attrGroups' => $self->semStack[$stackPos - (8 - 1)]], $self->getAttributes($self->tokenStartStack[$stackPos - (8 - 1)], $self->tokenEndStack[$stackPos]));
20676 $self->checkPropertyHook($self->semValue, $stackPos - (8 - 5));
20677 }, 408 => static function ($self, $stackPos) {
20678 $self->semValue = null;
20679 }, 409 => static function ($self, $stackPos) {
20680 $self->semValue = $self->semStack[$stackPos - (3 - 2)];
20681 }, 410 => static function ($self, $stackPos) {
20682 $self->semValue = $self->semStack[$stackPos - (3 - 2)];
20683 }, 411 => static function ($self, $stackPos) {
20684 $self->semValue = 0;
20685 }, 412 => static function ($self, $stackPos) {
20686 $self->checkPropertyHookModifiers($self->semStack[$stackPos - (2 - 1)], $self->semStack[$stackPos - (2 - 2)], $stackPos - (2 - 2));
20687 $self->semValue = $self->semStack[$stackPos - (2 - 1)] | $self->semStack[$stackPos - (2 - 2)];
20688 }, 413 => null, 414 => null, 415 => static function ($self, $stackPos) {
20689 $self->semStack[$stackPos - (3 - 1)][] = $self->semStack[$stackPos - (3 - 3)];
20690 $self->semValue = $self->semStack[$stackPos - (3 - 1)];
20691 }, 416 => static function ($self, $stackPos) {
20692 $self->semValue = array($self->semStack[$stackPos - (1 - 1)]);
20693 }, 417 => static function ($self, $stackPos) {
20694 $self->semValue = array();
20695 }, 418 => null, 419 => null, 420 => static function ($self, $stackPos) {
20696 $self->semValue = new Expr\Assign($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
20697 }, 421 => static function ($self, $stackPos) {
20698 $self->semValue = new Expr\Assign($self->fixupArrayDestructuring($self->semStack[$stackPos - (3 - 1)]), $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
20699 }, 422 => static function ($self, $stackPos) {
20700 $self->semValue = new Expr\Assign($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
20701 }, 423 => static function ($self, $stackPos) {
20702 $self->semValue = new Expr\AssignRef($self->semStack[$stackPos - (4 - 1)], $self->semStack[$stackPos - (4 - 4)], $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]));
20703 }, 424 => static function ($self, $stackPos) {
20704 $self->semValue = new Expr\AssignRef($self->semStack[$stackPos - (4 - 1)], $self->semStack[$stackPos - (4 - 4)], $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]));
20705 if (!$self->phpVersion->allowsAssignNewByReference()) {
20706 $self->emitError(new Error('Cannot assign new by reference', $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos])));
20707 }
20708 }, 425 => null, 426 => null, 427 => static function ($self, $stackPos) {
20709 $self->semValue = new Expr\FuncCall(new Node\Name($self->semStack[$stackPos - (2 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos - (2 - 1)])), $self->semStack[$stackPos - (2 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
20710 }, 428 => static function ($self, $stackPos) {
20711 $self->semValue = new Expr\Clone_($self->semStack[$stackPos - (2 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
20712 }, 429 => static function ($self, $stackPos) {
20713 $self->semValue = new Expr\AssignOp\Plus($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
20714 }, 430 => static function ($self, $stackPos) {
20715 $self->semValue = new Expr\AssignOp\Minus($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
20716 }, 431 => static function ($self, $stackPos) {
20717 $self->semValue = new Expr\AssignOp\Mul($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
20718 }, 432 => static function ($self, $stackPos) {
20719 $self->semValue = new Expr\AssignOp\Div($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
20720 }, 433 => static function ($self, $stackPos) {
20721 $self->semValue = new Expr\AssignOp\Concat($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
20722 }, 434 => static function ($self, $stackPos) {
20723 $self->semValue = new Expr\AssignOp\Mod($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
20724 }, 435 => static function ($self, $stackPos) {
20725 $self->semValue = new Expr\AssignOp\BitwiseAnd($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
20726 }, 436 => static function ($self, $stackPos) {
20727 $self->semValue = new Expr\AssignOp\BitwiseOr($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
20728 }, 437 => static function ($self, $stackPos) {
20729 $self->semValue = new Expr\AssignOp\BitwiseXor($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
20730 }, 438 => static function ($self, $stackPos) {
20731 $self->semValue = new Expr\AssignOp\ShiftLeft($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
20732 }, 439 => static function ($self, $stackPos) {
20733 $self->semValue = new Expr\AssignOp\ShiftRight($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
20734 }, 440 => static function ($self, $stackPos) {
20735 $self->semValue = new Expr\AssignOp\Pow($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
20736 }, 441 => static function ($self, $stackPos) {
20737 $self->semValue = new Expr\AssignOp\Coalesce($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
20738 }, 442 => static function ($self, $stackPos) {
20739 $self->semValue = new Expr\PostInc($self->semStack[$stackPos - (2 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
20740 }, 443 => static function ($self, $stackPos) {
20741 $self->semValue = new Expr\PreInc($self->semStack[$stackPos - (2 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
20742 }, 444 => static function ($self, $stackPos) {
20743 $self->semValue = new Expr\PostDec($self->semStack[$stackPos - (2 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
20744 }, 445 => static function ($self, $stackPos) {
20745 $self->semValue = new Expr\PreDec($self->semStack[$stackPos - (2 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
20746 }, 446 => static function ($self, $stackPos) {
20747 $self->semValue = new Expr\BinaryOp\BooleanOr($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
20748 }, 447 => static function ($self, $stackPos) {
20749 $self->semValue = new Expr\BinaryOp\BooleanAnd($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
20750 }, 448 => static function ($self, $stackPos) {
20751 $self->semValue = new Expr\BinaryOp\LogicalOr($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
20752 }, 449 => static function ($self, $stackPos) {
20753 $self->semValue = new Expr\BinaryOp\LogicalAnd($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
20754 }, 450 => static function ($self, $stackPos) {
20755 $self->semValue = new Expr\BinaryOp\LogicalXor($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
20756 }, 451 => static function ($self, $stackPos) {
20757 $self->semValue = new Expr\BinaryOp\BitwiseOr($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
20758 }, 452 => static function ($self, $stackPos) {
20759 $self->semValue = new Expr\BinaryOp\BitwiseAnd($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
20760 }, 453 => static function ($self, $stackPos) {
20761 $self->semValue = new Expr\BinaryOp\BitwiseAnd($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
20762 }, 454 => static function ($self, $stackPos) {
20763 $self->semValue = new Expr\BinaryOp\BitwiseXor($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
20764 }, 455 => static function ($self, $stackPos) {
20765 $self->semValue = new Expr\BinaryOp\Concat($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
20766 }, 456 => static function ($self, $stackPos) {
20767 $self->semValue = new Expr\BinaryOp\Plus($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
20768 }, 457 => static function ($self, $stackPos) {
20769 $self->semValue = new Expr\BinaryOp\Minus($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
20770 }, 458 => static function ($self, $stackPos) {
20771 $self->semValue = new Expr\BinaryOp\Mul($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
20772 }, 459 => static function ($self, $stackPos) {
20773 $self->semValue = new Expr\BinaryOp\Div($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
20774 }, 460 => static function ($self, $stackPos) {
20775 $self->semValue = new Expr\BinaryOp\Mod($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
20776 }, 461 => static function ($self, $stackPos) {
20777 $self->semValue = new Expr\BinaryOp\ShiftLeft($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
20778 }, 462 => static function ($self, $stackPos) {
20779 $self->semValue = new Expr\BinaryOp\ShiftRight($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
20780 }, 463 => static function ($self, $stackPos) {
20781 $self->semValue = new Expr\BinaryOp\Pow($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
20782 }, 464 => static function ($self, $stackPos) {
20783 $self->semValue = new Expr\UnaryPlus($self->semStack[$stackPos - (2 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
20784 }, 465 => static function ($self, $stackPos) {
20785 $self->semValue = new Expr\UnaryMinus($self->semStack[$stackPos - (2 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
20786 }, 466 => static function ($self, $stackPos) {
20787 $self->semValue = new Expr\BooleanNot($self->semStack[$stackPos - (2 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
20788 }, 467 => static function ($self, $stackPos) {
20789 $self->semValue = new Expr\BitwiseNot($self->semStack[$stackPos - (2 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
20790 }, 468 => static function ($self, $stackPos) {
20791 $self->semValue = new Expr\BinaryOp\Identical($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
20792 }, 469 => static function ($self, $stackPos) {
20793 $self->semValue = new Expr\BinaryOp\NotIdentical($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
20794 }, 470 => static function ($self, $stackPos) {
20795 $self->semValue = new Expr\BinaryOp\Equal($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
20796 }, 471 => static function ($self, $stackPos) {
20797 $self->semValue = new Expr\BinaryOp\NotEqual($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
20798 }, 472 => static function ($self, $stackPos) {
20799 $self->semValue = new Expr\BinaryOp\Spaceship($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
20800 }, 473 => static function ($self, $stackPos) {
20801 $self->semValue = new Expr\BinaryOp\Smaller($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
20802 }, 474 => static function ($self, $stackPos) {
20803 $self->semValue = new Expr\BinaryOp\SmallerOrEqual($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
20804 }, 475 => static function ($self, $stackPos) {
20805 $self->semValue = new Expr\BinaryOp\Greater($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
20806 }, 476 => static function ($self, $stackPos) {
20807 $self->semValue = new Expr\BinaryOp\GreaterOrEqual($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
20808 }, 477 => static function ($self, $stackPos) {
20809 $self->semValue = new Expr\BinaryOp\Pipe($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
20810 $self->checkPipeOperatorParentheses($self->semStack[$stackPos - (3 - 3)]);
20811 }, 478 => static function ($self, $stackPos) {
20812 $self->semValue = new Expr\Instanceof_($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
20813 }, 479 => static function ($self, $stackPos) {
20814 $self->semValue = $self->semStack[$stackPos - (3 - 2)];
20815 if ($self->semValue instanceof Expr\ArrowFunction) {
20816 $self->parenthesizedArrowFunctions->offsetSet($self->semValue);
20817 }
20818 }, 480 => static function ($self, $stackPos) {
20819 $self->semValue = new Expr\Ternary($self->semStack[$stackPos - (5 - 1)], $self->semStack[$stackPos - (5 - 3)], $self->semStack[$stackPos - (5 - 5)], $self->getAttributes($self->tokenStartStack[$stackPos - (5 - 1)], $self->tokenEndStack[$stackPos]));
20820 }, 481 => static function ($self, $stackPos) {
20821 $self->semValue = new Expr\Ternary($self->semStack[$stackPos - (4 - 1)], null, $self->semStack[$stackPos - (4 - 4)], $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]));
20822 }, 482 => static function ($self, $stackPos) {
20823 $self->semValue = new Expr\BinaryOp\Coalesce($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
20824 }, 483 => static function ($self, $stackPos) {
20825 $self->semValue = new Expr\Isset_($self->semStack[$stackPos - (4 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]));
20826 }, 484 => static function ($self, $stackPos) {
20827 $self->semValue = new Expr\Empty_($self->semStack[$stackPos - (4 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]));
20828 }, 485 => static function ($self, $stackPos) {
20829 $self->semValue = new Expr\Include_($self->semStack[$stackPos - (2 - 2)], Expr\Include_::TYPE_INCLUDE, $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
20830 }, 486 => static function ($self, $stackPos) {
20831 $self->semValue = new Expr\Include_($self->semStack[$stackPos - (2 - 2)], Expr\Include_::TYPE_INCLUDE_ONCE, $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
20832 }, 487 => static function ($self, $stackPos) {
20833 $self->semValue = new Expr\Eval_($self->semStack[$stackPos - (4 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]));
20834 }, 488 => static function ($self, $stackPos) {
20835 $self->semValue = new Expr\Include_($self->semStack[$stackPos - (2 - 2)], Expr\Include_::TYPE_REQUIRE, $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
20836 }, 489 => static function ($self, $stackPos) {
20837 $self->semValue = new Expr\Include_($self->semStack[$stackPos - (2 - 2)], Expr\Include_::TYPE_REQUIRE_ONCE, $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
20838 }, 490 => static function ($self, $stackPos) {
20839 $attrs = $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]);
20840 $attrs['kind'] = $self->getIntCastKind($self->semStack[$stackPos - (2 - 1)]);
20841 $self->semValue = new Expr\Cast\Int_($self->semStack[$stackPos - (2 - 2)], $attrs);
20842 }, 491 => static function ($self, $stackPos) {
20843 $attrs = $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]);
20844 $attrs['kind'] = $self->getFloatCastKind($self->semStack[$stackPos - (2 - 1)]);
20845 $self->semValue = new Expr\Cast\Double($self->semStack[$stackPos - (2 - 2)], $attrs);
20846 }, 492 => static function ($self, $stackPos) {
20847 $attrs = $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]);
20848 $attrs['kind'] = $self->getStringCastKind($self->semStack[$stackPos - (2 - 1)]);
20849 $self->semValue = new Expr\Cast\String_($self->semStack[$stackPos - (2 - 2)], $attrs);
20850 }, 493 => static function ($self, $stackPos) {
20851 $self->semValue = new Expr\Cast\Array_($self->semStack[$stackPos - (2 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
20852 }, 494 => static function ($self, $stackPos) {
20853 $self->semValue = new Expr\Cast\Object_($self->semStack[$stackPos - (2 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
20854 }, 495 => static function ($self, $stackPos) {
20855 $attrs = $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]);
20856 $attrs['kind'] = $self->getBoolCastKind($self->semStack[$stackPos - (2 - 1)]);
20857 $self->semValue = new Expr\Cast\Bool_($self->semStack[$stackPos - (2 - 2)], $attrs);
20858 }, 496 => static function ($self, $stackPos) {
20859 $self->semValue = new Expr\Cast\Unset_($self->semStack[$stackPos - (2 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
20860 }, 497 => static function ($self, $stackPos) {
20861 $self->semValue = new Expr\Cast\Void_($self->semStack[$stackPos - (2 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
20862 }, 498 => static function ($self, $stackPos) {
20863 $self->semValue = $self->createExitExpr($self->semStack[$stackPos - (2 - 1)], $stackPos - (2 - 1), $self->semStack[$stackPos - (2 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
20864 }, 499 => static function ($self, $stackPos) {
20865 $self->semValue = new Expr\ErrorSuppress($self->semStack[$stackPos - (2 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
20866 }, 500 => null, 501 => static function ($self, $stackPos) {
20867 $self->semValue = new Expr\ShellExec($self->semStack[$stackPos - (3 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
20868 }, 502 => static function ($self, $stackPos) {
20869 $self->semValue = new Expr\Print_($self->semStack[$stackPos - (2 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
20870 }, 503 => static function ($self, $stackPos) {
20871 $self->semValue = new Expr\Yield_(null, null, $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
20872 }, 504 => static function ($self, $stackPos) {
20873 $self->semValue = new Expr\Yield_($self->semStack[$stackPos - (2 - 2)], null, $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
20874 }, 505 => static function ($self, $stackPos) {
20875 $self->semValue = new Expr\Yield_($self->semStack[$stackPos - (4 - 4)], $self->semStack[$stackPos - (4 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]));
20876 }, 506 => static function ($self, $stackPos) {
20877 $self->semValue = new Expr\YieldFrom($self->semStack[$stackPos - (2 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
20878 }, 507 => static function ($self, $stackPos) {
20879 $self->semValue = new Expr\Throw_($self->semStack[$stackPos - (2 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
20880 }, 508 => static function ($self, $stackPos) {
20881 $self->semValue = new Expr\ArrowFunction(['static' => \false, 'byRef' => $self->semStack[$stackPos - (8 - 2)], 'params' => $self->semStack[$stackPos - (8 - 4)], 'returnType' => $self->semStack[$stackPos - (8 - 6)], 'expr' => $self->semStack[$stackPos - (8 - 8)], 'attrGroups' => []], $self->getAttributes($self->tokenStartStack[$stackPos - (8 - 1)], $self->tokenEndStack[$stackPos]));
20882 }, 509 => static function ($self, $stackPos) {
20883 $self->semValue = new Expr\ArrowFunction(['static' => \true, 'byRef' => $self->semStack[$stackPos - (9 - 3)], 'params' => $self->semStack[$stackPos - (9 - 5)], 'returnType' => $self->semStack[$stackPos - (9 - 7)], 'expr' => $self->semStack[$stackPos - (9 - 9)], 'attrGroups' => []], $self->getAttributes($self->tokenStartStack[$stackPos - (9 - 1)], $self->tokenEndStack[$stackPos]));
20884 }, 510 => static function ($self, $stackPos) {
20885 $self->semValue = new Expr\Closure(['static' => \false, 'byRef' => $self->semStack[$stackPos - (8 - 2)], 'params' => $self->semStack[$stackPos - (8 - 4)], 'uses' => $self->semStack[$stackPos - (8 - 6)], 'returnType' => $self->semStack[$stackPos - (8 - 7)], 'stmts' => $self->semStack[$stackPos - (8 - 8)], 'attrGroups' => []], $self->getAttributes($self->tokenStartStack[$stackPos - (8 - 1)], $self->tokenEndStack[$stackPos]));
20886 }, 511 => static function ($self, $stackPos) {
20887 $self->semValue = new Expr\Closure(['static' => \true, 'byRef' => $self->semStack[$stackPos - (9 - 3)], 'params' => $self->semStack[$stackPos - (9 - 5)], 'uses' => $self->semStack[$stackPos - (9 - 7)], 'returnType' => $self->semStack[$stackPos - (9 - 8)], 'stmts' => $self->semStack[$stackPos - (9 - 9)], 'attrGroups' => []], $self->getAttributes($self->tokenStartStack[$stackPos - (9 - 1)], $self->tokenEndStack[$stackPos]));
20888 }, 512 => static function ($self, $stackPos) {
20889 $self->semValue = new Expr\ArrowFunction(['static' => \false, 'byRef' => $self->semStack[$stackPos - (9 - 3)], 'params' => $self->semStack[$stackPos - (9 - 5)], 'returnType' => $self->semStack[$stackPos - (9 - 7)], 'expr' => $self->semStack[$stackPos - (9 - 9)], 'attrGroups' => $self->semStack[$stackPos - (9 - 1)]], $self->getAttributes($self->tokenStartStack[$stackPos - (9 - 1)], $self->tokenEndStack[$stackPos]));
20890 }, 513 => static function ($self, $stackPos) {
20891 $self->semValue = new Expr\ArrowFunction(['static' => \true, 'byRef' => $self->semStack[$stackPos - (10 - 4)], 'params' => $self->semStack[$stackPos - (10 - 6)], 'returnType' => $self->semStack[$stackPos - (10 - 8)], 'expr' => $self->semStack[$stackPos - (10 - 10)], 'attrGroups' => $self->semStack[$stackPos - (10 - 1)]], $self->getAttributes($self->tokenStartStack[$stackPos - (10 - 1)], $self->tokenEndStack[$stackPos]));
20892 }, 514 => static function ($self, $stackPos) {
20893 $self->semValue = new Expr\Closure(['static' => \false, 'byRef' => $self->semStack[$stackPos - (9 - 3)], 'params' => $self->semStack[$stackPos - (9 - 5)], 'uses' => $self->semStack[$stackPos - (9 - 7)], 'returnType' => $self->semStack[$stackPos - (9 - 8)], 'stmts' => $self->semStack[$stackPos - (9 - 9)], 'attrGroups' => $self->semStack[$stackPos - (9 - 1)]], $self->getAttributes($self->tokenStartStack[$stackPos - (9 - 1)], $self->tokenEndStack[$stackPos]));
20894 }, 515 => static function ($self, $stackPos) {
20895 $self->semValue = new Expr\Closure(['static' => \true, 'byRef' => $self->semStack[$stackPos - (10 - 4)], 'params' => $self->semStack[$stackPos - (10 - 6)], 'uses' => $self->semStack[$stackPos - (10 - 8)], 'returnType' => $self->semStack[$stackPos - (10 - 9)], 'stmts' => $self->semStack[$stackPos - (10 - 10)], 'attrGroups' => $self->semStack[$stackPos - (10 - 1)]], $self->getAttributes($self->tokenStartStack[$stackPos - (10 - 1)], $self->tokenEndStack[$stackPos]));
20896 }, 516 => static function ($self, $stackPos) {
20897 $self->semValue = array(new Stmt\Class_(null, ['type' => $self->semStack[$stackPos - (8 - 2)], 'extends' => $self->semStack[$stackPos - (8 - 4)], 'implements' => $self->semStack[$stackPos - (8 - 5)], 'stmts' => $self->semStack[$stackPos - (8 - 7)], 'attrGroups' => $self->semStack[$stackPos - (8 - 1)]], $self->getAttributes($self->tokenStartStack[$stackPos - (8 - 1)], $self->tokenEndStack[$stackPos])), $self->semStack[$stackPos - (8 - 3)]);
20898 $self->checkClass($self->semValue[0], -1);
20899 }, 517 => static function ($self, $stackPos) {
20900 $self->semValue = new Expr\New_($self->semStack[$stackPos - (3 - 2)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
20901 }, 518 => static function ($self, $stackPos) {
20902 list($class, $ctorArgs) = $self->semStack[$stackPos - (2 - 2)];
20903 $self->semValue = new Expr\New_($class, $ctorArgs, $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
20904 }, 519 => static function ($self, $stackPos) {
20905 $self->semValue = new Expr\New_($self->semStack[$stackPos - (2 - 2)], [], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
20906 }, 520 => null, 521 => null, 522 => static function ($self, $stackPos) {
20907 $self->semValue = array();
20908 }, 523 => static function ($self, $stackPos) {
20909 $self->semValue = $self->semStack[$stackPos - (4 - 3)];
20910 }, 524 => null, 525 => static function ($self, $stackPos) {
20911 $self->semValue = array($self->semStack[$stackPos - (1 - 1)]);
20912 }, 526 => static function ($self, $stackPos) {
20913 $self->semStack[$stackPos - (3 - 1)][] = $self->semStack[$stackPos - (3 - 3)];
20914 $self->semValue = $self->semStack[$stackPos - (3 - 1)];
20915 }, 527 => static function ($self, $stackPos) {
20916 $self->semValue = new Node\ClosureUse($self->semStack[$stackPos - (2 - 2)], $self->semStack[$stackPos - (2 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
20917 }, 528 => static function ($self, $stackPos) {
20918 $self->semValue = new Name($self->semStack[$stackPos - (1 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
20919 }, 529 => static function ($self, $stackPos) {
20920 $self->semValue = new Expr\FuncCall($self->semStack[$stackPos - (2 - 1)], $self->semStack[$stackPos - (2 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
20921 }, 530 => static function ($self, $stackPos) {
20922 $self->semValue = new Expr\FuncCall($self->semStack[$stackPos - (2 - 1)], $self->semStack[$stackPos - (2 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
20923 }, 531 => static function ($self, $stackPos) {
20924 $self->semValue = new Expr\FuncCall($self->semStack[$stackPos - (2 - 1)], $self->semStack[$stackPos - (2 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
20925 }, 532 => static function ($self, $stackPos) {
20926 $self->semValue = new Expr\StaticCall($self->semStack[$stackPos - (4 - 1)], $self->semStack[$stackPos - (4 - 3)], $self->semStack[$stackPos - (4 - 4)], $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]));
20927 }, 533 => static function ($self, $stackPos) {
20928 $self->semValue = new Name($self->semStack[$stackPos - (1 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
20929 }, 534 => null, 535 => static function ($self, $stackPos) {
20930 $self->semValue = new Name($self->semStack[$stackPos - (1 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
20931 }, 536 => static function ($self, $stackPos) {
20932 $self->semValue = new Name($self->semStack[$stackPos - (1 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
20933 }, 537 => static function ($self, $stackPos) {
20934 $self->semValue = new Name\FullyQualified(substr($self->semStack[$stackPos - (1 - 1)], 1), $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
20935 }, 538 => static function ($self, $stackPos) {
20936 $self->semValue = new Name\Relative(substr($self->semStack[$stackPos - (1 - 1)], 10), $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
20937 }, 539 => null, 540 => null, 541 => static function ($self, $stackPos) {
20938 $self->semValue = $self->semStack[$stackPos - (3 - 2)];
20939 }, 542 => static function ($self, $stackPos) {
20940 $self->semValue = new Expr\Error($self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
20941 $self->errorState = 2;
20942 }, 543 => null, 544 => null, 545 => static function ($self, $stackPos) {
20943 $self->semValue = array();
20944 }, 546 => static function ($self, $stackPos) {
20945 $self->semValue = array($self->semStack[$stackPos - (1 - 1)]);
20946 foreach ($self->semValue as $s) {
20947 if ($s instanceof Node\InterpolatedStringPart) {
20948 $s->value = Node\Scalar\String_::parseEscapeSequences($s->value, '`', $self->phpVersion->supportsUnicodeEscapes());
20949 }
20950 }
20951 }, 547 => static function ($self, $stackPos) {
20952 foreach ($self->semStack[$stackPos - (1 - 1)] as $s) {
20953 if ($s instanceof Node\InterpolatedStringPart) {
20954 $s->value = Node\Scalar\String_::parseEscapeSequences($s->value, '`', $self->phpVersion->supportsUnicodeEscapes());
20955 }
20956 }
20957 $self->semValue = $self->semStack[$stackPos - (1 - 1)];
20958 }, 548 => static function ($self, $stackPos) {
20959 $self->semValue = array();
20960 }, 549 => null, 550 => static function ($self, $stackPos) {
20961 $self->semValue = new Expr\ConstFetch($self->semStack[$stackPos - (1 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
20962 }, 551 => static function ($self, $stackPos) {
20963 $self->semValue = new Scalar\MagicConst\Line($self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
20964 }, 552 => static function ($self, $stackPos) {
20965 $self->semValue = new Scalar\MagicConst\File($self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
20966 }, 553 => static function ($self, $stackPos) {
20967 $self->semValue = new Scalar\MagicConst\Dir($self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
20968 }, 554 => static function ($self, $stackPos) {
20969 $self->semValue = new Scalar\MagicConst\Class_($self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
20970 }, 555 => static function ($self, $stackPos) {
20971 $self->semValue = new Scalar\MagicConst\Trait_($self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
20972 }, 556 => static function ($self, $stackPos) {
20973 $self->semValue = new Scalar\MagicConst\Method($self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
20974 }, 557 => static function ($self, $stackPos) {
20975 $self->semValue = new Scalar\MagicConst\Function_($self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
20976 }, 558 => static function ($self, $stackPos) {
20977 $self->semValue = new Scalar\MagicConst\Namespace_($self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
20978 }, 559 => static function ($self, $stackPos) {
20979 $self->semValue = new Scalar\MagicConst\Property($self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
20980 }, 560 => static function ($self, $stackPos) {
20981 $self->semValue = new Expr\ClassConstFetch($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
20982 }, 561 => static function ($self, $stackPos) {
20983 $self->semValue = new Expr\ClassConstFetch($self->semStack[$stackPos - (5 - 1)], $self->semStack[$stackPos - (5 - 4)], $self->getAttributes($self->tokenStartStack[$stackPos - (5 - 1)], $self->tokenEndStack[$stackPos]));
20984 }, 562 => static function ($self, $stackPos) {
20985 $self->semValue = new Expr\ClassConstFetch($self->semStack[$stackPos - (3 - 1)], new Expr\Error($self->getAttributes($self->tokenStartStack[$stackPos - (3 - 3)], $self->tokenEndStack[$stackPos - (3 - 3)])), $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
20986 $self->errorState = 2;
20987 }, 563 => static function ($self, $stackPos) {
20988 $attrs = $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]);
20989 $attrs['kind'] = Expr\Array_::KIND_SHORT;
20990 $self->semValue = new Expr\Array_($self->semStack[$stackPos - (3 - 2)], $attrs);
20991 }, 564 => static function ($self, $stackPos) {
20992 $attrs = $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]);
20993 $attrs['kind'] = Expr\Array_::KIND_LONG;
20994 $self->semValue = new Expr\Array_($self->semStack[$stackPos - (4 - 3)], $attrs);
20995 $self->createdArrays->offsetSet($self->semValue);
20996 }, 565 => static function ($self, $stackPos) {
20997 $self->semValue = $self->semStack[$stackPos - (1 - 1)];
20998 $self->createdArrays->offsetSet($self->semValue);
20999 }, 566 => static function ($self, $stackPos) {
21000 $self->semValue = Scalar\String_::fromString($self->semStack[$stackPos - (1 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]), $self->phpVersion->supportsUnicodeEscapes());
21001 }, 567 => static function ($self, $stackPos) {
21002 $attrs = $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]);
21003 $attrs['kind'] = Scalar\String_::KIND_DOUBLE_QUOTED;
21004 foreach ($self->semStack[$stackPos - (3 - 2)] as $s) {
21005 if ($s instanceof Node\InterpolatedStringPart) {
21006 $s->value = Node\Scalar\String_::parseEscapeSequences($s->value, '"', $self->phpVersion->supportsUnicodeEscapes());
21007 }
21008 }
21009 $self->semValue = new Scalar\InterpolatedString($self->semStack[$stackPos - (3 - 2)], $attrs);
21010 }, 568 => static function ($self, $stackPos) {
21011 $self->semValue = $self->parseLNumber($self->semStack[$stackPos - (1 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]), $self->phpVersion->allowsInvalidOctals());
21012 }, 569 => static function ($self, $stackPos) {
21013 $self->semValue = Scalar\Float_::fromString($self->semStack[$stackPos - (1 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
21014 }, 570 => null, 571 => null, 572 => null, 573 => static function ($self, $stackPos) {
21015 $self->semValue = $self->parseDocString($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 2)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]), $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 3)], $self->tokenEndStack[$stackPos - (3 - 3)]), \true);
21016 }, 574 => static function ($self, $stackPos) {
21017 $self->semValue = $self->parseDocString($self->semStack[$stackPos - (2 - 1)], '', $self->semStack[$stackPos - (2 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]), $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 2)], $self->tokenEndStack[$stackPos - (2 - 2)]), \true);
21018 }, 575 => static function ($self, $stackPos) {
21019 $self->semValue = $self->parseDocString($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 2)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]), $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 3)], $self->tokenEndStack[$stackPos - (3 - 3)]), \true);
21020 }, 576 => static function ($self, $stackPos) {
21021 $self->semValue = null;
21022 }, 577 => null, 578 => null, 579 => static function ($self, $stackPos) {
21023 $self->semValue = $self->semStack[$stackPos - (3 - 2)];
21024 }, 580 => null, 581 => null, 582 => null, 583 => null, 584 => null, 585 => null, 586 => static function ($self, $stackPos) {
21025 $self->semValue = $self->semStack[$stackPos - (3 - 2)];
21026 }, 587 => null, 588 => null, 589 => null, 590 => static function ($self, $stackPos) {
21027 $self->semValue = new Expr\ArrayDimFetch($self->semStack[$stackPos - (4 - 1)], $self->semStack[$stackPos - (4 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]));
21028 }, 591 => null, 592 => static function ($self, $stackPos) {
21029 $self->semValue = new Expr\MethodCall($self->semStack[$stackPos - (4 - 1)], $self->semStack[$stackPos - (4 - 3)], $self->semStack[$stackPos - (4 - 4)], $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]));
21030 }, 593 => static function ($self, $stackPos) {
21031 $self->semValue = new Expr\NullsafeMethodCall($self->semStack[$stackPos - (4 - 1)], $self->semStack[$stackPos - (4 - 3)], $self->semStack[$stackPos - (4 - 4)], $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]));
21032 }, 594 => static function ($self, $stackPos) {
21033 $self->semValue = null;
21034 }, 595 => null, 596 => null, 597 => null, 598 => static function ($self, $stackPos) {
21035 $self->semValue = new Expr\PropertyFetch($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
21036 }, 599 => static function ($self, $stackPos) {
21037 $self->semValue = new Expr\NullsafePropertyFetch($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
21038 }, 600 => null, 601 => static function ($self, $stackPos) {
21039 $self->semValue = new Expr\Variable($self->semStack[$stackPos - (4 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]));
21040 }, 602 => static function ($self, $stackPos) {
21041 $self->semValue = new Expr\Variable($self->semStack[$stackPos - (2 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
21042 }, 603 => static function ($self, $stackPos) {
21043 $self->semValue = new Expr\Variable(new Expr\Error($self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos])), $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
21044 $self->errorState = 2;
21045 }, 604 => static function ($self, $stackPos) {
21046 $var = $self->semStack[$stackPos - (1 - 1)]->name;
21047 $self->semValue = \is_string($var) ? new Node\VarLikeIdentifier($var, $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos])) : $var;
21048 }, 605 => static function ($self, $stackPos) {
21049 $self->semValue = new Expr\StaticPropertyFetch($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
21050 }, 606 => null, 607 => static function ($self, $stackPos) {
21051 $self->semValue = new Expr\ArrayDimFetch($self->semStack[$stackPos - (4 - 1)], $self->semStack[$stackPos - (4 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]));
21052 }, 608 => static function ($self, $stackPos) {
21053 $self->semValue = new Expr\PropertyFetch($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
21054 }, 609 => static function ($self, $stackPos) {
21055 $self->semValue = new Expr\NullsafePropertyFetch($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
21056 }, 610 => static function ($self, $stackPos) {
21057 $self->semValue = new Expr\StaticPropertyFetch($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
21058 }, 611 => static function ($self, $stackPos) {
21059 $self->semValue = new Expr\StaticPropertyFetch($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
21060 }, 612 => null, 613 => static function ($self, $stackPos) {
21061 $self->semValue = $self->semStack[$stackPos - (3 - 2)];
21062 }, 614 => null, 615 => null, 616 => static function ($self, $stackPos) {
21063 $self->semValue = $self->semStack[$stackPos - (3 - 2)];
21064 }, 617 => null, 618 => static function ($self, $stackPos) {
21065 $self->semValue = new Expr\Error($self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
21066 $self->errorState = 2;
21067 }, 619 => static function ($self, $stackPos) {
21068 $self->semValue = new Expr\List_($self->semStack[$stackPos - (4 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]));
21069 $self->semValue->setAttribute('kind', Expr\List_::KIND_LIST);
21070 $self->postprocessList($self->semValue);
21071 }, 620 => static function ($self, $stackPos) {
21072 $self->semValue = $self->semStack[$stackPos - (1 - 1)];
21073 $end = count($self->semValue) - 1;
21074 if ($self->semValue[$end]->value instanceof Expr\Error) {
21075 array_pop($self->semValue);
21076 }
21077 }, 621 => null, 622 => static function ($self, $stackPos) {
21078 /* do nothing -- prevent default action of $$=$self->semStack[$1]. See $551. */
21079 }, 623 => static function ($self, $stackPos) {
21080 $self->semStack[$stackPos - (3 - 1)][] = $self->semStack[$stackPos - (3 - 3)];
21081 $self->semValue = $self->semStack[$stackPos - (3 - 1)];
21082 }, 624 => static function ($self, $stackPos) {
21083 $self->semValue = array($self->semStack[$stackPos - (1 - 1)]);
21084 }, 625 => static function ($self, $stackPos) {
21085 $self->semValue = new Node\ArrayItem($self->semStack[$stackPos - (1 - 1)], null, \false, $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
21086 }, 626 => static function ($self, $stackPos) {
21087 $self->semValue = new Node\ArrayItem($self->semStack[$stackPos - (2 - 2)], null, \true, $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
21088 }, 627 => static function ($self, $stackPos) {
21089 $self->semValue = new Node\ArrayItem($self->semStack[$stackPos - (1 - 1)], null, \false, $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
21090 }, 628 => static function ($self, $stackPos) {
21091 $self->semValue = new Node\ArrayItem($self->semStack[$stackPos - (3 - 3)], $self->semStack[$stackPos - (3 - 1)], \false, $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
21092 }, 629 => static function ($self, $stackPos) {
21093 $self->semValue = new Node\ArrayItem($self->semStack[$stackPos - (4 - 4)], $self->semStack[$stackPos - (4 - 1)], \true, $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]));
21094 }, 630 => static function ($self, $stackPos) {
21095 $self->semValue = new Node\ArrayItem($self->semStack[$stackPos - (3 - 3)], $self->semStack[$stackPos - (3 - 1)], \false, $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
21096 }, 631 => static function ($self, $stackPos) {
21097 $self->semValue = new Node\ArrayItem($self->semStack[$stackPos - (2 - 2)], null, \false, $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]), \true);
21098 }, 632 => static function ($self, $stackPos) {
21099 /* Create an Error node now to remember the position. We'll later either report an error,
21100 or convert this into a null element, depending on whether this is a creation or destructuring context. */
21101 $attrs = $self->createEmptyElemAttributes($self->tokenPos);
21102 $self->semValue = new Node\ArrayItem(new Expr\Error($attrs), null, \false, $attrs);
21103 }, 633 => static function ($self, $stackPos) {
21104 $self->semStack[$stackPos - (2 - 1)][] = $self->semStack[$stackPos - (2 - 2)];
21105 $self->semValue = $self->semStack[$stackPos - (2 - 1)];
21106 }, 634 => static function ($self, $stackPos) {
21107 $self->semStack[$stackPos - (2 - 1)][] = $self->semStack[$stackPos - (2 - 2)];
21108 $self->semValue = $self->semStack[$stackPos - (2 - 1)];
21109 }, 635 => static function ($self, $stackPos) {
21110 $self->semValue = array($self->semStack[$stackPos - (1 - 1)]);
21111 }, 636 => static function ($self, $stackPos) {
21112 $self->semValue = array($self->semStack[$stackPos - (2 - 1)], $self->semStack[$stackPos - (2 - 2)]);
21113 }, 637 => static function ($self, $stackPos) {
21114 $attrs = $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]);
21115 $attrs['rawValue'] = $self->semStack[$stackPos - (1 - 1)];
21116 $self->semValue = new Node\InterpolatedStringPart($self->semStack[$stackPos - (1 - 1)], $attrs);
21117 }, 638 => static function ($self, $stackPos) {
21118 $self->semValue = new Expr\Variable($self->semStack[$stackPos - (1 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
21119 }, 639 => null, 640 => static function ($self, $stackPos) {
21120 $self->semValue = new Expr\ArrayDimFetch($self->semStack[$stackPos - (4 - 1)], $self->semStack[$stackPos - (4 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (4 - 1)], $self->tokenEndStack[$stackPos]));
21121 }, 641 => static function ($self, $stackPos) {
21122 $self->semValue = new Expr\PropertyFetch($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
21123 }, 642 => static function ($self, $stackPos) {
21124 $self->semValue = new Expr\NullsafePropertyFetch($self->semStack[$stackPos - (3 - 1)], $self->semStack[$stackPos - (3 - 3)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
21125 }, 643 => static function ($self, $stackPos) {
21126 $self->semValue = new Expr\Variable($self->semStack[$stackPos - (3 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
21127 }, 644 => static function ($self, $stackPos) {
21128 $self->semValue = new Expr\Variable($self->semStack[$stackPos - (3 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (3 - 1)], $self->tokenEndStack[$stackPos]));
21129 }, 645 => static function ($self, $stackPos) {
21130 $self->semValue = new Expr\ArrayDimFetch($self->semStack[$stackPos - (6 - 2)], $self->semStack[$stackPos - (6 - 4)], $self->getAttributes($self->tokenStartStack[$stackPos - (6 - 1)], $self->tokenEndStack[$stackPos]));
21131 }, 646 => static function ($self, $stackPos) {
21132 $self->semValue = $self->semStack[$stackPos - (3 - 2)];
21133 }, 647 => static function ($self, $stackPos) {
21134 $self->semValue = new Scalar\String_($self->semStack[$stackPos - (1 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
21135 }, 648 => static function ($self, $stackPos) {
21136 $self->semValue = $self->parseNumString($self->semStack[$stackPos - (1 - 1)], $self->getAttributes($self->tokenStartStack[$stackPos - (1 - 1)], $self->tokenEndStack[$stackPos]));
21137 }, 649 => static function ($self, $stackPos) {
21138 $self->semValue = $self->parseNumString('-' . $self->semStack[$stackPos - (2 - 2)], $self->getAttributes($self->tokenStartStack[$stackPos - (2 - 1)], $self->tokenEndStack[$stackPos]));
21139 }, 650 => null];
21140 }
21141 }
21142 <?php
21143
21144 declare (strict_types=1);
21145 namespace PHPUnitPHAR\PhpParser;
21146
21147 /*
21148 * This parser is based on a skeleton written by Moriyoshi Koizumi, which in
21149 * turn is based on work by Masato Bito.
21150 */
21151 use PHPUnitPHAR\PhpParser\Node\Arg;
21152 use PHPUnitPHAR\PhpParser\Node\Expr;
21153 use PHPUnitPHAR\PhpParser\Node\Expr\Array_;
21154 use PHPUnitPHAR\PhpParser\Node\Expr\Cast\Double;
21155 use PHPUnitPHAR\PhpParser\Node\Identifier;
21156 use PHPUnitPHAR\PhpParser\Node\InterpolatedStringPart;
21157 use PHPUnitPHAR\PhpParser\Node\Name;
21158 use PHPUnitPHAR\PhpParser\Node\Param;
21159 use PHPUnitPHAR\PhpParser\Node\PropertyHook;
21160 use PHPUnitPHAR\PhpParser\Node\Scalar\InterpolatedString;
21161 use PHPUnitPHAR\PhpParser\Node\Scalar\Int_;
21162 use PHPUnitPHAR\PhpParser\Node\Scalar\String_;
21163 use PHPUnitPHAR\PhpParser\Node\Stmt;
21164 use PHPUnitPHAR\PhpParser\Node\Stmt\Class_;
21165 use PHPUnitPHAR\PhpParser\Node\Stmt\ClassConst;
21166 use PHPUnitPHAR\PhpParser\Node\Stmt\ClassMethod;
21167 use PHPUnitPHAR\PhpParser\Node\Stmt\Const_;
21168 use PHPUnitPHAR\PhpParser\Node\Stmt\Else_;
21169 use PHPUnitPHAR\PhpParser\Node\Stmt\ElseIf_;
21170 use PHPUnitPHAR\PhpParser\Node\Stmt\Enum_;
21171 use PHPUnitPHAR\PhpParser\Node\Stmt\Interface_;
21172 use PHPUnitPHAR\PhpParser\Node\Stmt\Namespace_;
21173 use PHPUnitPHAR\PhpParser\Node\Stmt\Nop;
21174 use PHPUnitPHAR\PhpParser\Node\Stmt\Property;
21175 use PHPUnitPHAR\PhpParser\Node\Stmt\TryCatch;
21176 use PHPUnitPHAR\PhpParser\Node\UseItem;
21177 use PHPUnitPHAR\PhpParser\Node\VarLikeIdentifier;
21178 use PHPUnitPHAR\PhpParser\NodeVisitor\CommentAnnotatingVisitor;
21179 abstract class ParserAbstract implements Parser
21180 {
21181 private const SYMBOL_NONE = -1;
21182 /** @var Lexer Lexer that is used when parsing */
21183 protected Lexer $lexer;
21184 /** @var PhpVersion PHP version to target on a best-effort basis */
21185 protected PhpVersion $phpVersion;
21186 /*
21187 * The following members will be filled with generated parsing data:
21188 */
21189 /** @var int Size of $tokenToSymbol map */
21190 protected int $tokenToSymbolMapSize;
21191 /** @var int Size of $action table */
21192 protected int $actionTableSize;
21193 /** @var int Size of $goto table */
21194 protected int $gotoTableSize;
21195 /** @var int Symbol number signifying an invalid token */
21196 protected int $invalidSymbol;
21197 /** @var int Symbol number of error recovery token */
21198 protected int $errorSymbol;
21199 /** @var int Action number signifying default action */
21200 protected int $defaultAction;
21201 /** @var int Rule number signifying that an unexpected token was encountered */
21202 protected int $unexpectedTokenRule;
21203 protected int $YY2TBLSTATE;
21204 /** @var int Number of non-leaf states */
21205 protected int $numNonLeafStates;
21206 /** @var int[] Map of PHP token IDs to internal symbols */
21207 protected array $phpTokenToSymbol;
21208 /** @var array<int, bool> Map of PHP token IDs to drop */
21209 protected array $dropTokens;
21210 /** @var int[] Map of external symbols (static::T_*) to internal symbols */
21211 protected array $tokenToSymbol;
21212 /** @var string[] Map of symbols to their names */
21213 protected array $symbolToName;
21214 /** @var array<int, string> Names of the production rules (only necessary for debugging) */
21215 protected array $productions;
21216 /** @var int[] Map of states to a displacement into the $action table. The corresponding action for this
21217 * state/symbol pair is $action[$actionBase[$state] + $symbol]. If $actionBase[$state] is 0, the
21218 * action is defaulted, i.e. $actionDefault[$state] should be used instead. */
21219 protected array $actionBase;
21220 /** @var int[] Table of actions. Indexed according to $actionBase comment. */
21221 protected array $action;
21222 /** @var int[] Table indexed analogously to $action. If $actionCheck[$actionBase[$state] + $symbol] != $symbol
21223 * then the action is defaulted, i.e. $actionDefault[$state] should be used instead. */
21224 protected array $actionCheck;
21225 /** @var int[] Map of states to their default action */
21226 protected array $actionDefault;
21227 /** @var callable[] Semantic action callbacks */
21228 protected array $reduceCallbacks;
21229 /** @var int[] Map of non-terminals to a displacement into the $goto table. The corresponding goto state for this
21230 * non-terminal/state pair is $goto[$gotoBase[$nonTerminal] + $state] (unless defaulted) */
21231 protected array $gotoBase;
21232 /** @var int[] Table of states to goto after reduction. Indexed according to $gotoBase comment. */
21233 protected array $goto;
21234 /** @var int[] Table indexed analogously to $goto. If $gotoCheck[$gotoBase[$nonTerminal] + $state] != $nonTerminal
21235 * then the goto state is defaulted, i.e. $gotoDefault[$nonTerminal] should be used. */
21236 protected array $gotoCheck;
21237 /** @var int[] Map of non-terminals to the default state to goto after their reduction */
21238 protected array $gotoDefault;
21239 /** @var int[] Map of rules to the non-terminal on their left-hand side, i.e. the non-terminal to use for
21240 * determining the state to goto after reduction. */
21241 protected array $ruleToNonTerminal;
21242 /** @var int[] Map of rules to the length of their right-hand side, which is the number of elements that have to
21243 * be popped from the stack(s) on reduction. */
21244 protected array $ruleToLength;
21245 /*
21246 * The following members are part of the parser state:
21247 */
21248 /** @var mixed Temporary value containing the result of last semantic action (reduction) */
21249 protected $semValue;
21250 /** @var mixed[] Semantic value stack (contains values of tokens and semantic action results) */
21251 protected array $semStack;
21252 /** @var int[] Token start position stack */
21253 protected array $tokenStartStack;
21254 /** @var int[] Token end position stack */
21255 protected array $tokenEndStack;
21256 /** @var ErrorHandler Error handler */
21257 protected ErrorHandler $errorHandler;
21258 /** @var int Error state, used to avoid error floods */
21259 protected int $errorState;
21260 /** @var \SplObjectStorage<Array_, null>|null Array nodes created during parsing, for postprocessing of empty elements. */
21261 protected ?\SplObjectStorage $createdArrays;
21262 /** @var \SplObjectStorage<Expr\ArrowFunction, null>|null
21263 * Arrow functions that are wrapped in parentheses, to enforce the pipe operator parentheses requirements.
21264 */
21265 protected ?\SplObjectStorage $parenthesizedArrowFunctions;
21266 /** @var Token[] Tokens for the current parse */
21267 protected array $tokens;
21268 /** @var int Current position in token array */
21269 protected int $tokenPos;
21270 /**
21271 * Initialize $reduceCallbacks map.
21272 */
21273 abstract protected function initReduceCallbacks(): void;
21274 /**
21275 * Creates a parser instance.
21276 *
21277 * Options:
21278 * * phpVersion: ?PhpVersion,
21279 *
21280 * @param Lexer $lexer A lexer
21281 * @param PhpVersion $phpVersion PHP version to target, defaults to latest supported. This
21282 * option is best-effort: Even if specified, parsing will generally assume the latest
21283 * supported version and only adjust behavior in minor ways, for example by omitting
21284 * errors in older versions and interpreting type hints as a name or identifier depending
21285 * on version.
21286 */
21287 public function __construct(Lexer $lexer, ?PhpVersion $phpVersion = null)
21288 {
21289 $this->lexer = $lexer;
21290 $this->phpVersion = $phpVersion ?? PhpVersion::getNewestSupported();
21291 $this->initReduceCallbacks();
21292 $this->phpTokenToSymbol = $this->createTokenMap();
21293 $this->dropTokens = array_fill_keys([\T_WHITESPACE, \T_OPEN_TAG, \T_COMMENT, \T_DOC_COMMENT, \T_BAD_CHARACTER], \true);
21294 }
21295 /**
21296 * Parses PHP code into a node tree.
21297 *
21298 * If a non-throwing error handler is used, the parser will continue parsing after an error
21299 * occurred and attempt to build a partial AST.
21300 *
21301 * @param string $code The source code to parse
21302 * @param ErrorHandler|null $errorHandler Error handler to use for lexer/parser errors, defaults
21303 * to ErrorHandler\Throwing.
21304 *
21305 * @return Node\Stmt[]|null Array of statements (or null non-throwing error handler is used and
21306 * the parser was unable to recover from an error).
21307 */
21308 public function parse(string $code, ?ErrorHandler $errorHandler = null): ?array
21309 {
21310 $this->errorHandler = $errorHandler ?: new ErrorHandler\Throwing();
21311 $this->createdArrays = new \SplObjectStorage();
21312 $this->parenthesizedArrowFunctions = new \SplObjectStorage();
21313 $this->tokens = $this->lexer->tokenize($code, $this->errorHandler);
21314 $result = $this->doParse();
21315 // Report errors for any empty elements used inside arrays. This is delayed until after the main parse,
21316 // because we don't know a priori whether a given array expression will be used in a destructuring context
21317 // or not.
21318 foreach ($this->createdArrays as $node) {
21319 foreach ($node->items as $item) {
21320 if ($item->value instanceof Expr\Error) {
21321 $this->errorHandler->handleError(new Error('Cannot use empty array elements in arrays', $item->getAttributes()));
21322 }
21323 }
21324 }
21325 // Clear out some of the interior state, so we don't hold onto unnecessary
21326 // memory between uses of the parser
21327 $this->tokenStartStack = [];
21328 $this->tokenEndStack = [];
21329 $this->semStack = [];
21330 $this->semValue = null;
21331 $this->createdArrays = null;
21332 $this->parenthesizedArrowFunctions = null;
21333 if ($result !== null) {
21334 $traverser = new NodeTraverser(new CommentAnnotatingVisitor($this->tokens));
21335 $traverser->traverse($result);
21336 }
21337 return $result;
21338 }
21339 public function getTokens(): array
21340 {
21341 return $this->tokens;
21342 }
21343 /** @return Stmt[]|null */
21344 protected function doParse(): ?array
21345 {
21346 // We start off with no lookahead-token
21347 $symbol = self::SYMBOL_NONE;
21348 $tokenValue = null;
21349 $this->tokenPos = -1;
21350 // Keep stack of start and end attributes
21351 $this->tokenStartStack = [];
21352 $this->tokenEndStack = [0];
21353 // Start off in the initial state and keep a stack of previous states
21354 $state = 0;
21355 $stateStack = [$state];
21356 // Semantic value stack (contains values of tokens and semantic action results)
21357 $this->semStack = [];
21358 // Current position in the stack(s)
21359 $stackPos = 0;
21360 $this->errorState = 0;
21361 for (;;) {
21362 //$this->traceNewState($state, $symbol);
21363 if ($this->actionBase[$state] === 0) {
21364 $rule = $this->actionDefault[$state];
21365 } else {
21366 if ($symbol === self::SYMBOL_NONE) {
21367 do {
21368 $token = $this->tokens[++$this->tokenPos];
21369 $tokenId = $token->id;
21370 } while (isset($this->dropTokens[$tokenId]));
21371 // Map the lexer token id to the internally used symbols.
21372 $tokenValue = $token->text;
21373 if (!isset($this->phpTokenToSymbol[$tokenId])) {
21374 throw new \RangeException(sprintf('The lexer returned an invalid token (id=%d, value=%s)', $tokenId, $tokenValue));
21375 }
21376 $symbol = $this->phpTokenToSymbol[$tokenId];
21377 //$this->traceRead($symbol);
21378 }
21379 $idx = $this->actionBase[$state] + $symbol;
21380 if (($idx >= 0 && $idx < $this->actionTableSize && $this->actionCheck[$idx] === $symbol || $state < $this->YY2TBLSTATE && ($idx = $this->actionBase[$state + $this->numNonLeafStates] + $symbol) >= 0 && $idx < $this->actionTableSize && $this->actionCheck[$idx] === $symbol) && ($action = $this->action[$idx]) !== $this->defaultAction) {
21381 /*
21382 * >= numNonLeafStates: shift and reduce
21383 * > 0: shift
21384 * = 0: accept
21385 * < 0: reduce
21386 * = -YYUNEXPECTED: error
21387 */
21388 if ($action > 0) {
21389 /* shift */
21390 //$this->traceShift($symbol);
21391 ++$stackPos;
21392 $stateStack[$stackPos] = $state = $action;
21393 $this->semStack[$stackPos] = $tokenValue;
21394 $this->tokenStartStack[$stackPos] = $this->tokenPos;
21395 $this->tokenEndStack[$stackPos] = $this->tokenPos;
21396 $symbol = self::SYMBOL_NONE;
21397 if ($this->errorState) {
21398 --$this->errorState;
21399 }
21400 if ($action < $this->numNonLeafStates) {
21401 continue;
21402 }
21403 /* $yyn >= numNonLeafStates means shift-and-reduce */
21404 $rule = $action - $this->numNonLeafStates;
21405 } else {
21406 $rule = -$action;
21407 }
21408 } else {
21409 $rule = $this->actionDefault[$state];
21410 }
21411 }
21412 for (;;) {
21413 if ($rule === 0) {
21414 /* accept */
21415 //$this->traceAccept();
21416 return $this->semValue;
21417 }
21418 if ($rule !== $this->unexpectedTokenRule) {
21419 /* reduce */
21420 //$this->traceReduce($rule);
21421 $ruleLength = $this->ruleToLength[$rule];
21422 try {
21423 $callback = $this->reduceCallbacks[$rule];
21424 if ($callback !== null) {
21425 $callback($this, $stackPos);
21426 } elseif ($ruleLength > 0) {
21427 $this->semValue = $this->semStack[$stackPos - $ruleLength + 1];
21428 }
21429 } catch (Error $e) {
21430 if (-1 === $e->getStartLine()) {
21431 $e->setStartLine($this->tokens[$this->tokenPos]->line);
21432 }
21433 $this->emitError($e);
21434 // Can't recover from this type of error
21435 return null;
21436 }
21437 /* Goto - shift nonterminal */
21438 $lastTokenEnd = $this->tokenEndStack[$stackPos];
21439 $stackPos -= $ruleLength;
21440 $nonTerminal = $this->ruleToNonTerminal[$rule];
21441 $idx = $this->gotoBase[$nonTerminal] + $stateStack[$stackPos];
21442 if ($idx >= 0 && $idx < $this->gotoTableSize && $this->gotoCheck[$idx] === $nonTerminal) {
21443 $state = $this->goto[$idx];
21444 } else {
21445 $state = $this->gotoDefault[$nonTerminal];
21446 }
21447 ++$stackPos;
21448 $stateStack[$stackPos] = $state;
21449 $this->semStack[$stackPos] = $this->semValue;
21450 $this->tokenEndStack[$stackPos] = $lastTokenEnd;
21451 if ($ruleLength === 0) {
21452 // Empty productions use the start attributes of the lookahead token.
21453 $this->tokenStartStack[$stackPos] = $this->tokenPos;
21454 }
21455 } else {
21456 /* error */
21457 switch ($this->errorState) {
21458 case 0:
21459 $msg = $this->getErrorMessage($symbol, $state);
21460 $this->emitError(new Error($msg, $this->getAttributesForToken($this->tokenPos)));
21461 // Break missing intentionally
21462 // no break
21463 case 1:
21464 case 2:
21465 $this->errorState = 3;
21466 // Pop until error-expecting state uncovered
21467 while (!(($idx = $this->actionBase[$state] + $this->errorSymbol) >= 0 && $idx < $this->actionTableSize && $this->actionCheck[$idx] === $this->errorSymbol || $state < $this->YY2TBLSTATE && ($idx = $this->actionBase[$state + $this->numNonLeafStates] + $this->errorSymbol) >= 0 && $idx < $this->actionTableSize && $this->actionCheck[$idx] === $this->errorSymbol) || ($action = $this->action[$idx]) === $this->defaultAction) {
21468 // Not totally sure about this
21469 if ($stackPos <= 0) {
21470 // Could not recover from error
21471 return null;
21472 }
21473 $state = $stateStack[--$stackPos];
21474 //$this->tracePop($state);
21475 }
21476 //$this->traceShift($this->errorSymbol);
21477 ++$stackPos;
21478 $stateStack[$stackPos] = $state = $action;
21479 // We treat the error symbol as being empty, so we reset the end attributes
21480 // to the end attributes of the last non-error symbol
21481 $this->tokenStartStack[$stackPos] = $this->tokenPos;
21482 $this->tokenEndStack[$stackPos] = $this->tokenEndStack[$stackPos - 1];
21483 break;
21484 case 3:
21485 if ($symbol === 0) {
21486 // Reached EOF without recovering from error
21487 return null;
21488 }
21489 //$this->traceDiscard($symbol);
21490 $symbol = self::SYMBOL_NONE;
21491 break 2;
21492 }
21493 }
21494 if ($state < $this->numNonLeafStates) {
21495 break;
21496 }
21497 /* >= numNonLeafStates means shift-and-reduce */
21498 $rule = $state - $this->numNonLeafStates;
21499 }
21500 }
21501 }
21502 protected function emitError(Error $error): void
21503 {
21504 $this->errorHandler->handleError($error);
21505 }
21506 /**
21507 * Format error message including expected tokens.
21508 *
21509 * @param int $symbol Unexpected symbol
21510 * @param int $state State at time of error
21511 *
21512 * @return string Formatted error message
21513 */
21514 protected function getErrorMessage(int $symbol, int $state): string
21515 {
21516 $expectedString = '';
21517 if ($expected = $this->getExpectedTokens($state)) {
21518 $expectedString = ', expecting ' . implode(' or ', $expected);
21519 }
21520 return 'Syntax error, unexpected ' . $this->symbolToName[$symbol] . $expectedString;
21521 }
21522 /**
21523 * Get limited number of expected tokens in given state.
21524 *
21525 * @param int $state State
21526 *
21527 * @return string[] Expected tokens. If too many, an empty array is returned.
21528 */
21529 protected function getExpectedTokens(int $state): array
21530 {
21531 $expected = [];
21532 $base = $this->actionBase[$state];
21533 foreach ($this->symbolToName as $symbol => $name) {
21534 $idx = $base + $symbol;
21535 if ($idx >= 0 && $idx < $this->actionTableSize && $this->actionCheck[$idx] === $symbol || $state < $this->YY2TBLSTATE && ($idx = $this->actionBase[$state + $this->numNonLeafStates] + $symbol) >= 0 && $idx < $this->actionTableSize && $this->actionCheck[$idx] === $symbol) {
21536 if ($this->action[$idx] !== $this->unexpectedTokenRule && $this->action[$idx] !== $this->defaultAction && $symbol !== $this->errorSymbol) {
21537 if (count($expected) === 4) {
21538 /* Too many expected tokens */
21539 return [];
21540 }
21541 $expected[] = $name;
21542 }
21543 }
21544 }
21545 return $expected;
21546 }
21547 /**
21548 * Get attributes for a node with the given start and end token positions.
21549 *
21550 * @param int $tokenStartPos Token position the node starts at
21551 * @param int $tokenEndPos Token position the node ends at
21552 * @return array<string, mixed> Attributes
21553 */
21554 protected function getAttributes(int $tokenStartPos, int $tokenEndPos): array
21555 {
21556 $startToken = $this->tokens[$tokenStartPos];
21557 $afterEndToken = $this->tokens[$tokenEndPos + 1];
21558 return ['startLine' => $startToken->line, 'startTokenPos' => $tokenStartPos, 'startFilePos' => $startToken->pos, 'endLine' => $afterEndToken->line, 'endTokenPos' => $tokenEndPos, 'endFilePos' => $afterEndToken->pos - 1];
21559 }
21560 /**
21561 * Get attributes for a single token at the given token position.
21562 *
21563 * @return array<string, mixed> Attributes
21564 */
21565 protected function getAttributesForToken(int $tokenPos): array
21566 {
21567 if ($tokenPos < \count($this->tokens) - 1) {
21568 return $this->getAttributes($tokenPos, $tokenPos);
21569 }
21570 // Get attributes for the sentinel token.
21571 $token = $this->tokens[$tokenPos];
21572 return ['startLine' => $token->line, 'startTokenPos' => $tokenPos, 'startFilePos' => $token->pos, 'endLine' => $token->line, 'endTokenPos' => $tokenPos, 'endFilePos' => $token->pos];
21573 }
21574 /*
21575 * Tracing functions used for debugging the parser.
21576 */
21577 /*
21578 protected function traceNewState($state, $symbol): void {
21579 echo '% State ' . $state
21580 . ', Lookahead ' . ($symbol == self::SYMBOL_NONE ? '--none--' : $this->symbolToName[$symbol]) . "\n";
21581 }
21582
21583 protected function traceRead($symbol): void {
21584 echo '% Reading ' . $this->symbolToName[$symbol] . "\n";
21585 }
21586
21587 protected function traceShift($symbol): void {
21588 echo '% Shift ' . $this->symbolToName[$symbol] . "\n";
21589 }
21590
21591 protected function traceAccept(): void {
21592 echo "% Accepted.\n";
21593 }
21594
21595 protected function traceReduce($n): void {
21596 echo '% Reduce by (' . $n . ') ' . $this->productions[$n] . "\n";
21597 }
21598
21599 protected function tracePop($state): void {
21600 echo '% Recovering, uncovered state ' . $state . "\n";
21601 }
21602
21603 protected function traceDiscard($symbol): void {
21604 echo '% Discard ' . $this->symbolToName[$symbol] . "\n";
21605 }
21606 */
21607 /*
21608 * Helper functions invoked by semantic actions
21609 */
21610 /**
21611 * Moves statements of semicolon-style namespaces into $ns->stmts and checks various error conditions.
21612 *
21613 * @param Node\Stmt[] $stmts
21614 * @return Node\Stmt[]
21615 */
21616 protected function handleNamespaces(array $stmts): array
21617 {
21618 $hasErrored = \false;
21619 $style = $this->getNamespacingStyle($stmts);
21620 if (null === $style) {
21621 // not namespaced, nothing to do
21622 return $stmts;
21623 }
21624 if ('brace' === $style) {
21625 // For braced namespaces we only have to check that there are no invalid statements between the namespaces
21626 $afterFirstNamespace = \false;
21627 foreach ($stmts as $stmt) {
21628 if ($stmt instanceof Node\Stmt\Namespace_) {
21629 $afterFirstNamespace = \true;
21630 } elseif (!$stmt instanceof Node\Stmt\HaltCompiler && !$stmt instanceof Node\Stmt\Nop && $afterFirstNamespace && !$hasErrored) {
21631 $this->emitError(new Error('No code may exist outside of namespace {}', $stmt->getAttributes()));
21632 $hasErrored = \true;
21633 // Avoid one error for every statement
21634 }
21635 }
21636 return $stmts;
21637 } else {
21638 // For semicolon namespaces we have to move the statements after a namespace declaration into ->stmts
21639 $resultStmts = [];
21640 $targetStmts =& $resultStmts;
21641 $lastNs = null;
21642 foreach ($stmts as $stmt) {
21643 if ($stmt instanceof Node\Stmt\Namespace_) {
21644 if ($lastNs !== null) {
21645 $this->fixupNamespaceAttributes($lastNs);
21646 }
21647 if ($stmt->stmts === null) {
21648 $stmt->stmts = [];
21649 $targetStmts =& $stmt->stmts;
21650 $resultStmts[] = $stmt;
21651 } else {
21652 // This handles the invalid case of mixed style namespaces
21653 $resultStmts[] = $stmt;
21654 $targetStmts =& $resultStmts;
21655 }
21656 $lastNs = $stmt;
21657 } elseif ($stmt instanceof Node\Stmt\HaltCompiler) {
21658 // __halt_compiler() is not moved into the namespace
21659 $resultStmts[] = $stmt;
21660 } else {
21661 $targetStmts[] = $stmt;
21662 }
21663 }
21664 if ($lastNs !== null) {
21665 $this->fixupNamespaceAttributes($lastNs);
21666 }
21667 return $resultStmts;
21668 }
21669 }
21670 private function fixupNamespaceAttributes(Node\Stmt\Namespace_ $stmt): void
21671 {
21672 // We moved the statements into the namespace node, as such the end of the namespace node
21673 // needs to be extended to the end of the statements.
21674 if (empty($stmt->stmts)) {
21675 return;
21676 }
21677 // We only move the builtin end attributes here. This is the best we can do with the
21678 // knowledge we have.
21679 $endAttributes = ['endLine', 'endFilePos', 'endTokenPos'];
21680 $lastStmt = $stmt->stmts[count($stmt->stmts) - 1];
21681 foreach ($endAttributes as $endAttribute) {
21682 if ($lastStmt->hasAttribute($endAttribute)) {
21683 $stmt->setAttribute($endAttribute, $lastStmt->getAttribute($endAttribute));
21684 }
21685 }
21686 }
21687 /** @return array<string, mixed> */
21688 private function getNamespaceErrorAttributes(Namespace_ $node): array
21689 {
21690 $attrs = $node->getAttributes();
21691 // Adjust end attributes to only cover the "namespace" keyword, not the whole namespace.
21692 if (isset($attrs['startLine'])) {
21693 $attrs['endLine'] = $attrs['startLine'];
21694 }
21695 if (isset($attrs['startTokenPos'])) {
21696 $attrs['endTokenPos'] = $attrs['startTokenPos'];
21697 }
21698 if (isset($attrs['startFilePos'])) {
21699 $attrs['endFilePos'] = $attrs['startFilePos'] + \strlen('namespace') - 1;
21700 }
21701 return $attrs;
21702 }
21703 /**
21704 * Determine namespacing style (semicolon or brace)
21705 *
21706 * @param Node[] $stmts Top-level statements.
21707 *
21708 * @return null|string One of "semicolon", "brace" or null (no namespaces)
21709 */
21710 private function getNamespacingStyle(array $stmts): ?string
21711 {
21712 $style = null;
21713 $hasNotAllowedStmts = \false;
21714 foreach ($stmts as $i => $stmt) {
21715 if ($stmt instanceof Node\Stmt\Namespace_) {
21716 $currentStyle = null === $stmt->stmts ? 'semicolon' : 'brace';
21717 if (null === $style) {
21718 $style = $currentStyle;
21719 if ($hasNotAllowedStmts) {
21720 $this->emitError(new Error('Namespace declaration statement has to be the very first statement in the script', $this->getNamespaceErrorAttributes($stmt)));
21721 }
21722 } elseif ($style !== $currentStyle) {
21723 $this->emitError(new Error('Cannot mix bracketed namespace declarations with unbracketed namespace declarations', $this->getNamespaceErrorAttributes($stmt)));
21724 // Treat like semicolon style for namespace normalization
21725 return 'semicolon';
21726 }
21727 continue;
21728 }
21729 /* declare(), __halt_compiler() and nops can be used before a namespace declaration */
21730 if ($stmt instanceof Node\Stmt\Declare_ || $stmt instanceof Node\Stmt\HaltCompiler || $stmt instanceof Node\Stmt\Nop) {
21731 continue;
21732 }
21733 /* There may be a hashbang line at the very start of the file */
21734 if ($i === 0 && $stmt instanceof Node\Stmt\InlineHTML && preg_match('/\A#!.*\r?\n\z/', $stmt->value)) {
21735 continue;
21736 }
21737 /* Everything else if forbidden before namespace declarations */
21738 $hasNotAllowedStmts = \true;
21739 }
21740 return $style;
21741 }
21742 /** @return Name|Identifier */
21743 protected function handleBuiltinTypes(Name $name)
21744 {
21745 if (!$name->isUnqualified()) {
21746 return $name;
21747 }
21748 $lowerName = $name->toLowerString();
21749 if (!$this->phpVersion->supportsBuiltinType($lowerName)) {
21750 return $name;
21751 }
21752 return new Node\Identifier($lowerName, $name->getAttributes());
21753 }
21754 /**
21755 * Get combined start and end attributes at a stack location
21756 *
21757 * @param int $stackPos Stack location
21758 *
21759 * @return array<string, mixed> Combined start and end attributes
21760 */
21761 protected function getAttributesAt(int $stackPos): array
21762 {
21763 return $this->getAttributes($this->tokenStartStack[$stackPos], $this->tokenEndStack[$stackPos]);
21764 }
21765 protected function getFloatCastKind(string $cast): int
21766 {
21767 $cast = strtolower($cast);
21768 if (strpos($cast, 'float') !== \false) {
21769 return Double::KIND_FLOAT;
21770 }
21771 if (strpos($cast, 'real') !== \false) {
21772 return Double::KIND_REAL;
21773 }
21774 return Double::KIND_DOUBLE;
21775 }
21776 protected function getIntCastKind(string $cast): int
21777 {
21778 $cast = strtolower($cast);
21779 if (strpos($cast, 'integer') !== \false) {
21780 return Expr\Cast\Int_::KIND_INTEGER;
21781 }
21782 return Expr\Cast\Int_::KIND_INT;
21783 }
21784 protected function getBoolCastKind(string $cast): int
21785 {
21786 $cast = strtolower($cast);
21787 if (strpos($cast, 'boolean') !== \false) {
21788 return Expr\Cast\Bool_::KIND_BOOLEAN;
21789 }
21790 return Expr\Cast\Bool_::KIND_BOOL;
21791 }
21792 protected function getStringCastKind(string $cast): int
21793 {
21794 $cast = strtolower($cast);
21795 if (strpos($cast, 'binary') !== \false) {
21796 return Expr\Cast\String_::KIND_BINARY;
21797 }
21798 return Expr\Cast\String_::KIND_STRING;
21799 }
21800 /** @param array<string, mixed> $attributes */
21801 protected function parseLNumber(string $str, array $attributes, bool $allowInvalidOctal = \false): Int_
21802 {
21803 try {
21804 return Int_::fromString($str, $attributes, $allowInvalidOctal);
21805 } catch (Error $error) {
21806 $this->emitError($error);
21807 // Use dummy value
21808 return new Int_(0, $attributes);
21809 }
21810 }
21811 /**
21812 * Parse a T_NUM_STRING token into either an integer or string node.
21813 *
21814 * @param string $str Number string
21815 * @param array<string, mixed> $attributes Attributes
21816 *
21817 * @return Int_|String_ Integer or string node.
21818 */
21819 protected function parseNumString(string $str, array $attributes)
21820 {
21821 if (!preg_match('/^(?:0|-?[1-9][0-9]*)$/', $str)) {
21822 return new String_($str, $attributes);
21823 }
21824 $num = +$str;
21825 if (!is_int($num)) {
21826 return new String_($str, $attributes);
21827 }
21828 return new Int_($num, $attributes);
21829 }
21830 /** @param array<string, mixed> $attributes */
21831 protected function stripIndentation(string $string, int $indentLen, string $indentChar, bool $newlineAtStart, bool $newlineAtEnd, array $attributes): string
21832 {
21833 if ($indentLen === 0) {
21834 return $string;
21835 }
21836 $start = $newlineAtStart ? '(?:(?<=\n)|\A)' : '(?<=\n)';
21837 $end = $newlineAtEnd ? '(?:(?=[\r\n])|\z)' : '(?=[\r\n])';
21838 $regex = '/' . $start . '([ \t]*)(' . $end . ')?/';
21839 return preg_replace_callback($regex, function ($matches) use ($indentLen, $indentChar, $attributes) {
21840 $prefix = substr($matches[1], 0, $indentLen);
21841 if (\false !== strpos($prefix, $indentChar === " " ? "\t" : " ")) {
21842 $this->emitError(new Error('Invalid indentation - tabs and spaces cannot be mixed', $attributes));
21843 } elseif (strlen($prefix) < $indentLen && !isset($matches[2])) {
21844 $this->emitError(new Error('Invalid body indentation level ' . '(expecting an indentation level of at least ' . $indentLen . ')', $attributes));
21845 }
21846 return substr($matches[0], strlen($prefix));
21847 }, $string);
21848 }
21849 /**
21850 * @param string|(Expr|InterpolatedStringPart)[] $contents
21851 * @param array<string, mixed> $attributes
21852 * @param array<string, mixed> $endTokenAttributes
21853 */
21854 protected function parseDocString(string $startToken, $contents, string $endToken, array $attributes, array $endTokenAttributes, bool $parseUnicodeEscape): Expr
21855 {
21856 $kind = strpos($startToken, "'") === \false ? String_::KIND_HEREDOC : String_::KIND_NOWDOC;
21857 $regex = '/\A[bB]?<<<[ \t]*[\'"]?([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)[\'"]?(?:\r\n|\n|\r)\z/';
21858 $result = preg_match($regex, $startToken, $matches);
21859 assert($result === 1);
21860 $label = $matches[1];
21861 $result = preg_match('/\A[ \t]*/', $endToken, $matches);
21862 assert($result === 1);
21863 $indentation = $matches[0];
21864 $attributes['kind'] = $kind;
21865 $attributes['docLabel'] = $label;
21866 $attributes['docIndentation'] = $indentation;
21867 $indentHasSpaces = \false !== strpos($indentation, " ");
21868 $indentHasTabs = \false !== strpos($indentation, "\t");
21869 if ($indentHasSpaces && $indentHasTabs) {
21870 $this->emitError(new Error('Invalid indentation - tabs and spaces cannot be mixed', $endTokenAttributes));
21871 // Proceed processing as if this doc string is not indented
21872 $indentation = '';
21873 }
21874 $indentLen = \strlen($indentation);
21875 $indentChar = $indentHasSpaces ? " " : "\t";
21876 if (\is_string($contents)) {
21877 if ($contents === '') {
21878 $attributes['rawValue'] = $contents;
21879 return new String_('', $attributes);
21880 }
21881 $contents = $this->stripIndentation($contents, $indentLen, $indentChar, \true, \true, $attributes);
21882 $contents = preg_replace('~(\r\n|\n|\r)\z~', '', $contents);
21883 $attributes['rawValue'] = $contents;
21884 if ($kind === String_::KIND_HEREDOC) {
21885 $contents = String_::parseEscapeSequences($contents, null, $parseUnicodeEscape);
21886 }
21887 return new String_($contents, $attributes);
21888 } else {
21889 assert(count($contents) > 0);
21890 if (!$contents[0] instanceof Node\InterpolatedStringPart) {
21891 // If there is no leading encapsed string part, pretend there is an empty one
21892 $this->stripIndentation('', $indentLen, $indentChar, \true, \false, $contents[0]->getAttributes());
21893 }
21894 $newContents = [];
21895 foreach ($contents as $i => $part) {
21896 if ($part instanceof Node\InterpolatedStringPart) {
21897 $isLast = $i === \count($contents) - 1;
21898 $part->value = $this->stripIndentation($part->value, $indentLen, $indentChar, $i === 0, $isLast, $part->getAttributes());
21899 if ($isLast) {
21900 $part->value = preg_replace('~(\r\n|\n|\r)\z~', '', $part->value);
21901 }
21902 $part->setAttribute('rawValue', $part->value);
21903 $part->value = String_::parseEscapeSequences($part->value, null, $parseUnicodeEscape);
21904 if ('' === $part->value) {
21905 continue;
21906 }
21907 }
21908 $newContents[] = $part;
21909 }
21910 return new InterpolatedString($newContents, $attributes);
21911 }
21912 }
21913 protected function createCommentFromToken(Token $token, int $tokenPos): Comment
21914 {
21915 assert($token->id === \T_COMMENT || $token->id == \T_DOC_COMMENT);
21916 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);
21917 }
21918 /**
21919 * Get last comment before the given token position, if any
21920 */
21921 protected function getCommentBeforeToken(int $tokenPos): ?Comment
21922 {
21923 while (--$tokenPos >= 0) {
21924 $token = $this->tokens[$tokenPos];
21925 if (!isset($this->dropTokens[$token->id])) {
21926 break;
21927 }
21928 if ($token->id === \T_COMMENT || $token->id === \T_DOC_COMMENT) {
21929 return $this->createCommentFromToken($token, $tokenPos);
21930 }
21931 }
21932 return null;
21933 }
21934 /**
21935 * Create a zero-length nop to capture preceding comments, if any.
21936 */
21937 protected function maybeCreateZeroLengthNop(int $tokenPos): ?Nop
21938 {
21939 $comment = $this->getCommentBeforeToken($tokenPos);
21940 if ($comment === null) {
21941 return null;
21942 }
21943 $commentEndLine = $comment->getEndLine();
21944 $commentEndFilePos = $comment->getEndFilePos();
21945 $commentEndTokenPos = $comment->getEndTokenPos();
21946 $attributes = ['startLine' => $commentEndLine, 'endLine' => $commentEndLine, 'startFilePos' => $commentEndFilePos + 1, 'endFilePos' => $commentEndFilePos, 'startTokenPos' => $commentEndTokenPos + 1, 'endTokenPos' => $commentEndTokenPos];
21947 return new Nop($attributes);
21948 }
21949 protected function maybeCreateNop(int $tokenStartPos, int $tokenEndPos): ?Nop
21950 {
21951 if ($this->getCommentBeforeToken($tokenStartPos) === null) {
21952 return null;
21953 }
21954 return new Nop($this->getAttributes($tokenStartPos, $tokenEndPos));
21955 }
21956 protected function handleHaltCompiler(): string
21957 {
21958 // Prevent the lexer from returning any further tokens.
21959 $nextToken = $this->tokens[$this->tokenPos + 1];
21960 $this->tokenPos = \count($this->tokens) - 2;
21961 // Return text after __halt_compiler.
21962 return $nextToken->id === \T_INLINE_HTML ? $nextToken->text : '';
21963 }
21964 protected function inlineHtmlHasLeadingNewline(int $stackPos): bool
21965 {
21966 $tokenPos = $this->tokenStartStack[$stackPos];
21967 $token = $this->tokens[$tokenPos];
21968 assert($token->id == \T_INLINE_HTML);
21969 if ($tokenPos > 0) {
21970 $prevToken = $this->tokens[$tokenPos - 1];
21971 assert($prevToken->id == \T_CLOSE_TAG);
21972 return \false !== strpos($prevToken->text, "\n") || \false !== strpos($prevToken->text, "\r");
21973 }
21974 return \true;
21975 }
21976 /**
21977 * @return array<string, mixed>
21978 */
21979 protected function createEmptyElemAttributes(int $tokenPos): array
21980 {
21981 return $this->getAttributesForToken($tokenPos);
21982 }
21983 protected function fixupArrayDestructuring(Array_ $node): Expr\List_
21984 {
21985 $this->createdArrays->offsetUnset($node);
21986 return new Expr\List_(array_map(function (Node\ArrayItem $item) {
21987 if ($item->value instanceof Expr\Error) {
21988 // We used Error as a placeholder for empty elements, which are legal for destructuring.
21989 return null;
21990 }
21991 if ($item->value instanceof Array_) {
21992 return new Node\ArrayItem($this->fixupArrayDestructuring($item->value), $item->key, $item->byRef, $item->getAttributes());
21993 }
21994 return $item;
21995 }, $node->items), ['kind' => Expr\List_::KIND_ARRAY] + $node->getAttributes());
21996 }
21997 protected function postprocessList(Expr\List_ $node): void
21998 {
21999 foreach ($node->items as $i => $item) {
22000 if ($item->value instanceof Expr\Error) {
22001 // We used Error as a placeholder for empty elements, which are legal for destructuring.
22002 $node->items[$i] = null;
22003 }
22004 }
22005 }
22006 /** @param ElseIf_|Else_ $node */
22007 protected function fixupAlternativeElse($node): void
22008 {
22009 // Make sure a trailing nop statement carrying comments is part of the node.
22010 $numStmts = \count($node->stmts);
22011 if ($numStmts !== 0 && $node->stmts[$numStmts - 1] instanceof Nop) {
22012 $nopAttrs = $node->stmts[$numStmts - 1]->getAttributes();
22013 if (isset($nopAttrs['endLine'])) {
22014 $node->setAttribute('endLine', $nopAttrs['endLine']);
22015 }
22016 if (isset($nopAttrs['endFilePos'])) {
22017 $node->setAttribute('endFilePos', $nopAttrs['endFilePos']);
22018 }
22019 if (isset($nopAttrs['endTokenPos'])) {
22020 $node->setAttribute('endTokenPos', $nopAttrs['endTokenPos']);
22021 }
22022 }
22023 }
22024 protected function checkClassModifier(int $a, int $b, int $modifierPos): void
22025 {
22026 try {
22027 Modifiers::verifyClassModifier($a, $b);
22028 } catch (Error $error) {
22029 $error->setAttributes($this->getAttributesAt($modifierPos));
22030 $this->emitError($error);
22031 }
22032 }
22033 protected function checkModifier(int $a, int $b, int $modifierPos): void
22034 {
22035 // Jumping through some hoops here because verifyModifier() is also used elsewhere
22036 try {
22037 Modifiers::verifyModifier($a, $b);
22038 } catch (Error $error) {
22039 $error->setAttributes($this->getAttributesAt($modifierPos));
22040 $this->emitError($error);
22041 }
22042 }
22043 protected function checkParam(Param $node): void
22044 {
22045 if ($node->variadic && null !== $node->default) {
22046 $this->emitError(new Error('Variadic parameter cannot have a default value', $node->default->getAttributes()));
22047 }
22048 }
22049 protected function checkTryCatch(TryCatch $node): void
22050 {
22051 if (empty($node->catches) && null === $node->finally) {
22052 $this->emitError(new Error('Cannot use try without catch or finally', $node->getAttributes()));
22053 }
22054 }
22055 protected function checkNamespace(Namespace_ $node): void
22056 {
22057 if (null !== $node->stmts) {
22058 foreach ($node->stmts as $stmt) {
22059 if ($stmt instanceof Namespace_) {
22060 $this->emitError(new Error('Namespace declarations cannot be nested', $stmt->getAttributes()));
22061 }
22062 }
22063 }
22064 }
22065 private function checkClassName(?Identifier $name, int $namePos): void
22066 {
22067 if (null !== $name && $name->isSpecialClassName()) {
22068 $this->emitError(new Error(sprintf('Cannot use \'%s\' as class name as it is reserved', $name), $this->getAttributesAt($namePos)));
22069 }
22070 }
22071 /** @param Name[] $interfaces */
22072 private function checkImplementedInterfaces(array $interfaces): void
22073 {
22074 foreach ($interfaces as $interface) {
22075 if ($interface->isSpecialClassName()) {
22076 $this->emitError(new Error(sprintf('Cannot use \'%s\' as interface name as it is reserved', $interface), $interface->getAttributes()));
22077 }
22078 }
22079 }
22080 protected function checkClass(Class_ $node, int $namePos): void
22081 {
22082 $this->checkClassName($node->name, $namePos);
22083 if ($node->extends && $node->extends->isSpecialClassName()) {
22084 $this->emitError(new Error(sprintf('Cannot use \'%s\' as class name as it is reserved', $node->extends), $node->extends->getAttributes()));
22085 }
22086 $this->checkImplementedInterfaces($node->implements);
22087 }
22088 protected function checkInterface(Interface_ $node, int $namePos): void
22089 {
22090 $this->checkClassName($node->name, $namePos);
22091 $this->checkImplementedInterfaces($node->extends);
22092 }
22093 protected function checkEnum(Enum_ $node, int $namePos): void
22094 {
22095 $this->checkClassName($node->name, $namePos);
22096 $this->checkImplementedInterfaces($node->implements);
22097 }
22098 protected function checkClassMethod(ClassMethod $node, int $modifierPos): void
22099 {
22100 if ($node->flags & Modifiers::STATIC) {
22101 switch ($node->name->toLowerString()) {
22102 case '__construct':
22103 $this->emitError(new Error(sprintf('Constructor %s() cannot be static', $node->name), $this->getAttributesAt($modifierPos)));
22104 break;
22105 case '__destruct':
22106 $this->emitError(new Error(sprintf('Destructor %s() cannot be static', $node->name), $this->getAttributesAt($modifierPos)));
22107 break;
22108 case '__clone':
22109 $this->emitError(new Error(sprintf('Clone method %s() cannot be static', $node->name), $this->getAttributesAt($modifierPos)));
22110 break;
22111 }
22112 }
22113 if ($node->flags & Modifiers::READONLY) {
22114 $this->emitError(new Error(sprintf('Method %s() cannot be readonly', $node->name), $this->getAttributesAt($modifierPos)));
22115 }
22116 }
22117 protected function checkClassConst(ClassConst $node, int $modifierPos): void
22118 {
22119 foreach ([Modifiers::STATIC, Modifiers::ABSTRACT, Modifiers::READONLY] as $modifier) {
22120 if ($node->flags & $modifier) {
22121 $this->emitError(new Error("Cannot use '" . Modifiers::toString($modifier) . "' as constant modifier", $this->getAttributesAt($modifierPos)));
22122 }
22123 }
22124 }
22125 protected function checkUseUse(UseItem $node, int $namePos): void
22126 {
22127 if ($node->alias && $node->alias->isSpecialClassName()) {
22128 $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)));
22129 }
22130 }
22131 protected function checkPropertyHooksForMultiProperty(Property $property, int $hookPos): void
22132 {
22133 if (count($property->props) > 1) {
22134 $this->emitError(new Error('Cannot use hooks when declaring multiple properties', $this->getAttributesAt($hookPos)));
22135 }
22136 }
22137 /** @param PropertyHook[] $hooks */
22138 protected function checkEmptyPropertyHookList(array $hooks, int $hookPos): void
22139 {
22140 if (empty($hooks)) {
22141 $this->emitError(new Error('Property hook list cannot be empty', $this->getAttributesAt($hookPos)));
22142 }
22143 }
22144 protected function checkPropertyHook(PropertyHook $hook, ?int $paramListPos): void
22145 {
22146 $name = $hook->name->toLowerString();
22147 if ($name !== 'get' && $name !== 'set') {
22148 $this->emitError(new Error('Unknown hook "' . $hook->name . '", expected "get" or "set"', $hook->name->getAttributes()));
22149 }
22150 if ($name === 'get' && $paramListPos !== null) {
22151 $this->emitError(new Error('get hook must not have a parameter list', $this->getAttributesAt($paramListPos)));
22152 }
22153 }
22154 protected function checkPropertyHookModifiers(int $a, int $b, int $modifierPos): void
22155 {
22156 try {
22157 Modifiers::verifyModifier($a, $b);
22158 } catch (Error $error) {
22159 $error->setAttributes($this->getAttributesAt($modifierPos));
22160 $this->emitError($error);
22161 }
22162 if ($b != Modifiers::FINAL) {
22163 $this->emitError(new Error('Cannot use the ' . Modifiers::toString($b) . ' modifier on a property hook', $this->getAttributesAt($modifierPos)));
22164 }
22165 }
22166 protected function checkConstantAttributes(Const_ $node): void
22167 {
22168 if ($node->attrGroups !== [] && count($node->consts) > 1) {
22169 $this->emitError(new Error('Cannot use attributes on multiple constants at once', $node->getAttributes()));
22170 }
22171 }
22172 protected function checkPipeOperatorParentheses(Expr $node): void
22173 {
22174 if ($node instanceof Expr\ArrowFunction && !$this->parenthesizedArrowFunctions->offsetExists($node)) {
22175 $this->emitError(new Error('Arrow functions on the right hand side of |> must be parenthesized', $node->getAttributes()));
22176 }
22177 }
22178 /**
22179 * @param Property|Param $node
22180 */
22181 protected function addPropertyNameToHooks(Node $node): void
22182 {
22183 if ($node instanceof Property) {
22184 $name = $node->props[0]->name->toString();
22185 } else {
22186 $name = $node->var->name;
22187 }
22188 foreach ($node->hooks as $hook) {
22189 $hook->setAttribute('propertyName', $name);
22190 }
22191 }
22192 /** @param array<Node\Arg|Node\VariadicPlaceholder> $args */
22193 private function isSimpleExit(array $args): bool
22194 {
22195 if (\count($args) === 0) {
22196 return \true;
22197 }
22198 if (\count($args) === 1) {
22199 $arg = $args[0];
22200 return $arg instanceof Arg && $arg->name === null && $arg->byRef === \false && $arg->unpack === \false;
22201 }
22202 return \false;
22203 }
22204 /**
22205 * @param array<Node\Arg|Node\VariadicPlaceholder> $args
22206 * @param array<string, mixed> $attrs
22207 */
22208 protected function createExitExpr(string $name, int $namePos, array $args, array $attrs): Expr
22209 {
22210 if ($this->isSimpleExit($args)) {
22211 // Create Exit node for backwards compatibility.
22212 $attrs['kind'] = strtolower($name) === 'exit' ? Expr\Exit_::KIND_EXIT : Expr\Exit_::KIND_DIE;
22213 return new Expr\Exit_(\count($args) === 1 ? $args[0]->value : null, $attrs);
22214 }
22215 return new Expr\FuncCall(new Name($name, $this->getAttributesAt($namePos)), $args, $attrs);
22216 }
22217 /**
22218 * Creates the token map.
22219 *
22220 * The token map maps the PHP internal token identifiers
22221 * to the identifiers used by the Parser. Additionally it
22222 * maps T_OPEN_TAG_WITH_ECHO to T_ECHO and T_CLOSE_TAG to ';'.
22223 *
22224 * @return array<int, int> The token map
22225 */
22226 protected function createTokenMap(): array
22227 {
22228 $tokenMap = [];
22229 // Single-char tokens use an identity mapping.
22230 for ($i = 0; $i < 256; ++$i) {
22231 $tokenMap[$i] = $i;
22232 }
22233 foreach ($this->symbolToName as $name) {
22234 if ($name[0] === 'T') {
22235 $tokenMap[\constant($name)] = constant(static::class . '::' . $name);
22236 }
22237 }
22238 // T_OPEN_TAG_WITH_ECHO with dropped T_OPEN_TAG results in T_ECHO
22239 $tokenMap[\T_OPEN_TAG_WITH_ECHO] = static::T_ECHO;
22240 // T_CLOSE_TAG is equivalent to ';'
22241 $tokenMap[\T_CLOSE_TAG] = ord(';');
22242 // We have created a map from PHP token IDs to external symbol IDs.
22243 // Now map them to the internal symbol ID.
22244 $fullTokenMap = [];
22245 foreach ($tokenMap as $phpToken => $extSymbol) {
22246 $intSymbol = $this->tokenToSymbol[$extSymbol];
22247 if ($intSymbol === $this->invalidSymbol) {
22248 continue;
22249 }
22250 $fullTokenMap[$phpToken] = $intSymbol;
22251 }
22252 return $fullTokenMap;
22253 }
22254 }
22255 <?php
22256
22257 declare (strict_types=1);
22258 namespace PHPUnitPHAR\PhpParser;
22259
22260 use PHPUnitPHAR\PhpParser\Parser\Php7;
22261 use PHPUnitPHAR\PhpParser\Parser\Php8;
22262 class ParserFactory
22263 {
22264 /**
22265 * Create a parser targeting the given version on a best-effort basis. The parser will generally
22266 * accept code for the newest supported version, but will try to accommodate code that becomes
22267 * invalid in newer versions or changes in interpretation.
22268 */
22269 public function createForVersion(PhpVersion $version): Parser
22270 {
22271 if ($version->isHostVersion()) {
22272 $lexer = new Lexer();
22273 } else {
22274 $lexer = new Lexer\Emulative($version);
22275 }
22276 if ($version->id >= 80000) {
22277 return new Php8($lexer, $version);
22278 }
22279 return new Php7($lexer, $version);
22280 }
22281 /**
22282 * Create a parser targeting the newest version supported by this library. Code for older
22283 * versions will be accepted if there have been no relevant backwards-compatibility breaks in
22284 * PHP.
22285 */
22286 public function createForNewestSupportedVersion(): Parser
22287 {
22288 return $this->createForVersion(PhpVersion::getNewestSupported());
22289 }
22290 /**
22291 * Create a parser targeting the host PHP version, that is the PHP version we're currently
22292 * running on. This parser will not use any token emulation.
22293 */
22294 public function createForHostVersion(): Parser
22295 {
22296 return $this->createForVersion(PhpVersion::getHostVersion());
22297 }
22298 }
22299 <?php
22300
22301 declare (strict_types=1);
22302 namespace PHPUnitPHAR\PhpParser;
22303
22304 /**
22305 * A PHP version, representing only the major and minor version components.
22306 */
22307 class PhpVersion
22308 {
22309 /** @var int Version ID in PHP_VERSION_ID format */
22310 public int $id;
22311 /** @var int[] Minimum versions for builtin types */
22312 private const BUILTIN_TYPE_VERSIONS = ['array' => 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];
22313 private function __construct(int $id)
22314 {
22315 $this->id = $id;
22316 }
22317 /**
22318 * Create a PhpVersion object from major and minor version components.
22319 */
22320 public static function fromComponents(int $major, int $minor): self
22321 {
22322 return new self($major * 10000 + $minor * 100);
22323 }
22324 /**
22325 * Get the newest PHP version supported by this library. Support for this version may be partial,
22326 * if it is still under development.
22327 */
22328 public static function getNewestSupported(): self
22329 {
22330 return self::fromComponents(8, 5);
22331 }
22332 /**
22333 * Get the host PHP version, that is the PHP version we're currently running on.
22334 */
22335 public static function getHostVersion(): self
22336 {
22337 return self::fromComponents(\PHP_MAJOR_VERSION, \PHP_MINOR_VERSION);
22338 }
22339 /**
22340 * Parse the version from a string like "8.1".
22341 */
22342 public static function fromString(string $version): self
22343 {
22344 if (!preg_match('/^(\d+)\.(\d+)/', $version, $matches)) {
22345 throw new \LogicException("Invalid PHP version \"{$version}\"");
22346 }
22347 return self::fromComponents((int) $matches[1], (int) $matches[2]);
22348 }
22349 /**
22350 * Check whether two versions are the same.
22351 */
22352 public function equals(PhpVersion $other): bool
22353 {
22354 return $this->id === $other->id;
22355 }
22356 /**
22357 * Check whether this version is greater than or equal to the argument.
22358 */
22359 public function newerOrEqual(PhpVersion $other): bool
22360 {
22361 return $this->id >= $other->id;
22362 }
22363 /**
22364 * Check whether this version is older than the argument.
22365 */
22366 public function older(PhpVersion $other): bool
22367 {
22368 return $this->id < $other->id;
22369 }
22370 /**
22371 * Check whether this is the host PHP version.
22372 */
22373 public function isHostVersion(): bool
22374 {
22375 return $this->equals(self::getHostVersion());
22376 }
22377 /**
22378 * Check whether this PHP version supports the given builtin type. Type name must be lowercase.
22379 */
22380 public function supportsBuiltinType(string $type): bool
22381 {
22382 $minVersion = self::BUILTIN_TYPE_VERSIONS[$type] ?? null;
22383 return $minVersion !== null && $this->id >= $minVersion;
22384 }
22385 /**
22386 * Whether this version supports [] array literals.
22387 */
22388 public function supportsShortArraySyntax(): bool
22389 {
22390 return $this->id >= 50400;
22391 }
22392 /**
22393 * Whether this version supports [] for destructuring.
22394 */
22395 public function supportsShortArrayDestructuring(): bool
22396 {
22397 return $this->id >= 70100;
22398 }
22399 /**
22400 * Whether this version supports flexible heredoc/nowdoc.
22401 */
22402 public function supportsFlexibleHeredoc(): bool
22403 {
22404 return $this->id >= 70300;
22405 }
22406 /**
22407 * Whether this version supports trailing commas in parameter lists.
22408 */
22409 public function supportsTrailingCommaInParamList(): bool
22410 {
22411 return $this->id >= 80000;
22412 }
22413 /**
22414 * Whether this version allows "$var =& new Obj".
22415 */
22416 public function allowsAssignNewByReference(): bool
22417 {
22418 return $this->id < 70000;
22419 }
22420 /**
22421 * Whether this version allows invalid octals like "08".
22422 */
22423 public function allowsInvalidOctals(): bool
22424 {
22425 return $this->id < 70000;
22426 }
22427 /**
22428 * Whether this version allows DEL (\x7f) to occur in identifiers.
22429 */
22430 public function allowsDelInIdentifiers(): bool
22431 {
22432 return $this->id < 70100;
22433 }
22434 /**
22435 * Whether this version supports yield in expression context without parentheses.
22436 */
22437 public function supportsYieldWithoutParentheses(): bool
22438 {
22439 return $this->id >= 70000;
22440 }
22441 /**
22442 * Whether this version supports unicode escape sequences in strings.
22443 */
22444 public function supportsUnicodeEscapes(): bool
22445 {
22446 return $this->id >= 70000;
22447 }
22448 /*
22449 * Whether this version supports attributes.
22450 */
22451 public function supportsAttributes(): bool
22452 {
22453 return $this->id >= 80000;
22454 }
22455 public function supportsNewDereferenceWithoutParentheses(): bool
22456 {
22457 return $this->id >= 80400;
22458 }
22459 }
22460 <?php
22461
22462 declare (strict_types=1);
22463 namespace PHPUnitPHAR\PhpParser;
22464
22465 use PHPUnitPHAR\PhpParser\Node\Expr;
22466 interface PrettyPrinter
22467 {
22468 /**
22469 * Pretty prints an array of statements.
22470 *
22471 * @param Node[] $stmts Array of statements
22472 *
22473 * @return string Pretty printed statements
22474 */
22475 public function prettyPrint(array $stmts): string;
22476 /**
22477 * Pretty prints an expression.
22478 *
22479 * @param Expr $node Expression node
22480 *
22481 * @return string Pretty printed node
22482 */
22483 public function prettyPrintExpr(Expr $node): string;
22484 /**
22485 * Pretty prints a file of statements (includes the opening <?php tag if it is required).
22486 *
22487 * @param Node[] $stmts Array of statements
22488 *
22489 * @return string Pretty printed statements
22490 */
22491 public function prettyPrintFile(array $stmts): string;
22492 /**
22493 * Perform a format-preserving pretty print of an AST.
22494 *
22495 * The format preservation is best effort. For some changes to the AST the formatting will not
22496 * be preserved (at least not locally).
22497 *
22498 * In order to use this method a number of prerequisites must be satisfied:
22499 * * The startTokenPos and endTokenPos attributes in the lexer must be enabled.
22500 * * The CloningVisitor must be run on the AST prior to modification.
22501 * * The original tokens must be provided, using the getTokens() method on the lexer.
22502 *
22503 * @param Node[] $stmts Modified AST with links to original AST
22504 * @param Node[] $origStmts Original AST with token offset information
22505 * @param Token[] $origTokens Tokens of the original code
22506 */
22507 public function printFormatPreserving(array $stmts, array $origStmts, array $origTokens): string;
22508 }
22509 <?php
22510
22511 declare (strict_types=1);
22512 namespace PHPUnitPHAR\PhpParser\PrettyPrinter;
22513
22514 use PHPUnitPHAR\PhpParser\Node;
22515 use PHPUnitPHAR\PhpParser\Node\Expr;
22516 use PHPUnitPHAR\PhpParser\Node\Expr\AssignOp;
22517 use PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp;
22518 use PHPUnitPHAR\PhpParser\Node\Expr\Cast;
22519 use PHPUnitPHAR\PhpParser\Node\Name;
22520 use PHPUnitPHAR\PhpParser\Node\Scalar;
22521 use PHPUnitPHAR\PhpParser\Node\Scalar\MagicConst;
22522 use PHPUnitPHAR\PhpParser\Node\Stmt;
22523 use PHPUnitPHAR\PhpParser\PrettyPrinterAbstract;
22524 class Standard extends PrettyPrinterAbstract
22525 {
22526 // Special nodes
22527 protected function pParam(Node\Param $node): string
22528 {
22529 return $this->pAttrGroups($node->attrGroups, $this->phpVersion->supportsAttributes()) . $this->pModifiers($node->flags) . ($node->type ? $this->p($node->type) . ' ' : '') . ($node->byRef ? '&' : '') . ($node->variadic ? '...' : '') . $this->p($node->var) . ($node->default ? ' = ' . $this->p($node->default) : '') . ($node->hooks ? ' {' . $this->pStmts($node->hooks) . $this->nl . '}' : '');
22530 }
22531 protected function pArg(Node\Arg $node): string
22532 {
22533 return ($node->name ? $node->name->toString() . ': ' : '') . ($node->byRef ? '&' : '') . ($node->unpack ? '...' : '') . $this->p($node->value);
22534 }
22535 protected function pVariadicPlaceholder(Node\VariadicPlaceholder $node): string
22536 {
22537 return '...';
22538 }
22539 protected function pConst(Node\Const_ $node): string
22540 {
22541 return $node->name . ' = ' . $this->p($node->value);
22542 }
22543 protected function pNullableType(Node\NullableType $node): string
22544 {
22545 return '?' . $this->p($node->type);
22546 }
22547 protected function pUnionType(Node\UnionType $node): string
22548 {
22549 $types = [];
22550 foreach ($node->types as $typeNode) {
22551 if ($typeNode instanceof Node\IntersectionType) {
22552 $types[] = '(' . $this->p($typeNode) . ')';
22553 continue;
22554 }
22555 $types[] = $this->p($typeNode);
22556 }
22557 return implode('|', $types);
22558 }
22559 protected function pIntersectionType(Node\IntersectionType $node): string
22560 {
22561 return $this->pImplode($node->types, '&');
22562 }
22563 protected function pIdentifier(Node\Identifier $node): string
22564 {
22565 return $node->name;
22566 }
22567 protected function pVarLikeIdentifier(Node\VarLikeIdentifier $node): string
22568 {
22569 return '$' . $node->name;
22570 }
22571 protected function pAttribute(Node\Attribute $node): string
22572 {
22573 return $this->p($node->name) . ($node->args ? '(' . $this->pCommaSeparated($node->args) . ')' : '');
22574 }
22575 protected function pAttributeGroup(Node\AttributeGroup $node): string
22576 {
22577 return '#[' . $this->pCommaSeparated($node->attrs) . ']';
22578 }
22579 // Names
22580 protected function pName(Name $node): string
22581 {
22582 return $node->name;
22583 }
22584 protected function pName_FullyQualified(Name\FullyQualified $node): string
22585 {
22586 return '\\' . $node->name;
22587 }
22588 protected function pName_Relative(Name\Relative $node): string
22589 {
22590 return 'namespace\\' . $node->name;
22591 }
22592 // Magic Constants
22593 protected function pScalar_MagicConst_Class(MagicConst\Class_ $node): string
22594 {
22595 return '__CLASS__';
22596 }
22597 protected function pScalar_MagicConst_Dir(MagicConst\Dir $node): string
22598 {
22599 return '__DIR__';
22600 }
22601 protected function pScalar_MagicConst_File(MagicConst\File $node): string
22602 {
22603 return '__FILE__';
22604 }
22605 protected function pScalar_MagicConst_Function(MagicConst\Function_ $node): string
22606 {
22607 return '__FUNCTION__';
22608 }
22609 protected function pScalar_MagicConst_Line(MagicConst\Line $node): string
22610 {
22611 return '__LINE__';
22612 }
22613 protected function pScalar_MagicConst_Method(MagicConst\Method $node): string
22614 {
22615 return '__METHOD__';
22616 }
22617 protected function pScalar_MagicConst_Namespace(MagicConst\Namespace_ $node): string
22618 {
22619 return '__NAMESPACE__';
22620 }
22621 protected function pScalar_MagicConst_Trait(MagicConst\Trait_ $node): string
22622 {
22623 return '__TRAIT__';
22624 }
22625 protected function pScalar_MagicConst_Property(MagicConst\Property $node): string
22626 {
22627 return '__PROPERTY__';
22628 }
22629 // Scalars
22630 private function indentString(string $str): string
22631 {
22632 return str_replace("\n", $this->nl, $str);
22633 }
22634 protected function pScalar_String(Scalar\String_ $node): string
22635 {
22636 $kind = $node->getAttribute('kind', Scalar\String_::KIND_SINGLE_QUOTED);
22637 switch ($kind) {
22638 case Scalar\String_::KIND_NOWDOC:
22639 $label = $node->getAttribute('docLabel');
22640 if ($label && !$this->containsEndLabel($node->value, $label)) {
22641 $shouldIdent = $this->phpVersion->supportsFlexibleHeredoc();
22642 $nl = $shouldIdent ? $this->nl : $this->newline;
22643 if ($node->value === '') {
22644 return "<<<'{$label}'{$nl}{$label}{$this->docStringEndToken}";
22645 }
22646 // Make sure trailing \r is not combined with following \n into CRLF.
22647 if ($node->value[strlen($node->value) - 1] !== "\r") {
22648 $value = $shouldIdent ? $this->indentString($node->value) : $node->value;
22649 return "<<<'{$label}'{$nl}{$value}{$nl}{$label}{$this->docStringEndToken}";
22650 }
22651 }
22652 /* break missing intentionally */
22653 // no break
22654 case Scalar\String_::KIND_SINGLE_QUOTED:
22655 return $this->pSingleQuotedString($node->value);
22656 case Scalar\String_::KIND_HEREDOC:
22657 $label = $node->getAttribute('docLabel');
22658 $escaped = $this->escapeString($node->value, null);
22659 if ($label && !$this->containsEndLabel($escaped, $label)) {
22660 $nl = $this->phpVersion->supportsFlexibleHeredoc() ? $this->nl : $this->newline;
22661 if ($escaped === '') {
22662 return "<<<{$label}{$nl}{$label}{$this->docStringEndToken}";
22663 }
22664 return "<<<{$label}{$nl}{$escaped}{$nl}{$label}{$this->docStringEndToken}";
22665 }
22666 /* break missing intentionally */
22667 // no break
22668 case Scalar\String_::KIND_DOUBLE_QUOTED:
22669 return '"' . $this->escapeString($node->value, '"') . '"';
22670 }
22671 throw new \Exception('Invalid string kind');
22672 }
22673 protected function pScalar_InterpolatedString(Scalar\InterpolatedString $node): string
22674 {
22675 if ($node->getAttribute('kind') === Scalar\String_::KIND_HEREDOC) {
22676 $label = $node->getAttribute('docLabel');
22677 if ($label && !$this->encapsedContainsEndLabel($node->parts, $label)) {
22678 $nl = $this->phpVersion->supportsFlexibleHeredoc() ? $this->nl : $this->newline;
22679 if (count($node->parts) === 1 && $node->parts[0] instanceof Node\InterpolatedStringPart && $node->parts[0]->value === '') {
22680 return "<<<{$label}{$nl}{$label}{$this->docStringEndToken}";
22681 }
22682 return "<<<{$label}{$nl}" . $this->pEncapsList($node->parts, null) . "{$nl}{$label}{$this->docStringEndToken}";
22683 }
22684 }
22685 return '"' . $this->pEncapsList($node->parts, '"') . '"';
22686 }
22687 protected function pScalar_Int(Scalar\Int_ $node): string
22688 {
22689 if ($node->getAttribute('shouldPrintRawValue') === \true) {
22690 return $node->getAttribute('rawValue');
22691 }
22692 if ($node->value === -\PHP_INT_MAX - 1) {
22693 // PHP_INT_MIN cannot be represented as a literal,
22694 // because the sign is not part of the literal
22695 return '(-' . \PHP_INT_MAX . '-1)';
22696 }
22697 $kind = $node->getAttribute('kind', Scalar\Int_::KIND_DEC);
22698 if (Scalar\Int_::KIND_DEC === $kind) {
22699 return (string) $node->value;
22700 }
22701 if ($node->value < 0) {
22702 $sign = '-';
22703 $str = (string) -$node->value;
22704 } else {
22705 $sign = '';
22706 $str = (string) $node->value;
22707 }
22708 switch ($kind) {
22709 case Scalar\Int_::KIND_BIN:
22710 return $sign . '0b' . base_convert($str, 10, 2);
22711 case Scalar\Int_::KIND_OCT:
22712 return $sign . '0' . base_convert($str, 10, 8);
22713 case Scalar\Int_::KIND_HEX:
22714 return $sign . '0x' . base_convert($str, 10, 16);
22715 }
22716 throw new \Exception('Invalid number kind');
22717 }
22718 protected function pScalar_Float(Scalar\Float_ $node): string
22719 {
22720 if (!is_finite($node->value)) {
22721 if ($node->value === \INF) {
22722 return '1.0E+1000';
22723 }
22724 if ($node->value === -\INF) {
22725 return '-1.0E+1000';
22726 } else {
22727 return '\NAN';
22728 }
22729 }
22730 // Try to find a short full-precision representation
22731 $stringValue = sprintf('%.16G', $node->value);
22732 if ($node->value !== (float) $stringValue) {
22733 $stringValue = sprintf('%.17G', $node->value);
22734 }
22735 // %G is locale dependent and there exists no locale-independent alternative. We don't want
22736 // mess with switching locales here, so let's assume that a comma is the only non-standard
22737 // decimal separator we may encounter...
22738 $stringValue = str_replace(',', '.', $stringValue);
22739 // ensure that number is really printed as float
22740 return preg_match('/^-?[0-9]+$/', $stringValue) ? $stringValue . '.0' : $stringValue;
22741 }
22742 // Assignments
22743 protected function pExpr_Assign(Expr\Assign $node, int $precedence, int $lhsPrecedence): string
22744 {
22745 return $this->pPrefixOp(Expr\Assign::class, $this->p($node->var) . ' = ', $node->expr, $precedence, $lhsPrecedence);
22746 }
22747 protected function pExpr_AssignRef(Expr\AssignRef $node, int $precedence, int $lhsPrecedence): string
22748 {
22749 return $this->pPrefixOp(Expr\AssignRef::class, $this->p($node->var) . ' =& ', $node->expr, $precedence, $lhsPrecedence);
22750 }
22751 protected function pExpr_AssignOp_Plus(AssignOp\Plus $node, int $precedence, int $lhsPrecedence): string
22752 {
22753 return $this->pPrefixOp(AssignOp\Plus::class, $this->p($node->var) . ' += ', $node->expr, $precedence, $lhsPrecedence);
22754 }
22755 protected function pExpr_AssignOp_Minus(AssignOp\Minus $node, int $precedence, int $lhsPrecedence): string
22756 {
22757 return $this->pPrefixOp(AssignOp\Minus::class, $this->p($node->var) . ' -= ', $node->expr, $precedence, $lhsPrecedence);
22758 }
22759 protected function pExpr_AssignOp_Mul(AssignOp\Mul $node, int $precedence, int $lhsPrecedence): string
22760 {
22761 return $this->pPrefixOp(AssignOp\Mul::class, $this->p($node->var) . ' *= ', $node->expr, $precedence, $lhsPrecedence);
22762 }
22763 protected function pExpr_AssignOp_Div(AssignOp\Div $node, int $precedence, int $lhsPrecedence): string
22764 {
22765 return $this->pPrefixOp(AssignOp\Div::class, $this->p($node->var) . ' /= ', $node->expr, $precedence, $lhsPrecedence);
22766 }
22767 protected function pExpr_AssignOp_Concat(AssignOp\Concat $node, int $precedence, int $lhsPrecedence): string
22768 {
22769 return $this->pPrefixOp(AssignOp\Concat::class, $this->p($node->var) . ' .= ', $node->expr, $precedence, $lhsPrecedence);
22770 }
22771 protected function pExpr_AssignOp_Mod(AssignOp\Mod $node, int $precedence, int $lhsPrecedence): string
22772 {
22773 return $this->pPrefixOp(AssignOp\Mod::class, $this->p($node->var) . ' %= ', $node->expr, $precedence, $lhsPrecedence);
22774 }
22775 protected function pExpr_AssignOp_BitwiseAnd(AssignOp\BitwiseAnd $node, int $precedence, int $lhsPrecedence): string
22776 {
22777 return $this->pPrefixOp(AssignOp\BitwiseAnd::class, $this->p($node->var) . ' &= ', $node->expr, $precedence, $lhsPrecedence);
22778 }
22779 protected function pExpr_AssignOp_BitwiseOr(AssignOp\BitwiseOr $node, int $precedence, int $lhsPrecedence): string
22780 {
22781 return $this->pPrefixOp(AssignOp\BitwiseOr::class, $this->p($node->var) . ' |= ', $node->expr, $precedence, $lhsPrecedence);
22782 }
22783 protected function pExpr_AssignOp_BitwiseXor(AssignOp\BitwiseXor $node, int $precedence, int $lhsPrecedence): string
22784 {
22785 return $this->pPrefixOp(AssignOp\BitwiseXor::class, $this->p($node->var) . ' ^= ', $node->expr, $precedence, $lhsPrecedence);
22786 }
22787 protected function pExpr_AssignOp_ShiftLeft(AssignOp\ShiftLeft $node, int $precedence, int $lhsPrecedence): string
22788 {
22789 return $this->pPrefixOp(AssignOp\ShiftLeft::class, $this->p($node->var) . ' <<= ', $node->expr, $precedence, $lhsPrecedence);
22790 }
22791 protected function pExpr_AssignOp_ShiftRight(AssignOp\ShiftRight $node, int $precedence, int $lhsPrecedence): string
22792 {
22793 return $this->pPrefixOp(AssignOp\ShiftRight::class, $this->p($node->var) . ' >>= ', $node->expr, $precedence, $lhsPrecedence);
22794 }
22795 protected function pExpr_AssignOp_Pow(AssignOp\Pow $node, int $precedence, int $lhsPrecedence): string
22796 {
22797 return $this->pPrefixOp(AssignOp\Pow::class, $this->p($node->var) . ' **= ', $node->expr, $precedence, $lhsPrecedence);
22798 }
22799 protected function pExpr_AssignOp_Coalesce(AssignOp\Coalesce $node, int $precedence, int $lhsPrecedence): string
22800 {
22801 return $this->pPrefixOp(AssignOp\Coalesce::class, $this->p($node->var) . ' ??= ', $node->expr, $precedence, $lhsPrecedence);
22802 }
22803 // Binary expressions
22804 protected function pExpr_BinaryOp_Plus(BinaryOp\Plus $node, int $precedence, int $lhsPrecedence): string
22805 {
22806 return $this->pInfixOp(BinaryOp\Plus::class, $node->left, ' + ', $node->right, $precedence, $lhsPrecedence);
22807 }
22808 protected function pExpr_BinaryOp_Minus(BinaryOp\Minus $node, int $precedence, int $lhsPrecedence): string
22809 {
22810 return $this->pInfixOp(BinaryOp\Minus::class, $node->left, ' - ', $node->right, $precedence, $lhsPrecedence);
22811 }
22812 protected function pExpr_BinaryOp_Mul(BinaryOp\Mul $node, int $precedence, int $lhsPrecedence): string
22813 {
22814 return $this->pInfixOp(BinaryOp\Mul::class, $node->left, ' * ', $node->right, $precedence, $lhsPrecedence);
22815 }
22816 protected function pExpr_BinaryOp_Div(BinaryOp\Div $node, int $precedence, int $lhsPrecedence): string
22817 {
22818 return $this->pInfixOp(BinaryOp\Div::class, $node->left, ' / ', $node->right, $precedence, $lhsPrecedence);
22819 }
22820 protected function pExpr_BinaryOp_Concat(BinaryOp\Concat $node, int $precedence, int $lhsPrecedence): string
22821 {
22822 return $this->pInfixOp(BinaryOp\Concat::class, $node->left, ' . ', $node->right, $precedence, $lhsPrecedence);
22823 }
22824 protected function pExpr_BinaryOp_Mod(BinaryOp\Mod $node, int $precedence, int $lhsPrecedence): string
22825 {
22826 return $this->pInfixOp(BinaryOp\Mod::class, $node->left, ' % ', $node->right, $precedence, $lhsPrecedence);
22827 }
22828 protected function pExpr_BinaryOp_BooleanAnd(BinaryOp\BooleanAnd $node, int $precedence, int $lhsPrecedence): string
22829 {
22830 return $this->pInfixOp(BinaryOp\BooleanAnd::class, $node->left, ' && ', $node->right, $precedence, $lhsPrecedence);
22831 }
22832 protected function pExpr_BinaryOp_BooleanOr(BinaryOp\BooleanOr $node, int $precedence, int $lhsPrecedence): string
22833 {
22834 return $this->pInfixOp(BinaryOp\BooleanOr::class, $node->left, ' || ', $node->right, $precedence, $lhsPrecedence);
22835 }
22836 protected function pExpr_BinaryOp_BitwiseAnd(BinaryOp\BitwiseAnd $node, int $precedence, int $lhsPrecedence): string
22837 {
22838 return $this->pInfixOp(BinaryOp\BitwiseAnd::class, $node->left, ' & ', $node->right, $precedence, $lhsPrecedence);
22839 }
22840 protected function pExpr_BinaryOp_BitwiseOr(BinaryOp\BitwiseOr $node, int $precedence, int $lhsPrecedence): string
22841 {
22842 return $this->pInfixOp(BinaryOp\BitwiseOr::class, $node->left, ' | ', $node->right, $precedence, $lhsPrecedence);
22843 }
22844 protected function pExpr_BinaryOp_BitwiseXor(BinaryOp\BitwiseXor $node, int $precedence, int $lhsPrecedence): string
22845 {
22846 return $this->pInfixOp(BinaryOp\BitwiseXor::class, $node->left, ' ^ ', $node->right, $precedence, $lhsPrecedence);
22847 }
22848 protected function pExpr_BinaryOp_ShiftLeft(BinaryOp\ShiftLeft $node, int $precedence, int $lhsPrecedence): string
22849 {
22850 return $this->pInfixOp(BinaryOp\ShiftLeft::class, $node->left, ' << ', $node->right, $precedence, $lhsPrecedence);
22851 }
22852 protected function pExpr_BinaryOp_ShiftRight(BinaryOp\ShiftRight $node, int $precedence, int $lhsPrecedence): string
22853 {
22854 return $this->pInfixOp(BinaryOp\ShiftRight::class, $node->left, ' >> ', $node->right, $precedence, $lhsPrecedence);
22855 }
22856 protected function pExpr_BinaryOp_Pow(BinaryOp\Pow $node, int $precedence, int $lhsPrecedence): string
22857 {
22858 return $this->pInfixOp(BinaryOp\Pow::class, $node->left, ' ** ', $node->right, $precedence, $lhsPrecedence);
22859 }
22860 protected function pExpr_BinaryOp_LogicalAnd(BinaryOp\LogicalAnd $node, int $precedence, int $lhsPrecedence): string
22861 {
22862 return $this->pInfixOp(BinaryOp\LogicalAnd::class, $node->left, ' and ', $node->right, $precedence, $lhsPrecedence);
22863 }
22864 protected function pExpr_BinaryOp_LogicalOr(BinaryOp\LogicalOr $node, int $precedence, int $lhsPrecedence): string
22865 {
22866 return $this->pInfixOp(BinaryOp\LogicalOr::class, $node->left, ' or ', $node->right, $precedence, $lhsPrecedence);
22867 }
22868 protected function pExpr_BinaryOp_LogicalXor(BinaryOp\LogicalXor $node, int $precedence, int $lhsPrecedence): string
22869 {
22870 return $this->pInfixOp(BinaryOp\LogicalXor::class, $node->left, ' xor ', $node->right, $precedence, $lhsPrecedence);
22871 }
22872 protected function pExpr_BinaryOp_Equal(BinaryOp\Equal $node, int $precedence, int $lhsPrecedence): string
22873 {
22874 return $this->pInfixOp(BinaryOp\Equal::class, $node->left, ' == ', $node->right, $precedence, $lhsPrecedence);
22875 }
22876 protected function pExpr_BinaryOp_NotEqual(BinaryOp\NotEqual $node, int $precedence, int $lhsPrecedence): string
22877 {
22878 return $this->pInfixOp(BinaryOp\NotEqual::class, $node->left, ' != ', $node->right, $precedence, $lhsPrecedence);
22879 }
22880 protected function pExpr_BinaryOp_Identical(BinaryOp\Identical $node, int $precedence, int $lhsPrecedence): string
22881 {
22882 return $this->pInfixOp(BinaryOp\Identical::class, $node->left, ' === ', $node->right, $precedence, $lhsPrecedence);
22883 }
22884 protected function pExpr_BinaryOp_NotIdentical(BinaryOp\NotIdentical $node, int $precedence, int $lhsPrecedence): string
22885 {
22886 return $this->pInfixOp(BinaryOp\NotIdentical::class, $node->left, ' !== ', $node->right, $precedence, $lhsPrecedence);
22887 }
22888 protected function pExpr_BinaryOp_Spaceship(BinaryOp\Spaceship $node, int $precedence, int $lhsPrecedence): string
22889 {
22890 return $this->pInfixOp(BinaryOp\Spaceship::class, $node->left, ' <=> ', $node->right, $precedence, $lhsPrecedence);
22891 }
22892 protected function pExpr_BinaryOp_Greater(BinaryOp\Greater $node, int $precedence, int $lhsPrecedence): string
22893 {
22894 return $this->pInfixOp(BinaryOp\Greater::class, $node->left, ' > ', $node->right, $precedence, $lhsPrecedence);
22895 }
22896 protected function pExpr_BinaryOp_GreaterOrEqual(BinaryOp\GreaterOrEqual $node, int $precedence, int $lhsPrecedence): string
22897 {
22898 return $this->pInfixOp(BinaryOp\GreaterOrEqual::class, $node->left, ' >= ', $node->right, $precedence, $lhsPrecedence);
22899 }
22900 protected function pExpr_BinaryOp_Smaller(BinaryOp\Smaller $node, int $precedence, int $lhsPrecedence): string
22901 {
22902 return $this->pInfixOp(BinaryOp\Smaller::class, $node->left, ' < ', $node->right, $precedence, $lhsPrecedence);
22903 }
22904 protected function pExpr_BinaryOp_SmallerOrEqual(BinaryOp\SmallerOrEqual $node, int $precedence, int $lhsPrecedence): string
22905 {
22906 return $this->pInfixOp(BinaryOp\SmallerOrEqual::class, $node->left, ' <= ', $node->right, $precedence, $lhsPrecedence);
22907 }
22908 protected function pExpr_BinaryOp_Coalesce(BinaryOp\Coalesce $node, int $precedence, int $lhsPrecedence): string
22909 {
22910 return $this->pInfixOp(BinaryOp\Coalesce::class, $node->left, ' ?? ', $node->right, $precedence, $lhsPrecedence);
22911 }
22912 protected function pExpr_BinaryOp_Pipe(BinaryOp\Pipe $node, int $precedence, int $lhsPrecedence): string
22913 {
22914 if ($node->right instanceof Expr\ArrowFunction) {
22915 // Force parentheses around arrow functions.
22916 $lhsPrecedence = $this->precedenceMap[Expr\ArrowFunction::class][0];
22917 }
22918 return $this->pInfixOp(BinaryOp\Pipe::class, $node->left, ' |> ', $node->right, $precedence, $lhsPrecedence);
22919 }
22920 protected function pExpr_Instanceof(Expr\Instanceof_ $node, int $precedence, int $lhsPrecedence): string
22921 {
22922 return $this->pPostfixOp(Expr\Instanceof_::class, $node->expr, ' instanceof ' . $this->pNewOperand($node->class), $precedence, $lhsPrecedence);
22923 }
22924 // Unary expressions
22925 protected function pExpr_BooleanNot(Expr\BooleanNot $node, int $precedence, int $lhsPrecedence): string
22926 {
22927 return $this->pPrefixOp(Expr\BooleanNot::class, '!', $node->expr, $precedence, $lhsPrecedence);
22928 }
22929 protected function pExpr_BitwiseNot(Expr\BitwiseNot $node, int $precedence, int $lhsPrecedence): string
22930 {
22931 return $this->pPrefixOp(Expr\BitwiseNot::class, '~', $node->expr, $precedence, $lhsPrecedence);
22932 }
22933 protected function pExpr_UnaryMinus(Expr\UnaryMinus $node, int $precedence, int $lhsPrecedence): string
22934 {
22935 return $this->pPrefixOp(Expr\UnaryMinus::class, '-', $node->expr, $precedence, $lhsPrecedence);
22936 }
22937 protected function pExpr_UnaryPlus(Expr\UnaryPlus $node, int $precedence, int $lhsPrecedence): string
22938 {
22939 return $this->pPrefixOp(Expr\UnaryPlus::class, '+', $node->expr, $precedence, $lhsPrecedence);
22940 }
22941 protected function pExpr_PreInc(Expr\PreInc $node): string
22942 {
22943 return '++' . $this->p($node->var);
22944 }
22945 protected function pExpr_PreDec(Expr\PreDec $node): string
22946 {
22947 return '--' . $this->p($node->var);
22948 }
22949 protected function pExpr_PostInc(Expr\PostInc $node): string
22950 {
22951 return $this->p($node->var) . '++';
22952 }
22953 protected function pExpr_PostDec(Expr\PostDec $node): string
22954 {
22955 return $this->p($node->var) . '--';
22956 }
22957 protected function pExpr_ErrorSuppress(Expr\ErrorSuppress $node, int $precedence, int $lhsPrecedence): string
22958 {
22959 return $this->pPrefixOp(Expr\ErrorSuppress::class, '@', $node->expr, $precedence, $lhsPrecedence);
22960 }
22961 protected function pExpr_YieldFrom(Expr\YieldFrom $node, int $precedence, int $lhsPrecedence): string
22962 {
22963 return $this->pPrefixOp(Expr\YieldFrom::class, 'yield from ', $node->expr, $precedence, $lhsPrecedence);
22964 }
22965 protected function pExpr_Print(Expr\Print_ $node, int $precedence, int $lhsPrecedence): string
22966 {
22967 return $this->pPrefixOp(Expr\Print_::class, 'print ', $node->expr, $precedence, $lhsPrecedence);
22968 }
22969 // Casts
22970 protected function pExpr_Cast_Int(Cast\Int_ $node, int $precedence, int $lhsPrecedence): string
22971 {
22972 return $this->pPrefixOp(Cast\Int_::class, '(int) ', $node->expr, $precedence, $lhsPrecedence);
22973 }
22974 protected function pExpr_Cast_Double(Cast\Double $node, int $precedence, int $lhsPrecedence): string
22975 {
22976 $kind = $node->getAttribute('kind', Cast\Double::KIND_DOUBLE);
22977 if ($kind === Cast\Double::KIND_DOUBLE) {
22978 $cast = '(double)';
22979 } elseif ($kind === Cast\Double::KIND_FLOAT) {
22980 $cast = '(float)';
22981 } else {
22982 assert($kind === Cast\Double::KIND_REAL);
22983 $cast = '(real)';
22984 }
22985 return $this->pPrefixOp(Cast\Double::class, $cast . ' ', $node->expr, $precedence, $lhsPrecedence);
22986 }
22987 protected function pExpr_Cast_String(Cast\String_ $node, int $precedence, int $lhsPrecedence): string
22988 {
22989 return $this->pPrefixOp(Cast\String_::class, '(string) ', $node->expr, $precedence, $lhsPrecedence);
22990 }
22991 protected function pExpr_Cast_Array(Cast\Array_ $node, int $precedence, int $lhsPrecedence): string
22992 {
22993 return $this->pPrefixOp(Cast\Array_::class, '(array) ', $node->expr, $precedence, $lhsPrecedence);
22994 }
22995 protected function pExpr_Cast_Object(Cast\Object_ $node, int $precedence, int $lhsPrecedence): string
22996 {
22997 return $this->pPrefixOp(Cast\Object_::class, '(object) ', $node->expr, $precedence, $lhsPrecedence);
22998 }
22999 protected function pExpr_Cast_Bool(Cast\Bool_ $node, int $precedence, int $lhsPrecedence): string
23000 {
23001 return $this->pPrefixOp(Cast\Bool_::class, '(bool) ', $node->expr, $precedence, $lhsPrecedence);
23002 }
23003 protected function pExpr_Cast_Unset(Cast\Unset_ $node, int $precedence, int $lhsPrecedence): string
23004 {
23005 return $this->pPrefixOp(Cast\Unset_::class, '(unset) ', $node->expr, $precedence, $lhsPrecedence);
23006 }
23007 protected function pExpr_Cast_Void(Cast\Void_ $node, int $precedence, int $lhsPrecedence): string
23008 {
23009 return $this->pPrefixOp(Cast\Void_::class, '(void) ', $node->expr, $precedence, $lhsPrecedence);
23010 }
23011 // Function calls and similar constructs
23012 protected function pExpr_FuncCall(Expr\FuncCall $node): string
23013 {
23014 return $this->pCallLhs($node->name) . '(' . $this->pMaybeMultiline($node->args) . ')';
23015 }
23016 protected function pExpr_MethodCall(Expr\MethodCall $node): string
23017 {
23018 return $this->pDereferenceLhs($node->var) . '->' . $this->pObjectProperty($node->name) . '(' . $this->pMaybeMultiline($node->args) . ')';
23019 }
23020 protected function pExpr_NullsafeMethodCall(Expr\NullsafeMethodCall $node): string
23021 {
23022 return $this->pDereferenceLhs($node->var) . '?->' . $this->pObjectProperty($node->name) . '(' . $this->pMaybeMultiline($node->args) . ')';
23023 }
23024 protected function pExpr_StaticCall(Expr\StaticCall $node): string
23025 {
23026 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) . ')';
23027 }
23028 protected function pExpr_Empty(Expr\Empty_ $node): string
23029 {
23030 return 'empty(' . $this->p($node->expr) . ')';
23031 }
23032 protected function pExpr_Isset(Expr\Isset_ $node): string
23033 {
23034 return 'isset(' . $this->pCommaSeparated($node->vars) . ')';
23035 }
23036 protected function pExpr_Eval(Expr\Eval_ $node): string
23037 {
23038 return 'eval(' . $this->p($node->expr) . ')';
23039 }
23040 protected function pExpr_Include(Expr\Include_ $node, int $precedence, int $lhsPrecedence): string
23041 {
23042 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'];
23043 return $this->pPrefixOp(Expr\Include_::class, $map[$node->type] . ' ', $node->expr, $precedence, $lhsPrecedence);
23044 }
23045 protected function pExpr_List(Expr\List_ $node): string
23046 {
23047 $syntax = $node->getAttribute('kind', $this->phpVersion->supportsShortArrayDestructuring() ? Expr\List_::KIND_ARRAY : Expr\List_::KIND_LIST);
23048 if ($syntax === Expr\List_::KIND_ARRAY) {
23049 return '[' . $this->pMaybeMultiline($node->items, \true) . ']';
23050 } else {
23051 return 'list(' . $this->pMaybeMultiline($node->items, \true) . ')';
23052 }
23053 }
23054 // Other
23055 protected function pExpr_Error(Expr\Error $node): string
23056 {
23057 throw new \LogicException('Cannot pretty-print AST with Error nodes');
23058 }
23059 protected function pExpr_Variable(Expr\Variable $node): string
23060 {
23061 if ($node->name instanceof Expr) {
23062 return '${' . $this->p($node->name) . '}';
23063 } else {
23064 return '$' . $node->name;
23065 }
23066 }
23067 protected function pExpr_Array(Expr\Array_ $node): string
23068 {
23069 $syntax = $node->getAttribute('kind', $this->shortArraySyntax ? Expr\Array_::KIND_SHORT : Expr\Array_::KIND_LONG);
23070 if ($syntax === Expr\Array_::KIND_SHORT) {
23071 return '[' . $this->pMaybeMultiline($node->items, \true) . ']';
23072 } else {
23073 return 'array(' . $this->pMaybeMultiline($node->items, \true) . ')';
23074 }
23075 }
23076 protected function pKey(?Node $node): string
23077 {
23078 if ($node === null) {
23079 return '';
23080 }
23081 // => is not really an operator and does not typically participate in precedence resolution.
23082 // However, there is an exception if yield expressions with keys are involved:
23083 // [yield $a => $b] is interpreted as [(yield $a => $b)], so we need to ensure that
23084 // [(yield $a) => $b] is printed with parentheses. We approximate this by lowering the LHS
23085 // precedence to that of yield (which will also print unnecessary parentheses for rare low
23086 // precedence unary operators like include).
23087 $yieldPrecedence = $this->precedenceMap[Expr\Yield_::class][0];
23088 return $this->p($node, self::MAX_PRECEDENCE, $yieldPrecedence) . ' => ';
23089 }
23090 protected function pArrayItem(Node\ArrayItem $node): string
23091 {
23092 return $this->pKey($node->key) . ($node->byRef ? '&' : '') . ($node->unpack ? '...' : '') . $this->p($node->value);
23093 }
23094 protected function pExpr_ArrayDimFetch(Expr\ArrayDimFetch $node): string
23095 {
23096 return $this->pDereferenceLhs($node->var) . '[' . (null !== $node->dim ? $this->p($node->dim) : '') . ']';
23097 }
23098 protected function pExpr_ConstFetch(Expr\ConstFetch $node): string
23099 {
23100 return $this->p($node->name);
23101 }
23102 protected function pExpr_ClassConstFetch(Expr\ClassConstFetch $node): string
23103 {
23104 return $this->pStaticDereferenceLhs($node->class) . '::' . $this->pObjectProperty($node->name);
23105 }
23106 protected function pExpr_PropertyFetch(Expr\PropertyFetch $node): string
23107 {
23108 return $this->pDereferenceLhs($node->var) . '->' . $this->pObjectProperty($node->name);
23109 }
23110 protected function pExpr_NullsafePropertyFetch(Expr\NullsafePropertyFetch $node): string
23111 {
23112 return $this->pDereferenceLhs($node->var) . '?->' . $this->pObjectProperty($node->name);
23113 }
23114 protected function pExpr_StaticPropertyFetch(Expr\StaticPropertyFetch $node): string
23115 {
23116 return $this->pStaticDereferenceLhs($node->class) . '::$' . $this->pObjectProperty($node->name);
23117 }
23118 protected function pExpr_ShellExec(Expr\ShellExec $node): string
23119 {
23120 return '`' . $this->pEncapsList($node->parts, '`') . '`';
23121 }
23122 protected function pExpr_Closure(Expr\Closure $node): string
23123 {
23124 return $this->pAttrGroups($node->attrGroups, \true) . $this->pStatic($node->static) . 'function ' . ($node->byRef ? '&' : '') . '(' . $this->pParams($node->params) . ')' . (!empty($node->uses) ? ' use (' . $this->pCommaSeparated($node->uses) . ')' : '') . (null !== $node->returnType ? ': ' . $this->p($node->returnType) : '') . ' {' . $this->pStmts($node->stmts) . $this->nl . '}';
23125 }
23126 protected function pExpr_Match(Expr\Match_ $node): string
23127 {
23128 return 'match (' . $this->p($node->cond) . ') {' . $this->pCommaSeparatedMultiline($node->arms, \true) . $this->nl . '}';
23129 }
23130 protected function pMatchArm(Node\MatchArm $node): string
23131 {
23132 $result = '';
23133 if ($node->conds) {
23134 for ($i = 0, $c = \count($node->conds); $i + 1 < $c; $i++) {
23135 $result .= $this->p($node->conds[$i]) . ', ';
23136 }
23137 $result .= $this->pKey($node->conds[$i]);
23138 } else {
23139 $result = 'default => ';
23140 }
23141 return $result . $this->p($node->body);
23142 }
23143 protected function pExpr_ArrowFunction(Expr\ArrowFunction $node, int $precedence, int $lhsPrecedence): string
23144 {
23145 return $this->pPrefixOp(Expr\ArrowFunction::class, $this->pAttrGroups($node->attrGroups, \true) . $this->pStatic($node->static) . 'fn' . ($node->byRef ? '&' : '') . '(' . $this->pParams($node->params) . ')' . (null !== $node->returnType ? ': ' . $this->p($node->returnType) : '') . ' => ', $node->expr, $precedence, $lhsPrecedence);
23146 }
23147 protected function pClosureUse(Node\ClosureUse $node): string
23148 {
23149 return ($node->byRef ? '&' : '') . $this->p($node->var);
23150 }
23151 protected function pExpr_New(Expr\New_ $node): string
23152 {
23153 if ($node->class instanceof Stmt\Class_) {
23154 $args = $node->args ? '(' . $this->pMaybeMultiline($node->args) . ')' : '';
23155 return 'new ' . $this->pClassCommon($node->class, $args);
23156 }
23157 return 'new ' . $this->pNewOperand($node->class) . '(' . $this->pMaybeMultiline($node->args) . ')';
23158 }
23159 protected function pExpr_Clone(Expr\Clone_ $node, int $precedence, int $lhsPrecedence): string
23160 {
23161 return $this->pPrefixOp(Expr\Clone_::class, 'clone ', $node->expr, $precedence, $lhsPrecedence);
23162 }
23163 protected function pExpr_Ternary(Expr\Ternary $node, int $precedence, int $lhsPrecedence): string
23164 {
23165 // a bit of cheating: we treat the ternary as a binary op where the ?...: part is the operator.
23166 // this is okay because the part between ? and : never needs parentheses.
23167 return $this->pInfixOp(Expr\Ternary::class, $node->cond, ' ?' . (null !== $node->if ? ' ' . $this->p($node->if) . ' ' : '') . ': ', $node->else, $precedence, $lhsPrecedence);
23168 }
23169 protected function pExpr_Exit(Expr\Exit_ $node): string
23170 {
23171 $kind = $node->getAttribute('kind', Expr\Exit_::KIND_DIE);
23172 return ($kind === Expr\Exit_::KIND_EXIT ? 'exit' : 'die') . (null !== $node->expr ? '(' . $this->p($node->expr) . ')' : '');
23173 }
23174 protected function pExpr_Throw(Expr\Throw_ $node, int $precedence, int $lhsPrecedence): string
23175 {
23176 return $this->pPrefixOp(Expr\Throw_::class, 'throw ', $node->expr, $precedence, $lhsPrecedence);
23177 }
23178 protected function pExpr_Yield(Expr\Yield_ $node, int $precedence, int $lhsPrecedence): string
23179 {
23180 if ($node->value === null) {
23181 $opPrecedence = $this->precedenceMap[Expr\Yield_::class][0];
23182 return $opPrecedence >= $lhsPrecedence ? '(yield)' : 'yield';
23183 } else {
23184 if (!$this->phpVersion->supportsYieldWithoutParentheses()) {
23185 return '(yield ' . $this->pKey($node->key) . $this->p($node->value) . ')';
23186 }
23187 return $this->pPrefixOp(Expr\Yield_::class, 'yield ' . $this->pKey($node->key), $node->value, $precedence, $lhsPrecedence);
23188 }
23189 }
23190 // Declarations
23191 protected function pStmt_Namespace(Stmt\Namespace_ $node): string
23192 {
23193 if ($this->canUseSemicolonNamespaces) {
23194 return 'namespace ' . $this->p($node->name) . ';' . $this->nl . $this->pStmts($node->stmts, \false);
23195 } else {
23196 return 'namespace' . (null !== $node->name ? ' ' . $this->p($node->name) : '') . ' {' . $this->pStmts($node->stmts) . $this->nl . '}';
23197 }
23198 }
23199 protected function pStmt_Use(Stmt\Use_ $node): string
23200 {
23201 return 'use ' . $this->pUseType($node->type) . $this->pCommaSeparated($node->uses) . ';';
23202 }
23203 protected function pStmt_GroupUse(Stmt\GroupUse $node): string
23204 {
23205 return 'use ' . $this->pUseType($node->type) . $this->pName($node->prefix) . '\{' . $this->pCommaSeparated($node->uses) . '};';
23206 }
23207 protected function pUseItem(Node\UseItem $node): string
23208 {
23209 return $this->pUseType($node->type) . $this->p($node->name) . (null !== $node->alias ? ' as ' . $node->alias : '');
23210 }
23211 protected function pUseType(int $type): string
23212 {
23213 return $type === Stmt\Use_::TYPE_FUNCTION ? 'function ' : ($type === Stmt\Use_::TYPE_CONSTANT ? 'const ' : '');
23214 }
23215 protected function pStmt_Interface(Stmt\Interface_ $node): string
23216 {
23217 return $this->pAttrGroups($node->attrGroups) . 'interface ' . $node->name . (!empty($node->extends) ? ' extends ' . $this->pCommaSeparated($node->extends) : '') . $this->nl . '{' . $this->pStmts($node->stmts) . $this->nl . '}';
23218 }
23219 protected function pStmt_Enum(Stmt\Enum_ $node): string
23220 {
23221 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 . '}';
23222 }
23223 protected function pStmt_Class(Stmt\Class_ $node): string
23224 {
23225 return $this->pClassCommon($node, ' ' . $node->name);
23226 }
23227 protected function pStmt_Trait(Stmt\Trait_ $node): string
23228 {
23229 return $this->pAttrGroups($node->attrGroups) . 'trait ' . $node->name . $this->nl . '{' . $this->pStmts($node->stmts) . $this->nl . '}';
23230 }
23231 protected function pStmt_EnumCase(Stmt\EnumCase $node): string
23232 {
23233 return $this->pAttrGroups($node->attrGroups) . 'case ' . $node->name . ($node->expr ? ' = ' . $this->p($node->expr) : '') . ';';
23234 }
23235 protected function pStmt_TraitUse(Stmt\TraitUse $node): string
23236 {
23237 return 'use ' . $this->pCommaSeparated($node->traits) . (empty($node->adaptations) ? ';' : ' {' . $this->pStmts($node->adaptations) . $this->nl . '}');
23238 }
23239 protected function pStmt_TraitUseAdaptation_Precedence(Stmt\TraitUseAdaptation\Precedence $node): string
23240 {
23241 return $this->p($node->trait) . '::' . $node->method . ' insteadof ' . $this->pCommaSeparated($node->insteadof) . ';';
23242 }
23243 protected function pStmt_TraitUseAdaptation_Alias(Stmt\TraitUseAdaptation\Alias $node): string
23244 {
23245 return (null !== $node->trait ? $this->p($node->trait) . '::' : '') . $node->method . ' as' . (null !== $node->newModifier ? ' ' . rtrim($this->pModifiers($node->newModifier), ' ') : '') . (null !== $node->newName ? ' ' . $node->newName : '') . ';';
23246 }
23247 protected function pStmt_Property(Stmt\Property $node): string
23248 {
23249 return $this->pAttrGroups($node->attrGroups) . (0 === $node->flags ? 'var ' : $this->pModifiers($node->flags)) . ($node->type ? $this->p($node->type) . ' ' : '') . $this->pCommaSeparated($node->props) . ($node->hooks ? ' {' . $this->pStmts($node->hooks) . $this->nl . '}' : ';');
23250 }
23251 protected function pPropertyItem(Node\PropertyItem $node): string
23252 {
23253 return '$' . $node->name . (null !== $node->default ? ' = ' . $this->p($node->default) : '');
23254 }
23255 protected function pPropertyHook(Node\PropertyHook $node): string
23256 {
23257 return $this->pAttrGroups($node->attrGroups) . $this->pModifiers($node->flags) . ($node->byRef ? '&' : '') . $node->name . ($node->params ? '(' . $this->pParams($node->params) . ')' : '') . (\is_array($node->body) ? ' {' . $this->pStmts($node->body) . $this->nl . '}' : ($node->body !== null ? ' => ' . $this->p($node->body) : '') . ';');
23258 }
23259 protected function pStmt_ClassMethod(Stmt\ClassMethod $node): string
23260 {
23261 return $this->pAttrGroups($node->attrGroups) . $this->pModifiers($node->flags) . 'function ' . ($node->byRef ? '&' : '') . $node->name . '(' . $this->pParams($node->params) . ')' . (null !== $node->returnType ? ': ' . $this->p($node->returnType) : '') . (null !== $node->stmts ? $this->nl . '{' . $this->pStmts($node->stmts) . $this->nl . '}' : ';');
23262 }
23263 protected function pStmt_ClassConst(Stmt\ClassConst $node): string
23264 {
23265 return $this->pAttrGroups($node->attrGroups) . $this->pModifiers($node->flags) . 'const ' . (null !== $node->type ? $this->p($node->type) . ' ' : '') . $this->pCommaSeparated($node->consts) . ';';
23266 }
23267 protected function pStmt_Function(Stmt\Function_ $node): string
23268 {
23269 return $this->pAttrGroups($node->attrGroups) . 'function ' . ($node->byRef ? '&' : '') . $node->name . '(' . $this->pParams($node->params) . ')' . (null !== $node->returnType ? ': ' . $this->p($node->returnType) : '') . $this->nl . '{' . $this->pStmts($node->stmts) . $this->nl . '}';
23270 }
23271 protected function pStmt_Const(Stmt\Const_ $node): string
23272 {
23273 return $this->pAttrGroups($node->attrGroups) . 'const ' . $this->pCommaSeparated($node->consts) . ';';
23274 }
23275 protected function pStmt_Declare(Stmt\Declare_ $node): string
23276 {
23277 return 'declare (' . $this->pCommaSeparated($node->declares) . ')' . (null !== $node->stmts ? ' {' . $this->pStmts($node->stmts) . $this->nl . '}' : ';');
23278 }
23279 protected function pDeclareItem(Node\DeclareItem $node): string
23280 {
23281 return $node->key . '=' . $this->p($node->value);
23282 }
23283 // Control flow
23284 protected function pStmt_If(Stmt\If_ $node): string
23285 {
23286 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) : '');
23287 }
23288 protected function pStmt_ElseIf(Stmt\ElseIf_ $node): string
23289 {
23290 return 'elseif (' . $this->p($node->cond) . ') {' . $this->pStmts($node->stmts) . $this->nl . '}';
23291 }
23292 protected function pStmt_Else(Stmt\Else_ $node): string
23293 {
23294 if (\count($node->stmts) === 1 && $node->stmts[0] instanceof Stmt\If_) {
23295 // Print as "else if" rather than "else { if }"
23296 return 'else ' . $this->p($node->stmts[0]);
23297 }
23298 return 'else {' . $this->pStmts($node->stmts) . $this->nl . '}';
23299 }
23300 protected function pStmt_For(Stmt\For_ $node): string
23301 {
23302 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 . '}';
23303 }
23304 protected function pStmt_Foreach(Stmt\Foreach_ $node): string
23305 {
23306 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 . '}';
23307 }
23308 protected function pStmt_While(Stmt\While_ $node): string
23309 {
23310 return 'while (' . $this->p($node->cond) . ') {' . $this->pStmts($node->stmts) . $this->nl . '}';
23311 }
23312 protected function pStmt_Do(Stmt\Do_ $node): string
23313 {
23314 return 'do {' . $this->pStmts($node->stmts) . $this->nl . '} while (' . $this->p($node->cond) . ');';
23315 }
23316 protected function pStmt_Switch(Stmt\Switch_ $node): string
23317 {
23318 return 'switch (' . $this->p($node->cond) . ') {' . $this->pStmts($node->cases) . $this->nl . '}';
23319 }
23320 protected function pStmt_Case(Stmt\Case_ $node): string
23321 {
23322 return (null !== $node->cond ? 'case ' . $this->p($node->cond) : 'default') . ':' . $this->pStmts($node->stmts);
23323 }
23324 protected function pStmt_TryCatch(Stmt\TryCatch $node): string
23325 {
23326 return 'try {' . $this->pStmts($node->stmts) . $this->nl . '}' . ($node->catches ? ' ' . $this->pImplode($node->catches, ' ') : '') . ($node->finally !== null ? ' ' . $this->p($node->finally) : '');
23327 }
23328 protected function pStmt_Catch(Stmt\Catch_ $node): string
23329 {
23330 return 'catch (' . $this->pImplode($node->types, '|') . ($node->var !== null ? ' ' . $this->p($node->var) : '') . ') {' . $this->pStmts($node->stmts) . $this->nl . '}';
23331 }
23332 protected function pStmt_Finally(Stmt\Finally_ $node): string
23333 {
23334 return 'finally {' . $this->pStmts($node->stmts) . $this->nl . '}';
23335 }
23336 protected function pStmt_Break(Stmt\Break_ $node): string
23337 {
23338 return 'break' . ($node->num !== null ? ' ' . $this->p($node->num) : '') . ';';
23339 }
23340 protected function pStmt_Continue(Stmt\Continue_ $node): string
23341 {
23342 return 'continue' . ($node->num !== null ? ' ' . $this->p($node->num) : '') . ';';
23343 }
23344 protected function pStmt_Return(Stmt\Return_ $node): string
23345 {
23346 return 'return' . (null !== $node->expr ? ' ' . $this->p($node->expr) : '') . ';';
23347 }
23348 protected function pStmt_Label(Stmt\Label $node): string
23349 {
23350 return $node->name . ':';
23351 }
23352 protected function pStmt_Goto(Stmt\Goto_ $node): string
23353 {
23354 return 'goto ' . $node->name . ';';
23355 }
23356 // Other
23357 protected function pStmt_Expression(Stmt\Expression $node): string
23358 {
23359 return $this->p($node->expr) . ';';
23360 }
23361 protected function pStmt_Echo(Stmt\Echo_ $node): string
23362 {
23363 return 'echo ' . $this->pCommaSeparated($node->exprs) . ';';
23364 }
23365 protected function pStmt_Static(Stmt\Static_ $node): string
23366 {
23367 return 'static ' . $this->pCommaSeparated($node->vars) . ';';
23368 }
23369 protected function pStmt_Global(Stmt\Global_ $node): string
23370 {
23371 return 'global ' . $this->pCommaSeparated($node->vars) . ';';
23372 }
23373 protected function pStaticVar(Node\StaticVar $node): string
23374 {
23375 return $this->p($node->var) . (null !== $node->default ? ' = ' . $this->p($node->default) : '');
23376 }
23377 protected function pStmt_Unset(Stmt\Unset_ $node): string
23378 {
23379 return 'unset(' . $this->pCommaSeparated($node->vars) . ');';
23380 }
23381 protected function pStmt_InlineHTML(Stmt\InlineHTML $node): string
23382 {
23383 $newline = $node->getAttribute('hasLeadingNewline', \true) ? $this->newline : '';
23384 return '?>' . $newline . $node->value . '<?php ';
23385 }
23386 protected function pStmt_HaltCompiler(Stmt\HaltCompiler $node): string
23387 {
23388 return '__halt_compiler();' . $node->remaining;
23389 }
23390 protected function pStmt_Nop(Stmt\Nop $node): string
23391 {
23392 return '';
23393 }
23394 protected function pStmt_Block(Stmt\Block $node): string
23395 {
23396 return '{' . $this->pStmts($node->stmts) . $this->nl . '}';
23397 }
23398 // Helpers
23399 protected function pClassCommon(Stmt\Class_ $node, string $afterClassToken): string
23400 {
23401 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 . '}';
23402 }
23403 protected function pObjectProperty(Node $node): string
23404 {
23405 if ($node instanceof Expr) {
23406 return '{' . $this->p($node) . '}';
23407 } else {
23408 assert($node instanceof Node\Identifier);
23409 return $node->name;
23410 }
23411 }
23412 /** @param (Expr|Node\InterpolatedStringPart)[] $encapsList */
23413 protected function pEncapsList(array $encapsList, ?string $quote): string
23414 {
23415 $return = '';
23416 foreach ($encapsList as $element) {
23417 if ($element instanceof Node\InterpolatedStringPart) {
23418 $return .= $this->escapeString($element->value, $quote);
23419 } else {
23420 $return .= '{' . $this->p($element) . '}';
23421 }
23422 }
23423 return $return;
23424 }
23425 protected function pSingleQuotedString(string $string): string
23426 {
23427 // It is idiomatic to only escape backslashes when necessary, i.e. when followed by ', \ or
23428 // the end of the string ('Foo\Bar' instead of 'Foo\\Bar'). However, we also don't want to
23429 // produce an odd number of backslashes, so '\\\\a' should not get rendered as '\\\a', even
23430 // though that would be legal.
23431 $regex = '/\'|\\\\(?=[\'\\\\]|$)|(?<=\\\\)\\\\/';
23432 return '\'' . preg_replace($regex, '\\\\$0', $string) . '\'';
23433 }
23434 protected function escapeString(string $string, ?string $quote): string
23435 {
23436 if (null === $quote) {
23437 // For doc strings, don't escape newlines
23438 $escaped = addcslashes($string, "\t\f\v\$\\");
23439 // But do escape isolated \r. Combined with the terminating newline, it might get
23440 // interpreted as \r\n and dropped from the string contents.
23441 $escaped = preg_replace('/\r(?!\n)/', '\r', $escaped);
23442 if ($this->phpVersion->supportsFlexibleHeredoc()) {
23443 $escaped = $this->indentString($escaped);
23444 }
23445 } else {
23446 $escaped = addcslashes($string, "\n\r\t\f\v\$" . $quote . "\\");
23447 }
23448 // Escape control characters and non-UTF-8 characters.
23449 // Regex based on https://stackoverflow.com/a/11709412/385378.
23450 $regex = '/(
23451 [\x00-\x08\x0E-\x1F] # Control characters
23452 | [\xC0-\xC1] # Invalid UTF-8 Bytes
23453 | [\xF5-\xFF] # Invalid UTF-8 Bytes
23454 | \xE0(?=[\x80-\x9F]) # Overlong encoding of prior code point
23455 | \xF0(?=[\x80-\x8F]) # Overlong encoding of prior code point
23456 | [\xC2-\xDF](?![\x80-\xBF]) # Invalid UTF-8 Sequence Start
23457 | [\xE0-\xEF](?![\x80-\xBF]{2}) # Invalid UTF-8 Sequence Start
23458 | [\xF0-\xF4](?![\x80-\xBF]{3}) # Invalid UTF-8 Sequence Start
23459 | (?<=[\x00-\x7F\xF5-\xFF])[\x80-\xBF] # Invalid UTF-8 Sequence Middle
23460 | (?<![\xC2-\xDF]|[\xE0-\xEF]|[\xE0-\xEF][\x80-\xBF]|[\xF0-\xF4]|[\xF0-\xF4][\x80-\xBF]|[\xF0-\xF4][\x80-\xBF]{2})[\x80-\xBF] # Overlong Sequence
23461 | (?<=[\xE0-\xEF])[\x80-\xBF](?![\x80-\xBF]) # Short 3 byte sequence
23462 | (?<=[\xF0-\xF4])[\x80-\xBF](?![\x80-\xBF]{2}) # Short 4 byte sequence
23463 | (?<=[\xF0-\xF4][\x80-\xBF])[\x80-\xBF](?![\x80-\xBF]) # Short 4 byte sequence (2)
23464 )/x';
23465 return preg_replace_callback($regex, function ($matches): string {
23466 assert(strlen($matches[0]) === 1);
23467 $hex = dechex(ord($matches[0]));
23468 return '\x' . str_pad($hex, 2, '0', \STR_PAD_LEFT);
23469 }, $escaped);
23470 }
23471 protected function containsEndLabel(string $string, string $label, bool $atStart = \true): bool
23472 {
23473 $start = $atStart ? '(?:^|[\r\n])[ \t]*' : '[\r\n][ \t]*';
23474 return \false !== strpos($string, $label) && preg_match('/' . $start . $label . '(?:$|[^_A-Za-z0-9\x80-\xff])/', $string);
23475 }
23476 /** @param (Expr|Node\InterpolatedStringPart)[] $parts */
23477 protected function encapsedContainsEndLabel(array $parts, string $label): bool
23478 {
23479 foreach ($parts as $i => $part) {
23480 if ($part instanceof Node\InterpolatedStringPart && $this->containsEndLabel($this->escapeString($part->value, null), $label, $i === 0)) {
23481 return \true;
23482 }
23483 }
23484 return \false;
23485 }
23486 protected function pDereferenceLhs(Node $node): string
23487 {
23488 if (!$this->dereferenceLhsRequiresParens($node)) {
23489 return $this->p($node);
23490 } else {
23491 return '(' . $this->p($node) . ')';
23492 }
23493 }
23494 protected function pStaticDereferenceLhs(Node $node): string
23495 {
23496 if (!$this->staticDereferenceLhsRequiresParens($node)) {
23497 return $this->p($node);
23498 } else {
23499 return '(' . $this->p($node) . ')';
23500 }
23501 }
23502 protected function pCallLhs(Node $node): string
23503 {
23504 if (!$this->callLhsRequiresParens($node)) {
23505 return $this->p($node);
23506 } else {
23507 return '(' . $this->p($node) . ')';
23508 }
23509 }
23510 protected function pNewOperand(Node $node): string
23511 {
23512 if (!$this->newOperandRequiresParens($node)) {
23513 return $this->p($node);
23514 } else {
23515 return '(' . $this->p($node) . ')';
23516 }
23517 }
23518 /**
23519 * @param Node[] $nodes
23520 */
23521 protected function hasNodeWithComments(array $nodes): bool
23522 {
23523 foreach ($nodes as $node) {
23524 if ($node && $node->getComments()) {
23525 return \true;
23526 }
23527 }
23528 return \false;
23529 }
23530 /** @param Node[] $nodes */
23531 protected function pMaybeMultiline(array $nodes, bool $trailingComma = \false): string
23532 {
23533 if (!$this->hasNodeWithComments($nodes)) {
23534 return $this->pCommaSeparated($nodes);
23535 } else {
23536 return $this->pCommaSeparatedMultiline($nodes, $trailingComma) . $this->nl;
23537 }
23538 }
23539 /** @param Node\Param[] $params
23540 */
23541 private function hasParamWithAttributes(array $params): bool
23542 {
23543 foreach ($params as $param) {
23544 if ($param->attrGroups) {
23545 return \true;
23546 }
23547 }
23548 return \false;
23549 }
23550 /** @param Node\Param[] $params */
23551 protected function pParams(array $params): string
23552 {
23553 if ($this->hasNodeWithComments($params) || $this->hasParamWithAttributes($params) && !$this->phpVersion->supportsAttributes()) {
23554 return $this->pCommaSeparatedMultiline($params, $this->phpVersion->supportsTrailingCommaInParamList()) . $this->nl;
23555 }
23556 return $this->pCommaSeparated($params);
23557 }
23558 /** @param Node\AttributeGroup[] $nodes */
23559 protected function pAttrGroups(array $nodes, bool $inline = \false): string
23560 {
23561 $result = '';
23562 $sep = $inline ? ' ' : $this->nl;
23563 foreach ($nodes as $node) {
23564 $result .= $this->p($node) . $sep;
23565 }
23566 return $result;
23567 }
23568 }
23569 <?php
23570
23571 declare (strict_types=1);
23572 namespace PHPUnitPHAR\PhpParser;
23573
23574 use PHPUnitPHAR\PhpParser\Internal\DiffElem;
23575 use PHPUnitPHAR\PhpParser\Internal\Differ;
23576 use PHPUnitPHAR\PhpParser\Internal\PrintableNewAnonClassNode;
23577 use PHPUnitPHAR\PhpParser\Internal\TokenStream;
23578 use PHPUnitPHAR\PhpParser\Node\AttributeGroup;
23579 use PHPUnitPHAR\PhpParser\Node\Expr;
23580 use PHPUnitPHAR\PhpParser\Node\Expr\AssignOp;
23581 use PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp;
23582 use PHPUnitPHAR\PhpParser\Node\Expr\Cast;
23583 use PHPUnitPHAR\PhpParser\Node\IntersectionType;
23584 use PHPUnitPHAR\PhpParser\Node\MatchArm;
23585 use PHPUnitPHAR\PhpParser\Node\Param;
23586 use PHPUnitPHAR\PhpParser\Node\PropertyHook;
23587 use PHPUnitPHAR\PhpParser\Node\Scalar;
23588 use PHPUnitPHAR\PhpParser\Node\Stmt;
23589 use PHPUnitPHAR\PhpParser\Node\UnionType;
23590 abstract class PrettyPrinterAbstract implements PrettyPrinter
23591 {
23592 protected const FIXUP_PREC_LEFT = 0;
23593 // LHS operand affected by precedence
23594 protected const FIXUP_PREC_RIGHT = 1;
23595 // RHS operand affected by precedence
23596 protected const FIXUP_PREC_UNARY = 2;
23597 // Only operand affected by precedence
23598 protected const FIXUP_CALL_LHS = 3;
23599 // LHS of call
23600 protected const FIXUP_DEREF_LHS = 4;
23601 // LHS of dereferencing operation
23602 protected const FIXUP_STATIC_DEREF_LHS = 5;
23603 // LHS of static dereferencing operation
23604 protected const FIXUP_BRACED_NAME = 6;
23605 // Name operand that may require bracing
23606 protected const FIXUP_VAR_BRACED_NAME = 7;
23607 // Name operand that may require ${} bracing
23608 protected const FIXUP_ENCAPSED = 8;
23609 // Encapsed string part
23610 protected const FIXUP_NEW = 9;
23611 // New/instanceof operand
23612 protected const MAX_PRECEDENCE = 1000;
23613 /** @var array<class-string, array{int, int, int}> */
23614 protected array $precedenceMap = [
23615 // [precedence, precedenceLHS, precedenceRHS]
23616 // Where the latter two are the precedences to use for the LHS and RHS of a binary operator,
23617 // where 1 is added to one of the sides depending on associativity. This information is not
23618 // used for unary operators and set to -1.
23619 Expr\Clone_::class => [-10, 0, 1],
23620 BinaryOp\Pow::class => [0, 0, 1],
23621 Expr\BitwiseNot::class => [10, -1, -1],
23622 Expr\UnaryPlus::class => [10, -1, -1],
23623 Expr\UnaryMinus::class => [10, -1, -1],
23624 Cast\Int_::class => [10, -1, -1],
23625 Cast\Double::class => [10, -1, -1],
23626 Cast\String_::class => [10, -1, -1],
23627 Cast\Array_::class => [10, -1, -1],
23628 Cast\Object_::class => [10, -1, -1],
23629 Cast\Bool_::class => [10, -1, -1],
23630 Cast\Unset_::class => [10, -1, -1],
23631 Expr\ErrorSuppress::class => [10, -1, -1],
23632 Expr\Instanceof_::class => [20, -1, -1],
23633 Expr\BooleanNot::class => [30, -1, -1],
23634 BinaryOp\Mul::class => [40, 41, 40],
23635 BinaryOp\Div::class => [40, 41, 40],
23636 BinaryOp\Mod::class => [40, 41, 40],
23637 BinaryOp\Plus::class => [50, 51, 50],
23638 BinaryOp\Minus::class => [50, 51, 50],
23639 // FIXME: This precedence is incorrect for PHP 8.
23640 BinaryOp\Concat::class => [50, 51, 50],
23641 BinaryOp\ShiftLeft::class => [60, 61, 60],
23642 BinaryOp\ShiftRight::class => [60, 61, 60],
23643 BinaryOp\Pipe::class => [65, 66, 65],
23644 BinaryOp\Smaller::class => [70, 70, 70],
23645 BinaryOp\SmallerOrEqual::class => [70, 70, 70],
23646 BinaryOp\Greater::class => [70, 70, 70],
23647 BinaryOp\GreaterOrEqual::class => [70, 70, 70],
23648 BinaryOp\Equal::class => [80, 80, 80],
23649 BinaryOp\NotEqual::class => [80, 80, 80],
23650 BinaryOp\Identical::class => [80, 80, 80],
23651 BinaryOp\NotIdentical::class => [80, 80, 80],
23652 BinaryOp\Spaceship::class => [80, 80, 80],
23653 BinaryOp\BitwiseAnd::class => [90, 91, 90],
23654 BinaryOp\BitwiseXor::class => [100, 101, 100],
23655 BinaryOp\BitwiseOr::class => [110, 111, 110],
23656 BinaryOp\BooleanAnd::class => [120, 121, 120],
23657 BinaryOp\BooleanOr::class => [130, 131, 130],
23658 BinaryOp\Coalesce::class => [140, 140, 141],
23659 Expr\Ternary::class => [150, 150, 150],
23660 Expr\Assign::class => [160, -1, -1],
23661 Expr\AssignRef::class => [160, -1, -1],
23662 AssignOp\Plus::class => [160, -1, -1],
23663 AssignOp\Minus::class => [160, -1, -1],
23664 AssignOp\Mul::class => [160, -1, -1],
23665 AssignOp\Div::class => [160, -1, -1],
23666 AssignOp\Concat::class => [160, -1, -1],
23667 AssignOp\Mod::class => [160, -1, -1],
23668 AssignOp\BitwiseAnd::class => [160, -1, -1],
23669 AssignOp\BitwiseOr::class => [160, -1, -1],
23670 AssignOp\BitwiseXor::class => [160, -1, -1],
23671 AssignOp\ShiftLeft::class => [160, -1, -1],
23672 AssignOp\ShiftRight::class => [160, -1, -1],
23673 AssignOp\Pow::class => [160, -1, -1],
23674 AssignOp\Coalesce::class => [160, -1, -1],
23675 Expr\YieldFrom::class => [170, -1, -1],
23676 Expr\Yield_::class => [175, -1, -1],
23677 Expr\Print_::class => [180, -1, -1],
23678 BinaryOp\LogicalAnd::class => [190, 191, 190],
23679 BinaryOp\LogicalXor::class => [200, 201, 200],
23680 BinaryOp\LogicalOr::class => [210, 211, 210],
23681 Expr\Include_::class => [220, -1, -1],
23682 Expr\ArrowFunction::class => [230, -1, -1],
23683 Expr\Throw_::class => [240, -1, -1],
23684 Expr\Cast\Void_::class => [250, -1, -1],
23685 ];
23686 /** @var int Current indentation level. */
23687 protected int $indentLevel;
23688 /** @var string String for single level of indentation */
23689 private string $indent;
23690 /** @var int Width in spaces to indent by. */
23691 private int $indentWidth;
23692 /** @var bool Whether to use tab indentation. */
23693 private bool $useTabs;
23694 /** @var int Width in spaces of one tab. */
23695 private int $tabWidth = 4;
23696 /** @var string Newline style. Does not include current indentation. */
23697 protected string $newline;
23698 /** @var string Newline including current indentation. */
23699 protected string $nl;
23700 /** @var string|null Token placed at end of doc string to ensure it is followed by a newline.
23701 * Null if flexible doc strings are used. */
23702 protected ?string $docStringEndToken;
23703 /** @var bool Whether semicolon namespaces can be used (i.e. no global namespace is used) */
23704 protected bool $canUseSemicolonNamespaces;
23705 /** @var bool Whether to use short array syntax if the node specifies no preference */
23706 protected bool $shortArraySyntax;
23707 /** @var PhpVersion PHP version to target */
23708 protected PhpVersion $phpVersion;
23709 /** @var TokenStream|null Original tokens for use in format-preserving pretty print */
23710 protected ?TokenStream $origTokens;
23711 /** @var Internal\Differ<Node> Differ for node lists */
23712 protected Differ $nodeListDiffer;
23713 /** @var array<string, bool> Map determining whether a certain character is a label character */
23714 protected array $labelCharMap;
23715 /**
23716 * @var array<string, array<string, int>> Map from token classes and subnode names to FIXUP_* constants.
23717 * This is used during format-preserving prints to place additional parens/braces if necessary.
23718 */
23719 protected array $fixupMap;
23720 /**
23721 * @var array<string, array{left?: int|string, right?: int|string}> Map from "{$node->getType()}->{$subNode}"
23722 * to ['left' => $l, 'right' => $r], where $l and $r specify the token type that needs to be stripped
23723 * when removing this node.
23724 */
23725 protected array $removalMap;
23726 /**
23727 * @var array<string, array{int|string|null, bool, string|null, string|null}> Map from
23728 * "{$node->getType()}->{$subNode}" to [$find, $beforeToken, $extraLeft, $extraRight].
23729 * $find is an optional token after which the insertion occurs. $extraLeft/Right
23730 * are optionally added before/after the main insertions.
23731 */
23732 protected array $insertionMap;
23733 /**
23734 * @var array<string, string> Map From "{$class}->{$subNode}" to string that should be inserted
23735 * between elements of this list subnode.
23736 */
23737 protected array $listInsertionMap;
23738 /**
23739 * @var array<string, array{int|string|null, string, string}>
23740 */
23741 protected array $emptyListInsertionMap;
23742 /** @var array<string, array{string, int, int}>
23743 * Map from "{$class}->{$subNode}" to [$printFn, $skipToken, $findToken] where $printFn is the function to
23744 * print the modifiers, $skipToken is the token to skip at the start and $findToken is the token before which
23745 * the modifiers should be reprinted. */
23746 protected array $modifierChangeMap;
23747 /**
23748 * Creates a pretty printer instance using the given options.
23749 *
23750 * Supported options:
23751 * * PhpVersion $phpVersion: The PHP version to target (default to PHP 7.4). This option
23752 * controls compatibility of the generated code with older PHP
23753 * versions in cases where a simple stylistic choice exists (e.g.
23754 * array() vs []). It is safe to pretty-print an AST for a newer
23755 * PHP version while specifying an older target (but the result will
23756 * of course not be compatible with the older version in that case).
23757 * * string $newline: The newline style to use. Should be "\n" (default) or "\r\n".
23758 * * string $indent: The indentation to use. Should either be all spaces or a single
23759 * tab. Defaults to four spaces (" ").
23760 * * bool $shortArraySyntax: Whether to use [] instead of array() as the default array
23761 * syntax, if the node does not specify a format. Defaults to whether
23762 * the phpVersion support short array syntax.
23763 *
23764 * @param array{
23765 * phpVersion?: PhpVersion, newline?: string, indent?: string, shortArraySyntax?: bool
23766 * } $options Dictionary of formatting options
23767 */
23768 public function __construct(array $options = [])
23769 {
23770 $this->phpVersion = $options['phpVersion'] ?? PhpVersion::fromComponents(7, 4);
23771 $this->newline = $options['newline'] ?? "\n";
23772 if ($this->newline !== "\n" && $this->newline != "\r\n") {
23773 throw new \LogicException('Option "newline" must be one of "\n" or "\r\n"');
23774 }
23775 $this->shortArraySyntax = $options['shortArraySyntax'] ?? $this->phpVersion->supportsShortArraySyntax();
23776 $this->docStringEndToken = $this->phpVersion->supportsFlexibleHeredoc() ? null : '_DOC_STRING_END_' . mt_rand();
23777 $this->indent = $indent = $options['indent'] ?? ' ';
23778 if ($indent === "\t") {
23779 $this->useTabs = \true;
23780 $this->indentWidth = $this->tabWidth;
23781 } elseif ($indent === \str_repeat(' ', \strlen($indent))) {
23782 $this->useTabs = \false;
23783 $this->indentWidth = \strlen($indent);
23784 } else {
23785 throw new \LogicException('Option "indent" must either be all spaces or a single tab');
23786 }
23787 }
23788 /**
23789 * Reset pretty printing state.
23790 */
23791 protected function resetState(): void
23792 {
23793 $this->indentLevel = 0;
23794 $this->nl = $this->newline;
23795 $this->origTokens = null;
23796 }
23797 /**
23798 * Set indentation level
23799 *
23800 * @param int $level Level in number of spaces
23801 */
23802 protected function setIndentLevel(int $level): void
23803 {
23804 $this->indentLevel = $level;
23805 if ($this->useTabs) {
23806 $tabs = \intdiv($level, $this->tabWidth);
23807 $spaces = $level % $this->tabWidth;
23808 $this->nl = $this->newline . \str_repeat("\t", $tabs) . \str_repeat(' ', $spaces);
23809 } else {
23810 $this->nl = $this->newline . \str_repeat(' ', $level);
23811 }
23812 }
23813 /**
23814 * Increase indentation level.
23815 */
23816 protected function indent(): void
23817 {
23818 $this->indentLevel += $this->indentWidth;
23819 $this->nl .= $this->indent;
23820 }
23821 /**
23822 * Decrease indentation level.
23823 */
23824 protected function outdent(): void
23825 {
23826 assert($this->indentLevel >= $this->indentWidth);
23827 $this->setIndentLevel($this->indentLevel - $this->indentWidth);
23828 }
23829 /**
23830 * Pretty prints an array of statements.
23831 *
23832 * @param Node[] $stmts Array of statements
23833 *
23834 * @return string Pretty printed statements
23835 */
23836 public function prettyPrint(array $stmts): string
23837 {
23838 $this->resetState();
23839 $this->preprocessNodes($stmts);
23840 return ltrim($this->handleMagicTokens($this->pStmts($stmts, \false)));
23841 }
23842 /**
23843 * Pretty prints an expression.
23844 *
23845 * @param Expr $node Expression node
23846 *
23847 * @return string Pretty printed node
23848 */
23849 public function prettyPrintExpr(Expr $node): string
23850 {
23851 $this->resetState();
23852 return $this->handleMagicTokens($this->p($node));
23853 }
23854 /**
23855 * Pretty prints a file of statements (includes the opening <?php tag if it is required).
23856 *
23857 * @param Node[] $stmts Array of statements
23858 *
23859 * @return string Pretty printed statements
23860 */
23861 public function prettyPrintFile(array $stmts): string
23862 {
23863 if (!$stmts) {
23864 return "<?php" . $this->newline . $this->newline;
23865 }
23866 $p = "<?php" . $this->newline . $this->newline . $this->prettyPrint($stmts);
23867 if ($stmts[0] instanceof Stmt\InlineHTML) {
23868 $p = preg_replace('/^<\?php\s+\?>\r?\n?/', '', $p);
23869 }
23870 if ($stmts[count($stmts) - 1] instanceof Stmt\InlineHTML) {
23871 $p = preg_replace('/<\?php$/', '', rtrim($p));
23872 }
23873 return $p;
23874 }
23875 /**
23876 * Preprocesses the top-level nodes to initialize pretty printer state.
23877 *
23878 * @param Node[] $nodes Array of nodes
23879 */
23880 protected function preprocessNodes(array $nodes): void
23881 {
23882 /* We can use semicolon-namespaces unless there is a global namespace declaration */
23883 $this->canUseSemicolonNamespaces = \true;
23884 foreach ($nodes as $node) {
23885 if ($node instanceof Stmt\Namespace_ && null === $node->name) {
23886 $this->canUseSemicolonNamespaces = \false;
23887 break;
23888 }
23889 }
23890 }
23891 /**
23892 * Handles (and removes) doc-string-end tokens.
23893 */
23894 protected function handleMagicTokens(string $str): string
23895 {
23896 if ($this->docStringEndToken !== null) {
23897 // Replace doc-string-end tokens with nothing or a newline
23898 $str = str_replace($this->docStringEndToken . ';' . $this->newline, ';' . $this->newline, $str);
23899 $str = str_replace($this->docStringEndToken, $this->newline, $str);
23900 }
23901 return $str;
23902 }
23903 /**
23904 * Pretty prints an array of nodes (statements) and indents them optionally.
23905 *
23906 * @param Node[] $nodes Array of nodes
23907 * @param bool $indent Whether to indent the printed nodes
23908 *
23909 * @return string Pretty printed statements
23910 */
23911 protected function pStmts(array $nodes, bool $indent = \true): string
23912 {
23913 if ($indent) {
23914 $this->indent();
23915 }
23916 $result = '';
23917 foreach ($nodes as $node) {
23918 $comments = $node->getComments();
23919 if ($comments) {
23920 $result .= $this->nl . $this->pComments($comments);
23921 if ($node instanceof Stmt\Nop) {
23922 continue;
23923 }
23924 }
23925 $result .= $this->nl . $this->p($node);
23926 }
23927 if ($indent) {
23928 $this->outdent();
23929 }
23930 return $result;
23931 }
23932 /**
23933 * Pretty-print an infix operation while taking precedence into account.
23934 *
23935 * @param string $class Node class of operator
23936 * @param Node $leftNode Left-hand side node
23937 * @param string $operatorString String representation of the operator
23938 * @param Node $rightNode Right-hand side node
23939 * @param int $precedence Precedence of parent operator
23940 * @param int $lhsPrecedence Precedence for unary operator on LHS of binary operator
23941 *
23942 * @return string Pretty printed infix operation
23943 */
23944 protected function pInfixOp(string $class, Node $leftNode, string $operatorString, Node $rightNode, int $precedence, int $lhsPrecedence): string
23945 {
23946 list($opPrecedence, $newPrecedenceLHS, $newPrecedenceRHS) = $this->precedenceMap[$class];
23947 $prefix = '';
23948 $suffix = '';
23949 if ($opPrecedence >= $precedence) {
23950 $prefix = '(';
23951 $suffix = ')';
23952 $lhsPrecedence = self::MAX_PRECEDENCE;
23953 }
23954 return $prefix . $this->p($leftNode, $newPrecedenceLHS, $newPrecedenceLHS) . $operatorString . $this->p($rightNode, $newPrecedenceRHS, $lhsPrecedence) . $suffix;
23955 }
23956 /**
23957 * Pretty-print a prefix operation while taking precedence into account.
23958 *
23959 * @param string $class Node class of operator
23960 * @param string $operatorString String representation of the operator
23961 * @param Node $node Node
23962 * @param int $precedence Precedence of parent operator
23963 * @param int $lhsPrecedence Precedence for unary operator on LHS of binary operator
23964 *
23965 * @return string Pretty printed prefix operation
23966 */
23967 protected function pPrefixOp(string $class, string $operatorString, Node $node, int $precedence, int $lhsPrecedence): string
23968 {
23969 $opPrecedence = $this->precedenceMap[$class][0];
23970 $prefix = '';
23971 $suffix = '';
23972 if ($opPrecedence >= $lhsPrecedence) {
23973 $prefix = '(';
23974 $suffix = ')';
23975 $lhsPrecedence = self::MAX_PRECEDENCE;
23976 }
23977 $printedArg = $this->p($node, $opPrecedence, $lhsPrecedence);
23978 if ($operatorString === '+' && $printedArg[0] === '+' || $operatorString === '-' && $printedArg[0] === '-') {
23979 // Avoid printing +(+$a) as ++$a and similar.
23980 $printedArg = '(' . $printedArg . ')';
23981 }
23982 return $prefix . $operatorString . $printedArg . $suffix;
23983 }
23984 /**
23985 * Pretty-print a postfix operation while taking precedence into account.
23986 *
23987 * @param string $class Node class of operator
23988 * @param string $operatorString String representation of the operator
23989 * @param Node $node Node
23990 * @param int $precedence Precedence of parent operator
23991 * @param int $lhsPrecedence Precedence for unary operator on LHS of binary operator
23992 *
23993 * @return string Pretty printed postfix operation
23994 */
23995 protected function pPostfixOp(string $class, Node $node, string $operatorString, int $precedence, int $lhsPrecedence): string
23996 {
23997 $opPrecedence = $this->precedenceMap[$class][0];
23998 $prefix = '';
23999 $suffix = '';
24000 if ($opPrecedence >= $precedence) {
24001 $prefix = '(';
24002 $suffix = ')';
24003 $lhsPrecedence = self::MAX_PRECEDENCE;
24004 }
24005 if ($opPrecedence < $lhsPrecedence) {
24006 $lhsPrecedence = $opPrecedence;
24007 }
24008 return $prefix . $this->p($node, $opPrecedence, $lhsPrecedence) . $operatorString . $suffix;
24009 }
24010 /**
24011 * Pretty prints an array of nodes and implodes the printed values.
24012 *
24013 * @param Node[] $nodes Array of Nodes to be printed
24014 * @param string $glue Character to implode with
24015 *
24016 * @return string Imploded pretty printed nodes> $pre
24017 */
24018 protected function pImplode(array $nodes, string $glue = ''): string
24019 {
24020 $pNodes = [];
24021 foreach ($nodes as $node) {
24022 if (null === $node) {
24023 $pNodes[] = '';
24024 } else {
24025 $pNodes[] = $this->p($node);
24026 }
24027 }
24028 return implode($glue, $pNodes);
24029 }
24030 /**
24031 * Pretty prints an array of nodes and implodes the printed values with commas.
24032 *
24033 * @param Node[] $nodes Array of Nodes to be printed
24034 *
24035 * @return string Comma separated pretty printed nodes
24036 */
24037 protected function pCommaSeparated(array $nodes): string
24038 {
24039 return $this->pImplode($nodes, ', ');
24040 }
24041 /**
24042 * Pretty prints a comma-separated list of nodes in multiline style, including comments.
24043 *
24044 * The result includes a leading newline and one level of indentation (same as pStmts).
24045 *
24046 * @param Node[] $nodes Array of Nodes to be printed
24047 * @param bool $trailingComma Whether to use a trailing comma
24048 *
24049 * @return string Comma separated pretty printed nodes in multiline style
24050 */
24051 protected function pCommaSeparatedMultiline(array $nodes, bool $trailingComma): string
24052 {
24053 $this->indent();
24054 $result = '';
24055 $lastIdx = count($nodes) - 1;
24056 foreach ($nodes as $idx => $node) {
24057 if ($node !== null) {
24058 $comments = $node->getComments();
24059 if ($comments) {
24060 $result .= $this->nl . $this->pComments($comments);
24061 }
24062 $result .= $this->nl . $this->p($node);
24063 } else {
24064 $result .= $this->nl;
24065 }
24066 if ($trailingComma || $idx !== $lastIdx) {
24067 $result .= ',';
24068 }
24069 }
24070 $this->outdent();
24071 return $result;
24072 }
24073 /**
24074 * Prints reformatted text of the passed comments.
24075 *
24076 * @param Comment[] $comments List of comments
24077 *
24078 * @return string Reformatted text of comments
24079 */
24080 protected function pComments(array $comments): string
24081 {
24082 $formattedComments = [];
24083 foreach ($comments as $comment) {
24084 $formattedComments[] = str_replace("\n", $this->nl, $comment->getReformattedText());
24085 }
24086 return implode($this->nl, $formattedComments);
24087 }
24088 /**
24089 * Perform a format-preserving pretty print of an AST.
24090 *
24091 * The format preservation is best effort. For some changes to the AST the formatting will not
24092 * be preserved (at least not locally).
24093 *
24094 * In order to use this method a number of prerequisites must be satisfied:
24095 * * The startTokenPos and endTokenPos attributes in the lexer must be enabled.
24096 * * The CloningVisitor must be run on the AST prior to modification.
24097 * * The original tokens must be provided, using the getTokens() method on the lexer.
24098 *
24099 * @param Node[] $stmts Modified AST with links to original AST
24100 * @param Node[] $origStmts Original AST with token offset information
24101 * @param Token[] $origTokens Tokens of the original code
24102 */
24103 public function printFormatPreserving(array $stmts, array $origStmts, array $origTokens): string
24104 {
24105 $this->initializeNodeListDiffer();
24106 $this->initializeLabelCharMap();
24107 $this->initializeFixupMap();
24108 $this->initializeRemovalMap();
24109 $this->initializeInsertionMap();
24110 $this->initializeListInsertionMap();
24111 $this->initializeEmptyListInsertionMap();
24112 $this->initializeModifierChangeMap();
24113 $this->resetState();
24114 $this->origTokens = new TokenStream($origTokens, $this->tabWidth);
24115 $this->preprocessNodes($stmts);
24116 $pos = 0;
24117 $result = $this->pArray($stmts, $origStmts, $pos, 0, 'File', 'stmts', null);
24118 if (null !== $result) {
24119 $result .= $this->origTokens->getTokenCode($pos, count($origTokens) - 1, 0);
24120 } else {
24121 // Fallback
24122 // TODO Add <?php properly
24123 $result = "<?php" . $this->newline . $this->pStmts($stmts, \false);
24124 }
24125 return $this->handleMagicTokens($result);
24126 }
24127 protected function pFallback(Node $node, int $precedence, int $lhsPrecedence): string
24128 {
24129 return $this->{'p' . $node->getType()}($node, $precedence, $lhsPrecedence);
24130 }
24131 /**
24132 * Pretty prints a node.
24133 *
24134 * This method also handles formatting preservation for nodes.
24135 *
24136 * @param Node $node Node to be pretty printed
24137 * @param int $precedence Precedence of parent operator
24138 * @param int $lhsPrecedence Precedence for unary operator on LHS of binary operator
24139 * @param bool $parentFormatPreserved Whether parent node has preserved formatting
24140 *
24141 * @return string Pretty printed node
24142 */
24143 protected function p(Node $node, int $precedence = self::MAX_PRECEDENCE, int $lhsPrecedence = self::MAX_PRECEDENCE, bool $parentFormatPreserved = \false): string
24144 {
24145 // No orig tokens means this is a normal pretty print without preservation of formatting
24146 if (!$this->origTokens) {
24147 return $this->{'p' . $node->getType()}($node, $precedence, $lhsPrecedence);
24148 }
24149 /** @var Node|null $origNode */
24150 $origNode = $node->getAttribute('origNode');
24151 if (null === $origNode) {
24152 return $this->pFallback($node, $precedence, $lhsPrecedence);
24153 }
24154 $class = \get_class($node);
24155 \assert($class === \get_class($origNode));
24156 $startPos = $origNode->getStartTokenPos();
24157 $endPos = $origNode->getEndTokenPos();
24158 \assert($startPos >= 0 && $endPos >= 0);
24159 $fallbackNode = $node;
24160 if ($node instanceof Expr\New_ && $node->class instanceof Stmt\Class_) {
24161 // Normalize node structure of anonymous classes
24162 assert($origNode instanceof Expr\New_);
24163 $node = PrintableNewAnonClassNode::fromNewNode($node);
24164 $origNode = PrintableNewAnonClassNode::fromNewNode($origNode);
24165 $class = PrintableNewAnonClassNode::class;
24166 }
24167 // InlineHTML node does not contain closing and opening PHP tags. If the parent formatting
24168 // is not preserved, then we need to use the fallback code to make sure the tags are
24169 // printed.
24170 if ($node instanceof Stmt\InlineHTML && !$parentFormatPreserved) {
24171 return $this->pFallback($fallbackNode, $precedence, $lhsPrecedence);
24172 }
24173 $indentAdjustment = $this->indentLevel - $this->origTokens->getIndentationBefore($startPos);
24174 $type = $node->getType();
24175 $fixupInfo = $this->fixupMap[$class] ?? null;
24176 $result = '';
24177 $pos = $startPos;
24178 foreach ($node->getSubNodeNames() as $subNodeName) {
24179 $subNode = $node->{$subNodeName};
24180 $origSubNode = $origNode->{$subNodeName};
24181 if (!$subNode instanceof Node && $subNode !== null || !$origSubNode instanceof Node && $origSubNode !== null) {
24182 if ($subNode === $origSubNode) {
24183 // Unchanged, can reuse old code
24184 continue;
24185 }
24186 if (is_array($subNode) && is_array($origSubNode)) {
24187 // Array subnode changed, we might be able to reconstruct it
24188 $listResult = $this->pArray($subNode, $origSubNode, $pos, $indentAdjustment, $class, $subNodeName, $fixupInfo[$subNodeName] ?? null);
24189 if (null === $listResult) {
24190 return $this->pFallback($fallbackNode, $precedence, $lhsPrecedence);
24191 }
24192 $result .= $listResult;
24193 continue;
24194 }
24195 // Check if this is a modifier change
24196 $key = $class . '->' . $subNodeName;
24197 if (!isset($this->modifierChangeMap[$key])) {
24198 return $this->pFallback($fallbackNode, $precedence, $lhsPrecedence);
24199 }
24200 [$printFn, $skipToken, $findToken] = $this->modifierChangeMap[$key];
24201 $skipWSPos = $this->origTokens->skipRight($pos, $skipToken);
24202 $result .= $this->origTokens->getTokenCode($pos, $skipWSPos, $indentAdjustment);
24203 $result .= $this->{$printFn}($subNode);
24204 $pos = $this->origTokens->findRight($skipWSPos, $findToken);
24205 continue;
24206 }
24207 $extraLeft = '';
24208 $extraRight = '';
24209 if ($origSubNode !== null) {
24210 $subStartPos = $origSubNode->getStartTokenPos();
24211 $subEndPos = $origSubNode->getEndTokenPos();
24212 \assert($subStartPos >= 0 && $subEndPos >= 0);
24213 } else {
24214 if ($subNode === null) {
24215 // Both null, nothing to do
24216 continue;
24217 }
24218 // A node has been inserted, check if we have insertion information for it
24219 $key = $type . '->' . $subNodeName;
24220 if (!isset($this->insertionMap[$key])) {
24221 return $this->pFallback($fallbackNode, $precedence, $lhsPrecedence);
24222 }
24223 list($findToken, $beforeToken, $extraLeft, $extraRight) = $this->insertionMap[$key];
24224 if (null !== $findToken) {
24225 $subStartPos = $this->origTokens->findRight($pos, $findToken) + (int) !$beforeToken;
24226 } else {
24227 $subStartPos = $pos;
24228 }
24229 if (null === $extraLeft && null !== $extraRight) {
24230 // If inserting on the right only, skipping whitespace looks better
24231 $subStartPos = $this->origTokens->skipRightWhitespace($subStartPos);
24232 }
24233 $subEndPos = $subStartPos - 1;
24234 }
24235 if (null === $subNode) {
24236 // A node has been removed, check if we have removal information for it
24237 $key = $type . '->' . $subNodeName;
24238 if (!isset($this->removalMap[$key])) {
24239 return $this->pFallback($fallbackNode, $precedence, $lhsPrecedence);
24240 }
24241 // Adjust positions to account for additional tokens that must be skipped
24242 $removalInfo = $this->removalMap[$key];
24243 if (isset($removalInfo['left'])) {
24244 $subStartPos = $this->origTokens->skipLeft($subStartPos - 1, $removalInfo['left']) + 1;
24245 }
24246 if (isset($removalInfo['right'])) {
24247 $subEndPos = $this->origTokens->skipRight($subEndPos + 1, $removalInfo['right']) - 1;
24248 }
24249 }
24250 $result .= $this->origTokens->getTokenCode($pos, $subStartPos, $indentAdjustment);
24251 if (null !== $subNode) {
24252 $result .= $extraLeft;
24253 $origIndentLevel = $this->indentLevel;
24254 $this->setIndentLevel(max($this->origTokens->getIndentationBefore($subStartPos) + $indentAdjustment, 0));
24255 // If it's the same node that was previously in this position, it certainly doesn't
24256 // need fixup. It's important to check this here, because our fixup checks are more
24257 // conservative than strictly necessary.
24258 if (isset($fixupInfo[$subNodeName]) && $subNode->getAttribute('origNode') !== $origSubNode) {
24259 $fixup = $fixupInfo[$subNodeName];
24260 $res = $this->pFixup($fixup, $subNode, $class, $subStartPos, $subEndPos);
24261 } else {
24262 $res = $this->p($subNode, self::MAX_PRECEDENCE, self::MAX_PRECEDENCE, \true);
24263 }
24264 $this->safeAppend($result, $res);
24265 $this->setIndentLevel($origIndentLevel);
24266 $result .= $extraRight;
24267 }
24268 $pos = $subEndPos + 1;
24269 }
24270 $result .= $this->origTokens->getTokenCode($pos, $endPos + 1, $indentAdjustment);
24271 return $result;
24272 }
24273 /**
24274 * Perform a format-preserving pretty print of an array.
24275 *
24276 * @param Node[] $nodes New nodes
24277 * @param Node[] $origNodes Original nodes
24278 * @param int $pos Current token position (updated by reference)
24279 * @param int $indentAdjustment Adjustment for indentation
24280 * @param string $parentNodeClass Class of the containing node.
24281 * @param string $subNodeName Name of array subnode.
24282 * @param null|int $fixup Fixup information for array item nodes
24283 *
24284 * @return null|string Result of pretty print or null if cannot preserve formatting
24285 */
24286 protected function pArray(array $nodes, array $origNodes, int &$pos, int $indentAdjustment, string $parentNodeClass, string $subNodeName, ?int $fixup): ?string
24287 {
24288 $diff = $this->nodeListDiffer->diffWithReplacements($origNodes, $nodes);
24289 $mapKey = $parentNodeClass . '->' . $subNodeName;
24290 $insertStr = $this->listInsertionMap[$mapKey] ?? null;
24291 $isStmtList = $subNodeName === 'stmts';
24292 $beforeFirstKeepOrReplace = \true;
24293 $skipRemovedNode = \false;
24294 $delayedAdd = [];
24295 $lastElemIndentLevel = $this->indentLevel;
24296 $insertNewline = \false;
24297 if ($insertStr === "\n") {
24298 $insertStr = '';
24299 $insertNewline = \true;
24300 }
24301 if ($isStmtList && \count($origNodes) === 1 && \count($nodes) !== 1) {
24302 $startPos = $origNodes[0]->getStartTokenPos();
24303 $endPos = $origNodes[0]->getEndTokenPos();
24304 \assert($startPos >= 0 && $endPos >= 0);
24305 if (!$this->origTokens->haveBraces($startPos, $endPos)) {
24306 // This was a single statement without braces, but either additional statements
24307 // have been added, or the single statement has been removed. This requires the
24308 // addition of braces. For now fall back.
24309 // TODO: Try to preserve formatting
24310 return null;
24311 }
24312 }
24313 $result = '';
24314 foreach ($diff as $i => $diffElem) {
24315 $diffType = $diffElem->type;
24316 /** @var Node|string|null $arrItem */
24317 $arrItem = $diffElem->new;
24318 /** @var Node|string|null $origArrItem */
24319 $origArrItem = $diffElem->old;
24320 if ($diffType === DiffElem::TYPE_KEEP || $diffType === DiffElem::TYPE_REPLACE) {
24321 $beforeFirstKeepOrReplace = \false;
24322 if ($origArrItem === null || $arrItem === null) {
24323 // We can only handle the case where both are null
24324 if ($origArrItem === $arrItem) {
24325 continue;
24326 }
24327 return null;
24328 }
24329 if (!$arrItem instanceof Node || !$origArrItem instanceof Node) {
24330 // We can only deal with nodes. This can occur for Names, which use string arrays.
24331 return null;
24332 }
24333 $itemStartPos = $origArrItem->getStartTokenPos();
24334 $itemEndPos = $origArrItem->getEndTokenPos();
24335 \assert($itemStartPos >= 0 && $itemEndPos >= 0 && $itemStartPos >= $pos);
24336 $origIndentLevel = $this->indentLevel;
24337 $lastElemIndentLevel = max($this->origTokens->getIndentationBefore($itemStartPos) + $indentAdjustment, 0);
24338 $this->setIndentLevel($lastElemIndentLevel);
24339 $comments = $arrItem->getComments();
24340 $origComments = $origArrItem->getComments();
24341 $commentStartPos = $origComments ? $origComments[0]->getStartTokenPos() : $itemStartPos;
24342 \assert($commentStartPos >= 0);
24343 if ($commentStartPos < $pos) {
24344 // Comments may be assigned to multiple nodes if they start at the same position.
24345 // Make sure we don't try to print them multiple times.
24346 $commentStartPos = $itemStartPos;
24347 }
24348 if ($skipRemovedNode) {
24349 if ($isStmtList && $this->origTokens->haveTagInRange($pos, $itemStartPos)) {
24350 // We'd remove an opening/closing PHP tag.
24351 // TODO: Preserve formatting.
24352 $this->setIndentLevel($origIndentLevel);
24353 return null;
24354 }
24355 } else {
24356 $result .= $this->origTokens->getTokenCode($pos, $commentStartPos, $indentAdjustment);
24357 }
24358 if (!empty($delayedAdd)) {
24359 /** @var Node $delayedAddNode */
24360 foreach ($delayedAdd as $delayedAddNode) {
24361 if ($insertNewline) {
24362 $delayedAddComments = $delayedAddNode->getComments();
24363 if ($delayedAddComments) {
24364 $result .= $this->pComments($delayedAddComments) . $this->nl;
24365 }
24366 }
24367 $this->safeAppend($result, $this->p($delayedAddNode, self::MAX_PRECEDENCE, self::MAX_PRECEDENCE, \true));
24368 if ($insertNewline) {
24369 $result .= $insertStr . $this->nl;
24370 } else {
24371 $result .= $insertStr;
24372 }
24373 }
24374 $delayedAdd = [];
24375 }
24376 if ($comments !== $origComments) {
24377 if ($comments) {
24378 $result .= $this->pComments($comments) . $this->nl;
24379 }
24380 } else {
24381 $result .= $this->origTokens->getTokenCode($commentStartPos, $itemStartPos, $indentAdjustment);
24382 }
24383 // If we had to remove anything, we have done so now.
24384 $skipRemovedNode = \false;
24385 } elseif ($diffType === DiffElem::TYPE_ADD) {
24386 if (null === $insertStr) {
24387 // We don't have insertion information for this list type
24388 return null;
24389 }
24390 if (!$arrItem instanceof Node) {
24391 // We only support list insertion of nodes.
24392 return null;
24393 }
24394 // We go multiline if the original code was multiline,
24395 // or if it's an array item with a comment above it.
24396 // Match always uses multiline formatting.
24397 if ($insertStr === ', ' && ($this->isMultiline($origNodes) || $arrItem->getComments() || $parentNodeClass === Expr\Match_::class)) {
24398 $insertStr = ',';
24399 $insertNewline = \true;
24400 }
24401 if ($beforeFirstKeepOrReplace) {
24402 // Will be inserted at the next "replace" or "keep" element
24403 $delayedAdd[] = $arrItem;
24404 continue;
24405 }
24406 $itemStartPos = $pos;
24407 $itemEndPos = $pos - 1;
24408 $origIndentLevel = $this->indentLevel;
24409 $this->setIndentLevel($lastElemIndentLevel);
24410 if ($insertNewline) {
24411 $result .= $insertStr . $this->nl;
24412 $comments = $arrItem->getComments();
24413 if ($comments) {
24414 $result .= $this->pComments($comments) . $this->nl;
24415 }
24416 } else {
24417 $result .= $insertStr;
24418 }
24419 } elseif ($diffType === DiffElem::TYPE_REMOVE) {
24420 if (!$origArrItem instanceof Node) {
24421 // We only support removal for nodes
24422 return null;
24423 }
24424 $itemStartPos = $origArrItem->getStartTokenPos();
24425 $itemEndPos = $origArrItem->getEndTokenPos();
24426 \assert($itemStartPos >= 0 && $itemEndPos >= 0);
24427 // Consider comments part of the node.
24428 $origComments = $origArrItem->getComments();
24429 if ($origComments) {
24430 $itemStartPos = $origComments[0]->getStartTokenPos();
24431 }
24432 if ($i === 0) {
24433 // If we're removing from the start, keep the tokens before the node and drop those after it,
24434 // instead of the other way around.
24435 $result .= $this->origTokens->getTokenCode($pos, $itemStartPos, $indentAdjustment);
24436 $skipRemovedNode = \true;
24437 } else if ($isStmtList && $this->origTokens->haveTagInRange($pos, $itemStartPos)) {
24438 // We'd remove an opening/closing PHP tag.
24439 // TODO: Preserve formatting.
24440 return null;
24441 }
24442 $pos = $itemEndPos + 1;
24443 continue;
24444 } else {
24445 throw new \Exception("Shouldn't happen");
24446 }
24447 if (null !== $fixup && $arrItem->getAttribute('origNode') !== $origArrItem) {
24448 $res = $this->pFixup($fixup, $arrItem, null, $itemStartPos, $itemEndPos);
24449 } else {
24450 $res = $this->p($arrItem, self::MAX_PRECEDENCE, self::MAX_PRECEDENCE, \true);
24451 }
24452 $this->safeAppend($result, $res);
24453 $this->setIndentLevel($origIndentLevel);
24454 $pos = $itemEndPos + 1;
24455 }
24456 if ($skipRemovedNode) {
24457 // TODO: Support removing single node.
24458 return null;
24459 }
24460 if (!empty($delayedAdd)) {
24461 if (!isset($this->emptyListInsertionMap[$mapKey])) {
24462 return null;
24463 }
24464 list($findToken, $extraLeft, $extraRight) = $this->emptyListInsertionMap[$mapKey];
24465 if (null !== $findToken) {
24466 $insertPos = $this->origTokens->findRight($pos, $findToken) + 1;
24467 $result .= $this->origTokens->getTokenCode($pos, $insertPos, $indentAdjustment);
24468 $pos = $insertPos;
24469 }
24470 $first = \true;
24471 $result .= $extraLeft;
24472 foreach ($delayedAdd as $delayedAddNode) {
24473 if (!$first) {
24474 $result .= $insertStr;
24475 if ($insertNewline) {
24476 $result .= $this->nl;
24477 }
24478 }
24479 $result .= $this->p($delayedAddNode, self::MAX_PRECEDENCE, self::MAX_PRECEDENCE, \true);
24480 $first = \false;
24481 }
24482 $result .= $extraRight === "\n" ? $this->nl : $extraRight;
24483 }
24484 return $result;
24485 }
24486 /**
24487 * Print node with fixups.
24488 *
24489 * Fixups here refer to the addition of extra parentheses, braces or other characters, that
24490 * are required to preserve program semantics in a certain context (e.g. to maintain precedence
24491 * or because only certain expressions are allowed in certain places).
24492 *
24493 * @param int $fixup Fixup type
24494 * @param Node $subNode Subnode to print
24495 * @param string|null $parentClass Class of parent node
24496 * @param int $subStartPos Original start pos of subnode
24497 * @param int $subEndPos Original end pos of subnode
24498 *
24499 * @return string Result of fixed-up print of subnode
24500 */
24501 protected function pFixup(int $fixup, Node $subNode, ?string $parentClass, int $subStartPos, int $subEndPos): string
24502 {
24503 switch ($fixup) {
24504 case self::FIXUP_PREC_LEFT:
24505 // We use a conservative approximation where lhsPrecedence == precedence.
24506 if (!$this->origTokens->haveParens($subStartPos, $subEndPos)) {
24507 $precedence = $this->precedenceMap[$parentClass][1];
24508 return $this->p($subNode, $precedence, $precedence);
24509 }
24510 break;
24511 case self::FIXUP_PREC_RIGHT:
24512 if (!$this->origTokens->haveParens($subStartPos, $subEndPos)) {
24513 $precedence = $this->precedenceMap[$parentClass][2];
24514 return $this->p($subNode, $precedence, $precedence);
24515 }
24516 break;
24517 case self::FIXUP_PREC_UNARY:
24518 if (!$this->origTokens->haveParens($subStartPos, $subEndPos)) {
24519 $precedence = $this->precedenceMap[$parentClass][0];
24520 return $this->p($subNode, $precedence, $precedence);
24521 }
24522 break;
24523 case self::FIXUP_CALL_LHS:
24524 if ($this->callLhsRequiresParens($subNode) && !$this->origTokens->haveParens($subStartPos, $subEndPos)) {
24525 return '(' . $this->p($subNode) . ')';
24526 }
24527 break;
24528 case self::FIXUP_DEREF_LHS:
24529 if ($this->dereferenceLhsRequiresParens($subNode) && !$this->origTokens->haveParens($subStartPos, $subEndPos)) {
24530 return '(' . $this->p($subNode) . ')';
24531 }
24532 break;
24533 case self::FIXUP_STATIC_DEREF_LHS:
24534 if ($this->staticDereferenceLhsRequiresParens($subNode) && !$this->origTokens->haveParens($subStartPos, $subEndPos)) {
24535 return '(' . $this->p($subNode) . ')';
24536 }
24537 break;
24538 case self::FIXUP_NEW:
24539 if ($this->newOperandRequiresParens($subNode) && !$this->origTokens->haveParens($subStartPos, $subEndPos)) {
24540 return '(' . $this->p($subNode) . ')';
24541 }
24542 break;
24543 case self::FIXUP_BRACED_NAME:
24544 case self::FIXUP_VAR_BRACED_NAME:
24545 if ($subNode instanceof Expr && !$this->origTokens->haveBraces($subStartPos, $subEndPos)) {
24546 return ($fixup === self::FIXUP_VAR_BRACED_NAME ? '$' : '') . '{' . $this->p($subNode) . '}';
24547 }
24548 break;
24549 case self::FIXUP_ENCAPSED:
24550 if (!$subNode instanceof Node\InterpolatedStringPart && !$this->origTokens->haveBraces($subStartPos, $subEndPos)) {
24551 return '{' . $this->p($subNode) . '}';
24552 }
24553 break;
24554 default:
24555 throw new \Exception('Cannot happen');
24556 }
24557 // Nothing special to do
24558 return $this->p($subNode);
24559 }
24560 /**
24561 * Appends to a string, ensuring whitespace between label characters.
24562 *
24563 * Example: "echo" and "$x" result in "echo$x", but "echo" and "x" result in "echo x".
24564 * Without safeAppend the result would be "echox", which does not preserve semantics.
24565 */
24566 protected function safeAppend(string &$str, string $append): void
24567 {
24568 if ($str === "") {
24569 $str = $append;
24570 return;
24571 }
24572 if ($append === "") {
24573 return;
24574 }
24575 if (!$this->labelCharMap[$append[0]] || !$this->labelCharMap[$str[\strlen($str) - 1]]) {
24576 $str .= $append;
24577 } else {
24578 $str .= " " . $append;
24579 }
24580 }
24581 /**
24582 * Determines whether the LHS of a call must be wrapped in parenthesis.
24583 *
24584 * @param Node $node LHS of a call
24585 *
24586 * @return bool Whether parentheses are required
24587 */
24588 protected function callLhsRequiresParens(Node $node): bool
24589 {
24590 if ($node instanceof Expr\New_) {
24591 return !$this->phpVersion->supportsNewDereferenceWithoutParentheses();
24592 }
24593 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_);
24594 }
24595 /**
24596 * Determines whether the LHS of an array/object operation must be wrapped in parentheses.
24597 *
24598 * @param Node $node LHS of dereferencing operation
24599 *
24600 * @return bool Whether parentheses are required
24601 */
24602 protected function dereferenceLhsRequiresParens(Node $node): bool
24603 {
24604 // A constant can occur on the LHS of an array/object deref, but not a static deref.
24605 return $this->staticDereferenceLhsRequiresParens($node) && !$node instanceof Expr\ConstFetch;
24606 }
24607 /**
24608 * Determines whether the LHS of a static operation must be wrapped in parentheses.
24609 *
24610 * @param Node $node LHS of dereferencing operation
24611 *
24612 * @return bool Whether parentheses are required
24613 */
24614 protected function staticDereferenceLhsRequiresParens(Node $node): bool
24615 {
24616 if ($node instanceof Expr\New_) {
24617 return !$this->phpVersion->supportsNewDereferenceWithoutParentheses();
24618 }
24619 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);
24620 }
24621 /**
24622 * Determines whether an expression used in "new" or "instanceof" requires parentheses.
24623 *
24624 * @param Node $node New or instanceof operand
24625 *
24626 * @return bool Whether parentheses are required
24627 */
24628 protected function newOperandRequiresParens(Node $node): bool
24629 {
24630 if ($node instanceof Node\Name || $node instanceof Expr\Variable) {
24631 return \false;
24632 }
24633 if ($node instanceof Expr\ArrayDimFetch || $node instanceof Expr\PropertyFetch || $node instanceof Expr\NullsafePropertyFetch) {
24634 return $this->newOperandRequiresParens($node->var);
24635 }
24636 if ($node instanceof Expr\StaticPropertyFetch) {
24637 return $this->newOperandRequiresParens($node->class);
24638 }
24639 return \true;
24640 }
24641 /**
24642 * Print modifiers, including trailing whitespace.
24643 *
24644 * @param int $modifiers Modifier mask to print
24645 *
24646 * @return string Printed modifiers
24647 */
24648 protected function pModifiers(int $modifiers): string
24649 {
24650 return ($modifiers & Modifiers::FINAL ? 'final ' : '') . ($modifiers & Modifiers::ABSTRACT ? 'abstract ' : '') . ($modifiers & Modifiers::PUBLIC ? 'public ' : '') . ($modifiers & Modifiers::PROTECTED ? 'protected ' : '') . ($modifiers & Modifiers::PRIVATE ? 'private ' : '') . ($modifiers & Modifiers::PUBLIC_SET ? 'public(set) ' : '') . ($modifiers & Modifiers::PROTECTED_SET ? 'protected(set) ' : '') . ($modifiers & Modifiers::PRIVATE_SET ? 'private(set) ' : '') . ($modifiers & Modifiers::STATIC ? 'static ' : '') . ($modifiers & Modifiers::READONLY ? 'readonly ' : '');
24651 }
24652 protected function pStatic(bool $static): string
24653 {
24654 return $static ? 'static ' : '';
24655 }
24656 /**
24657 * Determine whether a list of nodes uses multiline formatting.
24658 *
24659 * @param (Node|null)[] $nodes Node list
24660 *
24661 * @return bool Whether multiline formatting is used
24662 */
24663 protected function isMultiline(array $nodes): bool
24664 {
24665 if (\count($nodes) < 2) {
24666 return \false;
24667 }
24668 $pos = -1;
24669 foreach ($nodes as $node) {
24670 if (null === $node) {
24671 continue;
24672 }
24673 $endPos = $node->getEndTokenPos() + 1;
24674 if ($pos >= 0) {
24675 $text = $this->origTokens->getTokenCode($pos, $endPos, 0);
24676 if (\false === strpos($text, "\n")) {
24677 // We require that a newline is present between *every* item. If the formatting
24678 // is inconsistent, with only some items having newlines, we don't consider it
24679 // as multiline
24680 return \false;
24681 }
24682 }
24683 $pos = $endPos;
24684 }
24685 return \true;
24686 }
24687 /**
24688 * Lazily initializes label char map.
24689 *
24690 * The label char map determines whether a certain character may occur in a label.
24691 */
24692 protected function initializeLabelCharMap(): void
24693 {
24694 if (isset($this->labelCharMap)) {
24695 return;
24696 }
24697 $this->labelCharMap = [];
24698 for ($i = 0; $i < 256; $i++) {
24699 $chr = chr($i);
24700 $this->labelCharMap[$chr] = $i >= 0x80 || ctype_alnum($chr);
24701 }
24702 if ($this->phpVersion->allowsDelInIdentifiers()) {
24703 $this->labelCharMap[""] = \true;
24704 }
24705 }
24706 /**
24707 * Lazily initializes node list differ.
24708 *
24709 * The node list differ is used to determine differences between two array subnodes.
24710 */
24711 protected function initializeNodeListDiffer(): void
24712 {
24713 if (isset($this->nodeListDiffer)) {
24714 return;
24715 }
24716 $this->nodeListDiffer = new Internal\Differ(function ($a, $b) {
24717 if ($a instanceof Node && $b instanceof Node) {
24718 return $a === $b->getAttribute('origNode');
24719 }
24720 // Can happen for array destructuring
24721 return $a === null && $b === null;
24722 });
24723 }
24724 /**
24725 * Lazily initializes fixup map.
24726 *
24727 * The fixup map is used to determine whether a certain subnode of a certain node may require
24728 * some kind of "fixup" operation, e.g. the addition of parenthesis or braces.
24729 */
24730 protected function initializeFixupMap(): void
24731 {
24732 if (isset($this->fixupMap)) {
24733 return;
24734 }
24735 $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]];
24736 $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, BinaryOp\Pipe::class];
24737 foreach ($binaryOps as $binaryOp) {
24738 $this->fixupMap[$binaryOp] = ['left' => self::FIXUP_PREC_LEFT, 'right' => self::FIXUP_PREC_RIGHT];
24739 }
24740 $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];
24741 foreach ($prefixOps as $prefixOp) {
24742 $this->fixupMap[$prefixOp] = ['expr' => self::FIXUP_PREC_UNARY];
24743 }
24744 }
24745 /**
24746 * Lazily initializes the removal map.
24747 *
24748 * The removal map is used to determine which additional tokens should be removed when a
24749 * certain node is replaced by null.
24750 */
24751 protected function initializeRemovalMap(): void
24752 {
24753 if (isset($this->removalMap)) {
24754 return;
24755 }
24756 $stripBoth = ['left' => \T_WHITESPACE, 'right' => \T_WHITESPACE];
24757 $stripLeft = ['left' => \T_WHITESPACE];
24758 $stripRight = ['right' => \T_WHITESPACE];
24759 $stripDoubleArrow = ['right' => \T_DOUBLE_ARROW];
24760 $stripColon = ['left' => ':'];
24761 $stripEquals = ['left' => '='];
24762 $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];
24763 }
24764 protected function initializeInsertionMap(): void
24765 {
24766 if (isset($this->insertionMap)) {
24767 return;
24768 }
24769 // TODO: "yield" where both key and value are inserted doesn't work
24770 // [$find, $beforeToken, $extraLeft, $extraRight]
24771 $this->insertionMap = [
24772 'Expr_ArrayDimFetch->dim' => ['[', \false, null, null],
24773 'ArrayItem->key' => [null, \false, null, ' => '],
24774 'Expr_ArrowFunction->returnType' => [')', \false, ': ', null],
24775 'Expr_Closure->returnType' => [')', \false, ': ', null],
24776 'Expr_Ternary->if' => ['?', \false, ' ', ' '],
24777 'Expr_Yield->key' => [\T_YIELD, \false, null, ' => '],
24778 'Expr_Yield->value' => [\T_YIELD, \false, ' ', null],
24779 'Param->type' => [null, \false, null, ' '],
24780 'Param->default' => [null, \false, ' = ', null],
24781 'Stmt_Break->num' => [\T_BREAK, \false, ' ', null],
24782 'Stmt_Catch->var' => [null, \false, ' ', null],
24783 'Stmt_ClassMethod->returnType' => [')', \false, ': ', null],
24784 'Stmt_ClassConst->type' => [\T_CONST, \false, ' ', null],
24785 'Stmt_Class->extends' => [null, \false, ' extends ', null],
24786 'Stmt_Enum->scalarType' => [null, \false, ' : ', null],
24787 'Stmt_EnumCase->expr' => [null, \false, ' = ', null],
24788 'Expr_PrintableNewAnonClass->extends' => [null, \false, ' extends ', null],
24789 'Stmt_Continue->num' => [\T_CONTINUE, \false, ' ', null],
24790 'Stmt_Foreach->keyVar' => [\T_AS, \false, null, ' => '],
24791 'Stmt_Function->returnType' => [')', \false, ': ', null],
24792 'Stmt_If->else' => [null, \false, ' ', null],
24793 'Stmt_Namespace->name' => [\T_NAMESPACE, \false, ' ', null],
24794 'Stmt_Property->type' => [\T_VARIABLE, \true, null, ' '],
24795 'PropertyItem->default' => [null, \false, ' = ', null],
24796 'Stmt_Return->expr' => [\T_RETURN, \false, ' ', null],
24797 'Stmt_StaticVar->default' => [null, \false, ' = ', null],
24798 //'Stmt_TraitUseAdaptation_Alias->newName' => [T_AS, false, ' ', null], // TODO
24799 'Stmt_TryCatch->finally' => [null, \false, ' ', null],
24800 ];
24801 }
24802 protected function initializeListInsertionMap(): void
24803 {
24804 if (isset($this->listInsertionMap)) {
24805 return;
24806 }
24807 $this->listInsertionMap = [
24808 // special
24809 //'Expr_ShellExec->parts' => '', // TODO These need to be treated more carefully
24810 //'Scalar_InterpolatedString->parts' => '',
24811 Stmt\Catch_::class . '->types' => '|',
24812 UnionType::class . '->types' => '|',
24813 IntersectionType::class . '->types' => '&',
24814 Stmt\If_::class . '->elseifs' => ' ',
24815 Stmt\TryCatch::class . '->catches' => ' ',
24816 // comma-separated lists
24817 Expr\Array_::class . '->items' => ', ',
24818 Expr\ArrowFunction::class . '->params' => ', ',
24819 Expr\Closure::class . '->params' => ', ',
24820 Expr\Closure::class . '->uses' => ', ',
24821 Expr\FuncCall::class . '->args' => ', ',
24822 Expr\Isset_::class . '->vars' => ', ',
24823 Expr\List_::class . '->items' => ', ',
24824 Expr\MethodCall::class . '->args' => ', ',
24825 Expr\NullsafeMethodCall::class . '->args' => ', ',
24826 Expr\New_::class . '->args' => ', ',
24827 PrintableNewAnonClassNode::class . '->args' => ', ',
24828 Expr\StaticCall::class . '->args' => ', ',
24829 Stmt\ClassConst::class . '->consts' => ', ',
24830 Stmt\ClassMethod::class . '->params' => ', ',
24831 Stmt\Class_::class . '->implements' => ', ',
24832 Stmt\Enum_::class . '->implements' => ', ',
24833 PrintableNewAnonClassNode::class . '->implements' => ', ',
24834 Stmt\Const_::class . '->consts' => ', ',
24835 Stmt\Declare_::class . '->declares' => ', ',
24836 Stmt\Echo_::class . '->exprs' => ', ',
24837 Stmt\For_::class . '->init' => ', ',
24838 Stmt\For_::class . '->cond' => ', ',
24839 Stmt\For_::class . '->loop' => ', ',
24840 Stmt\Function_::class . '->params' => ', ',
24841 Stmt\Global_::class . '->vars' => ', ',
24842 Stmt\GroupUse::class . '->uses' => ', ',
24843 Stmt\Interface_::class . '->extends' => ', ',
24844 Expr\Match_::class . '->arms' => ', ',
24845 Stmt\Property::class . '->props' => ', ',
24846 Stmt\StaticVar::class . '->vars' => ', ',
24847 Stmt\TraitUse::class . '->traits' => ', ',
24848 Stmt\TraitUseAdaptation\Precedence::class . '->insteadof' => ', ',
24849 Stmt\Unset_::class . '->vars' => ', ',
24850 Stmt\UseUse::class . '->uses' => ', ',
24851 MatchArm::class . '->conds' => ', ',
24852 AttributeGroup::class . '->attrs' => ', ',
24853 PropertyHook::class . '->params' => ', ',
24854 // statement lists
24855 Expr\Closure::class . '->stmts' => "\n",
24856 Stmt\Case_::class . '->stmts' => "\n",
24857 Stmt\Catch_::class . '->stmts' => "\n",
24858 Stmt\Class_::class . '->stmts' => "\n",
24859 Stmt\Enum_::class . '->stmts' => "\n",
24860 PrintableNewAnonClassNode::class . '->stmts' => "\n",
24861 Stmt\Interface_::class . '->stmts' => "\n",
24862 Stmt\Trait_::class . '->stmts' => "\n",
24863 Stmt\ClassMethod::class . '->stmts' => "\n",
24864 Stmt\Declare_::class . '->stmts' => "\n",
24865 Stmt\Do_::class . '->stmts' => "\n",
24866 Stmt\ElseIf_::class . '->stmts' => "\n",
24867 Stmt\Else_::class . '->stmts' => "\n",
24868 Stmt\Finally_::class . '->stmts' => "\n",
24869 Stmt\Foreach_::class . '->stmts' => "\n",
24870 Stmt\For_::class . '->stmts' => "\n",
24871 Stmt\Function_::class . '->stmts' => "\n",
24872 Stmt\If_::class . '->stmts' => "\n",
24873 Stmt\Namespace_::class . '->stmts' => "\n",
24874 Stmt\Block::class . '->stmts' => "\n",
24875 // Attribute groups
24876 Stmt\Class_::class . '->attrGroups' => "\n",
24877 Stmt\Enum_::class . '->attrGroups' => "\n",
24878 Stmt\EnumCase::class . '->attrGroups' => "\n",
24879 Stmt\Interface_::class . '->attrGroups' => "\n",
24880 Stmt\Trait_::class . '->attrGroups' => "\n",
24881 Stmt\Function_::class . '->attrGroups' => "\n",
24882 Stmt\ClassMethod::class . '->attrGroups' => "\n",
24883 Stmt\ClassConst::class . '->attrGroups' => "\n",
24884 Stmt\Property::class . '->attrGroups' => "\n",
24885 PrintableNewAnonClassNode::class . '->attrGroups' => ' ',
24886 Expr\Closure::class . '->attrGroups' => ' ',
24887 Expr\ArrowFunction::class . '->attrGroups' => ' ',
24888 Param::class . '->attrGroups' => ' ',
24889 PropertyHook::class . '->attrGroups' => ' ',
24890 Stmt\Switch_::class . '->cases' => "\n",
24891 Stmt\TraitUse::class . '->adaptations' => "\n",
24892 Stmt\TryCatch::class . '->stmts' => "\n",
24893 Stmt\While_::class . '->stmts' => "\n",
24894 PropertyHook::class . '->body' => "\n",
24895 Stmt\Property::class . '->hooks' => "\n",
24896 Param::class . '->hooks' => "\n",
24897 // dummy for top-level context
24898 'File->stmts' => "\n",
24899 ];
24900 }
24901 protected function initializeEmptyListInsertionMap(): void
24902 {
24903 if (isset($this->emptyListInsertionMap)) {
24904 return;
24905 }
24906 // TODO Insertion into empty statement lists.
24907 // [$find, $extraLeft, $extraRight]
24908 $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, '', ' '], Stmt\Const_::class . '->attrGroups' => [null, '', "\n"], PrintableNewAnonClassNode::class . '->attrGroups' => [\T_NEW, ' ', '']];
24909 }
24910 protected function initializeModifierChangeMap(): void
24911 {
24912 if (isset($this->modifierChangeMap)) {
24913 return;
24914 }
24915 $this->modifierChangeMap = [Stmt\ClassConst::class . '->flags' => ['pModifiers', \T_WHITESPACE, \T_CONST], Stmt\ClassMethod::class . '->flags' => ['pModifiers', \T_WHITESPACE, \T_FUNCTION], Stmt\Class_::class . '->flags' => ['pModifiers', \T_WHITESPACE, \T_CLASS], Stmt\Property::class . '->flags' => ['pModifiers', \T_WHITESPACE, \T_VARIABLE], PrintableNewAnonClassNode::class . '->flags' => ['pModifiers', \T_NEW, \T_CLASS], Param::class . '->flags' => ['pModifiers', \T_WHITESPACE, \T_VARIABLE], PropertyHook::class . '->flags' => ['pModifiers', \T_WHITESPACE, \T_STRING], Expr\Closure::class . '->static' => ['pStatic', \T_WHITESPACE, \T_FUNCTION], Expr\ArrowFunction::class . '->static' => ['pStatic', \T_WHITESPACE, \T_FN]];
24916 // List of integer subnodes that are not modifiers:
24917 // Expr_Include->type
24918 // Stmt_GroupUse->type
24919 // Stmt_Use->type
24920 // UseItem->type
24921 }
24922 }
24923 <?php
24924
24925 declare (strict_types=1);
24926 namespace PHPUnitPHAR\PhpParser;
24927
24928 /**
24929 * A PHP token. On PHP 8.0 this extends from PhpToken.
24930 */
24931 class Token extends Internal\TokenPolyfill
24932 {
24933 /** Get (exclusive) zero-based end position of the token. */
24934 public function getEndPos(): int
24935 {
24936 return $this->pos + \strlen($this->text);
24937 }
24938 /** Get 1-based end line number of the token. */
24939 public function getEndLine(): int
24940 {
24941 return $this->line + \substr_count($this->text, "\n");
24942 }
24943 }
24944 <?php
24945
24946 declare (strict_types=1);
24947 namespace PHPUnitPHAR\PhpParser;
24948
24949 if (!\function_exists('PHPUnitPHAR\PhpParser\defineCompatibilityTokens')) {
24950 function defineCompatibilityTokens(): void
24951 {
24952 $compatTokens = [
24953 // PHP 8.0
24954 'T_NAME_QUALIFIED',
24955 'T_NAME_FULLY_QUALIFIED',
24956 'T_NAME_RELATIVE',
24957 'T_MATCH',
24958 'T_NULLSAFE_OBJECT_OPERATOR',
24959 'T_ATTRIBUTE',
24960 // PHP 8.1
24961 'T_ENUM',
24962 'T_AMPERSAND_NOT_FOLLOWED_BY_VAR_OR_VARARG',
24963 'T_AMPERSAND_FOLLOWED_BY_VAR_OR_VARARG',
24964 'T_READONLY',
24965 // PHP 8.4
24966 'T_PROPERTY_C',
24967 'T_PUBLIC_SET',
24968 'T_PROTECTED_SET',
24969 'T_PRIVATE_SET',
24970 // PHP 8.5
24971 'T_PIPE',
24972 'T_VOID_CAST',
24973 ];
24974 // PHP-Parser might be used together with another library that also emulates some or all
24975 // of these tokens. Perform a sanity-check that all already defined tokens have been
24976 // assigned a unique ID.
24977 $usedTokenIds = [];
24978 foreach ($compatTokens as $token) {
24979 if (\defined($token)) {
24980 $tokenId = \constant($token);
24981 if (!\is_int($tokenId)) {
24982 throw new \Error(sprintf('Token %s has ID of type %s, should be int. ' . 'You may be using a library with broken token emulation', $token, \gettype($tokenId)));
24983 }
24984 $clashingToken = $usedTokenIds[$tokenId] ?? null;
24985 if ($clashingToken !== null) {
24986 throw new \Error(sprintf('Token %s has same ID as token %s, ' . 'you may be using a library with broken token emulation', $token, $clashingToken));
24987 }
24988 $usedTokenIds[$tokenId] = $token;
24989 }
24990 }
24991 // Now define any tokens that have not yet been emulated. Try to assign IDs from -1
24992 // downwards, but skip any IDs that may already be in use.
24993 $newTokenId = -1;
24994 foreach ($compatTokens as $token) {
24995 if (!\defined($token)) {
24996 while (isset($usedTokenIds[$newTokenId])) {
24997 $newTokenId--;
24998 }
24999 \define($token, $newTokenId);
25000 $newTokenId--;
25001 }
25002 }
25003 }
25004 defineCompatibilityTokens();
25005 }
25006 BSD 3-Clause License
25007
25008 Copyright (c) 2016-2023, Sebastian Bergmann
25009 All rights reserved.
25010
25011 Redistribution and use in source and binary forms, with or without
25012 modification, are permitted provided that the following conditions are met:
25013
25014 1. Redistributions of source code must retain the above copyright notice, this
25015 list of conditions and the following disclaimer.
25016
25017 2. Redistributions in binary form must reproduce the above copyright notice,
25018 this list of conditions and the following disclaimer in the documentation
25019 and/or other materials provided with the distribution.
25020
25021 3. Neither the name of the copyright holder nor the names of its
25022 contributors may be used to endorse or promote products derived from
25023 this software without specific prior written permission.
25024
25025 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
25026 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25027 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
25028 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
25029 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25030 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25031 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25032 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25033 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25034 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25035 BSD 3-Clause License
25036
25037 Copyright (c) 2017-2023, Sebastian Bergmann
25038 All rights reserved.
25039
25040 Redistribution and use in source and binary forms, with or without
25041 modification, are permitted provided that the following conditions are met:
25042
25043 1. Redistributions of source code must retain the above copyright notice, this
25044 list of conditions and the following disclaimer.
25045
25046 2. Redistributions in binary form must reproduce the above copyright notice,
25047 this list of conditions and the following disclaimer in the documentation
25048 and/or other materials provided with the distribution.
25049
25050 3. Neither the name of the copyright holder nor the names of its
25051 contributors may be used to endorse or promote products derived from
25052 this software without specific prior written permission.
25053
25054 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
25055 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25056 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
25057 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
25058 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25059 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25060 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25061 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25062 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25063 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25064 Phar.io - Manifest
25065
25066 Copyright (c) 2016-2019 Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de>, and contributors
25067 All rights reserved.
25068
25069 Redistribution and use in source and binary forms, with or without modification,
25070 are permitted provided that the following conditions are met:
25071
25072 * Redistributions of source code must retain the above copyright notice,
25073 this list of conditions and the following disclaimer.
25074
25075 * Redistributions in binary form must reproduce the above copyright notice,
25076 this list of conditions and the following disclaimer in the documentation
25077 and/or other materials provided with the distribution.
25078
25079 * Neither the name of Arne Blankerts nor the names of contributors
25080 may be used to endorse or promote products derived from this software
25081 without specific prior written permission.
25082
25083 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
25084 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT * NOT LIMITED TO,
25085 THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
25086 PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
25087 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
25088 OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25089 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25090 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25091 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25092 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25093 POSSIBILITY OF SUCH DAMAGE.
25094
25095 <?php
25096
25097 declare (strict_types=1);
25098 /*
25099 * This file is part of PharIo\Manifest.
25100 *
25101 * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
25102 *
25103 * For the full copyright and license information, please view the LICENSE
25104 * file that was distributed with this source code.
25105 *
25106 */
25107 namespace PHPUnitPHAR\PharIo\Manifest;
25108
25109 use PHPUnitPHAR\PharIo\Version\Exception as VersionException;
25110 use PHPUnitPHAR\PharIo\Version\Version;
25111 use PHPUnitPHAR\PharIo\Version\VersionConstraintParser;
25112 use Throwable;
25113 use function sprintf;
25114 class ManifestDocumentMapper
25115 {
25116 public function map(ManifestDocument $document): Manifest
25117 {
25118 try {
25119 $contains = $document->getContainsElement();
25120 $type = $this->mapType($contains);
25121 $copyright = $this->mapCopyright($document->getCopyrightElement());
25122 $requirements = $this->mapRequirements($document->getRequiresElement());
25123 $bundledComponents = $this->mapBundledComponents($document);
25124 return new Manifest(new ApplicationName($contains->getName()), new Version($contains->getVersion()), $type, $copyright, $requirements, $bundledComponents);
25125 } catch (Throwable $e) {
25126 throw new ManifestDocumentMapperException($e->getMessage(), (int) $e->getCode(), $e);
25127 }
25128 }
25129 private function mapType(ContainsElement $contains): Type
25130 {
25131 switch ($contains->getType()) {
25132 case 'application':
25133 return Type::application();
25134 case 'library':
25135 return Type::library();
25136 case 'extension':
25137 return $this->mapExtension($contains->getExtensionElement());
25138 }
25139 throw new ManifestDocumentMapperException(sprintf('Unsupported type %s', $contains->getType()));
25140 }
25141 private function mapCopyright(CopyrightElement $copyright): CopyrightInformation
25142 {
25143 $authors = new AuthorCollection();
25144 foreach ($copyright->getAuthorElements() as $authorElement) {
25145 $authors->add(new Author($authorElement->getName(), $authorElement->hasEMail() ? new Email($authorElement->getEmail()) : null));
25146 }
25147 $licenseElement = $copyright->getLicenseElement();
25148 $license = new License($licenseElement->getType(), new Url($licenseElement->getUrl()));
25149 return new CopyrightInformation($authors, $license);
25150 }
25151 private function mapRequirements(RequiresElement $requires): RequirementCollection
25152 {
25153 $collection = new RequirementCollection();
25154 $phpElement = $requires->getPHPElement();
25155 $parser = new VersionConstraintParser();
25156 try {
25157 $versionConstraint = $parser->parse($phpElement->getVersion());
25158 } catch (VersionException $e) {
25159 throw new ManifestDocumentMapperException(sprintf('Unsupported version constraint - %s', $e->getMessage()), (int) $e->getCode(), $e);
25160 }
25161 $collection->add(new PhpVersionRequirement($versionConstraint));
25162 if (!$phpElement->hasExtElements()) {
25163 return $collection;
25164 }
25165 foreach ($phpElement->getExtElements() as $extElement) {
25166 $collection->add(new PhpExtensionRequirement($extElement->getName()));
25167 }
25168 return $collection;
25169 }
25170 private function mapBundledComponents(ManifestDocument $document): BundledComponentCollection
25171 {
25172 $collection = new BundledComponentCollection();
25173 if (!$document->hasBundlesElement()) {
25174 return $collection;
25175 }
25176 foreach ($document->getBundlesElement()->getComponentElements() as $componentElement) {
25177 $collection->add(new BundledComponent($componentElement->getName(), new Version($componentElement->getVersion())));
25178 }
25179 return $collection;
25180 }
25181 private function mapExtension(ExtensionElement $extension): Extension
25182 {
25183 try {
25184 $versionConstraint = (new VersionConstraintParser())->parse($extension->getCompatible());
25185 return Type::extension(new ApplicationName($extension->getFor()), $versionConstraint);
25186 } catch (VersionException $e) {
25187 throw new ManifestDocumentMapperException(sprintf('Unsupported version constraint - %s', $e->getMessage()), (int) $e->getCode(), $e);
25188 }
25189 }
25190 }
25191 <?php
25192
25193 declare (strict_types=1);
25194 /*
25195 * This file is part of PharIo\Manifest.
25196 *
25197 * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
25198 *
25199 * For the full copyright and license information, please view the LICENSE
25200 * file that was distributed with this source code.
25201 *
25202 */
25203 namespace PHPUnitPHAR\PharIo\Manifest;
25204
25205 use function sprintf;
25206 class ManifestLoader
25207 {
25208 public static function fromFile(string $filename): Manifest
25209 {
25210 try {
25211 return (new ManifestDocumentMapper())->map(ManifestDocument::fromFile($filename));
25212 } catch (Exception $e) {
25213 throw new ManifestLoaderException(sprintf('Loading %s failed.', $filename), (int) $e->getCode(), $e);
25214 }
25215 }
25216 public static function fromPhar(string $filename): Manifest
25217 {
25218 return self::fromFile('phar://' . $filename . '/manifest.xml');
25219 }
25220 public static function fromString(string $manifest): Manifest
25221 {
25222 try {
25223 return (new ManifestDocumentMapper())->map(ManifestDocument::fromString($manifest));
25224 } catch (Exception $e) {
25225 throw new ManifestLoaderException('Processing string failed', (int) $e->getCode(), $e);
25226 }
25227 }
25228 }
25229 <?php
25230
25231 declare (strict_types=1);
25232 /*
25233 * This file is part of PharIo\Manifest.
25234 *
25235 * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
25236 *
25237 * For the full copyright and license information, please view the LICENSE
25238 * file that was distributed with this source code.
25239 *
25240 */
25241 namespace PHPUnitPHAR\PharIo\Manifest;
25242
25243 use PHPUnitPHAR\PharIo\Version\AnyVersionConstraint;
25244 use PHPUnitPHAR\PharIo\Version\Version;
25245 use PHPUnitPHAR\PharIo\Version\VersionConstraint;
25246 use XMLWriter;
25247 use function count;
25248 use function file_put_contents;
25249 use function str_repeat;
25250 /** @psalm-suppress MissingConstructor */
25251 class ManifestSerializer
25252 {
25253 /** @var XMLWriter */
25254 private $xmlWriter;
25255 public function serializeToFile(Manifest $manifest, string $filename): void
25256 {
25257 file_put_contents($filename, $this->serializeToString($manifest));
25258 }
25259 public function serializeToString(Manifest $manifest): string
25260 {
25261 $this->startDocument();
25262 $this->addContains($manifest->getName(), $manifest->getVersion(), $manifest->getType());
25263 $this->addCopyright($manifest->getCopyrightInformation());
25264 $this->addRequirements($manifest->getRequirements());
25265 $this->addBundles($manifest->getBundledComponents());
25266 return $this->finishDocument();
25267 }
25268 private function startDocument(): void
25269 {
25270 $xmlWriter = new XMLWriter();
25271 $xmlWriter->openMemory();
25272 $xmlWriter->setIndent(\true);
25273 $xmlWriter->setIndentString(str_repeat(' ', 4));
25274 $xmlWriter->startDocument('1.0', 'UTF-8');
25275 $xmlWriter->startElement('phar');
25276 $xmlWriter->writeAttribute('xmlns', 'https://phar.io/xml/manifest/1.0');
25277 $this->xmlWriter = $xmlWriter;
25278 }
25279 private function finishDocument(): string
25280 {
25281 $this->xmlWriter->endElement();
25282 $this->xmlWriter->endDocument();
25283 return $this->xmlWriter->outputMemory();
25284 }
25285 private function addContains(ApplicationName $name, Version $version, Type $type): void
25286 {
25287 $this->xmlWriter->startElement('contains');
25288 $this->xmlWriter->writeAttribute('name', $name->asString());
25289 $this->xmlWriter->writeAttribute('version', $version->getVersionString());
25290 switch (\true) {
25291 case $type->isApplication():
25292 {
25293 $this->xmlWriter->writeAttribute('type', 'application');
25294 break;
25295 }
25296 case $type->isLibrary():
25297 {
25298 $this->xmlWriter->writeAttribute('type', 'library');
25299 break;
25300 }
25301 case $type->isExtension():
25302 {
25303 $this->xmlWriter->writeAttribute('type', 'extension');
25304 /* @var $type Extension */
25305 $this->addExtension($type->getApplicationName(), $type->getVersionConstraint());
25306 break;
25307 }
25308 default:
25309 {
25310 $this->xmlWriter->writeAttribute('type', 'custom');
25311 }
25312 }
25313 $this->xmlWriter->endElement();
25314 }
25315 private function addCopyright(CopyrightInformation $copyrightInformation): void
25316 {
25317 $this->xmlWriter->startElement('copyright');
25318 foreach ($copyrightInformation->getAuthors() as $author) {
25319 $this->xmlWriter->startElement('author');
25320 $this->xmlWriter->writeAttribute('name', $author->getName());
25321 $this->xmlWriter->writeAttribute('email', $author->getEmail()->asString());
25322 $this->xmlWriter->endElement();
25323 }
25324 $license = $copyrightInformation->getLicense();
25325 $this->xmlWriter->startElement('license');
25326 $this->xmlWriter->writeAttribute('type', $license->getName());
25327 $this->xmlWriter->writeAttribute('url', $license->getUrl()->asString());
25328 $this->xmlWriter->endElement();
25329 $this->xmlWriter->endElement();
25330 }
25331 private function addRequirements(RequirementCollection $requirementCollection): void
25332 {
25333 $phpRequirement = new AnyVersionConstraint();
25334 $extensions = [];
25335 foreach ($requirementCollection as $requirement) {
25336 if ($requirement instanceof PhpVersionRequirement) {
25337 $phpRequirement = $requirement->getVersionConstraint();
25338 continue;
25339 }
25340 if ($requirement instanceof PhpExtensionRequirement) {
25341 $extensions[] = $requirement->asString();
25342 }
25343 }
25344 $this->xmlWriter->startElement('requires');
25345 $this->xmlWriter->startElement('php');
25346 $this->xmlWriter->writeAttribute('version', $phpRequirement->asString());
25347 foreach ($extensions as $extension) {
25348 $this->xmlWriter->startElement('ext');
25349 $this->xmlWriter->writeAttribute('name', $extension);
25350 $this->xmlWriter->endElement();
25351 }
25352 $this->xmlWriter->endElement();
25353 $this->xmlWriter->endElement();
25354 }
25355 private function addBundles(BundledComponentCollection $bundledComponentCollection): void
25356 {
25357 if (count($bundledComponentCollection) === 0) {
25358 return;
25359 }
25360 $this->xmlWriter->startElement('bundles');
25361 foreach ($bundledComponentCollection as $bundledComponent) {
25362 $this->xmlWriter->startElement('component');
25363 $this->xmlWriter->writeAttribute('name', $bundledComponent->getName());
25364 $this->xmlWriter->writeAttribute('version', $bundledComponent->getVersion()->getVersionString());
25365 $this->xmlWriter->endElement();
25366 }
25367 $this->xmlWriter->endElement();
25368 }
25369 private function addExtension(ApplicationName $applicationName, VersionConstraint $versionConstraint): void
25370 {
25371 $this->xmlWriter->startElement('extension');
25372 $this->xmlWriter->writeAttribute('for', $applicationName->asString());
25373 $this->xmlWriter->writeAttribute('compatible', $versionConstraint->asString());
25374 $this->xmlWriter->endElement();
25375 }
25376 }
25377 <?php
25378
25379 declare (strict_types=1);
25380 /*
25381 * This file is part of PharIo\Manifest.
25382 *
25383 * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
25384 *
25385 * For the full copyright and license information, please view the LICENSE
25386 * file that was distributed with this source code.
25387 *
25388 */
25389 namespace PHPUnitPHAR\PharIo\Manifest;
25390
25391 use InvalidArgumentException;
25392 class ElementCollectionException extends InvalidArgumentException implements Exception
25393 {
25394 }
25395 <?php
25396
25397 declare (strict_types=1);
25398 /*
25399 * This file is part of PharIo\Manifest.
25400 *
25401 * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
25402 *
25403 * For the full copyright and license information, please view the LICENSE
25404 * file that was distributed with this source code.
25405 *
25406 */
25407 namespace PHPUnitPHAR\PharIo\Manifest;
25408
25409 use Throwable;
25410 interface Exception extends Throwable
25411 {
25412 }
25413 <?php
25414
25415 declare (strict_types=1);
25416 /*
25417 * This file is part of PharIo\Manifest.
25418 *
25419 * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
25420 *
25421 * For the full copyright and license information, please view the LICENSE
25422 * file that was distributed with this source code.
25423 *
25424 */
25425 namespace PHPUnitPHAR\PharIo\Manifest;
25426
25427 use InvalidArgumentException;
25428 class InvalidApplicationNameException extends InvalidArgumentException implements Exception
25429 {
25430 public const InvalidFormat = 2;
25431 }
25432 <?php
25433
25434 declare (strict_types=1);
25435 /*
25436 * This file is part of PharIo\Manifest.
25437 *
25438 * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
25439 *
25440 * For the full copyright and license information, please view the LICENSE
25441 * file that was distributed with this source code.
25442 *
25443 */
25444 namespace PHPUnitPHAR\PharIo\Manifest;
25445
25446 use InvalidArgumentException;
25447 class InvalidEmailException extends InvalidArgumentException implements Exception
25448 {
25449 }
25450 <?php
25451
25452 declare (strict_types=1);
25453 /*
25454 * This file is part of PharIo\Manifest.
25455 *
25456 * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
25457 *
25458 * For the full copyright and license information, please view the LICENSE
25459 * file that was distributed with this source code.
25460 *
25461 */
25462 namespace PHPUnitPHAR\PharIo\Manifest;
25463
25464 use InvalidArgumentException;
25465 class InvalidUrlException extends InvalidArgumentException implements Exception
25466 {
25467 }
25468 <?php
25469
25470 declare (strict_types=1);
25471 /*
25472 * This file is part of PharIo\Manifest.
25473 *
25474 * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
25475 *
25476 * For the full copyright and license information, please view the LICENSE
25477 * file that was distributed with this source code.
25478 *
25479 */
25480 namespace PHPUnitPHAR\PharIo\Manifest;
25481
25482 use RuntimeException;
25483 class ManifestDocumentException extends RuntimeException implements Exception
25484 {
25485 }
25486 <?php
25487
25488 declare (strict_types=1);
25489 /*
25490 * This file is part of PharIo\Manifest.
25491 *
25492 * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
25493 *
25494 * For the full copyright and license information, please view the LICENSE
25495 * file that was distributed with this source code.
25496 *
25497 */
25498 namespace PHPUnitPHAR\PharIo\Manifest;
25499
25500 use LibXMLError;
25501 use function sprintf;
25502 class ManifestDocumentLoadingException extends \Exception implements Exception
25503 {
25504 /** @var LibXMLError[] */
25505 private $libxmlErrors;
25506 /**
25507 * ManifestDocumentLoadingException constructor.
25508 *
25509 * @param LibXMLError[] $libxmlErrors
25510 */
25511 public function __construct(array $libxmlErrors)
25512 {
25513 $this->libxmlErrors = $libxmlErrors;
25514 $first = $this->libxmlErrors[0];
25515 parent::__construct(sprintf('%s (Line: %d / Column: %d / File: %s)', $first->message, $first->line, $first->column, $first->file), $first->code);
25516 }
25517 /**
25518 * @return LibXMLError[]
25519 */
25520 public function getLibxmlErrors(): array
25521 {
25522 return $this->libxmlErrors;
25523 }
25524 }
25525 <?php
25526
25527 declare (strict_types=1);
25528 /*
25529 * This file is part of PharIo\Manifest.
25530 *
25531 * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
25532 *
25533 * For the full copyright and license information, please view the LICENSE
25534 * file that was distributed with this source code.
25535 *
25536 */
25537 namespace PHPUnitPHAR\PharIo\Manifest;
25538
25539 use RuntimeException;
25540 class ManifestDocumentMapperException extends RuntimeException implements Exception
25541 {
25542 }
25543 <?php
25544
25545 declare (strict_types=1);
25546 /*
25547 * This file is part of PharIo\Manifest.
25548 *
25549 * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
25550 *
25551 * For the full copyright and license information, please view the LICENSE
25552 * file that was distributed with this source code.
25553 *
25554 */
25555 namespace PHPUnitPHAR\PharIo\Manifest;
25556
25557 use RuntimeException;
25558 class ManifestElementException extends RuntimeException implements Exception
25559 {
25560 }
25561 <?php
25562
25563 declare (strict_types=1);
25564 /*
25565 * This file is part of PharIo\Manifest.
25566 *
25567 * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
25568 *
25569 * For the full copyright and license information, please view the LICENSE
25570 * file that was distributed with this source code.
25571 *
25572 */
25573 namespace PHPUnitPHAR\PharIo\Manifest;
25574
25575 class ManifestLoaderException extends \Exception implements Exception
25576 {
25577 }
25578 <?php
25579
25580 declare (strict_types=1);
25581 /*
25582 * This file is part of PharIo\Manifest.
25583 *
25584 * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
25585 *
25586 * For the full copyright and license information, please view the LICENSE
25587 * file that was distributed with this source code.
25588 *
25589 */
25590 namespace PHPUnitPHAR\PharIo\Manifest;
25591
25592 use InvalidArgumentException;
25593 class NoEmailAddressException extends InvalidArgumentException implements Exception
25594 {
25595 }
25596 <?php
25597
25598 declare (strict_types=1);
25599 /*
25600 * This file is part of PharIo\Manifest.
25601 *
25602 * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
25603 *
25604 * For the full copyright and license information, please view the LICENSE
25605 * file that was distributed with this source code.
25606 *
25607 */
25608 namespace PHPUnitPHAR\PharIo\Manifest;
25609
25610 class Application extends Type
25611 {
25612 public function isApplication(): bool
25613 {
25614 return \true;
25615 }
25616 }
25617 <?php
25618
25619 declare (strict_types=1);
25620 /*
25621 * This file is part of PharIo\Manifest.
25622 *
25623 * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
25624 *
25625 * For the full copyright and license information, please view the LICENSE
25626 * file that was distributed with this source code.
25627 *
25628 */
25629 namespace PHPUnitPHAR\PharIo\Manifest;
25630
25631 use function preg_match;
25632 use function sprintf;
25633 class ApplicationName
25634 {
25635 /** @var string */
25636 private $name;
25637 public function __construct(string $name)
25638 {
25639 $this->ensureValidFormat($name);
25640 $this->name = $name;
25641 }
25642 public function asString(): string
25643 {
25644 return $this->name;
25645 }
25646 public function isEqual(ApplicationName $name): bool
25647 {
25648 return $this->name === $name->name;
25649 }
25650 private function ensureValidFormat(string $name): void
25651 {
25652 if (!preg_match('#\w/\w#', $name)) {
25653 throw new InvalidApplicationNameException(sprintf('Format of name "%s" is not valid - expected: vendor/packagename', $name), InvalidApplicationNameException::InvalidFormat);
25654 }
25655 }
25656 }
25657 <?php
25658
25659 declare (strict_types=1);
25660 /*
25661 * This file is part of PharIo\Manifest.
25662 *
25663 * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
25664 *
25665 * For the full copyright and license information, please view the LICENSE
25666 * file that was distributed with this source code.
25667 *
25668 */
25669 namespace PHPUnitPHAR\PharIo\Manifest;
25670
25671 use function sprintf;
25672 class Author
25673 {
25674 /** @var string */
25675 private $name;
25676 /** @var null|Email */
25677 private $email;
25678 public function __construct(string $name, ?Email $email = null)
25679 {
25680 $this->name = $name;
25681 $this->email = $email;
25682 }
25683 public function asString(): string
25684 {
25685 if (!$this->hasEmail()) {
25686 return $this->name;
25687 }
25688 return sprintf('%s <%s>', $this->name, $this->email->asString());
25689 }
25690 public function getName(): string
25691 {
25692 return $this->name;
25693 }
25694 /**
25695 * @psalm-assert-if-true Email $this->email
25696 */
25697 public function hasEmail(): bool
25698 {
25699 return $this->email !== null;
25700 }
25701 public function getEmail(): Email
25702 {
25703 if (!$this->hasEmail()) {
25704 throw new NoEmailAddressException();
25705 }
25706 return $this->email;
25707 }
25708 }
25709 <?php
25710
25711 declare (strict_types=1);
25712 /*
25713 * This file is part of PharIo\Manifest.
25714 *
25715 * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
25716 *
25717 * For the full copyright and license information, please view the LICENSE
25718 * file that was distributed with this source code.
25719 *
25720 */
25721 namespace PHPUnitPHAR\PharIo\Manifest;
25722
25723 use Countable;
25724 use IteratorAggregate;
25725 use function count;
25726 /** @template-implements IteratorAggregate<int,Author> */
25727 class AuthorCollection implements Countable, IteratorAggregate
25728 {
25729 /** @var Author[] */
25730 private $authors = [];
25731 public function add(Author $author): void
25732 {
25733 $this->authors[] = $author;
25734 }
25735 /**
25736 * @return Author[]
25737 */
25738 public function getAuthors(): array
25739 {
25740 return $this->authors;
25741 }
25742 public function count(): int
25743 {
25744 return count($this->authors);
25745 }
25746 public function getIterator(): AuthorCollectionIterator
25747 {
25748 return new AuthorCollectionIterator($this);
25749 }
25750 }
25751 <?php
25752
25753 declare (strict_types=1);
25754 /*
25755 * This file is part of PharIo\Manifest.
25756 *
25757 * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
25758 *
25759 * For the full copyright and license information, please view the LICENSE
25760 * file that was distributed with this source code.
25761 *
25762 */
25763 namespace PHPUnitPHAR\PharIo\Manifest;
25764
25765 use Iterator;
25766 use function count;
25767 /** @template-implements Iterator<int,Author> */
25768 class AuthorCollectionIterator implements Iterator
25769 {
25770 /** @var Author[] */
25771 private $authors;
25772 /** @var int */
25773 private $position = 0;
25774 public function __construct(AuthorCollection $authors)
25775 {
25776 $this->authors = $authors->getAuthors();
25777 }
25778 public function rewind(): void
25779 {
25780 $this->position = 0;
25781 }
25782 public function valid(): bool
25783 {
25784 return $this->position < count($this->authors);
25785 }
25786 public function key(): int
25787 {
25788 return $this->position;
25789 }
25790 public function current(): Author
25791 {
25792 return $this->authors[$this->position];
25793 }
25794 public function next(): void
25795 {
25796 $this->position++;
25797 }
25798 }
25799 <?php
25800
25801 declare (strict_types=1);
25802 /*
25803 * This file is part of PharIo\Manifest.
25804 *
25805 * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
25806 *
25807 * For the full copyright and license information, please view the LICENSE
25808 * file that was distributed with this source code.
25809 *
25810 */
25811 namespace PHPUnitPHAR\PharIo\Manifest;
25812
25813 use PHPUnitPHAR\PharIo\Version\Version;
25814 class BundledComponent
25815 {
25816 /** @var string */
25817 private $name;
25818 /** @var Version */
25819 private $version;
25820 public function __construct(string $name, Version $version)
25821 {
25822 $this->name = $name;
25823 $this->version = $version;
25824 }
25825 public function getName(): string
25826 {
25827 return $this->name;
25828 }
25829 public function getVersion(): Version
25830 {
25831 return $this->version;
25832 }
25833 }
25834 <?php
25835
25836 declare (strict_types=1);
25837 /*
25838 * This file is part of PharIo\Manifest.
25839 *
25840 * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
25841 *
25842 * For the full copyright and license information, please view the LICENSE
25843 * file that was distributed with this source code.
25844 *
25845 */
25846 namespace PHPUnitPHAR\PharIo\Manifest;
25847
25848 use Countable;
25849 use IteratorAggregate;
25850 use function count;
25851 /** @template-implements IteratorAggregate<int,BundledComponent> */
25852 class BundledComponentCollection implements Countable, IteratorAggregate
25853 {
25854 /** @var BundledComponent[] */
25855 private $bundledComponents = [];
25856 public function add(BundledComponent $bundledComponent): void
25857 {
25858 $this->bundledComponents[] = $bundledComponent;
25859 }
25860 /**
25861 * @return BundledComponent[]
25862 */
25863 public function getBundledComponents(): array
25864 {
25865 return $this->bundledComponents;
25866 }
25867 public function count(): int
25868 {
25869 return count($this->bundledComponents);
25870 }
25871 public function getIterator(): BundledComponentCollectionIterator
25872 {
25873 return new BundledComponentCollectionIterator($this);
25874 }
25875 }
25876 <?php
25877
25878 declare (strict_types=1);
25879 /*
25880 * This file is part of PharIo\Manifest.
25881 *
25882 * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
25883 *
25884 * For the full copyright and license information, please view the LICENSE
25885 * file that was distributed with this source code.
25886 *
25887 */
25888 namespace PHPUnitPHAR\PharIo\Manifest;
25889
25890 use Iterator;
25891 use function count;
25892 /** @template-implements Iterator<int,BundledComponent> */
25893 class BundledComponentCollectionIterator implements Iterator
25894 {
25895 /** @var BundledComponent[] */
25896 private $bundledComponents;
25897 /** @var int */
25898 private $position = 0;
25899 public function __construct(BundledComponentCollection $bundledComponents)
25900 {
25901 $this->bundledComponents = $bundledComponents->getBundledComponents();
25902 }
25903 public function rewind(): void
25904 {
25905 $this->position = 0;
25906 }
25907 public function valid(): bool
25908 {
25909 return $this->position < count($this->bundledComponents);
25910 }
25911 public function key(): int
25912 {
25913 return $this->position;
25914 }
25915 public function current(): BundledComponent
25916 {
25917 return $this->bundledComponents[$this->position];
25918 }
25919 public function next(): void
25920 {
25921 $this->position++;
25922 }
25923 }
25924 <?php
25925
25926 declare (strict_types=1);
25927 /*
25928 * This file is part of PharIo\Manifest.
25929 *
25930 * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
25931 *
25932 * For the full copyright and license information, please view the LICENSE
25933 * file that was distributed with this source code.
25934 *
25935 */
25936 namespace PHPUnitPHAR\PharIo\Manifest;
25937
25938 class CopyrightInformation
25939 {
25940 /** @var AuthorCollection */
25941 private $authors;
25942 /** @var License */
25943 private $license;
25944 public function __construct(AuthorCollection $authors, License $license)
25945 {
25946 $this->authors = $authors;
25947 $this->license = $license;
25948 }
25949 public function getAuthors(): AuthorCollection
25950 {
25951 return $this->authors;
25952 }
25953 public function getLicense(): License
25954 {
25955 return $this->license;
25956 }
25957 }
25958 <?php
25959
25960 declare (strict_types=1);
25961 /*
25962 * This file is part of PharIo\Manifest.
25963 *
25964 * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
25965 *
25966 * For the full copyright and license information, please view the LICENSE
25967 * file that was distributed with this source code.
25968 *
25969 */
25970 namespace PHPUnitPHAR\PharIo\Manifest;
25971
25972 use const FILTER_VALIDATE_EMAIL;
25973 use function filter_var;
25974 class Email
25975 {
25976 /** @var string */
25977 private $email;
25978 public function __construct(string $email)
25979 {
25980 $this->ensureEmailIsValid($email);
25981 $this->email = $email;
25982 }
25983 public function asString(): string
25984 {
25985 return $this->email;
25986 }
25987 private function ensureEmailIsValid(string $url): void
25988 {
25989 if (filter_var($url, FILTER_VALIDATE_EMAIL) === \false) {
25990 throw new InvalidEmailException();
25991 }
25992 }
25993 }
25994 <?php
25995
25996 declare (strict_types=1);
25997 /*
25998 * This file is part of PharIo\Manifest.
25999 *
26000 * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
26001 *
26002 * For the full copyright and license information, please view the LICENSE
26003 * file that was distributed with this source code.
26004 *
26005 */
26006 namespace PHPUnitPHAR\PharIo\Manifest;
26007
26008 use PHPUnitPHAR\PharIo\Version\Version;
26009 use PHPUnitPHAR\PharIo\Version\VersionConstraint;
26010 class Extension extends Type
26011 {
26012 /** @var ApplicationName */
26013 private $application;
26014 /** @var VersionConstraint */
26015 private $versionConstraint;
26016 public function __construct(ApplicationName $application, VersionConstraint $versionConstraint)
26017 {
26018 $this->application = $application;
26019 $this->versionConstraint = $versionConstraint;
26020 }
26021 public function getApplicationName(): ApplicationName
26022 {
26023 return $this->application;
26024 }
26025 public function getVersionConstraint(): VersionConstraint
26026 {
26027 return $this->versionConstraint;
26028 }
26029 public function isExtension(): bool
26030 {
26031 return \true;
26032 }
26033 public function isExtensionFor(ApplicationName $name): bool
26034 {
26035 return $this->application->isEqual($name);
26036 }
26037 public function isCompatibleWith(ApplicationName $name, Version $version): bool
26038 {
26039 return $this->isExtensionFor($name) && $this->versionConstraint->complies($version);
26040 }
26041 }
26042 <?php
26043
26044 declare (strict_types=1);
26045 /*
26046 * This file is part of PharIo\Manifest.
26047 *
26048 * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
26049 *
26050 * For the full copyright and license information, please view the LICENSE
26051 * file that was distributed with this source code.
26052 *
26053 */
26054 namespace PHPUnitPHAR\PharIo\Manifest;
26055
26056 class Library extends Type
26057 {
26058 public function isLibrary(): bool
26059 {
26060 return \true;
26061 }
26062 }
26063 <?php
26064
26065 declare (strict_types=1);
26066 /*
26067 * This file is part of PharIo\Manifest.
26068 *
26069 * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
26070 *
26071 * For the full copyright and license information, please view the LICENSE
26072 * file that was distributed with this source code.
26073 *
26074 */
26075 namespace PHPUnitPHAR\PharIo\Manifest;
26076
26077 class License
26078 {
26079 /** @var string */
26080 private $name;
26081 /** @var Url */
26082 private $url;
26083 public function __construct(string $name, Url $url)
26084 {
26085 $this->name = $name;
26086 $this->url = $url;
26087 }
26088 public function getName(): string
26089 {
26090 return $this->name;
26091 }
26092 public function getUrl(): Url
26093 {
26094 return $this->url;
26095 }
26096 }
26097 <?php
26098
26099 declare (strict_types=1);
26100 /*
26101 * This file is part of PharIo\Manifest.
26102 *
26103 * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
26104 *
26105 * For the full copyright and license information, please view the LICENSE
26106 * file that was distributed with this source code.
26107 *
26108 */
26109 namespace PHPUnitPHAR\PharIo\Manifest;
26110
26111 use PHPUnitPHAR\PharIo\Version\Version;
26112 class Manifest
26113 {
26114 /** @var ApplicationName */
26115 private $name;
26116 /** @var Version */
26117 private $version;
26118 /** @var Type */
26119 private $type;
26120 /** @var CopyrightInformation */
26121 private $copyrightInformation;
26122 /** @var RequirementCollection */
26123 private $requirements;
26124 /** @var BundledComponentCollection */
26125 private $bundledComponents;
26126 public function __construct(ApplicationName $name, Version $version, Type $type, CopyrightInformation $copyrightInformation, RequirementCollection $requirements, BundledComponentCollection $bundledComponents)
26127 {
26128 $this->name = $name;
26129 $this->version = $version;
26130 $this->type = $type;
26131 $this->copyrightInformation = $copyrightInformation;
26132 $this->requirements = $requirements;
26133 $this->bundledComponents = $bundledComponents;
26134 }
26135 public function getName(): ApplicationName
26136 {
26137 return $this->name;
26138 }
26139 public function getVersion(): Version
26140 {
26141 return $this->version;
26142 }
26143 public function getType(): Type
26144 {
26145 return $this->type;
26146 }
26147 public function getCopyrightInformation(): CopyrightInformation
26148 {
26149 return $this->copyrightInformation;
26150 }
26151 public function getRequirements(): RequirementCollection
26152 {
26153 return $this->requirements;
26154 }
26155 public function getBundledComponents(): BundledComponentCollection
26156 {
26157 return $this->bundledComponents;
26158 }
26159 public function isApplication(): bool
26160 {
26161 return $this->type->isApplication();
26162 }
26163 public function isLibrary(): bool
26164 {
26165 return $this->type->isLibrary();
26166 }
26167 public function isExtension(): bool
26168 {
26169 return $this->type->isExtension();
26170 }
26171 public function isExtensionFor(ApplicationName $application, ?Version $version = null): bool
26172 {
26173 if (!$this->isExtension()) {
26174 return \false;
26175 }
26176 /** @var Extension $type */
26177 $type = $this->type;
26178 if ($version !== null) {
26179 return $type->isCompatibleWith($application, $version);
26180 }
26181 return $type->isExtensionFor($application);
26182 }
26183 }
26184 <?php
26185
26186 declare (strict_types=1);
26187 /*
26188 * This file is part of PharIo\Manifest.
26189 *
26190 * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
26191 *
26192 * For the full copyright and license information, please view the LICENSE
26193 * file that was distributed with this source code.
26194 *
26195 */
26196 namespace PHPUnitPHAR\PharIo\Manifest;
26197
26198 class PhpExtensionRequirement implements Requirement
26199 {
26200 /** @var string */
26201 private $extension;
26202 public function __construct(string $extension)
26203 {
26204 $this->extension = $extension;
26205 }
26206 public function asString(): string
26207 {
26208 return $this->extension;
26209 }
26210 }
26211 <?php
26212
26213 declare (strict_types=1);
26214 /*
26215 * This file is part of PharIo\Manifest.
26216 *
26217 * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
26218 *
26219 * For the full copyright and license information, please view the LICENSE
26220 * file that was distributed with this source code.
26221 *
26222 */
26223 namespace PHPUnitPHAR\PharIo\Manifest;
26224
26225 use PHPUnitPHAR\PharIo\Version\VersionConstraint;
26226 class PhpVersionRequirement implements Requirement
26227 {
26228 /** @var VersionConstraint */
26229 private $versionConstraint;
26230 public function __construct(VersionConstraint $versionConstraint)
26231 {
26232 $this->versionConstraint = $versionConstraint;
26233 }
26234 public function getVersionConstraint(): VersionConstraint
26235 {
26236 return $this->versionConstraint;
26237 }
26238 }
26239 <?php
26240
26241 declare (strict_types=1);
26242 /*
26243 * This file is part of PharIo\Manifest.
26244 *
26245 * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
26246 *
26247 * For the full copyright and license information, please view the LICENSE
26248 * file that was distributed with this source code.
26249 *
26250 */
26251 namespace PHPUnitPHAR\PharIo\Manifest;
26252
26253 interface Requirement
26254 {
26255 }
26256 <?php
26257
26258 declare (strict_types=1);
26259 /*
26260 * This file is part of PharIo\Manifest.
26261 *
26262 * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
26263 *
26264 * For the full copyright and license information, please view the LICENSE
26265 * file that was distributed with this source code.
26266 *
26267 */
26268 namespace PHPUnitPHAR\PharIo\Manifest;
26269
26270 use Countable;
26271 use IteratorAggregate;
26272 use function count;
26273 /** @template-implements IteratorAggregate<int,Requirement> */
26274 class RequirementCollection implements Countable, IteratorAggregate
26275 {
26276 /** @var Requirement[] */
26277 private $requirements = [];
26278 public function add(Requirement $requirement): void
26279 {
26280 $this->requirements[] = $requirement;
26281 }
26282 /**
26283 * @return Requirement[]
26284 */
26285 public function getRequirements(): array
26286 {
26287 return $this->requirements;
26288 }
26289 public function count(): int
26290 {
26291 return count($this->requirements);
26292 }
26293 public function getIterator(): RequirementCollectionIterator
26294 {
26295 return new RequirementCollectionIterator($this);
26296 }
26297 }
26298 <?php
26299
26300 declare (strict_types=1);
26301 /*
26302 * This file is part of PharIo\Manifest.
26303 *
26304 * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
26305 *
26306 * For the full copyright and license information, please view the LICENSE
26307 * file that was distributed with this source code.
26308 *
26309 */
26310 namespace PHPUnitPHAR\PharIo\Manifest;
26311
26312 use Iterator;
26313 use function count;
26314 /** @template-implements Iterator<int,Requirement> */
26315 class RequirementCollectionIterator implements Iterator
26316 {
26317 /** @var Requirement[] */
26318 private $requirements;
26319 /** @var int */
26320 private $position = 0;
26321 public function __construct(RequirementCollection $requirements)
26322 {
26323 $this->requirements = $requirements->getRequirements();
26324 }
26325 public function rewind(): void
26326 {
26327 $this->position = 0;
26328 }
26329 public function valid(): bool
26330 {
26331 return $this->position < count($this->requirements);
26332 }
26333 public function key(): int
26334 {
26335 return $this->position;
26336 }
26337 public function current(): Requirement
26338 {
26339 return $this->requirements[$this->position];
26340 }
26341 public function next(): void
26342 {
26343 $this->position++;
26344 }
26345 }
26346 <?php
26347
26348 declare (strict_types=1);
26349 /*
26350 * This file is part of PharIo\Manifest.
26351 *
26352 * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
26353 *
26354 * For the full copyright and license information, please view the LICENSE
26355 * file that was distributed with this source code.
26356 *
26357 */
26358 namespace PHPUnitPHAR\PharIo\Manifest;
26359
26360 use PHPUnitPHAR\PharIo\Version\VersionConstraint;
26361 abstract class Type
26362 {
26363 public static function application(): Application
26364 {
26365 return new Application();
26366 }
26367 public static function library(): Library
26368 {
26369 return new Library();
26370 }
26371 public static function extension(ApplicationName $application, VersionConstraint $versionConstraint): Extension
26372 {
26373 return new Extension($application, $versionConstraint);
26374 }
26375 /** @psalm-assert-if-true Application $this */
26376 public function isApplication(): bool
26377 {
26378 return \false;
26379 }
26380 /** @psalm-assert-if-true Library $this */
26381 public function isLibrary(): bool
26382 {
26383 return \false;
26384 }
26385 /** @psalm-assert-if-true Extension $this */
26386 public function isExtension(): bool
26387 {
26388 return \false;
26389 }
26390 }
26391 <?php
26392
26393 declare (strict_types=1);
26394 /*
26395 * This file is part of PharIo\Manifest.
26396 *
26397 * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
26398 *
26399 * For the full copyright and license information, please view the LICENSE
26400 * file that was distributed with this source code.
26401 *
26402 */
26403 namespace PHPUnitPHAR\PharIo\Manifest;
26404
26405 use const FILTER_VALIDATE_URL;
26406 use function filter_var;
26407 class Url
26408 {
26409 /** @var string */
26410 private $url;
26411 public function __construct(string $url)
26412 {
26413 $this->ensureUrlIsValid($url);
26414 $this->url = $url;
26415 }
26416 public function asString(): string
26417 {
26418 return $this->url;
26419 }
26420 /**
26421 * @throws InvalidUrlException
26422 */
26423 private function ensureUrlIsValid(string $url): void
26424 {
26425 if (filter_var($url, FILTER_VALIDATE_URL) === \false) {
26426 throw new InvalidUrlException();
26427 }
26428 }
26429 }
26430 <?php
26431
26432 declare (strict_types=1);
26433 /*
26434 * This file is part of PharIo\Manifest.
26435 *
26436 * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
26437 *
26438 * For the full copyright and license information, please view the LICENSE
26439 * file that was distributed with this source code.
26440 *
26441 */
26442 namespace PHPUnitPHAR\PharIo\Manifest;
26443
26444 class AuthorElement extends ManifestElement
26445 {
26446 public function getName(): string
26447 {
26448 return $this->getAttributeValue('name');
26449 }
26450 public function getEmail(): string
26451 {
26452 return $this->getAttributeValue('email');
26453 }
26454 public function hasEMail(): bool
26455 {
26456 return $this->hasAttribute('email');
26457 }
26458 }
26459 <?php
26460
26461 declare (strict_types=1);
26462 /*
26463 * This file is part of PharIo\Manifest.
26464 *
26465 * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
26466 *
26467 * For the full copyright and license information, please view the LICENSE
26468 * file that was distributed with this source code.
26469 *
26470 */
26471 namespace PHPUnitPHAR\PharIo\Manifest;
26472
26473 class AuthorElementCollection extends ElementCollection
26474 {
26475 public function current(): AuthorElement
26476 {
26477 return new AuthorElement($this->getCurrentElement());
26478 }
26479 }
26480 <?php
26481
26482 declare (strict_types=1);
26483 /*
26484 * This file is part of PharIo\Manifest.
26485 *
26486 * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
26487 *
26488 * For the full copyright and license information, please view the LICENSE
26489 * file that was distributed with this source code.
26490 *
26491 */
26492 namespace PHPUnitPHAR\PharIo\Manifest;
26493
26494 class BundlesElement extends ManifestElement
26495 {
26496 public function getComponentElements(): ComponentElementCollection
26497 {
26498 return new ComponentElementCollection($this->getChildrenByName('component'));
26499 }
26500 }
26501 <?php
26502
26503 declare (strict_types=1);
26504 /*
26505 * This file is part of PharIo\Manifest.
26506 *
26507 * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
26508 *
26509 * For the full copyright and license information, please view the LICENSE
26510 * file that was distributed with this source code.
26511 *
26512 */
26513 namespace PHPUnitPHAR\PharIo\Manifest;
26514
26515 class ComponentElement extends ManifestElement
26516 {
26517 public function getName(): string
26518 {
26519 return $this->getAttributeValue('name');
26520 }
26521 public function getVersion(): string
26522 {
26523 return $this->getAttributeValue('version');
26524 }
26525 }
26526 <?php
26527
26528 declare (strict_types=1);
26529 /*
26530 * This file is part of PharIo\Manifest.
26531 *
26532 * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
26533 *
26534 * For the full copyright and license information, please view the LICENSE
26535 * file that was distributed with this source code.
26536 *
26537 */
26538 namespace PHPUnitPHAR\PharIo\Manifest;
26539
26540 class ComponentElementCollection extends ElementCollection
26541 {
26542 public function current(): ComponentElement
26543 {
26544 return new ComponentElement($this->getCurrentElement());
26545 }
26546 }
26547 <?php
26548
26549 declare (strict_types=1);
26550 /*
26551 * This file is part of PharIo\Manifest.
26552 *
26553 * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
26554 *
26555 * For the full copyright and license information, please view the LICENSE
26556 * file that was distributed with this source code.
26557 *
26558 */
26559 namespace PHPUnitPHAR\PharIo\Manifest;
26560
26561 class ContainsElement extends ManifestElement
26562 {
26563 public function getName(): string
26564 {
26565 return $this->getAttributeValue('name');
26566 }
26567 public function getVersion(): string
26568 {
26569 return $this->getAttributeValue('version');
26570 }
26571 public function getType(): string
26572 {
26573 return $this->getAttributeValue('type');
26574 }
26575 public function getExtensionElement(): ExtensionElement
26576 {
26577 return new ExtensionElement($this->getChildByName('extension'));
26578 }
26579 }
26580 <?php
26581
26582 declare (strict_types=1);
26583 /*
26584 * This file is part of PharIo\Manifest.
26585 *
26586 * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
26587 *
26588 * For the full copyright and license information, please view the LICENSE
26589 * file that was distributed with this source code.
26590 *
26591 */
26592 namespace PHPUnitPHAR\PharIo\Manifest;
26593
26594 class CopyrightElement extends ManifestElement
26595 {
26596 public function getAuthorElements(): AuthorElementCollection
26597 {
26598 return new AuthorElementCollection($this->getChildrenByName('author'));
26599 }
26600 public function getLicenseElement(): LicenseElement
26601 {
26602 return new LicenseElement($this->getChildByName('license'));
26603 }
26604 }
26605 <?php
26606
26607 declare (strict_types=1);
26608 /*
26609 * This file is part of PharIo\Manifest.
26610 *
26611 * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
26612 *
26613 * For the full copyright and license information, please view the LICENSE
26614 * file that was distributed with this source code.
26615 *
26616 */
26617 namespace PHPUnitPHAR\PharIo\Manifest;
26618
26619 use DOMElement;
26620 use DOMNodeList;
26621 use Iterator;
26622 use ReturnTypeWillChange;
26623 use function count;
26624 use function get_class;
26625 use function sprintf;
26626 /** @template-implements Iterator<int,DOMElement> */
26627 abstract class ElementCollection implements Iterator
26628 {
26629 /** @var DOMElement[] */
26630 private $nodes = [];
26631 /** @var int */
26632 private $position;
26633 public function __construct(DOMNodeList $nodeList)
26634 {
26635 $this->position = 0;
26636 $this->importNodes($nodeList);
26637 }
26638 #[ReturnTypeWillChange]
26639 abstract public function current();
26640 public function next(): void
26641 {
26642 $this->position++;
26643 }
26644 public function key(): int
26645 {
26646 return $this->position;
26647 }
26648 public function valid(): bool
26649 {
26650 return $this->position < count($this->nodes);
26651 }
26652 public function rewind(): void
26653 {
26654 $this->position = 0;
26655 }
26656 protected function getCurrentElement(): DOMElement
26657 {
26658 return $this->nodes[$this->position];
26659 }
26660 private function importNodes(DOMNodeList $nodeList): void
26661 {
26662 foreach ($nodeList as $node) {
26663 if (!$node instanceof DOMElement) {
26664 throw new ElementCollectionException(sprintf('\DOMElement expected, got \%s', get_class($node)));
26665 }
26666 $this->nodes[] = $node;
26667 }
26668 }
26669 }
26670 <?php
26671
26672 declare (strict_types=1);
26673 /*
26674 * This file is part of PharIo\Manifest.
26675 *
26676 * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
26677 *
26678 * For the full copyright and license information, please view the LICENSE
26679 * file that was distributed with this source code.
26680 *
26681 */
26682 namespace PHPUnitPHAR\PharIo\Manifest;
26683
26684 class ExtElement extends ManifestElement
26685 {
26686 public function getName(): string
26687 {
26688 return $this->getAttributeValue('name');
26689 }
26690 }
26691 <?php
26692
26693 declare (strict_types=1);
26694 /*
26695 * This file is part of PharIo\Manifest.
26696 *
26697 * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
26698 *
26699 * For the full copyright and license information, please view the LICENSE
26700 * file that was distributed with this source code.
26701 *
26702 */
26703 namespace PHPUnitPHAR\PharIo\Manifest;
26704
26705 class ExtElementCollection extends ElementCollection
26706 {
26707 public function current(): ExtElement
26708 {
26709 return new ExtElement($this->getCurrentElement());
26710 }
26711 }
26712 <?php
26713
26714 declare (strict_types=1);
26715 /*
26716 * This file is part of PharIo\Manifest.
26717 *
26718 * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
26719 *
26720 * For the full copyright and license information, please view the LICENSE
26721 * file that was distributed with this source code.
26722 *
26723 */
26724 namespace PHPUnitPHAR\PharIo\Manifest;
26725
26726 class ExtensionElement extends ManifestElement
26727 {
26728 public function getFor(): string
26729 {
26730 return $this->getAttributeValue('for');
26731 }
26732 public function getCompatible(): string
26733 {
26734 return $this->getAttributeValue('compatible');
26735 }
26736 }
26737 <?php
26738
26739 declare (strict_types=1);
26740 /*
26741 * This file is part of PharIo\Manifest.
26742 *
26743 * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
26744 *
26745 * For the full copyright and license information, please view the LICENSE
26746 * file that was distributed with this source code.
26747 *
26748 */
26749 namespace PHPUnitPHAR\PharIo\Manifest;
26750
26751 class LicenseElement extends ManifestElement
26752 {
26753 public function getType(): string
26754 {
26755 return $this->getAttributeValue('type');
26756 }
26757 public function getUrl(): string
26758 {
26759 return $this->getAttributeValue('url');
26760 }
26761 }
26762 <?php
26763
26764 declare (strict_types=1);
26765 /*
26766 * This file is part of PharIo\Manifest.
26767 *
26768 * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
26769 *
26770 * For the full copyright and license information, please view the LICENSE
26771 * file that was distributed with this source code.
26772 *
26773 */
26774 namespace PHPUnitPHAR\PharIo\Manifest;
26775
26776 use DOMDocument;
26777 use DOMElement;
26778 use Throwable;
26779 use function count;
26780 use function file_get_contents;
26781 use function is_file;
26782 use function libxml_clear_errors;
26783 use function libxml_get_errors;
26784 use function libxml_use_internal_errors;
26785 use function sprintf;
26786 class ManifestDocument
26787 {
26788 public const XMLNS = 'https://phar.io/xml/manifest/1.0';
26789 /** @var DOMDocument */
26790 private $dom;
26791 public static function fromFile(string $filename): ManifestDocument
26792 {
26793 if (!is_file($filename)) {
26794 throw new ManifestDocumentException(sprintf('File "%s" not found', $filename));
26795 }
26796 return self::fromString(file_get_contents($filename));
26797 }
26798 public static function fromString(string $xmlString): ManifestDocument
26799 {
26800 $prev = libxml_use_internal_errors(\true);
26801 libxml_clear_errors();
26802 try {
26803 $dom = new DOMDocument();
26804 $dom->loadXML($xmlString);
26805 $errors = libxml_get_errors();
26806 libxml_use_internal_errors($prev);
26807 } catch (Throwable $t) {
26808 throw new ManifestDocumentException($t->getMessage(), 0, $t);
26809 }
26810 if (count($errors) !== 0) {
26811 throw new ManifestDocumentLoadingException($errors);
26812 }
26813 return new self($dom);
26814 }
26815 private function __construct(DOMDocument $dom)
26816 {
26817 $this->ensureCorrectDocumentType($dom);
26818 $this->dom = $dom;
26819 }
26820 public function getContainsElement(): ContainsElement
26821 {
26822 return new ContainsElement($this->fetchElementByName('contains'));
26823 }
26824 public function getCopyrightElement(): CopyrightElement
26825 {
26826 return new CopyrightElement($this->fetchElementByName('copyright'));
26827 }
26828 public function getRequiresElement(): RequiresElement
26829 {
26830 return new RequiresElement($this->fetchElementByName('requires'));
26831 }
26832 public function hasBundlesElement(): bool
26833 {
26834 return $this->dom->getElementsByTagNameNS(self::XMLNS, 'bundles')->length === 1;
26835 }
26836 public function getBundlesElement(): BundlesElement
26837 {
26838 return new BundlesElement($this->fetchElementByName('bundles'));
26839 }
26840 private function ensureCorrectDocumentType(DOMDocument $dom): void
26841 {
26842 $root = $dom->documentElement;
26843 if ($root->localName !== 'phar' || $root->namespaceURI !== self::XMLNS) {
26844 throw new ManifestDocumentException('Not a phar.io manifest document');
26845 }
26846 }
26847 private function fetchElementByName(string $elementName): DOMElement
26848 {
26849 $element = $this->dom->getElementsByTagNameNS(self::XMLNS, $elementName)->item(0);
26850 if (!$element instanceof DOMElement) {
26851 throw new ManifestDocumentException(sprintf('Element %s missing', $elementName));
26852 }
26853 return $element;
26854 }
26855 }
26856 <?php
26857
26858 declare (strict_types=1);
26859 /*
26860 * This file is part of PharIo\Manifest.
26861 *
26862 * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
26863 *
26864 * For the full copyright and license information, please view the LICENSE
26865 * file that was distributed with this source code.
26866 *
26867 */
26868 namespace PHPUnitPHAR\PharIo\Manifest;
26869
26870 use DOMElement;
26871 use DOMNodeList;
26872 use function sprintf;
26873 class ManifestElement
26874 {
26875 public const XMLNS = 'https://phar.io/xml/manifest/1.0';
26876 /** @var DOMElement */
26877 private $element;
26878 public function __construct(DOMElement $element)
26879 {
26880 $this->element = $element;
26881 }
26882 protected function getAttributeValue(string $name): string
26883 {
26884 if (!$this->element->hasAttribute($name)) {
26885 throw new ManifestElementException(sprintf('Attribute %s not set on element %s', $name, $this->element->localName));
26886 }
26887 return $this->element->getAttribute($name);
26888 }
26889 protected function hasAttribute(string $name): bool
26890 {
26891 return $this->element->hasAttribute($name);
26892 }
26893 protected function getChildByName(string $elementName): DOMElement
26894 {
26895 $element = $this->element->getElementsByTagNameNS(self::XMLNS, $elementName)->item(0);
26896 if (!$element instanceof DOMElement) {
26897 throw new ManifestElementException(sprintf('Element %s missing', $elementName));
26898 }
26899 return $element;
26900 }
26901 protected function getChildrenByName(string $elementName): DOMNodeList
26902 {
26903 $elementList = $this->element->getElementsByTagNameNS(self::XMLNS, $elementName);
26904 if ($elementList->length === 0) {
26905 throw new ManifestElementException(sprintf('Element(s) %s missing', $elementName));
26906 }
26907 return $elementList;
26908 }
26909 protected function hasChild(string $elementName): bool
26910 {
26911 return $this->element->getElementsByTagNameNS(self::XMLNS, $elementName)->length !== 0;
26912 }
26913 }
26914 <?php
26915
26916 declare (strict_types=1);
26917 /*
26918 * This file is part of PharIo\Manifest.
26919 *
26920 * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
26921 *
26922 * For the full copyright and license information, please view the LICENSE
26923 * file that was distributed with this source code.
26924 *
26925 */
26926 namespace PHPUnitPHAR\PharIo\Manifest;
26927
26928 class PhpElement extends ManifestElement
26929 {
26930 public function getVersion(): string
26931 {
26932 return $this->getAttributeValue('version');
26933 }
26934 public function hasExtElements(): bool
26935 {
26936 return $this->hasChild('ext');
26937 }
26938 public function getExtElements(): ExtElementCollection
26939 {
26940 return new ExtElementCollection($this->getChildrenByName('ext'));
26941 }
26942 }
26943 <?php
26944
26945 declare (strict_types=1);
26946 /*
26947 * This file is part of PharIo\Manifest.
26948 *
26949 * Copyright (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de> and contributors
26950 *
26951 * For the full copyright and license information, please view the LICENSE
26952 * file that was distributed with this source code.
26953 *
26954 */
26955 namespace PHPUnitPHAR\PharIo\Manifest;
26956
26957 class RequiresElement extends ManifestElement
26958 {
26959 public function getPHPElement(): PhpElement
26960 {
26961 return new PhpElement($this->getChildByName('php'));
26962 }
26963 }
26964 <?php
26965
26966 declare (strict_types=1);
26967 /*
26968 * This file is part of PharIo\Version.
26969 *
26970 * (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de>
26971 *
26972 * For the full copyright and license information, please view the LICENSE
26973 * file that was distributed with this source code.
26974 */
26975 namespace PHPUnitPHAR\PharIo\Version;
26976
26977 class BuildMetaData
26978 {
26979 /** @var string */
26980 private $value;
26981 public function __construct(string $value)
26982 {
26983 $this->value = $value;
26984 }
26985 public function asString(): string
26986 {
26987 return $this->value;
26988 }
26989 public function equals(BuildMetaData $other): bool
26990 {
26991 return $this->asString() === $other->asString();
26992 }
26993 }
26994 Copyright (c) 2016-2017 Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de> and contributors
26995 All rights reserved.
26996
26997 Redistribution and use in source and binary forms, with or without modification,
26998 are permitted provided that the following conditions are met:
26999
27000 * Redistributions of source code must retain the above copyright notice,
27001 this list of conditions and the following disclaimer.
27002
27003 * Redistributions in binary form must reproduce the above copyright notice,
27004 this list of conditions and the following disclaimer in the documentation
27005 and/or other materials provided with the distribution.
27006
27007 * Neither the name of the copyright holder nor the names of contributors
27008 may be used to endorse or promote products derived from this software
27009 without specific prior written permission.
27010
27011 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
27012 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT * NOT LIMITED TO,
27013 THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
27014 PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
27015 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
27016 OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27017 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27018 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27019 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27020 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27021 POSSIBILITY OF SUCH DAMAGE.
27022
27023 <?php
27024
27025 declare (strict_types=1);
27026 namespace PHPUnitPHAR\PharIo\Version;
27027
27028 class PreReleaseSuffix
27029 {
27030 private const valueScoreMap = ['dev' => 0, 'a' => 1, 'alpha' => 1, 'b' => 2, 'beta' => 2, 'rc' => 3, 'p' => 4, 'pl' => 4, 'patch' => 4];
27031 /** @var string */
27032 private $value;
27033 /** @var int */
27034 private $valueScore;
27035 /** @var int */
27036 private $number = 0;
27037 /** @var string */
27038 private $full;
27039 /**
27040 * @throws InvalidPreReleaseSuffixException
27041 */
27042 public function __construct(string $value)
27043 {
27044 $this->parseValue($value);
27045 }
27046 public function asString(): string
27047 {
27048 return $this->full;
27049 }
27050 public function getValue(): string
27051 {
27052 return $this->value;
27053 }
27054 public function getNumber(): ?int
27055 {
27056 return $this->number;
27057 }
27058 public function isGreaterThan(PreReleaseSuffix $suffix): bool
27059 {
27060 if ($this->valueScore > $suffix->valueScore) {
27061 return \true;
27062 }
27063 if ($this->valueScore < $suffix->valueScore) {
27064 return \false;
27065 }
27066 return $this->getNumber() > $suffix->getNumber();
27067 }
27068 private function mapValueToScore(string $value): int
27069 {
27070 $value = \strtolower($value);
27071 return self::valueScoreMap[$value];
27072 }
27073 private function parseValue(string $value): void
27074 {
27075 $regex = '/-?((dev|beta|b|rc|alpha|a|patch|p|pl)\.?(\d*)).*$/i';
27076 if (\preg_match($regex, $value, $matches) !== 1) {
27077 throw new InvalidPreReleaseSuffixException(\sprintf('Invalid label %s', $value));
27078 }
27079 $this->full = $matches[1];
27080 $this->value = $matches[2];
27081 if ($matches[3] !== '') {
27082 $this->number = (int) $matches[3];
27083 }
27084 $this->valueScore = $this->mapValueToScore($matches[2]);
27085 }
27086 }
27087 <?php
27088
27089 declare (strict_types=1);
27090 /*
27091 * This file is part of PharIo\Version.
27092 *
27093 * (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de>
27094 *
27095 * For the full copyright and license information, please view the LICENSE
27096 * file that was distributed with this source code.
27097 */
27098 namespace PHPUnitPHAR\PharIo\Version;
27099
27100 class Version
27101 {
27102 /** @var string */
27103 private $originalVersionString;
27104 /** @var VersionNumber */
27105 private $major;
27106 /** @var VersionNumber */
27107 private $minor;
27108 /** @var VersionNumber */
27109 private $patch;
27110 /** @var null|PreReleaseSuffix */
27111 private $preReleaseSuffix;
27112 /** @var null|BuildMetaData */
27113 private $buildMetadata;
27114 public function __construct(string $versionString)
27115 {
27116 $this->ensureVersionStringIsValid($versionString);
27117 $this->originalVersionString = $versionString;
27118 }
27119 /**
27120 * @throws NoPreReleaseSuffixException
27121 */
27122 public function getPreReleaseSuffix(): PreReleaseSuffix
27123 {
27124 if ($this->preReleaseSuffix === null) {
27125 throw new NoPreReleaseSuffixException('No pre-release suffix set');
27126 }
27127 return $this->preReleaseSuffix;
27128 }
27129 public function getOriginalString(): string
27130 {
27131 return $this->originalVersionString;
27132 }
27133 public function getVersionString(): string
27134 {
27135 $str = \sprintf('%d.%d.%d', $this->getMajor()->getValue() ?? 0, $this->getMinor()->getValue() ?? 0, $this->getPatch()->getValue() ?? 0);
27136 if (!$this->hasPreReleaseSuffix()) {
27137 return $str;
27138 }
27139 return $str . '-' . $this->getPreReleaseSuffix()->asString();
27140 }
27141 public function hasPreReleaseSuffix(): bool
27142 {
27143 return $this->preReleaseSuffix !== null;
27144 }
27145 public function equals(Version $other): bool
27146 {
27147 if ($this->getVersionString() !== $other->getVersionString()) {
27148 return \false;
27149 }
27150 if ($this->hasBuildMetaData() !== $other->hasBuildMetaData()) {
27151 return \false;
27152 }
27153 if ($this->hasBuildMetaData() && $other->hasBuildMetaData() && !$this->getBuildMetaData()->equals($other->getBuildMetaData())) {
27154 return \false;
27155 }
27156 return \true;
27157 }
27158 public function isGreaterThan(Version $version): bool
27159 {
27160 if ($version->getMajor()->getValue() > $this->getMajor()->getValue()) {
27161 return \false;
27162 }
27163 if ($version->getMajor()->getValue() < $this->getMajor()->getValue()) {
27164 return \true;
27165 }
27166 if ($version->getMinor()->getValue() > $this->getMinor()->getValue()) {
27167 return \false;
27168 }
27169 if ($version->getMinor()->getValue() < $this->getMinor()->getValue()) {
27170 return \true;
27171 }
27172 if ($version->getPatch()->getValue() > $this->getPatch()->getValue()) {
27173 return \false;
27174 }
27175 if ($version->getPatch()->getValue() < $this->getPatch()->getValue()) {
27176 return \true;
27177 }
27178 if (!$version->hasPreReleaseSuffix() && !$this->hasPreReleaseSuffix()) {
27179 return \false;
27180 }
27181 if ($version->hasPreReleaseSuffix() && !$this->hasPreReleaseSuffix()) {
27182 return \true;
27183 }
27184 if (!$version->hasPreReleaseSuffix() && $this->hasPreReleaseSuffix()) {
27185 return \false;
27186 }
27187 return $this->getPreReleaseSuffix()->isGreaterThan($version->getPreReleaseSuffix());
27188 }
27189 public function getMajor(): VersionNumber
27190 {
27191 return $this->major;
27192 }
27193 public function getMinor(): VersionNumber
27194 {
27195 return $this->minor;
27196 }
27197 public function getPatch(): VersionNumber
27198 {
27199 return $this->patch;
27200 }
27201 /**
27202 * @psalm-assert-if-true BuildMetaData $this->buildMetadata
27203 * @psalm-assert-if-true BuildMetaData $this->getBuildMetaData()
27204 */
27205 public function hasBuildMetaData(): bool
27206 {
27207 return $this->buildMetadata !== null;
27208 }
27209 /**
27210 * @throws NoBuildMetaDataException
27211 */
27212 public function getBuildMetaData(): BuildMetaData
27213 {
27214 if (!$this->hasBuildMetaData()) {
27215 throw new NoBuildMetaDataException('No build metadata set');
27216 }
27217 return $this->buildMetadata;
27218 }
27219 /**
27220 * @param string[] $matches
27221 *
27222 * @throws InvalidPreReleaseSuffixException
27223 */
27224 private function parseVersion(array $matches): void
27225 {
27226 $this->major = new VersionNumber((int) $matches['Major']);
27227 $this->minor = new VersionNumber((int) $matches['Minor']);
27228 $this->patch = isset($matches['Patch']) ? new VersionNumber((int) $matches['Patch']) : new VersionNumber(0);
27229 if (isset($matches['PreReleaseSuffix']) && $matches['PreReleaseSuffix'] !== '') {
27230 $this->preReleaseSuffix = new PreReleaseSuffix($matches['PreReleaseSuffix']);
27231 }
27232 if (isset($matches['BuildMetadata'])) {
27233 $this->buildMetadata = new BuildMetaData($matches['BuildMetadata']);
27234 }
27235 }
27236 /**
27237 * @param string $version
27238 *
27239 * @throws InvalidVersionException
27240 */
27241 private function ensureVersionStringIsValid($version): void
27242 {
27243 $regex = '/^v?
27244 (?P<Major>0|[1-9]\d*)
27245 \.
27246 (?P<Minor>0|[1-9]\d*)
27247 (\.
27248 (?P<Patch>0|[1-9]\d*)
27249 )?
27250 (?:
27251 -
27252 (?<PreReleaseSuffix>(?:(dev|beta|b|rc|alpha|a|patch|p|pl)\.?\d*))
27253 )?
27254 (?:
27255 \+
27256 (?P<BuildMetadata>[0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-@]+)*)
27257 )?
27258 $/xi';
27259 if (\preg_match($regex, $version, $matches) !== 1) {
27260 throw new InvalidVersionException(\sprintf("Version string '%s' does not follow SemVer semantics", $version));
27261 }
27262 $this->parseVersion($matches);
27263 }
27264 }
27265 <?php
27266
27267 declare (strict_types=1);
27268 /*
27269 * This file is part of PharIo\Version.
27270 *
27271 * (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de>
27272 *
27273 * For the full copyright and license information, please view the LICENSE
27274 * file that was distributed with this source code.
27275 */
27276 namespace PHPUnitPHAR\PharIo\Version;
27277
27278 class VersionConstraintParser
27279 {
27280 /**
27281 * @throws UnsupportedVersionConstraintException
27282 */
27283 public function parse(string $value): VersionConstraint
27284 {
27285 if (\strpos($value, '|') !== \false) {
27286 return $this->handleOrGroup($value);
27287 }
27288 if (!\preg_match('/^[\^~*]?v?[\d.*]+(?:-.*)?$/i', $value)) {
27289 throw new UnsupportedVersionConstraintException(\sprintf('Version constraint %s is not supported.', $value));
27290 }
27291 switch ($value[0]) {
27292 case '~':
27293 return $this->handleTildeOperator($value);
27294 case '^':
27295 return $this->handleCaretOperator($value);
27296 }
27297 $constraint = new VersionConstraintValue($value);
27298 if ($constraint->getMajor()->isAny()) {
27299 return new AnyVersionConstraint();
27300 }
27301 if ($constraint->getMinor()->isAny()) {
27302 return new SpecificMajorVersionConstraint($constraint->getVersionString(), $constraint->getMajor()->getValue() ?? 0);
27303 }
27304 if ($constraint->getPatch()->isAny()) {
27305 return new SpecificMajorAndMinorVersionConstraint($constraint->getVersionString(), $constraint->getMajor()->getValue() ?? 0, $constraint->getMinor()->getValue() ?? 0);
27306 }
27307 return new ExactVersionConstraint($constraint->getVersionString());
27308 }
27309 private function handleOrGroup(string $value): OrVersionConstraintGroup
27310 {
27311 $constraints = [];
27312 foreach (\preg_split('{\s*\|\|?\s*}', \trim($value)) as $groupSegment) {
27313 $constraints[] = $this->parse(\trim($groupSegment));
27314 }
27315 return new OrVersionConstraintGroup($value, $constraints);
27316 }
27317 private function handleTildeOperator(string $value): AndVersionConstraintGroup
27318 {
27319 $constraintValue = new VersionConstraintValue(\substr($value, 1));
27320 if ($constraintValue->getPatch()->isAny()) {
27321 return $this->handleCaretOperator($value);
27322 }
27323 $constraints = [new GreaterThanOrEqualToVersionConstraint($value, new Version(\substr($value, 1))), new SpecificMajorAndMinorVersionConstraint($value, $constraintValue->getMajor()->getValue() ?? 0, $constraintValue->getMinor()->getValue() ?? 0)];
27324 return new AndVersionConstraintGroup($value, $constraints);
27325 }
27326 private function handleCaretOperator(string $value): AndVersionConstraintGroup
27327 {
27328 $constraintValue = new VersionConstraintValue(\substr($value, 1));
27329 $constraints = [new GreaterThanOrEqualToVersionConstraint($value, new Version(\substr($value, 1)))];
27330 if ($constraintValue->getMajor()->getValue() === 0) {
27331 $constraints[] = new SpecificMajorAndMinorVersionConstraint($value, $constraintValue->getMajor()->getValue() ?? 0, $constraintValue->getMinor()->getValue() ?? 0);
27332 } else {
27333 $constraints[] = new SpecificMajorVersionConstraint($value, $constraintValue->getMajor()->getValue() ?? 0);
27334 }
27335 return new AndVersionConstraintGroup($value, $constraints);
27336 }
27337 }
27338 <?php
27339
27340 declare (strict_types=1);
27341 namespace PHPUnitPHAR\PharIo\Version;
27342
27343 class VersionConstraintValue
27344 {
27345 /** @var VersionNumber */
27346 private $major;
27347 /** @var VersionNumber */
27348 private $minor;
27349 /** @var VersionNumber */
27350 private $patch;
27351 /** @var string */
27352 private $label = '';
27353 /** @var string */
27354 private $buildMetaData = '';
27355 /** @var string */
27356 private $versionString = '';
27357 public function __construct(string $versionString)
27358 {
27359 $this->versionString = $versionString;
27360 $this->parseVersion($versionString);
27361 }
27362 public function getLabel(): string
27363 {
27364 return $this->label;
27365 }
27366 public function getBuildMetaData(): string
27367 {
27368 return $this->buildMetaData;
27369 }
27370 public function getVersionString(): string
27371 {
27372 return $this->versionString;
27373 }
27374 public function getMajor(): VersionNumber
27375 {
27376 return $this->major;
27377 }
27378 public function getMinor(): VersionNumber
27379 {
27380 return $this->minor;
27381 }
27382 public function getPatch(): VersionNumber
27383 {
27384 return $this->patch;
27385 }
27386 private function parseVersion(string $versionString): void
27387 {
27388 $this->extractBuildMetaData($versionString);
27389 $this->extractLabel($versionString);
27390 $this->stripPotentialVPrefix($versionString);
27391 $versionSegments = \explode('.', $versionString);
27392 $this->major = new VersionNumber(\is_numeric($versionSegments[0]) ? (int) $versionSegments[0] : null);
27393 $minorValue = isset($versionSegments[1]) && \is_numeric($versionSegments[1]) ? (int) $versionSegments[1] : null;
27394 $patchValue = isset($versionSegments[2]) && \is_numeric($versionSegments[2]) ? (int) $versionSegments[2] : null;
27395 $this->minor = new VersionNumber($minorValue);
27396 $this->patch = new VersionNumber($patchValue);
27397 }
27398 private function extractBuildMetaData(string &$versionString): void
27399 {
27400 if (\preg_match('/\+(.*)/', $versionString, $matches) === 1) {
27401 $this->buildMetaData = $matches[1];
27402 $versionString = \str_replace($matches[0], '', $versionString);
27403 }
27404 }
27405 private function extractLabel(string &$versionString): void
27406 {
27407 if (\preg_match('/-(.*)/', $versionString, $matches) === 1) {
27408 $this->label = $matches[1];
27409 $versionString = \str_replace($matches[0], '', $versionString);
27410 }
27411 }
27412 private function stripPotentialVPrefix(string &$versionString): void
27413 {
27414 if ($versionString[0] !== 'v') {
27415 return;
27416 }
27417 $versionString = \substr($versionString, 1);
27418 }
27419 }
27420 <?php
27421
27422 declare (strict_types=1);
27423 /*
27424 * This file is part of PharIo\Version.
27425 *
27426 * (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de>
27427 *
27428 * For the full copyright and license information, please view the LICENSE
27429 * file that was distributed with this source code.
27430 */
27431 namespace PHPUnitPHAR\PharIo\Version;
27432
27433 class VersionNumber
27434 {
27435 /** @var ?int */
27436 private $value;
27437 public function __construct(?int $value)
27438 {
27439 $this->value = $value;
27440 }
27441 public function isAny(): bool
27442 {
27443 return $this->value === null;
27444 }
27445 public function getValue(): ?int
27446 {
27447 return $this->value;
27448 }
27449 }
27450 <?php
27451
27452 declare (strict_types=1);
27453 /*
27454 * This file is part of PharIo\Version.
27455 *
27456 * (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de>
27457 *
27458 * For the full copyright and license information, please view the LICENSE
27459 * file that was distributed with this source code.
27460 */
27461 namespace PHPUnitPHAR\PharIo\Version;
27462
27463 abstract class AbstractVersionConstraint implements VersionConstraint
27464 {
27465 /** @var string */
27466 private $originalValue;
27467 public function __construct(string $originalValue)
27468 {
27469 $this->originalValue = $originalValue;
27470 }
27471 public function asString(): string
27472 {
27473 return $this->originalValue;
27474 }
27475 }
27476 <?php
27477
27478 declare (strict_types=1);
27479 /*
27480 * This file is part of PharIo\Version.
27481 *
27482 * (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de>
27483 *
27484 * For the full copyright and license information, please view the LICENSE
27485 * file that was distributed with this source code.
27486 */
27487 namespace PHPUnitPHAR\PharIo\Version;
27488
27489 class AndVersionConstraintGroup extends AbstractVersionConstraint
27490 {
27491 /** @var VersionConstraint[] */
27492 private $constraints = [];
27493 /**
27494 * @param VersionConstraint[] $constraints
27495 */
27496 public function __construct(string $originalValue, array $constraints)
27497 {
27498 parent::__construct($originalValue);
27499 $this->constraints = $constraints;
27500 }
27501 public function complies(Version $version): bool
27502 {
27503 foreach ($this->constraints as $constraint) {
27504 if (!$constraint->complies($version)) {
27505 return \false;
27506 }
27507 }
27508 return \true;
27509 }
27510 }
27511 <?php
27512
27513 declare (strict_types=1);
27514 /*
27515 * This file is part of PharIo\Version.
27516 *
27517 * (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de>
27518 *
27519 * For the full copyright and license information, please view the LICENSE
27520 * file that was distributed with this source code.
27521 */
27522 namespace PHPUnitPHAR\PharIo\Version;
27523
27524 class AnyVersionConstraint implements VersionConstraint
27525 {
27526 public function complies(Version $version): bool
27527 {
27528 return \true;
27529 }
27530 public function asString(): string
27531 {
27532 return '*';
27533 }
27534 }
27535 <?php
27536
27537 declare (strict_types=1);
27538 /*
27539 * This file is part of PharIo\Version.
27540 *
27541 * (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de>
27542 *
27543 * For the full copyright and license information, please view the LICENSE
27544 * file that was distributed with this source code.
27545 */
27546 namespace PHPUnitPHAR\PharIo\Version;
27547
27548 class ExactVersionConstraint extends AbstractVersionConstraint
27549 {
27550 public function complies(Version $version): bool
27551 {
27552 $other = $version->getVersionString();
27553 if ($version->hasBuildMetaData()) {
27554 $other .= '+' . $version->getBuildMetaData()->asString();
27555 }
27556 return $this->asString() === $other;
27557 }
27558 }
27559 <?php
27560
27561 declare (strict_types=1);
27562 /*
27563 * This file is part of PharIo\Version.
27564 *
27565 * (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de>
27566 *
27567 * For the full copyright and license information, please view the LICENSE
27568 * file that was distributed with this source code.
27569 */
27570 namespace PHPUnitPHAR\PharIo\Version;
27571
27572 class GreaterThanOrEqualToVersionConstraint extends AbstractVersionConstraint
27573 {
27574 /** @var Version */
27575 private $minimalVersion;
27576 public function __construct(string $originalValue, Version $minimalVersion)
27577 {
27578 parent::__construct($originalValue);
27579 $this->minimalVersion = $minimalVersion;
27580 }
27581 public function complies(Version $version): bool
27582 {
27583 return $version->getVersionString() === $this->minimalVersion->getVersionString() || $version->isGreaterThan($this->minimalVersion);
27584 }
27585 }
27586 <?php
27587
27588 declare (strict_types=1);
27589 /*
27590 * This file is part of PharIo\Version.
27591 *
27592 * (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de>
27593 *
27594 * For the full copyright and license information, please view the LICENSE
27595 * file that was distributed with this source code.
27596 */
27597 namespace PHPUnitPHAR\PharIo\Version;
27598
27599 class OrVersionConstraintGroup extends AbstractVersionConstraint
27600 {
27601 /** @var VersionConstraint[] */
27602 private $constraints = [];
27603 /**
27604 * @param string $originalValue
27605 * @param VersionConstraint[] $constraints
27606 */
27607 public function __construct($originalValue, array $constraints)
27608 {
27609 parent::__construct($originalValue);
27610 $this->constraints = $constraints;
27611 }
27612 public function complies(Version $version): bool
27613 {
27614 foreach ($this->constraints as $constraint) {
27615 if ($constraint->complies($version)) {
27616 return \true;
27617 }
27618 }
27619 return \false;
27620 }
27621 }
27622 <?php
27623
27624 declare (strict_types=1);
27625 /*
27626 * This file is part of PharIo\Version.
27627 *
27628 * (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de>
27629 *
27630 * For the full copyright and license information, please view the LICENSE
27631 * file that was distributed with this source code.
27632 */
27633 namespace PHPUnitPHAR\PharIo\Version;
27634
27635 class SpecificMajorAndMinorVersionConstraint extends AbstractVersionConstraint
27636 {
27637 /** @var int */
27638 private $major;
27639 /** @var int */
27640 private $minor;
27641 public function __construct(string $originalValue, int $major, int $minor)
27642 {
27643 parent::__construct($originalValue);
27644 $this->major = $major;
27645 $this->minor = $minor;
27646 }
27647 public function complies(Version $version): bool
27648 {
27649 if ($version->getMajor()->getValue() !== $this->major) {
27650 return \false;
27651 }
27652 return $version->getMinor()->getValue() === $this->minor;
27653 }
27654 }
27655 <?php
27656
27657 declare (strict_types=1);
27658 /*
27659 * This file is part of PharIo\Version.
27660 *
27661 * (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de>
27662 *
27663 * For the full copyright and license information, please view the LICENSE
27664 * file that was distributed with this source code.
27665 */
27666 namespace PHPUnitPHAR\PharIo\Version;
27667
27668 class SpecificMajorVersionConstraint extends AbstractVersionConstraint
27669 {
27670 /** @var int */
27671 private $major;
27672 public function __construct(string $originalValue, int $major)
27673 {
27674 parent::__construct($originalValue);
27675 $this->major = $major;
27676 }
27677 public function complies(Version $version): bool
27678 {
27679 return $version->getMajor()->getValue() === $this->major;
27680 }
27681 }
27682 <?php
27683
27684 declare (strict_types=1);
27685 /*
27686 * This file is part of PharIo\Version.
27687 *
27688 * (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de>
27689 *
27690 * For the full copyright and license information, please view the LICENSE
27691 * file that was distributed with this source code.
27692 */
27693 namespace PHPUnitPHAR\PharIo\Version;
27694
27695 interface VersionConstraint
27696 {
27697 public function complies(Version $version): bool;
27698 public function asString(): string;
27699 }
27700 <?php
27701
27702 declare (strict_types=1);
27703 /*
27704 * This file is part of PharIo\Version.
27705 *
27706 * (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de>
27707 *
27708 * For the full copyright and license information, please view the LICENSE
27709 * file that was distributed with this source code.
27710 */
27711 namespace PHPUnitPHAR\PharIo\Version;
27712
27713 use Throwable;
27714 interface Exception extends Throwable
27715 {
27716 }
27717 <?php
27718
27719 declare (strict_types=1);
27720 namespace PHPUnitPHAR\PharIo\Version;
27721
27722 class InvalidPreReleaseSuffixException extends \Exception implements Exception
27723 {
27724 }
27725 <?php
27726
27727 declare (strict_types=1);
27728 namespace PHPUnitPHAR\PharIo\Version;
27729
27730 class InvalidVersionException extends \InvalidArgumentException implements Exception
27731 {
27732 }
27733 <?php
27734
27735 declare (strict_types=1);
27736 namespace PHPUnitPHAR\PharIo\Version;
27737
27738 class NoBuildMetaDataException extends \Exception implements Exception
27739 {
27740 }
27741 <?php
27742
27743 declare (strict_types=1);
27744 namespace PHPUnitPHAR\PharIo\Version;
27745
27746 class NoPreReleaseSuffixException extends \Exception implements Exception
27747 {
27748 }
27749 <?php
27750
27751 declare (strict_types=1);
27752 /*
27753 * This file is part of PharIo\Version.
27754 *
27755 * (c) Arne Blankerts <arne@blankerts.de>, Sebastian Heuer <sebastian@phpeople.de>, Sebastian Bergmann <sebastian@phpunit.de>
27756 *
27757 * For the full copyright and license information, please view the LICENSE
27758 * file that was distributed with this source code.
27759 */
27760 namespace PHPUnitPHAR\PharIo\Version;
27761
27762 final class UnsupportedVersionConstraintException extends \RuntimeException implements Exception
27763 {
27764 }
27765 <?php
27766
27767 declare (strict_types=1);
27768 /*
27769 * This file is part of phpunit/php-code-coverage.
27770 *
27771 * (c) Sebastian Bergmann <sebastian@phpunit.de>
27772 *
27773 * For the full copyright and license information, please view the LICENSE
27774 * file that was distributed with this source code.
27775 */
27776 namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage;
27777
27778 use function array_diff;
27779 use function array_diff_key;
27780 use function array_flip;
27781 use function array_keys;
27782 use function array_merge;
27783 use function array_merge_recursive;
27784 use function array_unique;
27785 use function count;
27786 use function explode;
27787 use function is_array;
27788 use function is_file;
27789 use function sort;
27790 use ReflectionClass;
27791 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Data\ProcessedCodeCoverageData;
27792 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Data\RawCodeCoverageData;
27793 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Driver\Driver;
27794 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Node\Builder;
27795 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Node\Directory;
27796 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\StaticAnalysis\CachingFileAnalyser;
27797 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\StaticAnalysis\FileAnalyser;
27798 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\StaticAnalysis\ParsingFileAnalyser;
27799 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Test\TestSize\TestSize;
27800 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Test\TestStatus\TestStatus;
27801 use PHPUnitPHAR\SebastianBergmann\CodeUnitReverseLookup\Wizard;
27802 /**
27803 * Provides collection functionality for PHP code coverage information.
27804 *
27805 * @psalm-type TestType = array{
27806 * size: string,
27807 * status: string,
27808 * }
27809 */
27810 final class CodeCoverage
27811 {
27812 private const UNCOVERED_FILES = 'UNCOVERED_FILES';
27813 private readonly Driver $driver;
27814 private readonly Filter $filter;
27815 private readonly Wizard $wizard;
27816 private bool $checkForUnintentionallyCoveredCode = \false;
27817 private bool $includeUncoveredFiles = \true;
27818 private bool $ignoreDeprecatedCode = \false;
27819 private ?string $currentId = null;
27820 private ?TestSize $currentSize = null;
27821 private ProcessedCodeCoverageData $data;
27822 private bool $useAnnotationsForIgnoringCode = \true;
27823 /**
27824 * @psalm-var array<string,list<int>>
27825 */
27826 private array $linesToBeIgnored = [];
27827 /**
27828 * @psalm-var array<string, TestType>
27829 */
27830 private array $tests = [];
27831 /**
27832 * @psalm-var list<class-string>
27833 */
27834 private array $parentClassesExcludedFromUnintentionallyCoveredCodeCheck = [];
27835 private ?FileAnalyser $analyser = null;
27836 private ?string $cacheDirectory = null;
27837 private ?Directory $cachedReport = null;
27838 public function __construct(Driver $driver, Filter $filter)
27839 {
27840 $this->driver = $driver;
27841 $this->filter = $filter;
27842 $this->data = new ProcessedCodeCoverageData();
27843 $this->wizard = new Wizard();
27844 }
27845 /**
27846 * Returns the code coverage information as a graph of node objects.
27847 */
27848 public function getReport(): Directory
27849 {
27850 if ($this->cachedReport === null) {
27851 $this->cachedReport = (new Builder($this->analyser()))->build($this);
27852 }
27853 return $this->cachedReport;
27854 }
27855 /**
27856 * Clears collected code coverage data.
27857 */
27858 public function clear(): void
27859 {
27860 $this->currentId = null;
27861 $this->currentSize = null;
27862 $this->data = new ProcessedCodeCoverageData();
27863 $this->tests = [];
27864 $this->cachedReport = null;
27865 }
27866 /**
27867 * @internal
27868 */
27869 public function clearCache(): void
27870 {
27871 $this->cachedReport = null;
27872 }
27873 /**
27874 * Returns the filter object used.
27875 */
27876 public function filter(): Filter
27877 {
27878 return $this->filter;
27879 }
27880 /**
27881 * Returns the collected code coverage data.
27882 */
27883 public function getData(bool $raw = \false): ProcessedCodeCoverageData
27884 {
27885 if (!$raw) {
27886 if ($this->includeUncoveredFiles) {
27887 $this->addUncoveredFilesFromFilter();
27888 }
27889 }
27890 return $this->data;
27891 }
27892 /**
27893 * Sets the coverage data.
27894 */
27895 public function setData(ProcessedCodeCoverageData $data): void
27896 {
27897 $this->data = $data;
27898 }
27899 /**
27900 * @psalm-return array<string, TestType>
27901 */
27902 public function getTests(): array
27903 {
27904 return $this->tests;
27905 }
27906 /**
27907 * @psalm-param array<string, TestType> $tests
27908 */
27909 public function setTests(array $tests): void
27910 {
27911 $this->tests = $tests;
27912 }
27913 public function start(string $id, ?TestSize $size = null, bool $clear = \false): void
27914 {
27915 if ($clear) {
27916 $this->clear();
27917 }
27918 $this->currentId = $id;
27919 $this->currentSize = $size;
27920 $this->driver->start();
27921 $this->cachedReport = null;
27922 }
27923 /**
27924 * @psalm-param array<string,list<int>> $linesToBeIgnored
27925 */
27926 public function stop(bool $append = \true, ?TestStatus $status = null, array|false $linesToBeCovered = [], array $linesToBeUsed = [], array $linesToBeIgnored = []): RawCodeCoverageData
27927 {
27928 $data = $this->driver->stop();
27929 $this->linesToBeIgnored = array_merge_recursive($this->linesToBeIgnored, $linesToBeIgnored);
27930 $this->append($data, null, $append, $status, $linesToBeCovered, $linesToBeUsed, $linesToBeIgnored);
27931 $this->currentId = null;
27932 $this->currentSize = null;
27933 $this->cachedReport = null;
27934 return $data;
27935 }
27936 /**
27937 * @psalm-param array<string,list<int>> $linesToBeIgnored
27938 *
27939 * @throws ReflectionException
27940 * @throws TestIdMissingException
27941 * @throws UnintentionallyCoveredCodeException
27942 */
27943 public function append(RawCodeCoverageData $rawData, ?string $id = null, bool $append = \true, ?TestStatus $status = null, array|false $linesToBeCovered = [], array $linesToBeUsed = [], array $linesToBeIgnored = []): void
27944 {
27945 if ($id === null) {
27946 $id = $this->currentId;
27947 }
27948 if ($id === null) {
27949 throw new TestIdMissingException();
27950 }
27951 $this->cachedReport = null;
27952 if ($status === null) {
27953 $status = TestStatus::unknown();
27954 }
27955 $size = $this->currentSize;
27956 if ($size === null) {
27957 $size = TestSize::unknown();
27958 }
27959 $this->applyFilter($rawData);
27960 $this->applyExecutableLinesFilter($rawData);
27961 if ($this->useAnnotationsForIgnoringCode) {
27962 $this->applyIgnoredLinesFilter($rawData, $linesToBeIgnored);
27963 }
27964 $this->data->initializeUnseenData($rawData);
27965 if (!$append) {
27966 return;
27967 }
27968 if ($id === self::UNCOVERED_FILES) {
27969 return;
27970 }
27971 $this->applyCoversAndUsesFilter($rawData, $linesToBeCovered, $linesToBeUsed, $size);
27972 if (empty($rawData->lineCoverage())) {
27973 return;
27974 }
27975 $this->tests[$id] = ['size' => $size->asString(), 'status' => $status->asString()];
27976 $this->data->markCodeAsExecutedByTestCase($id, $rawData);
27977 }
27978 /**
27979 * Merges the data from another instance.
27980 */
27981 public function merge(self $that): void
27982 {
27983 $this->filter->includeFiles($that->filter()->files());
27984 $this->data->merge($that->data);
27985 $this->tests = array_merge($this->tests, $that->getTests());
27986 $this->cachedReport = null;
27987 }
27988 public function enableCheckForUnintentionallyCoveredCode(): void
27989 {
27990 $this->checkForUnintentionallyCoveredCode = \true;
27991 }
27992 public function disableCheckForUnintentionallyCoveredCode(): void
27993 {
27994 $this->checkForUnintentionallyCoveredCode = \false;
27995 }
27996 public function includeUncoveredFiles(): void
27997 {
27998 $this->includeUncoveredFiles = \true;
27999 }
28000 public function excludeUncoveredFiles(): void
28001 {
28002 $this->includeUncoveredFiles = \false;
28003 }
28004 public function enableAnnotationsForIgnoringCode(): void
28005 {
28006 $this->useAnnotationsForIgnoringCode = \true;
28007 }
28008 public function disableAnnotationsForIgnoringCode(): void
28009 {
28010 $this->useAnnotationsForIgnoringCode = \false;
28011 }
28012 public function ignoreDeprecatedCode(): void
28013 {
28014 $this->ignoreDeprecatedCode = \true;
28015 }
28016 public function doNotIgnoreDeprecatedCode(): void
28017 {
28018 $this->ignoreDeprecatedCode = \false;
28019 }
28020 /**
28021 * @psalm-assert-if-true !null $this->cacheDirectory
28022 */
28023 public function cachesStaticAnalysis(): bool
28024 {
28025 return $this->cacheDirectory !== null;
28026 }
28027 public function cacheStaticAnalysis(string $directory): void
28028 {
28029 $this->cacheDirectory = $directory;
28030 }
28031 public function doNotCacheStaticAnalysis(): void
28032 {
28033 $this->cacheDirectory = null;
28034 }
28035 /**
28036 * @throws StaticAnalysisCacheNotConfiguredException
28037 */
28038 public function cacheDirectory(): string
28039 {
28040 if (!$this->cachesStaticAnalysis()) {
28041 throw new StaticAnalysisCacheNotConfiguredException('The static analysis cache is not configured');
28042 }
28043 return $this->cacheDirectory;
28044 }
28045 /**
28046 * @psalm-param class-string $className
28047 */
28048 public function excludeSubclassesOfThisClassFromUnintentionallyCoveredCodeCheck(string $className): void
28049 {
28050 $this->parentClassesExcludedFromUnintentionallyCoveredCodeCheck[] = $className;
28051 }
28052 public function enableBranchAndPathCoverage(): void
28053 {
28054 $this->driver->enableBranchAndPathCoverage();
28055 }
28056 public function disableBranchAndPathCoverage(): void
28057 {
28058 $this->driver->disableBranchAndPathCoverage();
28059 }
28060 public function collectsBranchAndPathCoverage(): bool
28061 {
28062 return $this->driver->collectsBranchAndPathCoverage();
28063 }
28064 public function detectsDeadCode(): bool
28065 {
28066 return $this->driver->detectsDeadCode();
28067 }
28068 /**
28069 * @throws ReflectionException
28070 * @throws UnintentionallyCoveredCodeException
28071 */
28072 private function applyCoversAndUsesFilter(RawCodeCoverageData $rawData, array|false $linesToBeCovered, array $linesToBeUsed, TestSize $size): void
28073 {
28074 if ($linesToBeCovered === \false) {
28075 $rawData->clear();
28076 return;
28077 }
28078 if (empty($linesToBeCovered)) {
28079 return;
28080 }
28081 if ($this->checkForUnintentionallyCoveredCode && !$size->isMedium() && !$size->isLarge()) {
28082 $this->performUnintentionallyCoveredCodeCheck($rawData, $linesToBeCovered, $linesToBeUsed);
28083 }
28084 $rawLineData = $rawData->lineCoverage();
28085 $filesWithNoCoverage = array_diff_key($rawLineData, $linesToBeCovered);
28086 foreach (array_keys($filesWithNoCoverage) as $fileWithNoCoverage) {
28087 $rawData->removeCoverageDataForFile($fileWithNoCoverage);
28088 }
28089 if (is_array($linesToBeCovered)) {
28090 foreach ($linesToBeCovered as $fileToBeCovered => $includedLines) {
28091 $rawData->keepLineCoverageDataOnlyForLines($fileToBeCovered, $includedLines);
28092 $rawData->keepFunctionCoverageDataOnlyForLines($fileToBeCovered, $includedLines);
28093 }
28094 }
28095 }
28096 private function applyFilter(RawCodeCoverageData $data): void
28097 {
28098 if ($this->filter->isEmpty()) {
28099 return;
28100 }
28101 foreach (array_keys($data->lineCoverage()) as $filename) {
28102 if ($this->filter->isExcluded($filename)) {
28103 $data->removeCoverageDataForFile($filename);
28104 }
28105 }
28106 }
28107 private function applyExecutableLinesFilter(RawCodeCoverageData $data): void
28108 {
28109 foreach (array_keys($data->lineCoverage()) as $filename) {
28110 if (!$this->filter->isFile($filename)) {
28111 continue;
28112 }
28113 $linesToBranchMap = $this->analyser()->executableLinesIn($filename);
28114 $data->keepLineCoverageDataOnlyForLines($filename, array_keys($linesToBranchMap));
28115 $data->markExecutableLineByBranch($filename, $linesToBranchMap);
28116 }
28117 }
28118 /**
28119 * @psalm-param array<string,list<int>> $linesToBeIgnored
28120 */
28121 private function applyIgnoredLinesFilter(RawCodeCoverageData $data, array $linesToBeIgnored): void
28122 {
28123 foreach (array_keys($data->lineCoverage()) as $filename) {
28124 if (!$this->filter->isFile($filename)) {
28125 continue;
28126 }
28127 if (isset($linesToBeIgnored[$filename])) {
28128 $data->removeCoverageDataForLines($filename, $linesToBeIgnored[$filename]);
28129 }
28130 $data->removeCoverageDataForLines($filename, $this->analyser()->ignoredLinesFor($filename));
28131 }
28132 }
28133 /**
28134 * @throws UnintentionallyCoveredCodeException
28135 */
28136 private function addUncoveredFilesFromFilter(): void
28137 {
28138 $uncoveredFiles = array_diff($this->filter->files(), $this->data->coveredFiles());
28139 foreach ($uncoveredFiles as $uncoveredFile) {
28140 if (is_file($uncoveredFile)) {
28141 $this->append(RawCodeCoverageData::fromUncoveredFile($uncoveredFile, $this->analyser()), self::UNCOVERED_FILES, linesToBeIgnored: $this->linesToBeIgnored);
28142 }
28143 }
28144 }
28145 /**
28146 * @throws ReflectionException
28147 * @throws UnintentionallyCoveredCodeException
28148 */
28149 private function performUnintentionallyCoveredCodeCheck(RawCodeCoverageData $data, array $linesToBeCovered, array $linesToBeUsed): void
28150 {
28151 $allowedLines = $this->getAllowedLines($linesToBeCovered, $linesToBeUsed);
28152 $unintentionallyCoveredUnits = [];
28153 foreach ($data->lineCoverage() as $file => $_data) {
28154 foreach ($_data as $line => $flag) {
28155 if ($flag === 1 && !isset($allowedLines[$file][$line])) {
28156 $unintentionallyCoveredUnits[] = $this->wizard->lookup($file, $line);
28157 }
28158 }
28159 }
28160 $unintentionallyCoveredUnits = $this->processUnintentionallyCoveredUnits($unintentionallyCoveredUnits);
28161 if (!empty($unintentionallyCoveredUnits)) {
28162 throw new UnintentionallyCoveredCodeException($unintentionallyCoveredUnits);
28163 }
28164 }
28165 private function getAllowedLines(array $linesToBeCovered, array $linesToBeUsed): array
28166 {
28167 $allowedLines = [];
28168 foreach (array_keys($linesToBeCovered) as $file) {
28169 if (!isset($allowedLines[$file])) {
28170 $allowedLines[$file] = [];
28171 }
28172 $allowedLines[$file] = array_merge($allowedLines[$file], $linesToBeCovered[$file]);
28173 }
28174 foreach (array_keys($linesToBeUsed) as $file) {
28175 if (!isset($allowedLines[$file])) {
28176 $allowedLines[$file] = [];
28177 }
28178 $allowedLines[$file] = array_merge($allowedLines[$file], $linesToBeUsed[$file]);
28179 }
28180 foreach (array_keys($allowedLines) as $file) {
28181 $allowedLines[$file] = array_flip(array_unique($allowedLines[$file]));
28182 }
28183 return $allowedLines;
28184 }
28185 /**
28186 * @param list<string> $unintentionallyCoveredUnits
28187 *
28188 * @throws ReflectionException
28189 *
28190 * @return list<string>
28191 */
28192 private function processUnintentionallyCoveredUnits(array $unintentionallyCoveredUnits): array
28193 {
28194 $unintentionallyCoveredUnits = array_unique($unintentionallyCoveredUnits);
28195 $processed = [];
28196 foreach ($unintentionallyCoveredUnits as $unintentionallyCoveredUnit) {
28197 $tmp = explode('::', $unintentionallyCoveredUnit);
28198 if (count($tmp) !== 2) {
28199 $processed[] = $unintentionallyCoveredUnit;
28200 continue;
28201 }
28202 try {
28203 $class = new ReflectionClass($tmp[0]);
28204 foreach ($this->parentClassesExcludedFromUnintentionallyCoveredCodeCheck as $parentClass) {
28205 if ($class->isSubclassOf($parentClass)) {
28206 continue 2;
28207 }
28208 }
28209 } catch (\ReflectionException $e) {
28210 throw new ReflectionException($e->getMessage(), $e->getCode(), $e);
28211 }
28212 $processed[] = $tmp[0];
28213 }
28214 $processed = array_unique($processed);
28215 sort($processed);
28216 return $processed;
28217 }
28218 private function analyser(): FileAnalyser
28219 {
28220 if ($this->analyser !== null) {
28221 return $this->analyser;
28222 }
28223 $this->analyser = new ParsingFileAnalyser($this->useAnnotationsForIgnoringCode, $this->ignoreDeprecatedCode);
28224 if ($this->cachesStaticAnalysis()) {
28225 $this->analyser = new CachingFileAnalyser($this->cacheDirectory, $this->analyser, $this->useAnnotationsForIgnoringCode, $this->ignoreDeprecatedCode);
28226 }
28227 return $this->analyser;
28228 }
28229 }
28230 <?php
28231
28232 declare (strict_types=1);
28233 /*
28234 * This file is part of phpunit/php-code-coverage.
28235 *
28236 * (c) Sebastian Bergmann <sebastian@phpunit.de>
28237 *
28238 * For the full copyright and license information, please view the LICENSE
28239 * file that was distributed with this source code.
28240 */
28241 namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\Data;
28242
28243 use function array_key_exists;
28244 use function array_keys;
28245 use function array_merge;
28246 use function array_unique;
28247 use function count;
28248 use function is_array;
28249 use function ksort;
28250 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Driver\Driver;
28251 /**
28252 * @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
28253 *
28254 * @psalm-import-type XdebugFunctionCoverageType from \SebastianBergmann\CodeCoverage\Driver\XdebugDriver
28255 *
28256 * @psalm-type TestIdType = string
28257 */
28258 final class ProcessedCodeCoverageData
28259 {
28260 /**
28261 * Line coverage data.
28262 * An array of filenames, each having an array of linenumbers, each executable line having an array of testcase ids.
28263 *
28264 * @psalm-var array<string, array<int, null|list<TestIdType>>>
28265 */
28266 private array $lineCoverage = [];
28267 /**
28268 * Function coverage data.
28269 * Maintains base format of raw data (@see https://xdebug.org/docs/code_coverage), but each 'hit' entry is an array
28270 * of testcase ids.
28271 *
28272 * @psalm-var array<string, array<string, array{
28273 * branches: array<int, array{
28274 * op_start: int,
28275 * op_end: int,
28276 * line_start: int,
28277 * line_end: int,
28278 * hit: list<TestIdType>,
28279 * out: array<int, int>,
28280 * out_hit: array<int, int>,
28281 * }>,
28282 * paths: array<int, array{
28283 * path: array<int, int>,
28284 * hit: list<TestIdType>,
28285 * }>,
28286 * hit: list<TestIdType>
28287 * }>>
28288 */
28289 private array $functionCoverage = [];
28290 public function initializeUnseenData(RawCodeCoverageData $rawData): void
28291 {
28292 foreach ($rawData->lineCoverage() as $file => $lines) {
28293 if (!isset($this->lineCoverage[$file])) {
28294 $this->lineCoverage[$file] = [];
28295 foreach ($lines as $k => $v) {
28296 $this->lineCoverage[$file][$k] = $v === Driver::LINE_NOT_EXECUTABLE ? null : [];
28297 }
28298 }
28299 }
28300 foreach ($rawData->functionCoverage() as $file => $functions) {
28301 foreach ($functions as $functionName => $functionData) {
28302 if (isset($this->functionCoverage[$file][$functionName])) {
28303 $this->initPreviouslySeenFunction($file, $functionName, $functionData);
28304 } else {
28305 $this->initPreviouslyUnseenFunction($file, $functionName, $functionData);
28306 }
28307 }
28308 }
28309 }
28310 public function markCodeAsExecutedByTestCase(string $testCaseId, RawCodeCoverageData $executedCode): void
28311 {
28312 foreach ($executedCode->lineCoverage() as $file => $lines) {
28313 foreach ($lines as $k => $v) {
28314 if ($v === Driver::LINE_EXECUTED) {
28315 $this->lineCoverage[$file][$k][] = $testCaseId;
28316 }
28317 }
28318 }
28319 foreach ($executedCode->functionCoverage() as $file => $functions) {
28320 foreach ($functions as $functionName => $functionData) {
28321 foreach ($functionData['branches'] as $branchId => $branchData) {
28322 if ($branchData['hit'] === Driver::BRANCH_HIT) {
28323 $this->functionCoverage[$file][$functionName]['branches'][$branchId]['hit'][] = $testCaseId;
28324 }
28325 }
28326 foreach ($functionData['paths'] as $pathId => $pathData) {
28327 if ($pathData['hit'] === Driver::BRANCH_HIT) {
28328 $this->functionCoverage[$file][$functionName]['paths'][$pathId]['hit'][] = $testCaseId;
28329 }
28330 }
28331 }
28332 }
28333 }
28334 public function setLineCoverage(array $lineCoverage): void
28335 {
28336 $this->lineCoverage = $lineCoverage;
28337 }
28338 public function lineCoverage(): array
28339 {
28340 ksort($this->lineCoverage);
28341 return $this->lineCoverage;
28342 }
28343 public function setFunctionCoverage(array $functionCoverage): void
28344 {
28345 $this->functionCoverage = $functionCoverage;
28346 }
28347 public function functionCoverage(): array
28348 {
28349 ksort($this->functionCoverage);
28350 return $this->functionCoverage;
28351 }
28352 public function coveredFiles(): array
28353 {
28354 ksort($this->lineCoverage);
28355 return array_keys($this->lineCoverage);
28356 }
28357 public function renameFile(string $oldFile, string $newFile): void
28358 {
28359 $this->lineCoverage[$newFile] = $this->lineCoverage[$oldFile];
28360 if (isset($this->functionCoverage[$oldFile])) {
28361 $this->functionCoverage[$newFile] = $this->functionCoverage[$oldFile];
28362 }
28363 unset($this->lineCoverage[$oldFile], $this->functionCoverage[$oldFile]);
28364 }
28365 public function merge(self $newData): void
28366 {
28367 foreach ($newData->lineCoverage as $file => $lines) {
28368 if (!isset($this->lineCoverage[$file])) {
28369 $this->lineCoverage[$file] = $lines;
28370 continue;
28371 }
28372 // we should compare the lines if any of two contains data
28373 $compareLineNumbers = array_unique(array_merge(array_keys($this->lineCoverage[$file]), array_keys($newData->lineCoverage[$file])));
28374 foreach ($compareLineNumbers as $line) {
28375 $thatPriority = $this->priorityForLine($newData->lineCoverage[$file], $line);
28376 $thisPriority = $this->priorityForLine($this->lineCoverage[$file], $line);
28377 if ($thatPriority > $thisPriority) {
28378 $this->lineCoverage[$file][$line] = $newData->lineCoverage[$file][$line];
28379 } elseif ($thatPriority === $thisPriority && is_array($this->lineCoverage[$file][$line])) {
28380 $this->lineCoverage[$file][$line] = array_unique(array_merge($this->lineCoverage[$file][$line], $newData->lineCoverage[$file][$line]));
28381 }
28382 }
28383 }
28384 foreach ($newData->functionCoverage as $file => $functions) {
28385 if (!isset($this->functionCoverage[$file])) {
28386 $this->functionCoverage[$file] = $functions;
28387 continue;
28388 }
28389 foreach ($functions as $functionName => $functionData) {
28390 if (isset($this->functionCoverage[$file][$functionName])) {
28391 $this->initPreviouslySeenFunction($file, $functionName, $functionData);
28392 } else {
28393 $this->initPreviouslyUnseenFunction($file, $functionName, $functionData);
28394 }
28395 foreach ($functionData['branches'] as $branchId => $branchData) {
28396 $this->functionCoverage[$file][$functionName]['branches'][$branchId]['hit'] = array_unique(array_merge($this->functionCoverage[$file][$functionName]['branches'][$branchId]['hit'], $branchData['hit']));
28397 }
28398 foreach ($functionData['paths'] as $pathId => $pathData) {
28399 $this->functionCoverage[$file][$functionName]['paths'][$pathId]['hit'] = array_unique(array_merge($this->functionCoverage[$file][$functionName]['paths'][$pathId]['hit'], $pathData['hit']));
28400 }
28401 }
28402 }
28403 }
28404 /**
28405 * Determine the priority for a line.
28406 *
28407 * 1 = the line is not set
28408 * 2 = the line has not been tested
28409 * 3 = the line is dead code
28410 * 4 = the line has been tested
28411 *
28412 * During a merge, a higher number is better.
28413 */
28414 private function priorityForLine(array $data, int $line): int
28415 {
28416 if (!array_key_exists($line, $data)) {
28417 return 1;
28418 }
28419 if (is_array($data[$line]) && count($data[$line]) === 0) {
28420 return 2;
28421 }
28422 if ($data[$line] === null) {
28423 return 3;
28424 }
28425 return 4;
28426 }
28427 /**
28428 * For a function we have never seen before, copy all data over and simply init the 'hit' array.
28429 *
28430 * @psalm-param XdebugFunctionCoverageType $functionData
28431 */
28432 private function initPreviouslyUnseenFunction(string $file, string $functionName, array $functionData): void
28433 {
28434 $this->functionCoverage[$file][$functionName] = $functionData;
28435 foreach (array_keys($functionData['branches']) as $branchId) {
28436 $this->functionCoverage[$file][$functionName]['branches'][$branchId]['hit'] = [];
28437 }
28438 foreach (array_keys($functionData['paths']) as $pathId) {
28439 $this->functionCoverage[$file][$functionName]['paths'][$pathId]['hit'] = [];
28440 }
28441 }
28442 /**
28443 * For a function we have seen before, only copy over and init the 'hit' array for any unseen branches and paths.
28444 * Techniques such as mocking and where the contents of a file are different vary during tests (e.g. compiling
28445 * containers) mean that the functions inside a file cannot be relied upon to be static.
28446 *
28447 * @psalm-param XdebugFunctionCoverageType $functionData
28448 */
28449 private function initPreviouslySeenFunction(string $file, string $functionName, array $functionData): void
28450 {
28451 foreach ($functionData['branches'] as $branchId => $branchData) {
28452 if (!isset($this->functionCoverage[$file][$functionName]['branches'][$branchId])) {
28453 $this->functionCoverage[$file][$functionName]['branches'][$branchId] = $branchData;
28454 $this->functionCoverage[$file][$functionName]['branches'][$branchId]['hit'] = [];
28455 }
28456 }
28457 foreach ($functionData['paths'] as $pathId => $pathData) {
28458 if (!isset($this->functionCoverage[$file][$functionName]['paths'][$pathId])) {
28459 $this->functionCoverage[$file][$functionName]['paths'][$pathId] = $pathData;
28460 $this->functionCoverage[$file][$functionName]['paths'][$pathId]['hit'] = [];
28461 }
28462 }
28463 }
28464 }
28465 <?php
28466
28467 declare (strict_types=1);
28468 /*
28469 * This file is part of phpunit/php-code-coverage.
28470 *
28471 * (c) Sebastian Bergmann <sebastian@phpunit.de>
28472 *
28473 * For the full copyright and license information, please view the LICENSE
28474 * file that was distributed with this source code.
28475 */
28476 namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\Data;
28477
28478 use function array_diff;
28479 use function array_diff_key;
28480 use function array_flip;
28481 use function array_intersect;
28482 use function array_intersect_key;
28483 use function count;
28484 use function explode;
28485 use function file_get_contents;
28486 use function in_array;
28487 use function is_file;
28488 use function preg_replace;
28489 use function range;
28490 use function str_ends_with;
28491 use function str_starts_with;
28492 use function trim;
28493 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Driver\Driver;
28494 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\StaticAnalysis\FileAnalyser;
28495 /**
28496 * @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
28497 *
28498 * @psalm-import-type XdebugFunctionsCoverageType from \SebastianBergmann\CodeCoverage\Driver\XdebugDriver
28499 * @psalm-import-type XdebugCodeCoverageWithoutPathCoverageType from \SebastianBergmann\CodeCoverage\Driver\XdebugDriver
28500 * @psalm-import-type XdebugCodeCoverageWithPathCoverageType from \SebastianBergmann\CodeCoverage\Driver\XdebugDriver
28501 */
28502 final class RawCodeCoverageData
28503 {
28504 /**
28505 * @var array<string, array<int>>
28506 */
28507 private static array $emptyLineCache = [];
28508 /**
28509 * @psalm-var XdebugCodeCoverageWithoutPathCoverageType
28510 */
28511 private array $lineCoverage;
28512 /**
28513 * @psalm-var array<string, XdebugFunctionsCoverageType>
28514 */
28515 private array $functionCoverage;
28516 /**
28517 * @psalm-param XdebugCodeCoverageWithoutPathCoverageType $rawCoverage
28518 */
28519 public static function fromXdebugWithoutPathCoverage(array $rawCoverage): self
28520 {
28521 return new self($rawCoverage, []);
28522 }
28523 /**
28524 * @psalm-param XdebugCodeCoverageWithPathCoverageType $rawCoverage
28525 */
28526 public static function fromXdebugWithPathCoverage(array $rawCoverage): self
28527 {
28528 $lineCoverage = [];
28529 $functionCoverage = [];
28530 foreach ($rawCoverage as $file => $fileCoverageData) {
28531 // Xdebug annotates the function name of traits, strip that off
28532 foreach ($fileCoverageData['functions'] as $existingKey => $data) {
28533 if (str_ends_with($existingKey, '}') && !str_starts_with($existingKey, '{')) {
28534 // don't want to catch {main}
28535 $newKey = preg_replace('/\{.*}$/', '', $existingKey);
28536 $fileCoverageData['functions'][$newKey] = $data;
28537 unset($fileCoverageData['functions'][$existingKey]);
28538 }
28539 }
28540 $lineCoverage[$file] = $fileCoverageData['lines'];
28541 $functionCoverage[$file] = $fileCoverageData['functions'];
28542 }
28543 return new self($lineCoverage, $functionCoverage);
28544 }
28545 public static function fromUncoveredFile(string $filename, FileAnalyser $analyser): self
28546 {
28547 $lineCoverage = [];
28548 foreach ($analyser->executableLinesIn($filename) as $line => $branch) {
28549 $lineCoverage[$line] = Driver::LINE_NOT_EXECUTED;
28550 }
28551 return new self([$filename => $lineCoverage], []);
28552 }
28553 /**
28554 * @psalm-param XdebugCodeCoverageWithoutPathCoverageType $lineCoverage
28555 * @psalm-param array<string, XdebugFunctionsCoverageType> $functionCoverage
28556 */
28557 private function __construct(array $lineCoverage, array $functionCoverage)
28558 {
28559 $this->lineCoverage = $lineCoverage;
28560 $this->functionCoverage = $functionCoverage;
28561 $this->skipEmptyLines();
28562 }
28563 public function clear(): void
28564 {
28565 $this->lineCoverage = $this->functionCoverage = [];
28566 }
28567 /**
28568 * @psalm-return XdebugCodeCoverageWithoutPathCoverageType
28569 */
28570 public function lineCoverage(): array
28571 {
28572 return $this->lineCoverage;
28573 }
28574 /**
28575 * @psalm-return array<string, XdebugFunctionsCoverageType>
28576 */
28577 public function functionCoverage(): array
28578 {
28579 return $this->functionCoverage;
28580 }
28581 public function removeCoverageDataForFile(string $filename): void
28582 {
28583 unset($this->lineCoverage[$filename], $this->functionCoverage[$filename]);
28584 }
28585 /**
28586 * @param int[] $lines
28587 */
28588 public function keepLineCoverageDataOnlyForLines(string $filename, array $lines): void
28589 {
28590 if (!isset($this->lineCoverage[$filename])) {
28591 return;
28592 }
28593 $this->lineCoverage[$filename] = array_intersect_key($this->lineCoverage[$filename], array_flip($lines));
28594 }
28595 /**
28596 * @param int[] $linesToBranchMap
28597 */
28598 public function markExecutableLineByBranch(string $filename, array $linesToBranchMap): void
28599 {
28600 if (!isset($this->lineCoverage[$filename])) {
28601 return;
28602 }
28603 $linesByBranch = [];
28604 foreach ($linesToBranchMap as $line => $branch) {
28605 $linesByBranch[$branch][] = $line;
28606 }
28607 foreach ($this->lineCoverage[$filename] as $line => $lineStatus) {
28608 if (!isset($linesToBranchMap[$line])) {
28609 continue;
28610 }
28611 $branch = $linesToBranchMap[$line];
28612 if (!isset($linesByBranch[$branch])) {
28613 continue;
28614 }
28615 foreach ($linesByBranch[$branch] as $lineInBranch) {
28616 $this->lineCoverage[$filename][$lineInBranch] = $lineStatus;
28617 }
28618 if (Driver::LINE_EXECUTED === $lineStatus) {
28619 unset($linesByBranch[$branch]);
28620 }
28621 }
28622 }
28623 /**
28624 * @param int[] $lines
28625 */
28626 public function keepFunctionCoverageDataOnlyForLines(string $filename, array $lines): void
28627 {
28628 if (!isset($this->functionCoverage[$filename])) {
28629 return;
28630 }
28631 foreach ($this->functionCoverage[$filename] as $functionName => $functionData) {
28632 foreach ($functionData['branches'] as $branchId => $branch) {
28633 if (count(array_diff(range($branch['line_start'], $branch['line_end']), $lines)) > 0) {
28634 unset($this->functionCoverage[$filename][$functionName]['branches'][$branchId]);
28635 foreach ($functionData['paths'] as $pathId => $path) {
28636 if (in_array($branchId, $path['path'], \true)) {
28637 unset($this->functionCoverage[$filename][$functionName]['paths'][$pathId]);
28638 }
28639 }
28640 }
28641 }
28642 }
28643 }
28644 /**
28645 * @param int[] $lines
28646 */
28647 public function removeCoverageDataForLines(string $filename, array $lines): void
28648 {
28649 if (empty($lines)) {
28650 return;
28651 }
28652 if (!isset($this->lineCoverage[$filename])) {
28653 return;
28654 }
28655 $this->lineCoverage[$filename] = array_diff_key($this->lineCoverage[$filename], array_flip($lines));
28656 if (isset($this->functionCoverage[$filename])) {
28657 foreach ($this->functionCoverage[$filename] as $functionName => $functionData) {
28658 foreach ($functionData['branches'] as $branchId => $branch) {
28659 if (count(array_intersect($lines, range($branch['line_start'], $branch['line_end']))) > 0) {
28660 unset($this->functionCoverage[$filename][$functionName]['branches'][$branchId]);
28661 foreach ($functionData['paths'] as $pathId => $path) {
28662 if (in_array($branchId, $path['path'], \true)) {
28663 unset($this->functionCoverage[$filename][$functionName]['paths'][$pathId]);
28664 }
28665 }
28666 }
28667 }
28668 }
28669 }
28670 }
28671 /**
28672 * At the end of a file, the PHP interpreter always sees an implicit return. Where this occurs in a file that has
28673 * e.g. a class definition, that line cannot be invoked from a test and results in confusing coverage. This engine
28674 * implementation detail therefore needs to be masked which is done here by simply ensuring that all empty lines
28675 * are skipped over for coverage purposes.
28676 *
28677 * @see https://github.com/sebastianbergmann/php-code-coverage/issues/799
28678 */
28679 private function skipEmptyLines(): void
28680 {
28681 foreach ($this->lineCoverage as $filename => $coverage) {
28682 foreach ($this->getEmptyLinesForFile($filename) as $emptyLine) {
28683 unset($this->lineCoverage[$filename][$emptyLine]);
28684 }
28685 }
28686 }
28687 private function getEmptyLinesForFile(string $filename): array
28688 {
28689 if (!isset(self::$emptyLineCache[$filename])) {
28690 self::$emptyLineCache[$filename] = [];
28691 if (is_file($filename)) {
28692 $sourceLines = explode("\n", file_get_contents($filename));
28693 foreach ($sourceLines as $line => $source) {
28694 if (trim($source) === '') {
28695 self::$emptyLineCache[$filename][] = $line + 1;
28696 }
28697 }
28698 }
28699 }
28700 return self::$emptyLineCache[$filename];
28701 }
28702 }
28703 <?php
28704
28705 declare (strict_types=1);
28706 /*
28707 * This file is part of phpunit/php-code-coverage.
28708 *
28709 * (c) Sebastian Bergmann <sebastian@phpunit.de>
28710 *
28711 * For the full copyright and license information, please view the LICENSE
28712 * file that was distributed with this source code.
28713 */
28714 namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\Driver;
28715
28716 use function sprintf;
28717 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\BranchAndPathCoverageNotSupportedException;
28718 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Data\RawCodeCoverageData;
28719 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\DeadCodeDetectionNotSupportedException;
28720 /**
28721 * @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
28722 */
28723 abstract class Driver
28724 {
28725 /**
28726 * @var int
28727 *
28728 * @see http://xdebug.org/docs/code_coverage
28729 */
28730 public const LINE_NOT_EXECUTABLE = -2;
28731 /**
28732 * @var int
28733 *
28734 * @see http://xdebug.org/docs/code_coverage
28735 */
28736 public const LINE_NOT_EXECUTED = -1;
28737 /**
28738 * @var int
28739 *
28740 * @see http://xdebug.org/docs/code_coverage
28741 */
28742 public const LINE_EXECUTED = 1;
28743 /**
28744 * @var int
28745 *
28746 * @see http://xdebug.org/docs/code_coverage
28747 */
28748 public const BRANCH_NOT_HIT = 0;
28749 /**
28750 * @var int
28751 *
28752 * @see http://xdebug.org/docs/code_coverage
28753 */
28754 public const BRANCH_HIT = 1;
28755 private bool $collectBranchAndPathCoverage = \false;
28756 private bool $detectDeadCode = \false;
28757 public function canCollectBranchAndPathCoverage(): bool
28758 {
28759 return \false;
28760 }
28761 public function collectsBranchAndPathCoverage(): bool
28762 {
28763 return $this->collectBranchAndPathCoverage;
28764 }
28765 /**
28766 * @throws BranchAndPathCoverageNotSupportedException
28767 */
28768 public function enableBranchAndPathCoverage(): void
28769 {
28770 if (!$this->canCollectBranchAndPathCoverage()) {
28771 throw new BranchAndPathCoverageNotSupportedException(sprintf('%s does not support branch and path coverage', $this->nameAndVersion()));
28772 }
28773 $this->collectBranchAndPathCoverage = \true;
28774 }
28775 public function disableBranchAndPathCoverage(): void
28776 {
28777 $this->collectBranchAndPathCoverage = \false;
28778 }
28779 public function canDetectDeadCode(): bool
28780 {
28781 return \false;
28782 }
28783 public function detectsDeadCode(): bool
28784 {
28785 return $this->detectDeadCode;
28786 }
28787 /**
28788 * @throws DeadCodeDetectionNotSupportedException
28789 */
28790 public function enableDeadCodeDetection(): void
28791 {
28792 if (!$this->canDetectDeadCode()) {
28793 throw new DeadCodeDetectionNotSupportedException(sprintf('%s does not support dead code detection', $this->nameAndVersion()));
28794 }
28795 $this->detectDeadCode = \true;
28796 }
28797 public function disableDeadCodeDetection(): void
28798 {
28799 $this->detectDeadCode = \false;
28800 }
28801 abstract public function nameAndVersion(): string;
28802 abstract public function start(): void;
28803 abstract public function stop(): RawCodeCoverageData;
28804 }
28805 <?php
28806
28807 declare (strict_types=1);
28808 /*
28809 * This file is part of phpunit/php-code-coverage.
28810 *
28811 * (c) Sebastian Bergmann <sebastian@phpunit.de>
28812 *
28813 * For the full copyright and license information, please view the LICENSE
28814 * file that was distributed with this source code.
28815 */
28816 namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\Driver;
28817
28818 use const pcov\inclusive;
28819 use function array_intersect;
28820 use function extension_loaded;
28821 use function pcov\clear;
28822 use function pcov\collect;
28823 use function pcov\start;
28824 use function pcov\stop;
28825 use function pcov\waiting;
28826 use function phpversion;
28827 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Data\RawCodeCoverageData;
28828 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Filter;
28829 /**
28830 * @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
28831 */
28832 final class PcovDriver extends Driver
28833 {
28834 private readonly Filter $filter;
28835 /**
28836 * @throws PcovNotAvailableException
28837 */
28838 public function __construct(Filter $filter)
28839 {
28840 $this->ensurePcovIsAvailable();
28841 $this->filter = $filter;
28842 }
28843 public function start(): void
28844 {
28845 start();
28846 }
28847 public function stop(): RawCodeCoverageData
28848 {
28849 stop();
28850 $filesToCollectCoverageFor = waiting();
28851 $collected = [];
28852 if ($filesToCollectCoverageFor) {
28853 if (!$this->filter->isEmpty()) {
28854 $filesToCollectCoverageFor = array_intersect($filesToCollectCoverageFor, $this->filter->files());
28855 }
28856 $collected = collect(inclusive, $filesToCollectCoverageFor);
28857 clear();
28858 }
28859 return RawCodeCoverageData::fromXdebugWithoutPathCoverage($collected);
28860 }
28861 public function nameAndVersion(): string
28862 {
28863 return 'PCOV ' . phpversion('pcov');
28864 }
28865 /**
28866 * @throws PcovNotAvailableException
28867 */
28868 private function ensurePcovIsAvailable(): void
28869 {
28870 if (!extension_loaded('pcov')) {
28871 throw new PcovNotAvailableException();
28872 }
28873 }
28874 }
28875 <?php
28876
28877 declare (strict_types=1);
28878 /*
28879 * This file is part of phpunit/php-code-coverage.
28880 *
28881 * (c) Sebastian Bergmann <sebastian@phpunit.de>
28882 *
28883 * For the full copyright and license information, please view the LICENSE
28884 * file that was distributed with this source code.
28885 */
28886 namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\Driver;
28887
28888 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Filter;
28889 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\NoCodeCoverageDriverAvailableException;
28890 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\NoCodeCoverageDriverWithPathCoverageSupportAvailableException;
28891 use PHPUnitPHAR\SebastianBergmann\Environment\Runtime;
28892 final class Selector
28893 {
28894 /**
28895 * @throws NoCodeCoverageDriverAvailableException
28896 * @throws PcovNotAvailableException
28897 * @throws XdebugNotAvailableException
28898 * @throws XdebugNotEnabledException
28899 */
28900 public function forLineCoverage(Filter $filter): Driver
28901 {
28902 $runtime = new Runtime();
28903 if ($runtime->hasPCOV()) {
28904 return new PcovDriver($filter);
28905 }
28906 if ($runtime->hasXdebug()) {
28907 $driver = new XdebugDriver($filter);
28908 $driver->enableDeadCodeDetection();
28909 return $driver;
28910 }
28911 throw new NoCodeCoverageDriverAvailableException();
28912 }
28913 /**
28914 * @throws NoCodeCoverageDriverWithPathCoverageSupportAvailableException
28915 * @throws XdebugNotAvailableException
28916 * @throws XdebugNotEnabledException
28917 */
28918 public function forLineAndPathCoverage(Filter $filter): Driver
28919 {
28920 if ((new Runtime())->hasXdebug()) {
28921 $driver = new XdebugDriver($filter);
28922 $driver->enableDeadCodeDetection();
28923 $driver->enableBranchAndPathCoverage();
28924 return $driver;
28925 }
28926 throw new NoCodeCoverageDriverWithPathCoverageSupportAvailableException();
28927 }
28928 }
28929 <?php
28930
28931 declare (strict_types=1);
28932 /*
28933 * This file is part of phpunit/php-code-coverage.
28934 *
28935 * (c) Sebastian Bergmann <sebastian@phpunit.de>
28936 *
28937 * For the full copyright and license information, please view the LICENSE
28938 * file that was distributed with this source code.
28939 */
28940 namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\Driver;
28941
28942 use const XDEBUG_CC_BRANCH_CHECK;
28943 use const XDEBUG_CC_DEAD_CODE;
28944 use const XDEBUG_CC_UNUSED;
28945 use const XDEBUG_FILTER_CODE_COVERAGE;
28946 use const XDEBUG_PATH_INCLUDE;
28947 use function explode;
28948 use function extension_loaded;
28949 use function getenv;
28950 use function in_array;
28951 use function ini_get;
28952 use function phpversion;
28953 use function version_compare;
28954 use function xdebug_get_code_coverage;
28955 use function xdebug_info;
28956 use function xdebug_set_filter;
28957 use function xdebug_start_code_coverage;
28958 use function xdebug_stop_code_coverage;
28959 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Data\RawCodeCoverageData;
28960 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Filter;
28961 /**
28962 * @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
28963 *
28964 * @see https://xdebug.org/docs/code_coverage#xdebug_get_code_coverage
28965 *
28966 * @psalm-type XdebugLinesCoverageType = array<int, int>
28967 * @psalm-type XdebugBranchCoverageType = array{
28968 * op_start: int,
28969 * op_end: int,
28970 * line_start: int,
28971 * line_end: int,
28972 * hit: int,
28973 * out: array<int, int>,
28974 * out_hit: array<int, int>,
28975 * }
28976 * @psalm-type XdebugPathCoverageType = array{
28977 * path: array<int, int>,
28978 * hit: int,
28979 * }
28980 * @psalm-type XdebugFunctionCoverageType = array{
28981 * branches: array<int, XdebugBranchCoverageType>,
28982 * paths: array<int, XdebugPathCoverageType>,
28983 * }
28984 * @psalm-type XdebugFunctionsCoverageType = array<string, XdebugFunctionCoverageType>
28985 * @psalm-type XdebugPathAndBranchesCoverageType = array{
28986 * lines: XdebugLinesCoverageType,
28987 * functions: XdebugFunctionsCoverageType,
28988 * }
28989 * @psalm-type XdebugCodeCoverageWithoutPathCoverageType = array<string, XdebugLinesCoverageType>
28990 * @psalm-type XdebugCodeCoverageWithPathCoverageType = array<string, XdebugPathAndBranchesCoverageType>
28991 */
28992 final class XdebugDriver extends Driver
28993 {
28994 /**
28995 * @throws XdebugNotAvailableException
28996 * @throws XdebugNotEnabledException
28997 */
28998 public function __construct(Filter $filter)
28999 {
29000 $this->ensureXdebugIsAvailable();
29001 $this->ensureXdebugCodeCoverageFeatureIsEnabled();
29002 if (!$filter->isEmpty()) {
29003 xdebug_set_filter(XDEBUG_FILTER_CODE_COVERAGE, XDEBUG_PATH_INCLUDE, $filter->files());
29004 }
29005 }
29006 public function canCollectBranchAndPathCoverage(): bool
29007 {
29008 return \true;
29009 }
29010 public function canDetectDeadCode(): bool
29011 {
29012 return \true;
29013 }
29014 public function start(): void
29015 {
29016 $flags = XDEBUG_CC_UNUSED;
29017 if ($this->detectsDeadCode() || $this->collectsBranchAndPathCoverage()) {
29018 $flags |= XDEBUG_CC_DEAD_CODE;
29019 }
29020 if ($this->collectsBranchAndPathCoverage()) {
29021 $flags |= XDEBUG_CC_BRANCH_CHECK;
29022 }
29023 xdebug_start_code_coverage($flags);
29024 }
29025 public function stop(): RawCodeCoverageData
29026 {
29027 $data = xdebug_get_code_coverage();
29028 xdebug_stop_code_coverage();
29029 if ($this->collectsBranchAndPathCoverage()) {
29030 /* @var XdebugCodeCoverageWithPathCoverageType $data */
29031 return RawCodeCoverageData::fromXdebugWithPathCoverage($data);
29032 }
29033 /* @var XdebugCodeCoverageWithoutPathCoverageType $data */
29034 return RawCodeCoverageData::fromXdebugWithoutPathCoverage($data);
29035 }
29036 public function nameAndVersion(): string
29037 {
29038 return 'Xdebug ' . phpversion('xdebug');
29039 }
29040 /**
29041 * @throws XdebugNotAvailableException
29042 */
29043 private function ensureXdebugIsAvailable(): void
29044 {
29045 if (!extension_loaded('xdebug')) {
29046 throw new XdebugNotAvailableException();
29047 }
29048 }
29049 /**
29050 * @throws XdebugNotEnabledException
29051 */
29052 private function ensureXdebugCodeCoverageFeatureIsEnabled(): void
29053 {
29054 if (version_compare(phpversion('xdebug'), '3.1', '>=')) {
29055 if (!in_array('coverage', xdebug_info('mode'), \true)) {
29056 throw new XdebugNotEnabledException();
29057 }
29058 return;
29059 }
29060 $mode = getenv('XDEBUG_MODE');
29061 if ($mode === \false || $mode === '') {
29062 $mode = ini_get('xdebug.mode');
29063 }
29064 if ($mode === \false || !in_array('coverage', explode(',', $mode), \true)) {
29065 throw new XdebugNotEnabledException();
29066 }
29067 }
29068 }
29069 <?php
29070
29071 declare (strict_types=1);
29072 /*
29073 * This file is part of phpunit/php-code-coverage.
29074 *
29075 * (c) Sebastian Bergmann <sebastian@phpunit.de>
29076 *
29077 * For the full copyright and license information, please view the LICENSE
29078 * file that was distributed with this source code.
29079 */
29080 namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage;
29081
29082 use RuntimeException;
29083 final class BranchAndPathCoverageNotSupportedException extends RuntimeException implements Exception
29084 {
29085 }
29086 <?php
29087
29088 declare (strict_types=1);
29089 /*
29090 * This file is part of phpunit/php-code-coverage.
29091 *
29092 * (c) Sebastian Bergmann <sebastian@phpunit.de>
29093 *
29094 * For the full copyright and license information, please view the LICENSE
29095 * file that was distributed with this source code.
29096 */
29097 namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage;
29098
29099 use RuntimeException;
29100 final class DeadCodeDetectionNotSupportedException extends RuntimeException implements Exception
29101 {
29102 }
29103 <?php
29104
29105 declare (strict_types=1);
29106 /*
29107 * This file is part of phpunit/php-code-coverage.
29108 *
29109 * (c) Sebastian Bergmann <sebastian@phpunit.de>
29110 *
29111 * For the full copyright and license information, please view the LICENSE
29112 * file that was distributed with this source code.
29113 */
29114 namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\Util;
29115
29116 use RuntimeException;
29117 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Exception;
29118 final class DirectoryCouldNotBeCreatedException extends RuntimeException implements Exception
29119 {
29120 }
29121 <?php
29122
29123 declare (strict_types=1);
29124 /*
29125 * This file is part of phpunit/php-code-coverage.
29126 *
29127 * (c) Sebastian Bergmann <sebastian@phpunit.de>
29128 *
29129 * For the full copyright and license information, please view the LICENSE
29130 * file that was distributed with this source code.
29131 */
29132 namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage;
29133
29134 use Throwable;
29135 interface Exception extends Throwable
29136 {
29137 }
29138 <?php
29139
29140 declare (strict_types=1);
29141 /*
29142 * This file is part of phpunit/php-code-coverage.
29143 *
29144 * (c) Sebastian Bergmann <sebastian@phpunit.de>
29145 *
29146 * For the full copyright and license information, please view the LICENSE
29147 * file that was distributed with this source code.
29148 */
29149 namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage;
29150
29151 use RuntimeException;
29152 final class FileCouldNotBeWrittenException extends RuntimeException implements Exception
29153 {
29154 }
29155 <?php
29156
29157 declare (strict_types=1);
29158 /*
29159 * This file is part of phpunit/php-code-coverage.
29160 *
29161 * (c) Sebastian Bergmann <sebastian@phpunit.de>
29162 *
29163 * For the full copyright and license information, please view the LICENSE
29164 * file that was distributed with this source code.
29165 */
29166 namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage;
29167
29168 final class InvalidArgumentException extends \InvalidArgumentException implements Exception
29169 {
29170 }
29171 <?php
29172
29173 declare (strict_types=1);
29174 /*
29175 * This file is part of phpunit/php-code-coverage.
29176 *
29177 * (c) Sebastian Bergmann <sebastian@phpunit.de>
29178 *
29179 * For the full copyright and license information, please view the LICENSE
29180 * file that was distributed with this source code.
29181 */
29182 namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage;
29183
29184 use RuntimeException;
29185 final class NoCodeCoverageDriverAvailableException extends RuntimeException implements Exception
29186 {
29187 public function __construct()
29188 {
29189 parent::__construct('No code coverage driver available');
29190 }
29191 }
29192 <?php
29193
29194 declare (strict_types=1);
29195 /*
29196 * This file is part of phpunit/php-code-coverage.
29197 *
29198 * (c) Sebastian Bergmann <sebastian@phpunit.de>
29199 *
29200 * For the full copyright and license information, please view the LICENSE
29201 * file that was distributed with this source code.
29202 */
29203 namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage;
29204
29205 use RuntimeException;
29206 final class NoCodeCoverageDriverWithPathCoverageSupportAvailableException extends RuntimeException implements Exception
29207 {
29208 public function __construct()
29209 {
29210 parent::__construct('No code coverage driver with path coverage support available');
29211 }
29212 }
29213 <?php
29214
29215 declare (strict_types=1);
29216 /*
29217 * This file is part of phpunit/php-code-coverage.
29218 *
29219 * (c) Sebastian Bergmann <sebastian@phpunit.de>
29220 *
29221 * For the full copyright and license information, please view the LICENSE
29222 * file that was distributed with this source code.
29223 */
29224 namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage;
29225
29226 use RuntimeException;
29227 final class ParserException extends RuntimeException implements Exception
29228 {
29229 }
29230 <?php
29231
29232 declare (strict_types=1);
29233 /*
29234 * This file is part of phpunit/php-code-coverage.
29235 *
29236 * (c) Sebastian Bergmann <sebastian@phpunit.de>
29237 *
29238 * For the full copyright and license information, please view the LICENSE
29239 * file that was distributed with this source code.
29240 */
29241 namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\Driver;
29242
29243 use function sprintf;
29244 use RuntimeException;
29245 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Exception;
29246 final class PathExistsButIsNotDirectoryException extends RuntimeException implements Exception
29247 {
29248 public function __construct(string $path)
29249 {
29250 parent::__construct(sprintf('"%s" exists but is not a directory', $path));
29251 }
29252 }
29253 <?php
29254
29255 declare (strict_types=1);
29256 /*
29257 * This file is part of phpunit/php-code-coverage.
29258 *
29259 * (c) Sebastian Bergmann <sebastian@phpunit.de>
29260 *
29261 * For the full copyright and license information, please view the LICENSE
29262 * file that was distributed with this source code.
29263 */
29264 namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\Driver;
29265
29266 use RuntimeException;
29267 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Exception;
29268 final class PcovNotAvailableException extends RuntimeException implements Exception
29269 {
29270 public function __construct()
29271 {
29272 parent::__construct('The PCOV extension is not available');
29273 }
29274 }
29275 <?php
29276
29277 declare (strict_types=1);
29278 /*
29279 * This file is part of phpunit/php-code-coverage.
29280 *
29281 * (c) Sebastian Bergmann <sebastian@phpunit.de>
29282 *
29283 * For the full copyright and license information, please view the LICENSE
29284 * file that was distributed with this source code.
29285 */
29286 namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage;
29287
29288 use RuntimeException;
29289 final class ReflectionException extends RuntimeException implements Exception
29290 {
29291 }
29292 <?php
29293
29294 declare (strict_types=1);
29295 /*
29296 * This file is part of phpunit/php-code-coverage.
29297 *
29298 * (c) Sebastian Bergmann <sebastian@phpunit.de>
29299 *
29300 * For the full copyright and license information, please view the LICENSE
29301 * file that was distributed with this source code.
29302 */
29303 namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage;
29304
29305 use RuntimeException;
29306 final class ReportAlreadyFinalizedException extends RuntimeException implements Exception
29307 {
29308 public function __construct()
29309 {
29310 parent::__construct('The code coverage report has already been finalized');
29311 }
29312 }
29313 <?php
29314
29315 declare (strict_types=1);
29316 /*
29317 * This file is part of phpunit/php-code-coverage.
29318 *
29319 * (c) Sebastian Bergmann <sebastian@phpunit.de>
29320 *
29321 * For the full copyright and license information, please view the LICENSE
29322 * file that was distributed with this source code.
29323 */
29324 namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage;
29325
29326 use RuntimeException;
29327 final class StaticAnalysisCacheNotConfiguredException extends RuntimeException implements Exception
29328 {
29329 }
29330 <?php
29331
29332 declare (strict_types=1);
29333 /*
29334 * This file is part of phpunit/php-code-coverage.
29335 *
29336 * (c) Sebastian Bergmann <sebastian@phpunit.de>
29337 *
29338 * For the full copyright and license information, please view the LICENSE
29339 * file that was distributed with this source code.
29340 */
29341 namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage;
29342
29343 use RuntimeException;
29344 final class TestIdMissingException extends RuntimeException implements Exception
29345 {
29346 public function __construct()
29347 {
29348 parent::__construct('Test ID is missing');
29349 }
29350 }
29351 <?php
29352
29353 declare (strict_types=1);
29354 /*
29355 * This file is part of phpunit/php-code-coverage.
29356 *
29357 * (c) Sebastian Bergmann <sebastian@phpunit.de>
29358 *
29359 * For the full copyright and license information, please view the LICENSE
29360 * file that was distributed with this source code.
29361 */
29362 namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage;
29363
29364 use RuntimeException;
29365 final class UnintentionallyCoveredCodeException extends RuntimeException implements Exception
29366 {
29367 /**
29368 * @var list<string>
29369 */
29370 private readonly array $unintentionallyCoveredUnits;
29371 /**
29372 * @param list<string> $unintentionallyCoveredUnits
29373 */
29374 public function __construct(array $unintentionallyCoveredUnits)
29375 {
29376 $this->unintentionallyCoveredUnits = $unintentionallyCoveredUnits;
29377 parent::__construct($this->toString());
29378 }
29379 /**
29380 * @return list<string>
29381 */
29382 public function getUnintentionallyCoveredUnits(): array
29383 {
29384 return $this->unintentionallyCoveredUnits;
29385 }
29386 private function toString(): string
29387 {
29388 $message = '';
29389 foreach ($this->unintentionallyCoveredUnits as $unit) {
29390 $message .= '- ' . $unit . "\n";
29391 }
29392 return $message;
29393 }
29394 }
29395 <?php
29396
29397 declare (strict_types=1);
29398 /*
29399 * This file is part of phpunit/php-code-coverage.
29400 *
29401 * (c) Sebastian Bergmann <sebastian@phpunit.de>
29402 *
29403 * For the full copyright and license information, please view the LICENSE
29404 * file that was distributed with this source code.
29405 */
29406 namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\Driver;
29407
29408 use function sprintf;
29409 use RuntimeException;
29410 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Exception;
29411 final class WriteOperationFailedException extends RuntimeException implements Exception
29412 {
29413 public function __construct(string $path)
29414 {
29415 parent::__construct(sprintf('Cannot write to "%s"', $path));
29416 }
29417 }
29418 <?php
29419
29420 declare (strict_types=1);
29421 /*
29422 * This file is part of phpunit/php-code-coverage.
29423 *
29424 * (c) Sebastian Bergmann <sebastian@phpunit.de>
29425 *
29426 * For the full copyright and license information, please view the LICENSE
29427 * file that was distributed with this source code.
29428 */
29429 namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\Driver;
29430
29431 use RuntimeException;
29432 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Exception;
29433 final class XdebugNotAvailableException extends RuntimeException implements Exception
29434 {
29435 public function __construct()
29436 {
29437 parent::__construct('The Xdebug extension is not available');
29438 }
29439 }
29440 <?php
29441
29442 declare (strict_types=1);
29443 /*
29444 * This file is part of phpunit/php-code-coverage.
29445 *
29446 * (c) Sebastian Bergmann <sebastian@phpunit.de>
29447 *
29448 * For the full copyright and license information, please view the LICENSE
29449 * file that was distributed with this source code.
29450 */
29451 namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\Driver;
29452
29453 use RuntimeException;
29454 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Exception;
29455 final class XdebugNotEnabledException extends RuntimeException implements Exception
29456 {
29457 public function __construct()
29458 {
29459 parent::__construct('XDEBUG_MODE=coverage (environment variable) or xdebug.mode=coverage (PHP configuration setting) has to be set');
29460 }
29461 }
29462 <?php
29463
29464 declare (strict_types=1);
29465 /*
29466 * This file is part of phpunit/php-code-coverage.
29467 *
29468 * (c) Sebastian Bergmann <sebastian@phpunit.de>
29469 *
29470 * For the full copyright and license information, please view the LICENSE
29471 * file that was distributed with this source code.
29472 */
29473 namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage;
29474
29475 use RuntimeException;
29476 final class XmlException extends RuntimeException implements Exception
29477 {
29478 }
29479 <?php
29480
29481 declare (strict_types=1);
29482 /*
29483 * This file is part of phpunit/php-code-coverage.
29484 *
29485 * (c) Sebastian Bergmann <sebastian@phpunit.de>
29486 *
29487 * For the full copyright and license information, please view the LICENSE
29488 * file that was distributed with this source code.
29489 */
29490 namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage;
29491
29492 use function array_keys;
29493 use function is_file;
29494 use function realpath;
29495 use function str_contains;
29496 use function str_starts_with;
29497 use PHPUnitPHAR\SebastianBergmann\FileIterator\Facade as FileIteratorFacade;
29498 final class Filter
29499 {
29500 /**
29501 * @psalm-var array<string,true>
29502 */
29503 private array $files = [];
29504 /**
29505 * @psalm-var array<string,bool>
29506 */
29507 private array $isFileCache = [];
29508 /**
29509 * @deprecated
29510 */
29511 public function includeDirectory(string $directory, string $suffix = '.php', string $prefix = ''): void
29512 {
29513 foreach ((new FileIteratorFacade())->getFilesAsArray($directory, $suffix, $prefix) as $file) {
29514 $this->includeFile($file);
29515 }
29516 }
29517 /**
29518 * @psalm-param list<string> $files
29519 */
29520 public function includeFiles(array $filenames): void
29521 {
29522 foreach ($filenames as $filename) {
29523 $this->includeFile($filename);
29524 }
29525 }
29526 public function includeFile(string $filename): void
29527 {
29528 $filename = realpath($filename);
29529 if (!$filename) {
29530 return;
29531 }
29532 $this->files[$filename] = \true;
29533 }
29534 /**
29535 * @deprecated
29536 */
29537 public function excludeDirectory(string $directory, string $suffix = '.php', string $prefix = ''): void
29538 {
29539 foreach ((new FileIteratorFacade())->getFilesAsArray($directory, $suffix, $prefix) as $file) {
29540 $this->excludeFile($file);
29541 }
29542 }
29543 /**
29544 * @deprecated
29545 */
29546 public function excludeFile(string $filename): void
29547 {
29548 $filename = realpath($filename);
29549 if (!$filename || !isset($this->files[$filename])) {
29550 return;
29551 }
29552 unset($this->files[$filename]);
29553 }
29554 public function isFile(string $filename): bool
29555 {
29556 if (isset($this->isFileCache[$filename])) {
29557 return $this->isFileCache[$filename];
29558 }
29559 if ($filename === '-' || str_starts_with($filename, 'vfs://') || str_contains($filename, 'xdebug://debug-eval') || str_contains($filename, 'eval()\'d code') || str_contains($filename, 'runtime-created function') || str_contains($filename, 'runkit created function') || str_contains($filename, 'assert code') || str_contains($filename, 'regexp code') || str_contains($filename, 'Standard input code')) {
29560 $isFile = \false;
29561 } else {
29562 $isFile = is_file($filename);
29563 }
29564 $this->isFileCache[$filename] = $isFile;
29565 return $isFile;
29566 }
29567 public function isExcluded(string $filename): bool
29568 {
29569 return !isset($this->files[$filename]) || !$this->isFile($filename);
29570 }
29571 /**
29572 * @psalm-return list<string>
29573 */
29574 public function files(): array
29575 {
29576 return array_keys($this->files);
29577 }
29578 public function isEmpty(): bool
29579 {
29580 return empty($this->files);
29581 }
29582 }
29583 BSD 3-Clause License
29584
29585 Copyright (c) 2009-2024, Sebastian Bergmann
29586 All rights reserved.
29587
29588 Redistribution and use in source and binary forms, with or without
29589 modification, are permitted provided that the following conditions are met:
29590
29591 1. Redistributions of source code must retain the above copyright notice, this
29592 list of conditions and the following disclaimer.
29593
29594 2. Redistributions in binary form must reproduce the above copyright notice,
29595 this list of conditions and the following disclaimer in the documentation
29596 and/or other materials provided with the distribution.
29597
29598 3. Neither the name of the copyright holder nor the names of its
29599 contributors may be used to endorse or promote products derived from
29600 this software without specific prior written permission.
29601
29602 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
29603 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29604 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
29605 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
29606 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29607 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
29608 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29609 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29610 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29611 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29612 <?php
29613
29614 declare (strict_types=1);
29615 /*
29616 * This file is part of phpunit/php-code-coverage.
29617 *
29618 * (c) Sebastian Bergmann <sebastian@phpunit.de>
29619 *
29620 * For the full copyright and license information, please view the LICENSE
29621 * file that was distributed with this source code.
29622 */
29623 namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\Node;
29624
29625 use const DIRECTORY_SEPARATOR;
29626 use function array_merge;
29627 use function str_ends_with;
29628 use function str_replace;
29629 use function substr;
29630 use Countable;
29631 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Util\Percentage;
29632 /**
29633 * @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
29634 *
29635 * @psalm-import-type LinesOfCodeType from \SebastianBergmann\CodeCoverage\StaticAnalysis\FileAnalyser
29636 * @psalm-import-type ProcessedFunctionType from \SebastianBergmann\CodeCoverage\Node\File
29637 * @psalm-import-type ProcessedClassType from \SebastianBergmann\CodeCoverage\Node\File
29638 * @psalm-import-type ProcessedTraitType from \SebastianBergmann\CodeCoverage\Node\File
29639 */
29640 abstract class AbstractNode implements Countable
29641 {
29642 private readonly string $name;
29643 private string $pathAsString;
29644 private array $pathAsArray;
29645 private readonly ?AbstractNode $parent;
29646 private string $id;
29647 public function __construct(string $name, ?self $parent = null)
29648 {
29649 if (str_ends_with($name, DIRECTORY_SEPARATOR)) {
29650 $name = substr($name, 0, -1);
29651 }
29652 $this->name = $name;
29653 $this->parent = $parent;
29654 $this->processId();
29655 $this->processPath();
29656 }
29657 public function name(): string
29658 {
29659 return $this->name;
29660 }
29661 public function id(): string
29662 {
29663 return $this->id;
29664 }
29665 public function pathAsString(): string
29666 {
29667 return $this->pathAsString;
29668 }
29669 public function pathAsArray(): array
29670 {
29671 return $this->pathAsArray;
29672 }
29673 public function parent(): ?self
29674 {
29675 return $this->parent;
29676 }
29677 public function percentageOfTestedClasses(): Percentage
29678 {
29679 return Percentage::fromFractionAndTotal($this->numberOfTestedClasses(), $this->numberOfClasses());
29680 }
29681 public function percentageOfTestedTraits(): Percentage
29682 {
29683 return Percentage::fromFractionAndTotal($this->numberOfTestedTraits(), $this->numberOfTraits());
29684 }
29685 public function percentageOfTestedClassesAndTraits(): Percentage
29686 {
29687 return Percentage::fromFractionAndTotal($this->numberOfTestedClassesAndTraits(), $this->numberOfClassesAndTraits());
29688 }
29689 public function percentageOfTestedFunctions(): Percentage
29690 {
29691 return Percentage::fromFractionAndTotal($this->numberOfTestedFunctions(), $this->numberOfFunctions());
29692 }
29693 public function percentageOfTestedMethods(): Percentage
29694 {
29695 return Percentage::fromFractionAndTotal($this->numberOfTestedMethods(), $this->numberOfMethods());
29696 }
29697 public function percentageOfTestedFunctionsAndMethods(): Percentage
29698 {
29699 return Percentage::fromFractionAndTotal($this->numberOfTestedFunctionsAndMethods(), $this->numberOfFunctionsAndMethods());
29700 }
29701 public function percentageOfExecutedLines(): Percentage
29702 {
29703 return Percentage::fromFractionAndTotal($this->numberOfExecutedLines(), $this->numberOfExecutableLines());
29704 }
29705 public function percentageOfExecutedBranches(): Percentage
29706 {
29707 return Percentage::fromFractionAndTotal($this->numberOfExecutedBranches(), $this->numberOfExecutableBranches());
29708 }
29709 public function percentageOfExecutedPaths(): Percentage
29710 {
29711 return Percentage::fromFractionAndTotal($this->numberOfExecutedPaths(), $this->numberOfExecutablePaths());
29712 }
29713 public function numberOfClassesAndTraits(): int
29714 {
29715 return $this->numberOfClasses() + $this->numberOfTraits();
29716 }
29717 public function numberOfTestedClassesAndTraits(): int
29718 {
29719 return $this->numberOfTestedClasses() + $this->numberOfTestedTraits();
29720 }
29721 public function classesAndTraits(): array
29722 {
29723 return array_merge($this->classes(), $this->traits());
29724 }
29725 public function numberOfFunctionsAndMethods(): int
29726 {
29727 return $this->numberOfFunctions() + $this->numberOfMethods();
29728 }
29729 public function numberOfTestedFunctionsAndMethods(): int
29730 {
29731 return $this->numberOfTestedFunctions() + $this->numberOfTestedMethods();
29732 }
29733 /**
29734 * @psalm-return array<string, ProcessedClassType>
29735 */
29736 abstract public function classes(): array;
29737 /**
29738 * @psalm-return array<string, ProcessedTraitType>
29739 */
29740 abstract public function traits(): array;
29741 /**
29742 * @psalm-return array<string, ProcessedFunctionType>
29743 */
29744 abstract public function functions(): array;
29745 /**
29746 * @psalm-return LinesOfCodeType
29747 */
29748 abstract public function linesOfCode(): array;
29749 abstract public function numberOfExecutableLines(): int;
29750 abstract public function numberOfExecutedLines(): int;
29751 abstract public function numberOfExecutableBranches(): int;
29752 abstract public function numberOfExecutedBranches(): int;
29753 abstract public function numberOfExecutablePaths(): int;
29754 abstract public function numberOfExecutedPaths(): int;
29755 abstract public function numberOfClasses(): int;
29756 abstract public function numberOfTestedClasses(): int;
29757 abstract public function numberOfTraits(): int;
29758 abstract public function numberOfTestedTraits(): int;
29759 abstract public function numberOfMethods(): int;
29760 abstract public function numberOfTestedMethods(): int;
29761 abstract public function numberOfFunctions(): int;
29762 abstract public function numberOfTestedFunctions(): int;
29763 private function processId(): void
29764 {
29765 if ($this->parent === null) {
29766 $this->id = 'index';
29767 return;
29768 }
29769 $parentId = $this->parent->id();
29770 if ($parentId === 'index') {
29771 $this->id = str_replace(':', '_', $this->name);
29772 } else {
29773 $this->id = $parentId . '/' . $this->name;
29774 }
29775 }
29776 private function processPath(): void
29777 {
29778 if ($this->parent === null) {
29779 $this->pathAsArray = [$this];
29780 $this->pathAsString = $this->name;
29781 return;
29782 }
29783 $this->pathAsArray = $this->parent->pathAsArray();
29784 $this->pathAsString = $this->parent->pathAsString() . DIRECTORY_SEPARATOR . $this->name;
29785 $this->pathAsArray[] = $this;
29786 }
29787 }
29788 <?php
29789
29790 declare (strict_types=1);
29791 /*
29792 * This file is part of phpunit/php-code-coverage.
29793 *
29794 * (c) Sebastian Bergmann <sebastian@phpunit.de>
29795 *
29796 * For the full copyright and license information, please view the LICENSE
29797 * file that was distributed with this source code.
29798 */
29799 namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\Node;
29800
29801 use const DIRECTORY_SEPARATOR;
29802 use function array_shift;
29803 use function basename;
29804 use function count;
29805 use function dirname;
29806 use function explode;
29807 use function implode;
29808 use function is_file;
29809 use function str_ends_with;
29810 use function str_replace;
29811 use function str_starts_with;
29812 use function substr;
29813 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\CodeCoverage;
29814 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Data\ProcessedCodeCoverageData;
29815 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\StaticAnalysis\FileAnalyser;
29816 /**
29817 * @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
29818 *
29819 * @psalm-import-type TestType from \SebastianBergmann\CodeCoverage\CodeCoverage
29820 */
29821 final class Builder
29822 {
29823 private readonly FileAnalyser $analyser;
29824 public function __construct(FileAnalyser $analyser)
29825 {
29826 $this->analyser = $analyser;
29827 }
29828 public function build(CodeCoverage $coverage): Directory
29829 {
29830 $data = clone $coverage->getData();
29831 // clone because path munging is destructive to the original data
29832 $commonPath = $this->reducePaths($data);
29833 $root = new Directory($commonPath, null);
29834 $this->addItems($root, $this->buildDirectoryStructure($data), $coverage->getTests());
29835 return $root;
29836 }
29837 /**
29838 * @psalm-param array<string, TestType> $tests
29839 */
29840 private function addItems(Directory $root, array $items, array $tests): void
29841 {
29842 foreach ($items as $key => $value) {
29843 $key = (string) $key;
29844 if (str_ends_with($key, '/f')) {
29845 $key = substr($key, 0, -2);
29846 $filename = $root->pathAsString() . DIRECTORY_SEPARATOR . $key;
29847 if (is_file($filename)) {
29848 $root->addFile(new File($key, $root, $value['lineCoverage'], $value['functionCoverage'], $tests, $this->analyser->classesIn($filename), $this->analyser->traitsIn($filename), $this->analyser->functionsIn($filename), $this->analyser->linesOfCodeFor($filename)));
29849 }
29850 } else {
29851 $child = $root->addDirectory($key);
29852 $this->addItems($child, $value, $tests);
29853 }
29854 }
29855 }
29856 /**
29857 * Builds an array representation of the directory structure.
29858 *
29859 * For instance,
29860 *
29861 * <code>
29862 * Array
29863 * (
29864 * [Money.php] => Array
29865 * (
29866 * ...
29867 * )
29868 *
29869 * [MoneyBag.php] => Array
29870 * (
29871 * ...
29872 * )
29873 * )
29874 * </code>
29875 *
29876 * is transformed into
29877 *
29878 * <code>
29879 * Array
29880 * (
29881 * [.] => Array
29882 * (
29883 * [Money.php] => Array
29884 * (
29885 * ...
29886 * )
29887 *
29888 * [MoneyBag.php] => Array
29889 * (
29890 * ...
29891 * )
29892 * )
29893 * )
29894 * </code>
29895 *
29896 * @psalm-return array<string, array<string, array{lineCoverage: array<int, int>, functionCoverage: array<string, array<int, int>>}>>
29897 */
29898 private function buildDirectoryStructure(ProcessedCodeCoverageData $data): array
29899 {
29900 $result = [];
29901 foreach ($data->coveredFiles() as $originalPath) {
29902 $path = explode(DIRECTORY_SEPARATOR, $originalPath);
29903 $pointer =& $result;
29904 $max = count($path);
29905 for ($i = 0; $i < $max; $i++) {
29906 $type = '';
29907 if ($i === $max - 1) {
29908 $type = '/f';
29909 }
29910 $pointer =& $pointer[$path[$i] . $type];
29911 }
29912 $pointer = ['lineCoverage' => $data->lineCoverage()[$originalPath] ?? [], 'functionCoverage' => $data->functionCoverage()[$originalPath] ?? []];
29913 }
29914 return $result;
29915 }
29916 /**
29917 * Reduces the paths by cutting the longest common start path.
29918 *
29919 * For instance,
29920 *
29921 * <code>
29922 * Array
29923 * (
29924 * [/home/sb/Money/Money.php] => Array
29925 * (
29926 * ...
29927 * )
29928 *
29929 * [/home/sb/Money/MoneyBag.php] => Array
29930 * (
29931 * ...
29932 * )
29933 * )
29934 * </code>
29935 *
29936 * is reduced to
29937 *
29938 * <code>
29939 * Array
29940 * (
29941 * [Money.php] => Array
29942 * (
29943 * ...
29944 * )
29945 *
29946 * [MoneyBag.php] => Array
29947 * (
29948 * ...
29949 * )
29950 * )
29951 * </code>
29952 */
29953 private function reducePaths(ProcessedCodeCoverageData $coverage): string
29954 {
29955 if (empty($coverage->coveredFiles())) {
29956 return '.';
29957 }
29958 $commonPath = '';
29959 $paths = $coverage->coveredFiles();
29960 if (count($paths) === 1) {
29961 $commonPath = dirname($paths[0]) . DIRECTORY_SEPARATOR;
29962 $coverage->renameFile($paths[0], basename($paths[0]));
29963 return $commonPath;
29964 }
29965 $max = count($paths);
29966 for ($i = 0; $i < $max; $i++) {
29967 // strip phar:// prefixes
29968 if (str_starts_with($paths[$i], 'phar://')) {
29969 $paths[$i] = substr($paths[$i], 7);
29970 $paths[$i] = str_replace('/', DIRECTORY_SEPARATOR, $paths[$i]);
29971 }
29972 $paths[$i] = explode(DIRECTORY_SEPARATOR, $paths[$i]);
29973 if (empty($paths[$i][0])) {
29974 $paths[$i][0] = DIRECTORY_SEPARATOR;
29975 }
29976 }
29977 $done = \false;
29978 $max = count($paths);
29979 while (!$done) {
29980 for ($i = 0; $i < $max - 1; $i++) {
29981 if (!isset($paths[$i][0]) || !isset($paths[$i + 1][0]) || $paths[$i][0] !== $paths[$i + 1][0]) {
29982 $done = \true;
29983 break;
29984 }
29985 }
29986 if (!$done) {
29987 $commonPath .= $paths[0][0];
29988 if ($paths[0][0] !== DIRECTORY_SEPARATOR) {
29989 $commonPath .= DIRECTORY_SEPARATOR;
29990 }
29991 for ($i = 0; $i < $max; $i++) {
29992 array_shift($paths[$i]);
29993 }
29994 }
29995 }
29996 $original = $coverage->coveredFiles();
29997 $max = count($original);
29998 for ($i = 0; $i < $max; $i++) {
29999 $coverage->renameFile($original[$i], implode(DIRECTORY_SEPARATOR, $paths[$i]));
30000 }
30001 return substr($commonPath, 0, -1);
30002 }
30003 }
30004 <?php
30005
30006 declare (strict_types=1);
30007 /*
30008 * This file is part of phpunit/php-code-coverage.
30009 *
30010 * (c) Sebastian Bergmann <sebastian@phpunit.de>
30011 *
30012 * For the full copyright and license information, please view the LICENSE
30013 * file that was distributed with this source code.
30014 */
30015 namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\Node;
30016
30017 use function sprintf;
30018 /**
30019 * @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
30020 */
30021 final class CrapIndex
30022 {
30023 private readonly int $cyclomaticComplexity;
30024 private readonly float $codeCoverage;
30025 public function __construct(int $cyclomaticComplexity, float $codeCoverage)
30026 {
30027 $this->cyclomaticComplexity = $cyclomaticComplexity;
30028 $this->codeCoverage = $codeCoverage;
30029 }
30030 public function asString(): string
30031 {
30032 if ($this->codeCoverage === 0.0) {
30033 return (string) ($this->cyclomaticComplexity ** 2 + $this->cyclomaticComplexity);
30034 }
30035 if ($this->codeCoverage >= 95) {
30036 return (string) $this->cyclomaticComplexity;
30037 }
30038 return sprintf('%01.2F', $this->cyclomaticComplexity ** 2 * (1 - $this->codeCoverage / 100) ** 3 + $this->cyclomaticComplexity);
30039 }
30040 }
30041 <?php
30042
30043 declare (strict_types=1);
30044 /*
30045 * This file is part of phpunit/php-code-coverage.
30046 *
30047 * (c) Sebastian Bergmann <sebastian@phpunit.de>
30048 *
30049 * For the full copyright and license information, please view the LICENSE
30050 * file that was distributed with this source code.
30051 */
30052 namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\Node;
30053
30054 use function array_merge;
30055 use function count;
30056 use IteratorAggregate;
30057 use RecursiveIteratorIterator;
30058 /**
30059 * @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
30060 *
30061 * @psalm-import-type LinesOfCodeType from \SebastianBergmann\CodeCoverage\StaticAnalysis\FileAnalyser
30062 */
30063 final class Directory extends AbstractNode implements IteratorAggregate
30064 {
30065 /**
30066 * @var list<AbstractNode>
30067 */
30068 private array $children = [];
30069 /**
30070 * @var list<Directory>
30071 */
30072 private array $directories = [];
30073 /**
30074 * @var list<File>
30075 */
30076 private array $files = [];
30077 private ?array $classes = null;
30078 private ?array $traits = null;
30079 private ?array $functions = null;
30080 /**
30081 * @psalm-var null|LinesOfCodeType
30082 */
30083 private ?array $linesOfCode = null;
30084 private int $numFiles = -1;
30085 private int $numExecutableLines = -1;
30086 private int $numExecutedLines = -1;
30087 private int $numExecutableBranches = -1;
30088 private int $numExecutedBranches = -1;
30089 private int $numExecutablePaths = -1;
30090 private int $numExecutedPaths = -1;
30091 private int $numClasses = -1;
30092 private int $numTestedClasses = -1;
30093 private int $numTraits = -1;
30094 private int $numTestedTraits = -1;
30095 private int $numMethods = -1;
30096 private int $numTestedMethods = -1;
30097 private int $numFunctions = -1;
30098 private int $numTestedFunctions = -1;
30099 public function count(): int
30100 {
30101 if ($this->numFiles === -1) {
30102 $this->numFiles = 0;
30103 foreach ($this->children as $child) {
30104 $this->numFiles += count($child);
30105 }
30106 }
30107 return $this->numFiles;
30108 }
30109 public function getIterator(): RecursiveIteratorIterator
30110 {
30111 return new RecursiveIteratorIterator(new Iterator($this), RecursiveIteratorIterator::SELF_FIRST);
30112 }
30113 public function addDirectory(string $name): self
30114 {
30115 $directory = new self($name, $this);
30116 $this->children[] = $directory;
30117 $this->directories[] =& $this->children[count($this->children) - 1];
30118 return $directory;
30119 }
30120 public function addFile(File $file): void
30121 {
30122 $this->children[] = $file;
30123 $this->files[] =& $this->children[count($this->children) - 1];
30124 $this->numExecutableLines = -1;
30125 $this->numExecutedLines = -1;
30126 }
30127 public function directories(): array
30128 {
30129 return $this->directories;
30130 }
30131 public function files(): array
30132 {
30133 return $this->files;
30134 }
30135 public function children(): array
30136 {
30137 return $this->children;
30138 }
30139 public function classes(): array
30140 {
30141 if ($this->classes === null) {
30142 $this->classes = [];
30143 foreach ($this->children as $child) {
30144 $this->classes = array_merge($this->classes, $child->classes());
30145 }
30146 }
30147 return $this->classes;
30148 }
30149 public function traits(): array
30150 {
30151 if ($this->traits === null) {
30152 $this->traits = [];
30153 foreach ($this->children as $child) {
30154 $this->traits = array_merge($this->traits, $child->traits());
30155 }
30156 }
30157 return $this->traits;
30158 }
30159 public function functions(): array
30160 {
30161 if ($this->functions === null) {
30162 $this->functions = [];
30163 foreach ($this->children as $child) {
30164 $this->functions = array_merge($this->functions, $child->functions());
30165 }
30166 }
30167 return $this->functions;
30168 }
30169 /**
30170 * @psalm-return LinesOfCodeType
30171 */
30172 public function linesOfCode(): array
30173 {
30174 if ($this->linesOfCode === null) {
30175 $this->linesOfCode = ['linesOfCode' => 0, 'commentLinesOfCode' => 0, 'nonCommentLinesOfCode' => 0];
30176 foreach ($this->children as $child) {
30177 $childLinesOfCode = $child->linesOfCode();
30178 $this->linesOfCode['linesOfCode'] += $childLinesOfCode['linesOfCode'];
30179 $this->linesOfCode['commentLinesOfCode'] += $childLinesOfCode['commentLinesOfCode'];
30180 $this->linesOfCode['nonCommentLinesOfCode'] += $childLinesOfCode['nonCommentLinesOfCode'];
30181 }
30182 }
30183 return $this->linesOfCode;
30184 }
30185 public function numberOfExecutableLines(): int
30186 {
30187 if ($this->numExecutableLines === -1) {
30188 $this->numExecutableLines = 0;
30189 foreach ($this->children as $child) {
30190 $this->numExecutableLines += $child->numberOfExecutableLines();
30191 }
30192 }
30193 return $this->numExecutableLines;
30194 }
30195 public function numberOfExecutedLines(): int
30196 {
30197 if ($this->numExecutedLines === -1) {
30198 $this->numExecutedLines = 0;
30199 foreach ($this->children as $child) {
30200 $this->numExecutedLines += $child->numberOfExecutedLines();
30201 }
30202 }
30203 return $this->numExecutedLines;
30204 }
30205 public function numberOfExecutableBranches(): int
30206 {
30207 if ($this->numExecutableBranches === -1) {
30208 $this->numExecutableBranches = 0;
30209 foreach ($this->children as $child) {
30210 $this->numExecutableBranches += $child->numberOfExecutableBranches();
30211 }
30212 }
30213 return $this->numExecutableBranches;
30214 }
30215 public function numberOfExecutedBranches(): int
30216 {
30217 if ($this->numExecutedBranches === -1) {
30218 $this->numExecutedBranches = 0;
30219 foreach ($this->children as $child) {
30220 $this->numExecutedBranches += $child->numberOfExecutedBranches();
30221 }
30222 }
30223 return $this->numExecutedBranches;
30224 }
30225 public function numberOfExecutablePaths(): int
30226 {
30227 if ($this->numExecutablePaths === -1) {
30228 $this->numExecutablePaths = 0;
30229 foreach ($this->children as $child) {
30230 $this->numExecutablePaths += $child->numberOfExecutablePaths();
30231 }
30232 }
30233 return $this->numExecutablePaths;
30234 }
30235 public function numberOfExecutedPaths(): int
30236 {
30237 if ($this->numExecutedPaths === -1) {
30238 $this->numExecutedPaths = 0;
30239 foreach ($this->children as $child) {
30240 $this->numExecutedPaths += $child->numberOfExecutedPaths();
30241 }
30242 }
30243 return $this->numExecutedPaths;
30244 }
30245 public function numberOfClasses(): int
30246 {
30247 if ($this->numClasses === -1) {
30248 $this->numClasses = 0;
30249 foreach ($this->children as $child) {
30250 $this->numClasses += $child->numberOfClasses();
30251 }
30252 }
30253 return $this->numClasses;
30254 }
30255 public function numberOfTestedClasses(): int
30256 {
30257 if ($this->numTestedClasses === -1) {
30258 $this->numTestedClasses = 0;
30259 foreach ($this->children as $child) {
30260 $this->numTestedClasses += $child->numberOfTestedClasses();
30261 }
30262 }
30263 return $this->numTestedClasses;
30264 }
30265 public function numberOfTraits(): int
30266 {
30267 if ($this->numTraits === -1) {
30268 $this->numTraits = 0;
30269 foreach ($this->children as $child) {
30270 $this->numTraits += $child->numberOfTraits();
30271 }
30272 }
30273 return $this->numTraits;
30274 }
30275 public function numberOfTestedTraits(): int
30276 {
30277 if ($this->numTestedTraits === -1) {
30278 $this->numTestedTraits = 0;
30279 foreach ($this->children as $child) {
30280 $this->numTestedTraits += $child->numberOfTestedTraits();
30281 }
30282 }
30283 return $this->numTestedTraits;
30284 }
30285 public function numberOfMethods(): int
30286 {
30287 if ($this->numMethods === -1) {
30288 $this->numMethods = 0;
30289 foreach ($this->children as $child) {
30290 $this->numMethods += $child->numberOfMethods();
30291 }
30292 }
30293 return $this->numMethods;
30294 }
30295 public function numberOfTestedMethods(): int
30296 {
30297 if ($this->numTestedMethods === -1) {
30298 $this->numTestedMethods = 0;
30299 foreach ($this->children as $child) {
30300 $this->numTestedMethods += $child->numberOfTestedMethods();
30301 }
30302 }
30303 return $this->numTestedMethods;
30304 }
30305 public function numberOfFunctions(): int
30306 {
30307 if ($this->numFunctions === -1) {
30308 $this->numFunctions = 0;
30309 foreach ($this->children as $child) {
30310 $this->numFunctions += $child->numberOfFunctions();
30311 }
30312 }
30313 return $this->numFunctions;
30314 }
30315 public function numberOfTestedFunctions(): int
30316 {
30317 if ($this->numTestedFunctions === -1) {
30318 $this->numTestedFunctions = 0;
30319 foreach ($this->children as $child) {
30320 $this->numTestedFunctions += $child->numberOfTestedFunctions();
30321 }
30322 }
30323 return $this->numTestedFunctions;
30324 }
30325 }
30326 <?php
30327
30328 declare (strict_types=1);
30329 /*
30330 * This file is part of phpunit/php-code-coverage.
30331 *
30332 * (c) Sebastian Bergmann <sebastian@phpunit.de>
30333 *
30334 * For the full copyright and license information, please view the LICENSE
30335 * file that was distributed with this source code.
30336 */
30337 namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\Node;
30338
30339 use function array_filter;
30340 use function count;
30341 use function range;
30342 /**
30343 * @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
30344 *
30345 * @psalm-import-type CodeUnitFunctionType from \SebastianBergmann\CodeCoverage\StaticAnalysis\CodeUnitFindingVisitor
30346 * @psalm-import-type CodeUnitMethodType from \SebastianBergmann\CodeCoverage\StaticAnalysis\CodeUnitFindingVisitor
30347 * @psalm-import-type CodeUnitClassType from \SebastianBergmann\CodeCoverage\StaticAnalysis\CodeUnitFindingVisitor
30348 * @psalm-import-type CodeUnitTraitType from \SebastianBergmann\CodeCoverage\StaticAnalysis\CodeUnitFindingVisitor
30349 * @psalm-import-type LinesOfCodeType from \SebastianBergmann\CodeCoverage\StaticAnalysis\FileAnalyser
30350 * @psalm-import-type LinesType from \SebastianBergmann\CodeCoverage\StaticAnalysis\FileAnalyser
30351 *
30352 * @psalm-type ProcessedFunctionType = array{
30353 * functionName: string,
30354 * namespace: string,
30355 * signature: string,
30356 * startLine: int,
30357 * endLine: int,
30358 * executableLines: int,
30359 * executedLines: int,
30360 * executableBranches: int,
30361 * executedBranches: int,
30362 * executablePaths: int,
30363 * executedPaths: int,
30364 * ccn: int,
30365 * coverage: int|float,
30366 * crap: int|string,
30367 * link: string
30368 * }
30369 * @psalm-type ProcessedMethodType = array{
30370 * methodName: string,
30371 * visibility: string,
30372 * signature: string,
30373 * startLine: int,
30374 * endLine: int,
30375 * executableLines: int,
30376 * executedLines: int,
30377 * executableBranches: int,
30378 * executedBranches: int,
30379 * executablePaths: int,
30380 * executedPaths: int,
30381 * ccn: int,
30382 * coverage: float|int,
30383 * crap: int|string,
30384 * link: string
30385 * }
30386 * @psalm-type ProcessedClassType = array{
30387 * className: string,
30388 * namespace: string,
30389 * methods: array<string, ProcessedMethodType>,
30390 * startLine: int,
30391 * executableLines: int,
30392 * executedLines: int,
30393 * executableBranches: int,
30394 * executedBranches: int,
30395 * executablePaths: int,
30396 * executedPaths: int,
30397 * ccn: int,
30398 * coverage: int|float,
30399 * crap: int|string,
30400 * link: string
30401 * }
30402 * @psalm-type ProcessedTraitType = array{
30403 * traitName: string,
30404 * namespace: string,
30405 * methods: array<string, ProcessedMethodType>,
30406 * startLine: int,
30407 * executableLines: int,
30408 * executedLines: int,
30409 * executableBranches: int,
30410 * executedBranches: int,
30411 * executablePaths: int,
30412 * executedPaths: int,
30413 * ccn: int,
30414 * coverage: float|int,
30415 * crap: int|string,
30416 * link: string
30417 * }
30418 */
30419 final class File extends AbstractNode
30420 {
30421 /**
30422 * @psalm-var array<int, ?list<non-empty-string>>
30423 */
30424 private array $lineCoverageData;
30425 private array $functionCoverageData;
30426 private readonly array $testData;
30427 private int $numExecutableLines = 0;
30428 private int $numExecutedLines = 0;
30429 private int $numExecutableBranches = 0;
30430 private int $numExecutedBranches = 0;
30431 private int $numExecutablePaths = 0;
30432 private int $numExecutedPaths = 0;
30433 /**
30434 * @psalm-var array<string, ProcessedClassType>
30435 */
30436 private array $classes = [];
30437 /**
30438 * @psalm-var array<string, ProcessedTraitType>
30439 */
30440 private array $traits = [];
30441 /**
30442 * @psalm-var array<string, ProcessedFunctionType>
30443 */
30444 private array $functions = [];
30445 /**
30446 * @psalm-var LinesOfCodeType
30447 */
30448 private readonly array $linesOfCode;
30449 private ?int $numClasses = null;
30450 private int $numTestedClasses = 0;
30451 private ?int $numTraits = null;
30452 private int $numTestedTraits = 0;
30453 private ?int $numMethods = null;
30454 private ?int $numTestedMethods = null;
30455 private ?int $numTestedFunctions = null;
30456 /**
30457 * @var array<int, array|array{0: CodeUnitClassType, 1: string}|array{0: CodeUnitFunctionType}|array{0: CodeUnitTraitType, 1: string}>
30458 */
30459 private array $codeUnitsByLine = [];
30460 /**
30461 * @psalm-param array<int, ?list<non-empty-string>> $lineCoverageData
30462 * @psalm-param LinesOfCodeType $linesOfCode
30463 * @psalm-param array<string, CodeUnitClassType> $classes
30464 * @psalm-param array<string, CodeUnitTraitType> $traits
30465 * @psalm-param array<string, CodeUnitFunctionType> $functions
30466 */
30467 public function __construct(string $name, AbstractNode $parent, array $lineCoverageData, array $functionCoverageData, array $testData, array $classes, array $traits, array $functions, array $linesOfCode)
30468 {
30469 parent::__construct($name, $parent);
30470 $this->lineCoverageData = $lineCoverageData;
30471 $this->functionCoverageData = $functionCoverageData;
30472 $this->testData = $testData;
30473 $this->linesOfCode = $linesOfCode;
30474 $this->calculateStatistics($classes, $traits, $functions);
30475 }
30476 public function count(): int
30477 {
30478 return 1;
30479 }
30480 /**
30481 * @psalm-return array<int, ?list<non-empty-string>>
30482 */
30483 public function lineCoverageData(): array
30484 {
30485 return $this->lineCoverageData;
30486 }
30487 public function functionCoverageData(): array
30488 {
30489 return $this->functionCoverageData;
30490 }
30491 public function testData(): array
30492 {
30493 return $this->testData;
30494 }
30495 public function classes(): array
30496 {
30497 return $this->classes;
30498 }
30499 public function traits(): array
30500 {
30501 return $this->traits;
30502 }
30503 public function functions(): array
30504 {
30505 return $this->functions;
30506 }
30507 public function linesOfCode(): array
30508 {
30509 return $this->linesOfCode;
30510 }
30511 public function numberOfExecutableLines(): int
30512 {
30513 return $this->numExecutableLines;
30514 }
30515 public function numberOfExecutedLines(): int
30516 {
30517 return $this->numExecutedLines;
30518 }
30519 public function numberOfExecutableBranches(): int
30520 {
30521 return $this->numExecutableBranches;
30522 }
30523 public function numberOfExecutedBranches(): int
30524 {
30525 return $this->numExecutedBranches;
30526 }
30527 public function numberOfExecutablePaths(): int
30528 {
30529 return $this->numExecutablePaths;
30530 }
30531 public function numberOfExecutedPaths(): int
30532 {
30533 return $this->numExecutedPaths;
30534 }
30535 public function numberOfClasses(): int
30536 {
30537 if ($this->numClasses === null) {
30538 $this->numClasses = 0;
30539 foreach ($this->classes as $class) {
30540 foreach ($class['methods'] as $method) {
30541 if ($method['executableLines'] > 0) {
30542 $this->numClasses++;
30543 continue 2;
30544 }
30545 }
30546 }
30547 }
30548 return $this->numClasses;
30549 }
30550 public function numberOfTestedClasses(): int
30551 {
30552 return $this->numTestedClasses;
30553 }
30554 public function numberOfTraits(): int
30555 {
30556 if ($this->numTraits === null) {
30557 $this->numTraits = 0;
30558 foreach ($this->traits as $trait) {
30559 foreach ($trait['methods'] as $method) {
30560 if ($method['executableLines'] > 0) {
30561 $this->numTraits++;
30562 continue 2;
30563 }
30564 }
30565 }
30566 }
30567 return $this->numTraits;
30568 }
30569 public function numberOfTestedTraits(): int
30570 {
30571 return $this->numTestedTraits;
30572 }
30573 public function numberOfMethods(): int
30574 {
30575 if ($this->numMethods === null) {
30576 $this->numMethods = 0;
30577 foreach ($this->classes as $class) {
30578 foreach ($class['methods'] as $method) {
30579 if ($method['executableLines'] > 0) {
30580 $this->numMethods++;
30581 }
30582 }
30583 }
30584 foreach ($this->traits as $trait) {
30585 foreach ($trait['methods'] as $method) {
30586 if ($method['executableLines'] > 0) {
30587 $this->numMethods++;
30588 }
30589 }
30590 }
30591 }
30592 return $this->numMethods;
30593 }
30594 public function numberOfTestedMethods(): int
30595 {
30596 if ($this->numTestedMethods === null) {
30597 $this->numTestedMethods = 0;
30598 foreach ($this->classes as $class) {
30599 foreach ($class['methods'] as $method) {
30600 if ($method['executableLines'] > 0 && $method['coverage'] === 100) {
30601 $this->numTestedMethods++;
30602 }
30603 }
30604 }
30605 foreach ($this->traits as $trait) {
30606 foreach ($trait['methods'] as $method) {
30607 if ($method['executableLines'] > 0 && $method['coverage'] === 100) {
30608 $this->numTestedMethods++;
30609 }
30610 }
30611 }
30612 }
30613 return $this->numTestedMethods;
30614 }
30615 public function numberOfFunctions(): int
30616 {
30617 return count($this->functions);
30618 }
30619 public function numberOfTestedFunctions(): int
30620 {
30621 if ($this->numTestedFunctions === null) {
30622 $this->numTestedFunctions = 0;
30623 foreach ($this->functions as $function) {
30624 if ($function['executableLines'] > 0 && $function['coverage'] === 100) {
30625 $this->numTestedFunctions++;
30626 }
30627 }
30628 }
30629 return $this->numTestedFunctions;
30630 }
30631 /**
30632 * @psalm-param array<string, CodeUnitClassType> $classes
30633 * @psalm-param array<string, CodeUnitTraitType> $traits
30634 * @psalm-param array<string, CodeUnitFunctionType> $functions
30635 */
30636 private function calculateStatistics(array $classes, array $traits, array $functions): void
30637 {
30638 foreach (range(1, $this->linesOfCode['linesOfCode']) as $lineNumber) {
30639 $this->codeUnitsByLine[$lineNumber] = [];
30640 }
30641 $this->processClasses($classes);
30642 $this->processTraits($traits);
30643 $this->processFunctions($functions);
30644 foreach (range(1, $this->linesOfCode['linesOfCode']) as $lineNumber) {
30645 if (isset($this->lineCoverageData[$lineNumber])) {
30646 foreach ($this->codeUnitsByLine[$lineNumber] as &$codeUnit) {
30647 $codeUnit['executableLines']++;
30648 }
30649 unset($codeUnit);
30650 $this->numExecutableLines++;
30651 if (count($this->lineCoverageData[$lineNumber]) > 0) {
30652 foreach ($this->codeUnitsByLine[$lineNumber] as &$codeUnit) {
30653 $codeUnit['executedLines']++;
30654 }
30655 unset($codeUnit);
30656 $this->numExecutedLines++;
30657 }
30658 }
30659 }
30660 foreach ($this->traits as &$trait) {
30661 foreach ($trait['methods'] as &$method) {
30662 $methodLineCoverage = $method['executableLines'] ? $method['executedLines'] / $method['executableLines'] * 100 : 100;
30663 $methodBranchCoverage = $method['executableBranches'] ? $method['executedBranches'] / $method['executableBranches'] * 100 : 0;
30664 $methodPathCoverage = $method['executablePaths'] ? $method['executedPaths'] / $method['executablePaths'] * 100 : 0;
30665 $method['coverage'] = $methodBranchCoverage ?: $methodLineCoverage;
30666 $method['crap'] = (new CrapIndex($method['ccn'], $methodPathCoverage ?: $methodLineCoverage))->asString();
30667 $trait['ccn'] += $method['ccn'];
30668 }
30669 unset($method);
30670 $traitLineCoverage = $trait['executableLines'] ? $trait['executedLines'] / $trait['executableLines'] * 100 : 100;
30671 $traitBranchCoverage = $trait['executableBranches'] ? $trait['executedBranches'] / $trait['executableBranches'] * 100 : 0;
30672 $traitPathCoverage = $trait['executablePaths'] ? $trait['executedPaths'] / $trait['executablePaths'] * 100 : 0;
30673 $trait['coverage'] = $traitBranchCoverage ?: $traitLineCoverage;
30674 $trait['crap'] = (new CrapIndex($trait['ccn'], $traitPathCoverage ?: $traitLineCoverage))->asString();
30675 if ($trait['executableLines'] > 0 && $trait['coverage'] === 100) {
30676 $this->numTestedClasses++;
30677 }
30678 }
30679 unset($trait);
30680 foreach ($this->classes as &$class) {
30681 foreach ($class['methods'] as &$method) {
30682 $methodLineCoverage = $method['executableLines'] ? $method['executedLines'] / $method['executableLines'] * 100 : 100;
30683 $methodBranchCoverage = $method['executableBranches'] ? $method['executedBranches'] / $method['executableBranches'] * 100 : 0;
30684 $methodPathCoverage = $method['executablePaths'] ? $method['executedPaths'] / $method['executablePaths'] * 100 : 0;
30685 $method['coverage'] = $methodBranchCoverage ?: $methodLineCoverage;
30686 $method['crap'] = (new CrapIndex($method['ccn'], $methodPathCoverage ?: $methodLineCoverage))->asString();
30687 $class['ccn'] += $method['ccn'];
30688 }
30689 unset($method);
30690 $classLineCoverage = $class['executableLines'] ? $class['executedLines'] / $class['executableLines'] * 100 : 100;
30691 $classBranchCoverage = $class['executableBranches'] ? $class['executedBranches'] / $class['executableBranches'] * 100 : 0;
30692 $classPathCoverage = $class['executablePaths'] ? $class['executedPaths'] / $class['executablePaths'] * 100 : 0;
30693 $class['coverage'] = $classBranchCoverage ?: $classLineCoverage;
30694 $class['crap'] = (new CrapIndex($class['ccn'], $classPathCoverage ?: $classLineCoverage))->asString();
30695 if ($class['executableLines'] > 0 && $class['coverage'] === 100) {
30696 $this->numTestedClasses++;
30697 }
30698 }
30699 unset($class);
30700 foreach ($this->functions as &$function) {
30701 $functionLineCoverage = $function['executableLines'] ? $function['executedLines'] / $function['executableLines'] * 100 : 100;
30702 $functionBranchCoverage = $function['executableBranches'] ? $function['executedBranches'] / $function['executableBranches'] * 100 : 0;
30703 $functionPathCoverage = $function['executablePaths'] ? $function['executedPaths'] / $function['executablePaths'] * 100 : 0;
30704 $function['coverage'] = $functionBranchCoverage ?: $functionLineCoverage;
30705 $function['crap'] = (new CrapIndex($function['ccn'], $functionPathCoverage ?: $functionLineCoverage))->asString();
30706 if ($function['coverage'] === 100) {
30707 $this->numTestedFunctions++;
30708 }
30709 }
30710 }
30711 /**
30712 * @psalm-param array<string, CodeUnitClassType> $classes
30713 */
30714 private function processClasses(array $classes): void
30715 {
30716 $link = $this->id() . '.html#';
30717 foreach ($classes as $className => $class) {
30718 $this->classes[$className] = ['className' => $className, 'namespace' => $class['namespace'], 'methods' => [], 'startLine' => $class['startLine'], 'executableLines' => 0, 'executedLines' => 0, 'executableBranches' => 0, 'executedBranches' => 0, 'executablePaths' => 0, 'executedPaths' => 0, 'ccn' => 0, 'coverage' => 0, 'crap' => 0, 'link' => $link . $class['startLine']];
30719 foreach ($class['methods'] as $methodName => $method) {
30720 $methodData = $this->newMethod($className, $methodName, $method, $link);
30721 $this->classes[$className]['methods'][$methodName] = $methodData;
30722 $this->classes[$className]['executableBranches'] += $methodData['executableBranches'];
30723 $this->classes[$className]['executedBranches'] += $methodData['executedBranches'];
30724 $this->classes[$className]['executablePaths'] += $methodData['executablePaths'];
30725 $this->classes[$className]['executedPaths'] += $methodData['executedPaths'];
30726 $this->numExecutableBranches += $methodData['executableBranches'];
30727 $this->numExecutedBranches += $methodData['executedBranches'];
30728 $this->numExecutablePaths += $methodData['executablePaths'];
30729 $this->numExecutedPaths += $methodData['executedPaths'];
30730 foreach (range($method['startLine'], $method['endLine']) as $lineNumber) {
30731 $this->codeUnitsByLine[$lineNumber] = [&$this->classes[$className], &$this->classes[$className]['methods'][$methodName]];
30732 }
30733 }
30734 }
30735 }
30736 /**
30737 * @psalm-param array<string, CodeUnitTraitType> $traits
30738 */
30739 private function processTraits(array $traits): void
30740 {
30741 $link = $this->id() . '.html#';
30742 foreach ($traits as $traitName => $trait) {
30743 $this->traits[$traitName] = ['traitName' => $traitName, 'namespace' => $trait['namespace'], 'methods' => [], 'startLine' => $trait['startLine'], 'executableLines' => 0, 'executedLines' => 0, 'executableBranches' => 0, 'executedBranches' => 0, 'executablePaths' => 0, 'executedPaths' => 0, 'ccn' => 0, 'coverage' => 0, 'crap' => 0, 'link' => $link . $trait['startLine']];
30744 foreach ($trait['methods'] as $methodName => $method) {
30745 $methodData = $this->newMethod($traitName, $methodName, $method, $link);
30746 $this->traits[$traitName]['methods'][$methodName] = $methodData;
30747 $this->traits[$traitName]['executableBranches'] += $methodData['executableBranches'];
30748 $this->traits[$traitName]['executedBranches'] += $methodData['executedBranches'];
30749 $this->traits[$traitName]['executablePaths'] += $methodData['executablePaths'];
30750 $this->traits[$traitName]['executedPaths'] += $methodData['executedPaths'];
30751 $this->numExecutableBranches += $methodData['executableBranches'];
30752 $this->numExecutedBranches += $methodData['executedBranches'];
30753 $this->numExecutablePaths += $methodData['executablePaths'];
30754 $this->numExecutedPaths += $methodData['executedPaths'];
30755 foreach (range($method['startLine'], $method['endLine']) as $lineNumber) {
30756 $this->codeUnitsByLine[$lineNumber] = [&$this->traits[$traitName], &$this->traits[$traitName]['methods'][$methodName]];
30757 }
30758 }
30759 }
30760 }
30761 /**
30762 * @psalm-param array<string, CodeUnitFunctionType> $functions
30763 */
30764 private function processFunctions(array $functions): void
30765 {
30766 $link = $this->id() . '.html#';
30767 foreach ($functions as $functionName => $function) {
30768 $this->functions[$functionName] = ['functionName' => $functionName, 'namespace' => $function['namespace'], 'signature' => $function['signature'], 'startLine' => $function['startLine'], 'endLine' => $function['endLine'], 'executableLines' => 0, 'executedLines' => 0, 'executableBranches' => 0, 'executedBranches' => 0, 'executablePaths' => 0, 'executedPaths' => 0, 'ccn' => $function['ccn'], 'coverage' => 0, 'crap' => 0, 'link' => $link . $function['startLine']];
30769 foreach (range($function['startLine'], $function['endLine']) as $lineNumber) {
30770 $this->codeUnitsByLine[$lineNumber] = [&$this->functions[$functionName]];
30771 }
30772 if (isset($this->functionCoverageData[$functionName]['branches'])) {
30773 $this->functions[$functionName]['executableBranches'] = count($this->functionCoverageData[$functionName]['branches']);
30774 $this->functions[$functionName]['executedBranches'] = count(array_filter($this->functionCoverageData[$functionName]['branches'], static function (array $branch) {
30775 return (bool) $branch['hit'];
30776 }));
30777 }
30778 if (isset($this->functionCoverageData[$functionName]['paths'])) {
30779 $this->functions[$functionName]['executablePaths'] = count($this->functionCoverageData[$functionName]['paths']);
30780 $this->functions[$functionName]['executedPaths'] = count(array_filter($this->functionCoverageData[$functionName]['paths'], static function (array $path) {
30781 return (bool) $path['hit'];
30782 }));
30783 }
30784 $this->numExecutableBranches += $this->functions[$functionName]['executableBranches'];
30785 $this->numExecutedBranches += $this->functions[$functionName]['executedBranches'];
30786 $this->numExecutablePaths += $this->functions[$functionName]['executablePaths'];
30787 $this->numExecutedPaths += $this->functions[$functionName]['executedPaths'];
30788 }
30789 }
30790 /**
30791 * @psalm-param CodeUnitMethodType $method
30792 *
30793 * @psalm-return ProcessedMethodType
30794 */
30795 private function newMethod(string $className, string $methodName, array $method, string $link): array
30796 {
30797 $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']];
30798 $key = $className . '->' . $methodName;
30799 if (isset($this->functionCoverageData[$key]['branches'])) {
30800 $methodData['executableBranches'] = count($this->functionCoverageData[$key]['branches']);
30801 $methodData['executedBranches'] = count(array_filter($this->functionCoverageData[$key]['branches'], static function (array $branch) {
30802 return (bool) $branch['hit'];
30803 }));
30804 }
30805 if (isset($this->functionCoverageData[$key]['paths'])) {
30806 $methodData['executablePaths'] = count($this->functionCoverageData[$key]['paths']);
30807 $methodData['executedPaths'] = count(array_filter($this->functionCoverageData[$key]['paths'], static function (array $path) {
30808 return (bool) $path['hit'];
30809 }));
30810 }
30811 return $methodData;
30812 }
30813 }
30814 <?php
30815
30816 declare (strict_types=1);
30817 /*
30818 * This file is part of phpunit/php-code-coverage.
30819 *
30820 * (c) Sebastian Bergmann <sebastian@phpunit.de>
30821 *
30822 * For the full copyright and license information, please view the LICENSE
30823 * file that was distributed with this source code.
30824 */
30825 namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\Node;
30826
30827 use function count;
30828 use RecursiveIterator;
30829 /**
30830 * @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
30831 */
30832 final class Iterator implements RecursiveIterator
30833 {
30834 private int $position;
30835 /**
30836 * @var list<AbstractNode>
30837 */
30838 private readonly array $nodes;
30839 public function __construct(Directory $node)
30840 {
30841 $this->nodes = $node->children();
30842 }
30843 /**
30844 * Rewinds the Iterator to the first element.
30845 */
30846 public function rewind(): void
30847 {
30848 $this->position = 0;
30849 }
30850 /**
30851 * Checks if there is a current element after calls to rewind() or next().
30852 */
30853 public function valid(): bool
30854 {
30855 return $this->position < count($this->nodes);
30856 }
30857 /**
30858 * Returns the key of the current element.
30859 */
30860 public function key(): int
30861 {
30862 return $this->position;
30863 }
30864 /**
30865 * Returns the current element.
30866 */
30867 public function current(): ?AbstractNode
30868 {
30869 return $this->valid() ? $this->nodes[$this->position] : null;
30870 }
30871 /**
30872 * Moves forward to next element.
30873 */
30874 public function next(): void
30875 {
30876 $this->position++;
30877 }
30878 /**
30879 * Returns the sub iterator for the current element.
30880 */
30881 public function getChildren(): self
30882 {
30883 return new self($this->nodes[$this->position]);
30884 }
30885 /**
30886 * Checks whether the current element has children.
30887 */
30888 public function hasChildren(): bool
30889 {
30890 return $this->nodes[$this->position] instanceof Directory;
30891 }
30892 }
30893 <?php
30894
30895 declare (strict_types=1);
30896 /*
30897 * This file is part of phpunit/php-code-coverage.
30898 *
30899 * (c) Sebastian Bergmann <sebastian@phpunit.de>
30900 *
30901 * For the full copyright and license information, please view the LICENSE
30902 * file that was distributed with this source code.
30903 */
30904 namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\Report;
30905
30906 use function count;
30907 use function dirname;
30908 use function file_put_contents;
30909 use function is_string;
30910 use function ksort;
30911 use function max;
30912 use function range;
30913 use function str_contains;
30914 use function time;
30915 use DOMDocument;
30916 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\CodeCoverage;
30917 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Driver\WriteOperationFailedException;
30918 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Node\File;
30919 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Util\Filesystem;
30920 final class Clover
30921 {
30922 /**
30923 * @throws WriteOperationFailedException
30924 */
30925 public function process(CodeCoverage $coverage, ?string $target = null, ?string $name = null): string
30926 {
30927 $time = (string) time();
30928 $xmlDocument = new DOMDocument('1.0', 'UTF-8');
30929 $xmlDocument->formatOutput = \true;
30930 $xmlCoverage = $xmlDocument->createElement('coverage');
30931 $xmlCoverage->setAttribute('generated', $time);
30932 $xmlDocument->appendChild($xmlCoverage);
30933 $xmlProject = $xmlDocument->createElement('project');
30934 $xmlProject->setAttribute('timestamp', $time);
30935 if (is_string($name)) {
30936 $xmlProject->setAttribute('name', $name);
30937 }
30938 $xmlCoverage->appendChild($xmlProject);
30939 $packages = [];
30940 $report = $coverage->getReport();
30941 foreach ($report as $item) {
30942 if (!$item instanceof File) {
30943 continue;
30944 }
30945 /* @var File $item */
30946 $xmlFile = $xmlDocument->createElement('file');
30947 $xmlFile->setAttribute('name', $item->pathAsString());
30948 $classes = $item->classesAndTraits();
30949 $coverageData = $item->lineCoverageData();
30950 $lines = [];
30951 $namespace = 'global';
30952 foreach ($classes as $className => $class) {
30953 $classStatements = 0;
30954 $coveredClassStatements = 0;
30955 $coveredMethods = 0;
30956 $classMethods = 0;
30957 foreach ($class['methods'] as $methodName => $method) {
30958 if ($method['executableLines'] == 0) {
30959 continue;
30960 }
30961 $classMethods++;
30962 $classStatements += $method['executableLines'];
30963 $coveredClassStatements += $method['executedLines'];
30964 if ($method['coverage'] == 100) {
30965 $coveredMethods++;
30966 }
30967 $methodCount = 0;
30968 foreach (range($method['startLine'], $method['endLine']) as $line) {
30969 if (isset($coverageData[$line])) {
30970 $methodCount = max($methodCount, count($coverageData[$line]));
30971 }
30972 }
30973 $lines[$method['startLine']] = ['ccn' => $method['ccn'], 'count' => $methodCount, 'crap' => $method['crap'], 'type' => 'method', 'visibility' => $method['visibility'], 'name' => $methodName];
30974 }
30975 if (!empty($class['package']['namespace'])) {
30976 $namespace = $class['package']['namespace'];
30977 }
30978 $xmlClass = $xmlDocument->createElement('class');
30979 $xmlClass->setAttribute('name', $className);
30980 $xmlClass->setAttribute('namespace', $namespace);
30981 if (!empty($class['package']['fullPackage'])) {
30982 $xmlClass->setAttribute('fullPackage', $class['package']['fullPackage']);
30983 }
30984 if (!empty($class['package']['category'])) {
30985 $xmlClass->setAttribute('category', $class['package']['category']);
30986 }
30987 if (!empty($class['package']['package'])) {
30988 $xmlClass->setAttribute('package', $class['package']['package']);
30989 }
30990 if (!empty($class['package']['subpackage'])) {
30991 $xmlClass->setAttribute('subpackage', $class['package']['subpackage']);
30992 }
30993 $xmlFile->appendChild($xmlClass);
30994 $xmlMetrics = $xmlDocument->createElement('metrics');
30995 $xmlMetrics->setAttribute('complexity', (string) $class['ccn']);
30996 $xmlMetrics->setAttribute('methods', (string) $classMethods);
30997 $xmlMetrics->setAttribute('coveredmethods', (string) $coveredMethods);
30998 $xmlMetrics->setAttribute('conditionals', (string) $class['executableBranches']);
30999 $xmlMetrics->setAttribute('coveredconditionals', (string) $class['executedBranches']);
31000 $xmlMetrics->setAttribute('statements', (string) $classStatements);
31001 $xmlMetrics->setAttribute('coveredstatements', (string) $coveredClassStatements);
31002 $xmlMetrics->setAttribute('elements', (string) ($classMethods + $classStatements + $class['executableBranches']));
31003 $xmlMetrics->setAttribute('coveredelements', (string) ($coveredMethods + $coveredClassStatements + $class['executedBranches']));
31004 $xmlClass->appendChild($xmlMetrics);
31005 }
31006 foreach ($coverageData as $line => $data) {
31007 if ($data === null || isset($lines[$line])) {
31008 continue;
31009 }
31010 $lines[$line] = ['count' => count($data), 'type' => 'stmt'];
31011 }
31012 ksort($lines);
31013 foreach ($lines as $line => $data) {
31014 $xmlLine = $xmlDocument->createElement('line');
31015 $xmlLine->setAttribute('num', (string) $line);
31016 $xmlLine->setAttribute('type', $data['type']);
31017 if (isset($data['name'])) {
31018 $xmlLine->setAttribute('name', $data['name']);
31019 }
31020 if (isset($data['visibility'])) {
31021 $xmlLine->setAttribute('visibility', $data['visibility']);
31022 }
31023 if (isset($data['ccn'])) {
31024 $xmlLine->setAttribute('complexity', (string) $data['ccn']);
31025 }
31026 if (isset($data['crap'])) {
31027 $xmlLine->setAttribute('crap', (string) $data['crap']);
31028 }
31029 $xmlLine->setAttribute('count', (string) $data['count']);
31030 $xmlFile->appendChild($xmlLine);
31031 }
31032 $linesOfCode = $item->linesOfCode();
31033 $xmlMetrics = $xmlDocument->createElement('metrics');
31034 $xmlMetrics->setAttribute('loc', (string) $linesOfCode['linesOfCode']);
31035 $xmlMetrics->setAttribute('ncloc', (string) $linesOfCode['nonCommentLinesOfCode']);
31036 $xmlMetrics->setAttribute('classes', (string) $item->numberOfClassesAndTraits());
31037 $xmlMetrics->setAttribute('methods', (string) $item->numberOfMethods());
31038 $xmlMetrics->setAttribute('coveredmethods', (string) $item->numberOfTestedMethods());
31039 $xmlMetrics->setAttribute('conditionals', (string) $item->numberOfExecutableBranches());
31040 $xmlMetrics->setAttribute('coveredconditionals', (string) $item->numberOfExecutedBranches());
31041 $xmlMetrics->setAttribute('statements', (string) $item->numberOfExecutableLines());
31042 $xmlMetrics->setAttribute('coveredstatements', (string) $item->numberOfExecutedLines());
31043 $xmlMetrics->setAttribute('elements', (string) ($item->numberOfMethods() + $item->numberOfExecutableLines() + $item->numberOfExecutableBranches()));
31044 $xmlMetrics->setAttribute('coveredelements', (string) ($item->numberOfTestedMethods() + $item->numberOfExecutedLines() + $item->numberOfExecutedBranches()));
31045 $xmlFile->appendChild($xmlMetrics);
31046 if ($namespace === 'global') {
31047 $xmlProject->appendChild($xmlFile);
31048 } else {
31049 if (!isset($packages[$namespace])) {
31050 $packages[$namespace] = $xmlDocument->createElement('package');
31051 $packages[$namespace]->setAttribute('name', $namespace);
31052 $xmlProject->appendChild($packages[$namespace]);
31053 }
31054 $packages[$namespace]->appendChild($xmlFile);
31055 }
31056 }
31057 $linesOfCode = $report->linesOfCode();
31058 $xmlMetrics = $xmlDocument->createElement('metrics');
31059 $xmlMetrics->setAttribute('files', (string) count($report));
31060 $xmlMetrics->setAttribute('loc', (string) $linesOfCode['linesOfCode']);
31061 $xmlMetrics->setAttribute('ncloc', (string) $linesOfCode['nonCommentLinesOfCode']);
31062 $xmlMetrics->setAttribute('classes', (string) $report->numberOfClassesAndTraits());
31063 $xmlMetrics->setAttribute('methods', (string) $report->numberOfMethods());
31064 $xmlMetrics->setAttribute('coveredmethods', (string) $report->numberOfTestedMethods());
31065 $xmlMetrics->setAttribute('conditionals', (string) $report->numberOfExecutableBranches());
31066 $xmlMetrics->setAttribute('coveredconditionals', (string) $report->numberOfExecutedBranches());
31067 $xmlMetrics->setAttribute('statements', (string) $report->numberOfExecutableLines());
31068 $xmlMetrics->setAttribute('coveredstatements', (string) $report->numberOfExecutedLines());
31069 $xmlMetrics->setAttribute('elements', (string) ($report->numberOfMethods() + $report->numberOfExecutableLines() + $report->numberOfExecutableBranches()));
31070 $xmlMetrics->setAttribute('coveredelements', (string) ($report->numberOfTestedMethods() + $report->numberOfExecutedLines() + $report->numberOfExecutedBranches()));
31071 $xmlProject->appendChild($xmlMetrics);
31072 $buffer = $xmlDocument->saveXML();
31073 if ($target !== null) {
31074 if (!str_contains($target, '://')) {
31075 Filesystem::createDirectory(dirname($target));
31076 }
31077 if (@file_put_contents($target, $buffer) === \false) {
31078 throw new WriteOperationFailedException($target);
31079 }
31080 }
31081 return $buffer;
31082 }
31083 }
31084 <?php
31085
31086 declare (strict_types=1);
31087 /*
31088 * This file is part of phpunit/php-code-coverage.
31089 *
31090 * (c) Sebastian Bergmann <sebastian@phpunit.de>
31091 *
31092 * For the full copyright and license information, please view the LICENSE
31093 * file that was distributed with this source code.
31094 */
31095 namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\Report;
31096
31097 use function basename;
31098 use function count;
31099 use function dirname;
31100 use function file_put_contents;
31101 use function preg_match;
31102 use function range;
31103 use function str_contains;
31104 use function str_replace;
31105 use function time;
31106 use DOMImplementation;
31107 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\CodeCoverage;
31108 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Driver\WriteOperationFailedException;
31109 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Node\File;
31110 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Util\Filesystem;
31111 final class Cobertura
31112 {
31113 /**
31114 * @throws WriteOperationFailedException
31115 */
31116 public function process(CodeCoverage $coverage, ?string $target = null): string
31117 {
31118 $time = (string) time();
31119 $report = $coverage->getReport();
31120 $implementation = new DOMImplementation();
31121 $documentType = $implementation->createDocumentType('coverage', '', 'http://cobertura.sourceforge.net/xml/coverage-04.dtd');
31122 $document = $implementation->createDocument('', '', $documentType);
31123 $document->xmlVersion = '1.0';
31124 $document->encoding = 'UTF-8';
31125 $document->formatOutput = \true;
31126 $coverageElement = $document->createElement('coverage');
31127 $linesValid = $report->numberOfExecutableLines();
31128 $linesCovered = $report->numberOfExecutedLines();
31129 $lineRate = $linesValid === 0 ? 0 : $linesCovered / $linesValid;
31130 $coverageElement->setAttribute('line-rate', (string) $lineRate);
31131 $branchesValid = $report->numberOfExecutableBranches();
31132 $branchesCovered = $report->numberOfExecutedBranches();
31133 $branchRate = $branchesValid === 0 ? 0 : $branchesCovered / $branchesValid;
31134 $coverageElement->setAttribute('branch-rate', (string) $branchRate);
31135 $coverageElement->setAttribute('lines-covered', (string) $report->numberOfExecutedLines());
31136 $coverageElement->setAttribute('lines-valid', (string) $report->numberOfExecutableLines());
31137 $coverageElement->setAttribute('branches-covered', (string) $report->numberOfExecutedBranches());
31138 $coverageElement->setAttribute('branches-valid', (string) $report->numberOfExecutableBranches());
31139 $coverageElement->setAttribute('complexity', '');
31140 $coverageElement->setAttribute('version', '0.4');
31141 $coverageElement->setAttribute('timestamp', $time);
31142 $document->appendChild($coverageElement);
31143 $sourcesElement = $document->createElement('sources');
31144 $coverageElement->appendChild($sourcesElement);
31145 $sourceElement = $document->createElement('source', $report->pathAsString());
31146 $sourcesElement->appendChild($sourceElement);
31147 $packagesElement = $document->createElement('packages');
31148 $coverageElement->appendChild($packagesElement);
31149 $complexity = 0;
31150 foreach ($report as $item) {
31151 if (!$item instanceof File) {
31152 continue;
31153 }
31154 $packageElement = $document->createElement('package');
31155 $packageComplexity = 0;
31156 $packageElement->setAttribute('name', str_replace($report->pathAsString() . \DIRECTORY_SEPARATOR, '', $item->pathAsString()));
31157 $linesValid = $item->numberOfExecutableLines();
31158 $linesCovered = $item->numberOfExecutedLines();
31159 $lineRate = $linesValid === 0 ? 0 : $linesCovered / $linesValid;
31160 $packageElement->setAttribute('line-rate', (string) $lineRate);
31161 $branchesValid = $item->numberOfExecutableBranches();
31162 $branchesCovered = $item->numberOfExecutedBranches();
31163 $branchRate = $branchesValid === 0 ? 0 : $branchesCovered / $branchesValid;
31164 $packageElement->setAttribute('branch-rate', (string) $branchRate);
31165 $packageElement->setAttribute('complexity', '');
31166 $packagesElement->appendChild($packageElement);
31167 $classesElement = $document->createElement('classes');
31168 $packageElement->appendChild($classesElement);
31169 $classes = $item->classesAndTraits();
31170 $coverageData = $item->lineCoverageData();
31171 foreach ($classes as $className => $class) {
31172 $complexity += $class['ccn'];
31173 $packageComplexity += $class['ccn'];
31174 if (!empty($class['package']['namespace'])) {
31175 $className = $class['package']['namespace'] . '\\' . $className;
31176 }
31177 $linesValid = $class['executableLines'];
31178 $linesCovered = $class['executedLines'];
31179 $lineRate = $linesValid === 0 ? 0 : $linesCovered / $linesValid;
31180 $branchesValid = $class['executableBranches'];
31181 $branchesCovered = $class['executedBranches'];
31182 $branchRate = $branchesValid === 0 ? 0 : $branchesCovered / $branchesValid;
31183 $classElement = $document->createElement('class');
31184 $classElement->setAttribute('name', $className);
31185 $classElement->setAttribute('filename', str_replace($report->pathAsString() . \DIRECTORY_SEPARATOR, '', $item->pathAsString()));
31186 $classElement->setAttribute('line-rate', (string) $lineRate);
31187 $classElement->setAttribute('branch-rate', (string) $branchRate);
31188 $classElement->setAttribute('complexity', (string) $class['ccn']);
31189 $classesElement->appendChild($classElement);
31190 $methodsElement = $document->createElement('methods');
31191 $classElement->appendChild($methodsElement);
31192 $classLinesElement = $document->createElement('lines');
31193 $classElement->appendChild($classLinesElement);
31194 foreach ($class['methods'] as $methodName => $method) {
31195 if ($method['executableLines'] === 0) {
31196 continue;
31197 }
31198 preg_match("/\\((.*?)\\)/", $method['signature'], $signature);
31199 $linesValid = $method['executableLines'];
31200 $linesCovered = $method['executedLines'];
31201 $lineRate = $linesValid === 0 ? 0 : $linesCovered / $linesValid;
31202 $branchesValid = $method['executableBranches'];
31203 $branchesCovered = $method['executedBranches'];
31204 $branchRate = $branchesValid === 0 ? 0 : $branchesCovered / $branchesValid;
31205 $methodElement = $document->createElement('method');
31206 $methodElement->setAttribute('name', $methodName);
31207 $methodElement->setAttribute('signature', $signature[1]);
31208 $methodElement->setAttribute('line-rate', (string) $lineRate);
31209 $methodElement->setAttribute('branch-rate', (string) $branchRate);
31210 $methodElement->setAttribute('complexity', (string) $method['ccn']);
31211 $methodLinesElement = $document->createElement('lines');
31212 $methodElement->appendChild($methodLinesElement);
31213 foreach (range($method['startLine'], $method['endLine']) as $line) {
31214 if (!isset($coverageData[$line])) {
31215 continue;
31216 }
31217 $methodLineElement = $document->createElement('line');
31218 $methodLineElement->setAttribute('number', (string) $line);
31219 $methodLineElement->setAttribute('hits', (string) count($coverageData[$line]));
31220 $methodLinesElement->appendChild($methodLineElement);
31221 $classLineElement = $methodLineElement->cloneNode();
31222 $classLinesElement->appendChild($classLineElement);
31223 }
31224 $methodsElement->appendChild($methodElement);
31225 }
31226 }
31227 if ($item->numberOfFunctions() === 0) {
31228 $packageElement->setAttribute('complexity', (string) $packageComplexity);
31229 continue;
31230 }
31231 $functionsComplexity = 0;
31232 $functionsLinesValid = 0;
31233 $functionsLinesCovered = 0;
31234 $functionsBranchesValid = 0;
31235 $functionsBranchesCovered = 0;
31236 $classElement = $document->createElement('class');
31237 $classElement->setAttribute('name', basename($item->pathAsString()));
31238 $classElement->setAttribute('filename', str_replace($report->pathAsString() . \DIRECTORY_SEPARATOR, '', $item->pathAsString()));
31239 $methodsElement = $document->createElement('methods');
31240 $classElement->appendChild($methodsElement);
31241 $classLinesElement = $document->createElement('lines');
31242 $classElement->appendChild($classLinesElement);
31243 $functions = $item->functions();
31244 foreach ($functions as $functionName => $function) {
31245 if ($function['executableLines'] === 0) {
31246 continue;
31247 }
31248 $complexity += $function['ccn'];
31249 $packageComplexity += $function['ccn'];
31250 $functionsComplexity += $function['ccn'];
31251 $linesValid = $function['executableLines'];
31252 $linesCovered = $function['executedLines'];
31253 $lineRate = $linesValid === 0 ? 0 : $linesCovered / $linesValid;
31254 $functionsLinesValid += $linesValid;
31255 $functionsLinesCovered += $linesCovered;
31256 $branchesValid = $function['executableBranches'];
31257 $branchesCovered = $function['executedBranches'];
31258 $branchRate = $branchesValid === 0 ? 0 : $branchesCovered / $branchesValid;
31259 $functionsBranchesValid += $branchesValid;
31260 $functionsBranchesCovered += $branchesValid;
31261 $methodElement = $document->createElement('method');
31262 $methodElement->setAttribute('name', $functionName);
31263 $methodElement->setAttribute('signature', $function['signature']);
31264 $methodElement->setAttribute('line-rate', (string) $lineRate);
31265 $methodElement->setAttribute('branch-rate', (string) $branchRate);
31266 $methodElement->setAttribute('complexity', (string) $function['ccn']);
31267 $methodLinesElement = $document->createElement('lines');
31268 $methodElement->appendChild($methodLinesElement);
31269 foreach (range($function['startLine'], $function['endLine']) as $line) {
31270 if (!isset($coverageData[$line])) {
31271 continue;
31272 }
31273 $methodLineElement = $document->createElement('line');
31274 $methodLineElement->setAttribute('number', (string) $line);
31275 $methodLineElement->setAttribute('hits', (string) count($coverageData[$line]));
31276 $methodLinesElement->appendChild($methodLineElement);
31277 $classLineElement = $methodLineElement->cloneNode();
31278 $classLinesElement->appendChild($classLineElement);
31279 }
31280 $methodsElement->appendChild($methodElement);
31281 }
31282 $packageElement->setAttribute('complexity', (string) $packageComplexity);
31283 if ($functionsLinesValid === 0) {
31284 continue;
31285 }
31286 $lineRate = $functionsLinesCovered / $functionsLinesValid;
31287 $branchRate = $functionsBranchesValid === 0 ? 0 : $functionsBranchesCovered / $functionsBranchesValid;
31288 $classElement->setAttribute('line-rate', (string) $lineRate);
31289 $classElement->setAttribute('branch-rate', (string) $branchRate);
31290 $classElement->setAttribute('complexity', (string) $functionsComplexity);
31291 $classesElement->appendChild($classElement);
31292 }
31293 $coverageElement->setAttribute('complexity', (string) $complexity);
31294 $buffer = $document->saveXML();
31295 if ($target !== null) {
31296 if (!str_contains($target, '://')) {
31297 Filesystem::createDirectory(dirname($target));
31298 }
31299 if (@file_put_contents($target, $buffer) === \false) {
31300 throw new WriteOperationFailedException($target);
31301 }
31302 }
31303 return $buffer;
31304 }
31305 }
31306 <?php
31307
31308 declare (strict_types=1);
31309 /*
31310 * This file is part of phpunit/php-code-coverage.
31311 *
31312 * (c) Sebastian Bergmann <sebastian@phpunit.de>
31313 *
31314 * For the full copyright and license information, please view the LICENSE
31315 * file that was distributed with this source code.
31316 */
31317 namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\Report;
31318
31319 use function date;
31320 use function dirname;
31321 use function file_put_contents;
31322 use function htmlspecialchars;
31323 use function is_string;
31324 use function round;
31325 use function str_contains;
31326 use DOMDocument;
31327 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\CodeCoverage;
31328 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Driver\WriteOperationFailedException;
31329 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Node\File;
31330 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Util\Filesystem;
31331 final class Crap4j
31332 {
31333 private readonly int $threshold;
31334 public function __construct(int $threshold = 30)
31335 {
31336 $this->threshold = $threshold;
31337 }
31338 /**
31339 * @throws WriteOperationFailedException
31340 */
31341 public function process(CodeCoverage $coverage, ?string $target = null, ?string $name = null): string
31342 {
31343 $document = new DOMDocument('1.0', 'UTF-8');
31344 $document->formatOutput = \true;
31345 $root = $document->createElement('crap_result');
31346 $document->appendChild($root);
31347 $project = $document->createElement('project', is_string($name) ? $name : '');
31348 $root->appendChild($project);
31349 $root->appendChild($document->createElement('timestamp', date('Y-m-d H:i:s')));
31350 $stats = $document->createElement('stats');
31351 $methodsNode = $document->createElement('methods');
31352 $report = $coverage->getReport();
31353 unset($coverage);
31354 $fullMethodCount = 0;
31355 $fullCrapMethodCount = 0;
31356 $fullCrapLoad = 0;
31357 $fullCrap = 0;
31358 foreach ($report as $item) {
31359 $namespace = 'global';
31360 if (!$item instanceof File) {
31361 continue;
31362 }
31363 $file = $document->createElement('file');
31364 $file->setAttribute('name', $item->pathAsString());
31365 $classes = $item->classesAndTraits();
31366 foreach ($classes as $className => $class) {
31367 foreach ($class['methods'] as $methodName => $method) {
31368 $crapLoad = $this->crapLoad((float) $method['crap'], $method['ccn'], $method['coverage']);
31369 $fullCrap += $method['crap'];
31370 $fullCrapLoad += $crapLoad;
31371 $fullMethodCount++;
31372 if ($method['crap'] >= $this->threshold) {
31373 $fullCrapMethodCount++;
31374 }
31375 $methodNode = $document->createElement('method');
31376 if (!empty($class['namespace'])) {
31377 $namespace = $class['namespace'];
31378 }
31379 $methodNode->appendChild($document->createElement('package', $namespace));
31380 $methodNode->appendChild($document->createElement('className', $className));
31381 $methodNode->appendChild($document->createElement('methodName', $methodName));
31382 $methodNode->appendChild($document->createElement('methodSignature', htmlspecialchars($method['signature'])));
31383 $methodNode->appendChild($document->createElement('fullMethod', htmlspecialchars($method['signature'])));
31384 $methodNode->appendChild($document->createElement('crap', (string) $this->roundValue((float) $method['crap'])));
31385 $methodNode->appendChild($document->createElement('complexity', (string) $method['ccn']));
31386 $methodNode->appendChild($document->createElement('coverage', (string) $this->roundValue($method['coverage'])));
31387 $methodNode->appendChild($document->createElement('crapLoad', (string) round($crapLoad)));
31388 $methodsNode->appendChild($methodNode);
31389 }
31390 }
31391 }
31392 $stats->appendChild($document->createElement('name', 'Method Crap Stats'));
31393 $stats->appendChild($document->createElement('methodCount', (string) $fullMethodCount));
31394 $stats->appendChild($document->createElement('crapMethodCount', (string) $fullCrapMethodCount));
31395 $stats->appendChild($document->createElement('crapLoad', (string) round($fullCrapLoad)));
31396 $stats->appendChild($document->createElement('totalCrap', (string) $fullCrap));
31397 $crapMethodPercent = 0;
31398 if ($fullMethodCount > 0) {
31399 $crapMethodPercent = $this->roundValue(100 * $fullCrapMethodCount / $fullMethodCount);
31400 }
31401 $stats->appendChild($document->createElement('crapMethodPercent', (string) $crapMethodPercent));
31402 $root->appendChild($stats);
31403 $root->appendChild($methodsNode);
31404 $buffer = $document->saveXML();
31405 if ($target !== null) {
31406 if (!str_contains($target, '://')) {
31407 Filesystem::createDirectory(dirname($target));
31408 }
31409 if (@file_put_contents($target, $buffer) === \false) {
31410 throw new WriteOperationFailedException($target);
31411 }
31412 }
31413 return $buffer;
31414 }
31415 private function crapLoad(float $crapValue, int $cyclomaticComplexity, float $coveragePercent): float
31416 {
31417 $crapLoad = 0;
31418 if ($crapValue >= $this->threshold) {
31419 $crapLoad += $cyclomaticComplexity * (1.0 - $coveragePercent / 100);
31420 $crapLoad += $cyclomaticComplexity / $this->threshold;
31421 }
31422 return $crapLoad;
31423 }
31424 private function roundValue(float $value): float
31425 {
31426 return round($value, 2);
31427 }
31428 }
31429 <?php
31430
31431 declare (strict_types=1);
31432 /*
31433 * This file is part of phpunit/php-code-coverage.
31434 *
31435 * (c) Sebastian Bergmann <sebastian@phpunit.de>
31436 *
31437 * For the full copyright and license information, please view the LICENSE
31438 * file that was distributed with this source code.
31439 */
31440 namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\Report\Html;
31441
31442 /**
31443 * @psalm-immutable
31444 */
31445 final class Colors
31446 {
31447 private readonly string $successLow;
31448 private readonly string $successMedium;
31449 private readonly string $successHigh;
31450 private readonly string $warning;
31451 private readonly string $danger;
31452 public static function default(): self
31453 {
31454 return new self('#dff0d8', '#c3e3b5', '#99cb84', '#fcf8e3', '#f2dede');
31455 }
31456 public static function from(string $successLow, string $successMedium, string $successHigh, string $warning, string $danger): self
31457 {
31458 return new self($successLow, $successMedium, $successHigh, $warning, $danger);
31459 }
31460 private function __construct(string $successLow, string $successMedium, string $successHigh, string $warning, string $danger)
31461 {
31462 $this->successLow = $successLow;
31463 $this->successMedium = $successMedium;
31464 $this->successHigh = $successHigh;
31465 $this->warning = $warning;
31466 $this->danger = $danger;
31467 }
31468 public function successLow(): string
31469 {
31470 return $this->successLow;
31471 }
31472 public function successMedium(): string
31473 {
31474 return $this->successMedium;
31475 }
31476 public function successHigh(): string
31477 {
31478 return $this->successHigh;
31479 }
31480 public function warning(): string
31481 {
31482 return $this->warning;
31483 }
31484 public function danger(): string
31485 {
31486 return $this->danger;
31487 }
31488 }
31489 <?php
31490
31491 declare (strict_types=1);
31492 /*
31493 * This file is part of phpunit/php-code-coverage.
31494 *
31495 * (c) Sebastian Bergmann <sebastian@phpunit.de>
31496 *
31497 * For the full copyright and license information, please view the LICENSE
31498 * file that was distributed with this source code.
31499 */
31500 namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\Report\Html;
31501
31502 use function is_file;
31503 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\InvalidArgumentException;
31504 /**
31505 * @psalm-immutable
31506 */
31507 final class CustomCssFile
31508 {
31509 private readonly string $path;
31510 public static function default(): self
31511 {
31512 return new self(__DIR__ . '/Renderer/Template/css/custom.css');
31513 }
31514 /**
31515 * @throws InvalidArgumentException
31516 */
31517 public static function from(string $path): self
31518 {
31519 if (!is_file($path)) {
31520 throw new InvalidArgumentException('$path does not exist');
31521 }
31522 return new self($path);
31523 }
31524 private function __construct(string $path)
31525 {
31526 $this->path = $path;
31527 }
31528 public function path(): string
31529 {
31530 return $this->path;
31531 }
31532 }
31533 <?php
31534
31535 declare (strict_types=1);
31536 /*
31537 * This file is part of phpunit/php-code-coverage.
31538 *
31539 * (c) Sebastian Bergmann <sebastian@phpunit.de>
31540 *
31541 * For the full copyright and license information, please view the LICENSE
31542 * file that was distributed with this source code.
31543 */
31544 namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\Report\Html;
31545
31546 use const DIRECTORY_SEPARATOR;
31547 use function copy;
31548 use function date;
31549 use function dirname;
31550 use function str_ends_with;
31551 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\CodeCoverage;
31552 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\FileCouldNotBeWrittenException;
31553 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Node\Directory as DirectoryNode;
31554 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Report\Thresholds;
31555 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Util\Filesystem;
31556 use PHPUnitPHAR\SebastianBergmann\Template\Exception;
31557 use PHPUnitPHAR\SebastianBergmann\Template\Template;
31558 final class Facade
31559 {
31560 private readonly string $templatePath;
31561 private readonly string $generator;
31562 private readonly Colors $colors;
31563 private readonly Thresholds $thresholds;
31564 private readonly CustomCssFile $customCssFile;
31565 public function __construct(string $generator = '', ?Colors $colors = null, ?Thresholds $thresholds = null, ?CustomCssFile $customCssFile = null)
31566 {
31567 $this->generator = $generator;
31568 $this->colors = $colors ?? Colors::default();
31569 $this->thresholds = $thresholds ?? Thresholds::default();
31570 $this->customCssFile = $customCssFile ?? CustomCssFile::default();
31571 $this->templatePath = __DIR__ . '/Renderer/Template/';
31572 }
31573 public function process(CodeCoverage $coverage, string $target): void
31574 {
31575 $target = $this->directory($target);
31576 $report = $coverage->getReport();
31577 $date = date('D M j G:i:s T Y');
31578 $dashboard = new Dashboard($this->templatePath, $this->generator, $date, $this->thresholds, $coverage->collectsBranchAndPathCoverage());
31579 $directory = new Directory($this->templatePath, $this->generator, $date, $this->thresholds, $coverage->collectsBranchAndPathCoverage());
31580 $file = new File($this->templatePath, $this->generator, $date, $this->thresholds, $coverage->collectsBranchAndPathCoverage());
31581 $directory->render($report, $target . 'index.html');
31582 $dashboard->render($report, $target . 'dashboard.html');
31583 foreach ($report as $node) {
31584 $id = $node->id();
31585 if ($node instanceof DirectoryNode) {
31586 Filesystem::createDirectory($target . $id);
31587 $directory->render($node, $target . $id . '/index.html');
31588 $dashboard->render($node, $target . $id . '/dashboard.html');
31589 } else {
31590 $dir = dirname($target . $id);
31591 Filesystem::createDirectory($dir);
31592 $file->render($node, $target . $id);
31593 }
31594 }
31595 $this->copyFiles($target);
31596 $this->renderCss($target);
31597 }
31598 private function copyFiles(string $target): void
31599 {
31600 $dir = $this->directory($target . '_css');
31601 copy($this->templatePath . 'css/bootstrap.min.css', $dir . 'bootstrap.min.css');
31602 copy($this->templatePath . 'css/nv.d3.min.css', $dir . 'nv.d3.min.css');
31603 copy($this->customCssFile->path(), $dir . 'custom.css');
31604 copy($this->templatePath . 'css/octicons.css', $dir . 'octicons.css');
31605 $dir = $this->directory($target . '_icons');
31606 copy($this->templatePath . 'icons/file-code.svg', $dir . 'file-code.svg');
31607 copy($this->templatePath . 'icons/file-directory.svg', $dir . 'file-directory.svg');
31608 $dir = $this->directory($target . '_js');
31609 copy($this->templatePath . 'js/bootstrap.min.js', $dir . 'bootstrap.min.js');
31610 copy($this->templatePath . 'js/popper.min.js', $dir . 'popper.min.js');
31611 copy($this->templatePath . 'js/d3.min.js', $dir . 'd3.min.js');
31612 copy($this->templatePath . 'js/jquery.min.js', $dir . 'jquery.min.js');
31613 copy($this->templatePath . 'js/nv.d3.min.js', $dir . 'nv.d3.min.js');
31614 copy($this->templatePath . 'js/file.js', $dir . 'file.js');
31615 }
31616 private function renderCss(string $target): void
31617 {
31618 $template = new Template($this->templatePath . 'css/style.css', '{{', '}}');
31619 $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()]);
31620 try {
31621 $template->renderTo($this->directory($target . '_css') . 'style.css');
31622 } catch (Exception $e) {
31623 throw new FileCouldNotBeWrittenException($e->getMessage(), $e->getCode(), $e);
31624 }
31625 }
31626 private function directory(string $directory): string
31627 {
31628 if (!str_ends_with($directory, DIRECTORY_SEPARATOR)) {
31629 $directory .= DIRECTORY_SEPARATOR;
31630 }
31631 Filesystem::createDirectory($directory);
31632 return $directory;
31633 }
31634 }
31635 <?php
31636
31637 declare (strict_types=1);
31638 /*
31639 * This file is part of phpunit/php-code-coverage.
31640 *
31641 * (c) Sebastian Bergmann <sebastian@phpunit.de>
31642 *
31643 * For the full copyright and license information, please view the LICENSE
31644 * file that was distributed with this source code.
31645 */
31646 namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\Report\Html;
31647
31648 use function array_pop;
31649 use function count;
31650 use function sprintf;
31651 use function str_repeat;
31652 use function substr_count;
31653 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Node\AbstractNode;
31654 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Node\Directory as DirectoryNode;
31655 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Node\File as FileNode;
31656 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Report\Thresholds;
31657 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Version;
31658 use PHPUnitPHAR\SebastianBergmann\Environment\Runtime;
31659 use PHPUnitPHAR\SebastianBergmann\Template\Template;
31660 /**
31661 * @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
31662 */
31663 abstract class Renderer
31664 {
31665 protected string $templatePath;
31666 protected string $generator;
31667 protected string $date;
31668 protected Thresholds $thresholds;
31669 protected bool $hasBranchCoverage;
31670 protected string $version;
31671 public function __construct(string $templatePath, string $generator, string $date, Thresholds $thresholds, bool $hasBranchCoverage)
31672 {
31673 $this->templatePath = $templatePath;
31674 $this->generator = $generator;
31675 $this->date = $date;
31676 $this->thresholds = $thresholds;
31677 $this->version = Version::id();
31678 $this->hasBranchCoverage = $hasBranchCoverage;
31679 }
31680 protected function renderItemTemplate(Template $template, array $data): string
31681 {
31682 $numSeparator = '&nbsp;/&nbsp;';
31683 if (isset($data['numClasses']) && $data['numClasses'] > 0) {
31684 $classesLevel = $this->colorLevel($data['testedClassesPercent']);
31685 $classesNumber = $data['numTestedClasses'] . $numSeparator . $data['numClasses'];
31686 $classesBar = $this->coverageBar($data['testedClassesPercent']);
31687 } else {
31688 $classesLevel = '';
31689 $classesNumber = '0' . $numSeparator . '0';
31690 $classesBar = '';
31691 $data['testedClassesPercentAsString'] = 'n/a';
31692 }
31693 if ($data['numMethods'] > 0) {
31694 $methodsLevel = $this->colorLevel($data['testedMethodsPercent']);
31695 $methodsNumber = $data['numTestedMethods'] . $numSeparator . $data['numMethods'];
31696 $methodsBar = $this->coverageBar($data['testedMethodsPercent']);
31697 } else {
31698 $methodsLevel = '';
31699 $methodsNumber = '0' . $numSeparator . '0';
31700 $methodsBar = '';
31701 $data['testedMethodsPercentAsString'] = 'n/a';
31702 }
31703 if ($data['numExecutableLines'] > 0) {
31704 $linesLevel = $this->colorLevel($data['linesExecutedPercent']);
31705 $linesNumber = $data['numExecutedLines'] . $numSeparator . $data['numExecutableLines'];
31706 $linesBar = $this->coverageBar($data['linesExecutedPercent']);
31707 } else {
31708 $linesLevel = '';
31709 $linesNumber = '0' . $numSeparator . '0';
31710 $linesBar = '';
31711 $data['linesExecutedPercentAsString'] = 'n/a';
31712 }
31713 if ($data['numExecutablePaths'] > 0) {
31714 $pathsLevel = $this->colorLevel($data['pathsExecutedPercent']);
31715 $pathsNumber = $data['numExecutedPaths'] . $numSeparator . $data['numExecutablePaths'];
31716 $pathsBar = $this->coverageBar($data['pathsExecutedPercent']);
31717 } else {
31718 $pathsLevel = '';
31719 $pathsNumber = '0' . $numSeparator . '0';
31720 $pathsBar = '';
31721 $data['pathsExecutedPercentAsString'] = 'n/a';
31722 }
31723 if ($data['numExecutableBranches'] > 0) {
31724 $branchesLevel = $this->colorLevel($data['branchesExecutedPercent']);
31725 $branchesNumber = $data['numExecutedBranches'] . $numSeparator . $data['numExecutableBranches'];
31726 $branchesBar = $this->coverageBar($data['branchesExecutedPercent']);
31727 } else {
31728 $branchesLevel = '';
31729 $branchesNumber = '0' . $numSeparator . '0';
31730 $branchesBar = '';
31731 $data['branchesExecutedPercentAsString'] = 'n/a';
31732 }
31733 $template->setVar(['icon' => $data['icon'] ?? '', 'crap' => $data['crap'] ?? '', 'name' => $data['name'], 'lines_bar' => $linesBar, 'lines_executed_percent' => $data['linesExecutedPercentAsString'], 'lines_level' => $linesLevel, 'lines_number' => $linesNumber, 'paths_bar' => $pathsBar, 'paths_executed_percent' => $data['pathsExecutedPercentAsString'], 'paths_level' => $pathsLevel, 'paths_number' => $pathsNumber, 'branches_bar' => $branchesBar, 'branches_executed_percent' => $data['branchesExecutedPercentAsString'], 'branches_level' => $branchesLevel, 'branches_number' => $branchesNumber, 'methods_bar' => $methodsBar, 'methods_tested_percent' => $data['testedMethodsPercentAsString'], 'methods_level' => $methodsLevel, 'methods_number' => $methodsNumber, 'classes_bar' => $classesBar, 'classes_tested_percent' => $data['testedClassesPercentAsString'] ?? '', 'classes_level' => $classesLevel, 'classes_number' => $classesNumber]);
31734 return $template->render();
31735 }
31736 protected function setCommonTemplateVariables(Template $template, AbstractNode $node): void
31737 {
31738 $template->setVar(['id' => $node->id(), 'full_path' => $node->pathAsString(), 'path_to_root' => $this->pathToRoot($node), 'breadcrumbs' => $this->breadcrumbs($node), 'date' => $this->date, 'version' => $this->version, 'runtime' => $this->runtimeString(), 'generator' => $this->generator, 'low_upper_bound' => $this->thresholds->lowUpperBound(), 'high_lower_bound' => $this->thresholds->highLowerBound()]);
31739 }
31740 protected function breadcrumbs(AbstractNode $node): string
31741 {
31742 $breadcrumbs = '';
31743 $path = $node->pathAsArray();
31744 $pathToRoot = [];
31745 $max = count($path);
31746 if ($node instanceof FileNode) {
31747 $max--;
31748 }
31749 for ($i = 0; $i < $max; $i++) {
31750 $pathToRoot[] = str_repeat('../', $i);
31751 }
31752 foreach ($path as $step) {
31753 if ($step !== $node) {
31754 $breadcrumbs .= $this->inactiveBreadcrumb($step, array_pop($pathToRoot));
31755 } else {
31756 $breadcrumbs .= $this->activeBreadcrumb($step);
31757 }
31758 }
31759 return $breadcrumbs;
31760 }
31761 protected function activeBreadcrumb(AbstractNode $node): string
31762 {
31763 $buffer = sprintf(' <li class="breadcrumb-item active">%s</li>' . "\n", $node->name());
31764 if ($node instanceof DirectoryNode) {
31765 $buffer .= ' <li class="breadcrumb-item">(<a href="dashboard.html">Dashboard</a>)</li>' . "\n";
31766 }
31767 return $buffer;
31768 }
31769 protected function inactiveBreadcrumb(AbstractNode $node, string $pathToRoot): string
31770 {
31771 return sprintf(' <li class="breadcrumb-item"><a href="%sindex.html">%s</a></li>' . "\n", $pathToRoot, $node->name());
31772 }
31773 protected function pathToRoot(AbstractNode $node): string
31774 {
31775 $id = $node->id();
31776 $depth = substr_count($id, '/');
31777 if ($id !== 'index' && $node instanceof DirectoryNode) {
31778 $depth++;
31779 }
31780 return str_repeat('../', $depth);
31781 }
31782 protected function coverageBar(float $percent): string
31783 {
31784 $level = $this->colorLevel($percent);
31785 $templateName = $this->templatePath . ($this->hasBranchCoverage ? 'coverage_bar_branch.html' : 'coverage_bar.html');
31786 $template = new Template($templateName, '{{', '}}');
31787 $template->setVar(['level' => $level, 'percent' => sprintf('%.2F', $percent)]);
31788 return $template->render();
31789 }
31790 protected function colorLevel(float $percent): string
31791 {
31792 if ($percent <= $this->thresholds->lowUpperBound()) {
31793 return 'danger';
31794 }
31795 if ($percent > $this->thresholds->lowUpperBound() && $percent < $this->thresholds->highLowerBound()) {
31796 return 'warning';
31797 }
31798 return 'success';
31799 }
31800 private function runtimeString(): string
31801 {
31802 $runtime = new Runtime();
31803 return sprintf('<a href="%s" target="_top">%s %s</a>', $runtime->getVendorUrl(), $runtime->getName(), $runtime->getVersion());
31804 }
31805 }
31806 <?php
31807
31808 declare (strict_types=1);
31809 /*
31810 * This file is part of phpunit/php-code-coverage.
31811 *
31812 * (c) Sebastian Bergmann <sebastian@phpunit.de>
31813 *
31814 * For the full copyright and license information, please view the LICENSE
31815 * file that was distributed with this source code.
31816 */
31817 namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\Report\Html;
31818
31819 use function array_values;
31820 use function arsort;
31821 use function asort;
31822 use function count;
31823 use function explode;
31824 use function floor;
31825 use function json_encode;
31826 use function sprintf;
31827 use function str_replace;
31828 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\FileCouldNotBeWrittenException;
31829 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Node\AbstractNode;
31830 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Node\Directory as DirectoryNode;
31831 use PHPUnitPHAR\SebastianBergmann\Template\Exception;
31832 use PHPUnitPHAR\SebastianBergmann\Template\Template;
31833 /**
31834 * @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
31835 */
31836 final class Dashboard extends Renderer
31837 {
31838 public function render(DirectoryNode $node, string $file): void
31839 {
31840 $classes = $node->classesAndTraits();
31841 $templateName = $this->templatePath . ($this->hasBranchCoverage ? 'dashboard_branch.html' : 'dashboard.html');
31842 $template = new Template($templateName, '{{', '}}');
31843 $this->setCommonTemplateVariables($template, $node);
31844 $baseLink = $node->id() . '/';
31845 $complexity = $this->complexity($classes, $baseLink);
31846 $coverageDistribution = $this->coverageDistribution($classes);
31847 $insufficientCoverage = $this->insufficientCoverage($classes, $baseLink);
31848 $projectRisks = $this->projectRisks($classes, $baseLink);
31849 $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']]);
31850 try {
31851 $template->renderTo($file);
31852 } catch (Exception $e) {
31853 throw new FileCouldNotBeWrittenException($e->getMessage(), $e->getCode(), $e);
31854 }
31855 }
31856 protected function activeBreadcrumb(AbstractNode $node): string
31857 {
31858 return sprintf(' <li class="breadcrumb-item"><a href="index.html">%s</a></li>' . "\n" . ' <li class="breadcrumb-item active">(Dashboard)</li>' . "\n", $node->name());
31859 }
31860 /**
31861 * Returns the data for the Class/Method Complexity charts.
31862 */
31863 private function complexity(array $classes, string $baseLink): array
31864 {
31865 $result = ['class' => [], 'method' => []];
31866 foreach ($classes as $className => $class) {
31867 foreach ($class['methods'] as $methodName => $method) {
31868 if ($className !== '*') {
31869 $methodName = $className . '::' . $methodName;
31870 }
31871 $result['method'][] = [$method['coverage'], $method['ccn'], sprintf('<a href="%s">%s</a>', str_replace($baseLink, '', $method['link']), $methodName)];
31872 }
31873 $result['class'][] = [$class['coverage'], $class['ccn'], sprintf('<a href="%s">%s</a>', str_replace($baseLink, '', $class['link']), $className)];
31874 }
31875 return ['class' => json_encode($result['class']), 'method' => json_encode($result['method'])];
31876 }
31877 /**
31878 * Returns the data for the Class / Method Coverage Distribution chart.
31879 */
31880 private function coverageDistribution(array $classes): array
31881 {
31882 $result = ['class' => ['0%' => 0, '0-10%' => 0, '10-20%' => 0, '20-30%' => 0, '30-40%' => 0, '40-50%' => 0, '50-60%' => 0, '60-70%' => 0, '70-80%' => 0, '80-90%' => 0, '90-100%' => 0, '100%' => 0], 'method' => ['0%' => 0, '0-10%' => 0, '10-20%' => 0, '20-30%' => 0, '30-40%' => 0, '40-50%' => 0, '50-60%' => 0, '60-70%' => 0, '70-80%' => 0, '80-90%' => 0, '90-100%' => 0, '100%' => 0]];
31883 foreach ($classes as $class) {
31884 foreach ($class['methods'] as $methodName => $method) {
31885 if ($method['coverage'] === 0) {
31886 $result['method']['0%']++;
31887 } elseif ($method['coverage'] === 100) {
31888 $result['method']['100%']++;
31889 } else {
31890 $key = floor($method['coverage'] / 10) * 10;
31891 $key = $key . '-' . ($key + 10) . '%';
31892 $result['method'][$key]++;
31893 }
31894 }
31895 if ($class['coverage'] === 0) {
31896 $result['class']['0%']++;
31897 } elseif ($class['coverage'] === 100) {
31898 $result['class']['100%']++;
31899 } else {
31900 $key = floor($class['coverage'] / 10) * 10;
31901 $key = $key . '-' . ($key + 10) . '%';
31902 $result['class'][$key]++;
31903 }
31904 }
31905 return ['class' => json_encode(array_values($result['class'])), 'method' => json_encode(array_values($result['method']))];
31906 }
31907 /**
31908 * Returns the classes / methods with insufficient coverage.
31909 */
31910 private function insufficientCoverage(array $classes, string $baseLink): array
31911 {
31912 $leastTestedClasses = [];
31913 $leastTestedMethods = [];
31914 $result = ['class' => '', 'method' => ''];
31915 foreach ($classes as $className => $class) {
31916 foreach ($class['methods'] as $methodName => $method) {
31917 if ($method['coverage'] < $this->thresholds->highLowerBound()) {
31918 $key = $methodName;
31919 if ($className !== '*') {
31920 $key = $className . '::' . $methodName;
31921 }
31922 $leastTestedMethods[$key] = $method['coverage'];
31923 }
31924 }
31925 if ($class['coverage'] < $this->thresholds->highLowerBound()) {
31926 $leastTestedClasses[$className] = $class['coverage'];
31927 }
31928 }
31929 asort($leastTestedClasses);
31930 asort($leastTestedMethods);
31931 foreach ($leastTestedClasses as $className => $coverage) {
31932 $result['class'] .= sprintf(' <tr><td><a href="%s">%s</a></td><td class="text-right">%d%%</td></tr>' . "\n", str_replace($baseLink, '', $classes[$className]['link']), $className, $coverage);
31933 }
31934 foreach ($leastTestedMethods as $methodName => $coverage) {
31935 [$class, $method] = explode('::', $methodName);
31936 $result['method'] .= sprintf(' <tr><td><a href="%s"><abbr title="%s">%s</abbr></a></td><td class="text-right">%d%%</td></tr>' . "\n", str_replace($baseLink, '', $classes[$class]['methods'][$method]['link']), $methodName, $method, $coverage);
31937 }
31938 return $result;
31939 }
31940 /**
31941 * Returns the project risks according to the CRAP index.
31942 */
31943 private function projectRisks(array $classes, string $baseLink): array
31944 {
31945 $classRisks = [];
31946 $methodRisks = [];
31947 $result = ['class' => '', 'method' => ''];
31948 foreach ($classes as $className => $class) {
31949 foreach ($class['methods'] as $methodName => $method) {
31950 if ($method['coverage'] < $this->thresholds->highLowerBound() && $method['ccn'] > 1) {
31951 $key = $methodName;
31952 if ($className !== '*') {
31953 $key = $className . '::' . $methodName;
31954 }
31955 $methodRisks[$key] = $method['crap'];
31956 }
31957 }
31958 if ($class['coverage'] < $this->thresholds->highLowerBound() && $class['ccn'] > count($class['methods'])) {
31959 $classRisks[$className] = $class['crap'];
31960 }
31961 }
31962 arsort($classRisks);
31963 arsort($methodRisks);
31964 foreach ($classRisks as $className => $crap) {
31965 $result['class'] .= sprintf(' <tr><td><a href="%s">%s</a></td><td class="text-right">%d</td></tr>' . "\n", str_replace($baseLink, '', $classes[$className]['link']), $className, $crap);
31966 }
31967 foreach ($methodRisks as $methodName => $crap) {
31968 [$class, $method] = explode('::', $methodName);
31969 $result['method'] .= sprintf(' <tr><td><a href="%s"><abbr title="%s">%s</abbr></a></td><td class="text-right">%d</td></tr>' . "\n", str_replace($baseLink, '', $classes[$class]['methods'][$method]['link']), $methodName, $method, $crap);
31970 }
31971 return $result;
31972 }
31973 }
31974 <?php
31975
31976 declare (strict_types=1);
31977 /*
31978 * This file is part of phpunit/php-code-coverage.
31979 *
31980 * (c) Sebastian Bergmann <sebastian@phpunit.de>
31981 *
31982 * For the full copyright and license information, please view the LICENSE
31983 * file that was distributed with this source code.
31984 */
31985 namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\Report\Html;
31986
31987 use function count;
31988 use function sprintf;
31989 use function str_repeat;
31990 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\FileCouldNotBeWrittenException;
31991 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Node\AbstractNode as Node;
31992 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Node\Directory as DirectoryNode;
31993 use PHPUnitPHAR\SebastianBergmann\Template\Exception;
31994 use PHPUnitPHAR\SebastianBergmann\Template\Template;
31995 /**
31996 * @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
31997 */
31998 final class Directory extends Renderer
31999 {
32000 public function render(DirectoryNode $node, string $file): void
32001 {
32002 $templateName = $this->templatePath . ($this->hasBranchCoverage ? 'directory_branch.html' : 'directory.html');
32003 $template = new Template($templateName, '{{', '}}');
32004 $this->setCommonTemplateVariables($template, $node);
32005 $items = $this->renderItem($node, \true);
32006 foreach ($node->directories() as $item) {
32007 $items .= $this->renderItem($item);
32008 }
32009 foreach ($node->files() as $item) {
32010 $items .= $this->renderItem($item);
32011 }
32012 $template->setVar(['id' => $node->id(), 'items' => $items]);
32013 try {
32014 $template->renderTo($file);
32015 } catch (Exception $e) {
32016 throw new FileCouldNotBeWrittenException($e->getMessage(), $e->getCode(), $e);
32017 }
32018 }
32019 private function renderItem(Node $node, bool $total = \false): string
32020 {
32021 $data = ['numClasses' => $node->numberOfClassesAndTraits(), 'numTestedClasses' => $node->numberOfTestedClassesAndTraits(), 'numMethods' => $node->numberOfFunctionsAndMethods(), 'numTestedMethods' => $node->numberOfTestedFunctionsAndMethods(), 'linesExecutedPercent' => $node->percentageOfExecutedLines()->asFloat(), 'linesExecutedPercentAsString' => $node->percentageOfExecutedLines()->asString(), 'numExecutedLines' => $node->numberOfExecutedLines(), 'numExecutableLines' => $node->numberOfExecutableLines(), 'branchesExecutedPercent' => $node->percentageOfExecutedBranches()->asFloat(), 'branchesExecutedPercentAsString' => $node->percentageOfExecutedBranches()->asString(), 'numExecutedBranches' => $node->numberOfExecutedBranches(), 'numExecutableBranches' => $node->numberOfExecutableBranches(), 'pathsExecutedPercent' => $node->percentageOfExecutedPaths()->asFloat(), 'pathsExecutedPercentAsString' => $node->percentageOfExecutedPaths()->asString(), 'numExecutedPaths' => $node->numberOfExecutedPaths(), 'numExecutablePaths' => $node->numberOfExecutablePaths(), 'testedMethodsPercent' => $node->percentageOfTestedFunctionsAndMethods()->asFloat(), 'testedMethodsPercentAsString' => $node->percentageOfTestedFunctionsAndMethods()->asString(), 'testedClassesPercent' => $node->percentageOfTestedClassesAndTraits()->asFloat(), 'testedClassesPercentAsString' => $node->percentageOfTestedClassesAndTraits()->asString()];
32022 if ($total) {
32023 $data['name'] = 'Total';
32024 } else {
32025 $up = str_repeat('../', count($node->pathAsArray()) - 2);
32026 $data['icon'] = sprintf('<img src="%s_icons/file-code.svg" class="octicon" />', $up);
32027 if ($node instanceof DirectoryNode) {
32028 $data['name'] = sprintf('<a href="%s/index.html">%s</a>', $node->name(), $node->name());
32029 $data['icon'] = sprintf('<img src="%s_icons/file-directory.svg" class="octicon" />', $up);
32030 } elseif ($this->hasBranchCoverage) {
32031 $data['name'] = sprintf('%s <a class="small" href="%s.html">[line]</a> <a class="small" href="%s_branch.html">[branch]</a> <a class="small" href="%s_path.html">[path]</a>', $node->name(), $node->name(), $node->name(), $node->name());
32032 } else {
32033 $data['name'] = sprintf('<a href="%s.html">%s</a>', $node->name(), $node->name());
32034 }
32035 }
32036 $templateName = $this->templatePath . ($this->hasBranchCoverage ? 'directory_item_branch.html' : 'directory_item.html');
32037 return $this->renderItemTemplate(new Template($templateName, '{{', '}}'), $data);
32038 }
32039 }
32040 <?php
32041
32042 declare (strict_types=1);
32043 /*
32044 * This file is part of phpunit/php-code-coverage.
32045 *
32046 * (c) Sebastian Bergmann <sebastian@phpunit.de>
32047 *
32048 * For the full copyright and license information, please view the LICENSE
32049 * file that was distributed with this source code.
32050 */
32051 namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\Report\Html;
32052
32053 use const ENT_COMPAT;
32054 use const ENT_HTML401;
32055 use const ENT_SUBSTITUTE;
32056 use const T_ABSTRACT;
32057 use const T_ARRAY;
32058 use const T_AS;
32059 use const T_BREAK;
32060 use const T_CALLABLE;
32061 use const T_CASE;
32062 use const T_CATCH;
32063 use const T_CLASS;
32064 use const T_CLONE;
32065 use const T_COMMENT;
32066 use const T_CONST;
32067 use const T_CONTINUE;
32068 use const T_DECLARE;
32069 use const T_DEFAULT;
32070 use const T_DO;
32071 use const T_DOC_COMMENT;
32072 use const T_ECHO;
32073 use const T_ELSE;
32074 use const T_ELSEIF;
32075 use const T_EMPTY;
32076 use const T_ENDDECLARE;
32077 use const T_ENDFOR;
32078 use const T_ENDFOREACH;
32079 use const T_ENDIF;
32080 use const T_ENDSWITCH;
32081 use const T_ENDWHILE;
32082 use const T_EVAL;
32083 use const T_EXIT;
32084 use const T_EXTENDS;
32085 use const T_FINAL;
32086 use const T_FINALLY;
32087 use const T_FOR;
32088 use const T_FOREACH;
32089 use const T_FUNCTION;
32090 use const T_GLOBAL;
32091 use const T_GOTO;
32092 use const T_HALT_COMPILER;
32093 use const T_IF;
32094 use const T_IMPLEMENTS;
32095 use const T_INCLUDE;
32096 use const T_INCLUDE_ONCE;
32097 use const T_INLINE_HTML;
32098 use const T_INSTANCEOF;
32099 use const T_INSTEADOF;
32100 use const T_INTERFACE;
32101 use const T_ISSET;
32102 use const T_LIST;
32103 use const T_NAMESPACE;
32104 use const T_NEW;
32105 use const T_PRINT;
32106 use const T_PRIVATE;
32107 use const T_PROTECTED;
32108 use const T_PUBLIC;
32109 use const T_REQUIRE;
32110 use const T_REQUIRE_ONCE;
32111 use const T_RETURN;
32112 use const T_STATIC;
32113 use const T_SWITCH;
32114 use const T_THROW;
32115 use const T_TRAIT;
32116 use const T_TRY;
32117 use const T_UNSET;
32118 use const T_USE;
32119 use const T_VAR;
32120 use const T_WHILE;
32121 use const T_YIELD;
32122 use const T_YIELD_FROM;
32123 use function array_key_exists;
32124 use function array_keys;
32125 use function array_merge;
32126 use function array_pop;
32127 use function array_unique;
32128 use function count;
32129 use function explode;
32130 use function file_get_contents;
32131 use function htmlspecialchars;
32132 use function is_string;
32133 use function ksort;
32134 use function range;
32135 use function sort;
32136 use function sprintf;
32137 use function str_ends_with;
32138 use function str_replace;
32139 use function token_get_all;
32140 use function trim;
32141 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\FileCouldNotBeWrittenException;
32142 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Node\File as FileNode;
32143 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Util\Percentage;
32144 use PHPUnitPHAR\SebastianBergmann\Template\Exception;
32145 use PHPUnitPHAR\SebastianBergmann\Template\Template;
32146 /**
32147 * @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
32148 */
32149 final class File extends Renderer
32150 {
32151 /**
32152 * @psalm-var array<int,true>
32153 */
32154 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];
32155 private static array $formattedSourceCache = [];
32156 private int $htmlSpecialCharsFlags = ENT_COMPAT | ENT_HTML401 | ENT_SUBSTITUTE;
32157 public function render(FileNode $node, string $file): void
32158 {
32159 $templateName = $this->templatePath . ($this->hasBranchCoverage ? 'file_branch.html' : 'file.html');
32160 $template = new Template($templateName, '{{', '}}');
32161 $this->setCommonTemplateVariables($template, $node);
32162 $template->setVar(['items' => $this->renderItems($node), 'lines' => $this->renderSourceWithLineCoverage($node), 'legend' => '<p><span class="legend covered-by-small-tests">Covered by small (and larger) tests</span><span class="legend covered-by-medium-tests">Covered by medium (and large) tests</span><span class="legend covered-by-large-tests">Covered by large tests (and tests of unknown size)</span><span class="legend not-covered">Not covered</span><span class="legend not-coverable">Not coverable</span></p>', 'structure' => '']);
32163 try {
32164 $template->renderTo($file . '.html');
32165 } catch (Exception $e) {
32166 throw new FileCouldNotBeWrittenException($e->getMessage(), $e->getCode(), $e);
32167 }
32168 if ($this->hasBranchCoverage) {
32169 $template->setVar(['items' => $this->renderItems($node), 'lines' => $this->renderSourceWithBranchCoverage($node), 'legend' => '<p><span class="success"><strong>Fully covered</strong></span><span class="warning"><strong>Partially covered</strong></span><span class="danger"><strong>Not covered</strong></span></p>', 'structure' => $this->renderBranchStructure($node)]);
32170 try {
32171 $template->renderTo($file . '_branch.html');
32172 } catch (Exception $e) {
32173 throw new FileCouldNotBeWrittenException($e->getMessage(), $e->getCode(), $e);
32174 }
32175 $template->setVar(['items' => $this->renderItems($node), 'lines' => $this->renderSourceWithPathCoverage($node), 'legend' => '<p><span class="success"><strong>Fully covered</strong></span><span class="warning"><strong>Partially covered</strong></span><span class="danger"><strong>Not covered</strong></span></p>', 'structure' => $this->renderPathStructure($node)]);
32176 try {
32177 $template->renderTo($file . '_path.html');
32178 } catch (Exception $e) {
32179 throw new FileCouldNotBeWrittenException($e->getMessage(), $e->getCode(), $e);
32180 }
32181 }
32182 }
32183 private function renderItems(FileNode $node): string
32184 {
32185 $templateName = $this->templatePath . ($this->hasBranchCoverage ? 'file_item_branch.html' : 'file_item.html');
32186 $template = new Template($templateName, '{{', '}}');
32187 $methodTemplateName = $this->templatePath . ($this->hasBranchCoverage ? 'method_item_branch.html' : 'method_item.html');
32188 $methodItemTemplate = new Template($methodTemplateName, '{{', '}}');
32189 $items = $this->renderItemTemplate($template, ['name' => 'Total', 'numClasses' => $node->numberOfClassesAndTraits(), 'numTestedClasses' => $node->numberOfTestedClassesAndTraits(), 'numMethods' => $node->numberOfFunctionsAndMethods(), 'numTestedMethods' => $node->numberOfTestedFunctionsAndMethods(), 'linesExecutedPercent' => $node->percentageOfExecutedLines()->asFloat(), 'linesExecutedPercentAsString' => $node->percentageOfExecutedLines()->asString(), 'numExecutedLines' => $node->numberOfExecutedLines(), 'numExecutableLines' => $node->numberOfExecutableLines(), 'branchesExecutedPercent' => $node->percentageOfExecutedBranches()->asFloat(), 'branchesExecutedPercentAsString' => $node->percentageOfExecutedBranches()->asString(), 'numExecutedBranches' => $node->numberOfExecutedBranches(), 'numExecutableBranches' => $node->numberOfExecutableBranches(), 'pathsExecutedPercent' => $node->percentageOfExecutedPaths()->asFloat(), 'pathsExecutedPercentAsString' => $node->percentageOfExecutedPaths()->asString(), 'numExecutedPaths' => $node->numberOfExecutedPaths(), 'numExecutablePaths' => $node->numberOfExecutablePaths(), 'testedMethodsPercent' => $node->percentageOfTestedFunctionsAndMethods()->asFloat(), 'testedMethodsPercentAsString' => $node->percentageOfTestedFunctionsAndMethods()->asString(), 'testedClassesPercent' => $node->percentageOfTestedClassesAndTraits()->asFloat(), 'testedClassesPercentAsString' => $node->percentageOfTestedClassesAndTraits()->asString(), 'crap' => '<abbr title="Change Risk Anti-Patterns (CRAP) Index">CRAP</abbr>']);
32190 $items .= $this->renderFunctionItems($node->functions(), $methodItemTemplate);
32191 $items .= $this->renderTraitOrClassItems($node->traits(), $template, $methodItemTemplate);
32192 $items .= $this->renderTraitOrClassItems($node->classes(), $template, $methodItemTemplate);
32193 return $items;
32194 }
32195 private function renderTraitOrClassItems(array $items, Template $template, Template $methodItemTemplate): string
32196 {
32197 $buffer = '';
32198 if (empty($items)) {
32199 return $buffer;
32200 }
32201 foreach ($items as $name => $item) {
32202 $numMethods = 0;
32203 $numTestedMethods = 0;
32204 foreach ($item['methods'] as $method) {
32205 if ($method['executableLines'] > 0) {
32206 $numMethods++;
32207 if ($method['executedLines'] === $method['executableLines']) {
32208 $numTestedMethods++;
32209 }
32210 }
32211 }
32212 if ($item['executableLines'] > 0) {
32213 $numClasses = 1;
32214 $numTestedClasses = $numTestedMethods === $numMethods ? 1 : 0;
32215 $linesExecutedPercentAsString = Percentage::fromFractionAndTotal($item['executedLines'], $item['executableLines'])->asString();
32216 $branchesExecutedPercentAsString = Percentage::fromFractionAndTotal($item['executedBranches'], $item['executableBranches'])->asString();
32217 $pathsExecutedPercentAsString = Percentage::fromFractionAndTotal($item['executedPaths'], $item['executablePaths'])->asString();
32218 } else {
32219 $numClasses = 0;
32220 $numTestedClasses = 0;
32221 $linesExecutedPercentAsString = 'n/a';
32222 $branchesExecutedPercentAsString = 'n/a';
32223 $pathsExecutedPercentAsString = 'n/a';
32224 }
32225 $testedMethodsPercentage = Percentage::fromFractionAndTotal($numTestedMethods, $numMethods);
32226 $testedClassesPercentage = Percentage::fromFractionAndTotal($numTestedMethods === $numMethods ? 1 : 0, 1);
32227 $buffer .= $this->renderItemTemplate($template, ['name' => $this->abbreviateClassName($name), 'numClasses' => $numClasses, 'numTestedClasses' => $numTestedClasses, 'numMethods' => $numMethods, 'numTestedMethods' => $numTestedMethods, 'linesExecutedPercent' => Percentage::fromFractionAndTotal($item['executedLines'], $item['executableLines'])->asFloat(), 'linesExecutedPercentAsString' => $linesExecutedPercentAsString, 'numExecutedLines' => $item['executedLines'], 'numExecutableLines' => $item['executableLines'], 'branchesExecutedPercent' => Percentage::fromFractionAndTotal($item['executedBranches'], $item['executableBranches'])->asFloat(), 'branchesExecutedPercentAsString' => $branchesExecutedPercentAsString, 'numExecutedBranches' => $item['executedBranches'], 'numExecutableBranches' => $item['executableBranches'], 'pathsExecutedPercent' => Percentage::fromFractionAndTotal($item['executedPaths'], $item['executablePaths'])->asFloat(), 'pathsExecutedPercentAsString' => $pathsExecutedPercentAsString, 'numExecutedPaths' => $item['executedPaths'], 'numExecutablePaths' => $item['executablePaths'], 'testedMethodsPercent' => $testedMethodsPercentage->asFloat(), 'testedMethodsPercentAsString' => $testedMethodsPercentage->asString(), 'testedClassesPercent' => $testedClassesPercentage->asFloat(), 'testedClassesPercentAsString' => $testedClassesPercentage->asString(), 'crap' => $item['crap']]);
32228 foreach ($item['methods'] as $method) {
32229 $buffer .= $this->renderFunctionOrMethodItem($methodItemTemplate, $method, '&nbsp;');
32230 }
32231 }
32232 return $buffer;
32233 }
32234 private function renderFunctionItems(array $functions, Template $template): string
32235 {
32236 if (empty($functions)) {
32237 return '';
32238 }
32239 $buffer = '';
32240 foreach ($functions as $function) {
32241 $buffer .= $this->renderFunctionOrMethodItem($template, $function);
32242 }
32243 return $buffer;
32244 }
32245 private function renderFunctionOrMethodItem(Template $template, array $item, string $indent = ''): string
32246 {
32247 $numMethods = 0;
32248 $numTestedMethods = 0;
32249 if ($item['executableLines'] > 0) {
32250 $numMethods = 1;
32251 if ($item['executedLines'] === $item['executableLines']) {
32252 $numTestedMethods = 1;
32253 }
32254 }
32255 $executedLinesPercentage = Percentage::fromFractionAndTotal($item['executedLines'], $item['executableLines']);
32256 $executedBranchesPercentage = Percentage::fromFractionAndTotal($item['executedBranches'], $item['executableBranches']);
32257 $executedPathsPercentage = Percentage::fromFractionAndTotal($item['executedPaths'], $item['executablePaths']);
32258 $testedMethodsPercentage = Percentage::fromFractionAndTotal($numTestedMethods, 1);
32259 return $this->renderItemTemplate($template, ['name' => sprintf('%s<a href="#%d"><abbr title="%s">%s</abbr></a>', $indent, $item['startLine'], htmlspecialchars($item['signature'], $this->htmlSpecialCharsFlags), $item['functionName'] ?? $item['methodName']), 'numMethods' => $numMethods, 'numTestedMethods' => $numTestedMethods, 'linesExecutedPercent' => $executedLinesPercentage->asFloat(), 'linesExecutedPercentAsString' => $executedLinesPercentage->asString(), 'numExecutedLines' => $item['executedLines'], 'numExecutableLines' => $item['executableLines'], 'branchesExecutedPercent' => $executedBranchesPercentage->asFloat(), 'branchesExecutedPercentAsString' => $executedBranchesPercentage->asString(), 'numExecutedBranches' => $item['executedBranches'], 'numExecutableBranches' => $item['executableBranches'], 'pathsExecutedPercent' => $executedPathsPercentage->asFloat(), 'pathsExecutedPercentAsString' => $executedPathsPercentage->asString(), 'numExecutedPaths' => $item['executedPaths'], 'numExecutablePaths' => $item['executablePaths'], 'testedMethodsPercent' => $testedMethodsPercentage->asFloat(), 'testedMethodsPercentAsString' => $testedMethodsPercentage->asString(), 'crap' => $item['crap']]);
32260 }
32261 private function renderSourceWithLineCoverage(FileNode $node): string
32262 {
32263 $linesTemplate = new Template($this->templatePath . 'lines.html.dist', '{{', '}}');
32264 $singleLineTemplate = new Template($this->templatePath . 'line.html.dist', '{{', '}}');
32265 $coverageData = $node->lineCoverageData();
32266 $testData = $node->testData();
32267 $codeLines = $this->loadFile($node->pathAsString());
32268 $lines = '';
32269 $i = 1;
32270 foreach ($codeLines as $line) {
32271 $trClass = '';
32272 $popoverContent = '';
32273 $popoverTitle = '';
32274 if (array_key_exists($i, $coverageData)) {
32275 $numTests = $coverageData[$i] ? count($coverageData[$i]) : 0;
32276 if ($coverageData[$i] === null) {
32277 $trClass = 'warning';
32278 } elseif ($numTests === 0) {
32279 $trClass = 'danger';
32280 } else {
32281 if ($numTests > 1) {
32282 $popoverTitle = $numTests . ' tests cover line ' . $i;
32283 } else {
32284 $popoverTitle = '1 test covers line ' . $i;
32285 }
32286 $lineCss = 'covered-by-large-tests';
32287 $popoverContent = '<ul>';
32288 foreach ($coverageData[$i] as $test) {
32289 if ($lineCss === 'covered-by-large-tests' && $testData[$test]['size'] === 'medium') {
32290 $lineCss = 'covered-by-medium-tests';
32291 } elseif ($testData[$test]['size'] === 'small') {
32292 $lineCss = 'covered-by-small-tests';
32293 }
32294 $popoverContent .= $this->createPopoverContentForTest($test, $testData[$test]);
32295 }
32296 $popoverContent .= '</ul>';
32297 $trClass = $lineCss . ' popin';
32298 }
32299 }
32300 $popover = '';
32301 if (!empty($popoverTitle)) {
32302 $popover = sprintf(' data-title="%s" data-content="%s" data-placement="top" data-html="true"', $popoverTitle, htmlspecialchars($popoverContent, $this->htmlSpecialCharsFlags));
32303 }
32304 $lines .= $this->renderLine($singleLineTemplate, $i, $line, $trClass, $popover);
32305 $i++;
32306 }
32307 $linesTemplate->setVar(['lines' => $lines]);
32308 return $linesTemplate->render();
32309 }
32310 private function renderSourceWithBranchCoverage(FileNode $node): string
32311 {
32312 $linesTemplate = new Template($this->templatePath . 'lines.html.dist', '{{', '}}');
32313 $singleLineTemplate = new Template($this->templatePath . 'line.html.dist', '{{', '}}');
32314 $functionCoverageData = $node->functionCoverageData();
32315 $testData = $node->testData();
32316 $codeLines = $this->loadFile($node->pathAsString());
32317 $lineData = [];
32318 /** @var int $line */
32319 foreach (array_keys($codeLines) as $line) {
32320 $lineData[$line + 1] = ['includedInBranches' => 0, 'includedInHitBranches' => 0, 'tests' => []];
32321 }
32322 foreach ($functionCoverageData as $method) {
32323 foreach ($method['branches'] as $branch) {
32324 foreach (range($branch['line_start'], $branch['line_end']) as $line) {
32325 if (!isset($lineData[$line])) {
32326 // blank line at end of file is sometimes included here
32327 continue;
32328 }
32329 $lineData[$line]['includedInBranches']++;
32330 if ($branch['hit']) {
32331 $lineData[$line]['includedInHitBranches']++;
32332 $lineData[$line]['tests'] = array_unique(array_merge($lineData[$line]['tests'], $branch['hit']));
32333 }
32334 }
32335 }
32336 }
32337 $lines = '';
32338 $i = 1;
32339 /** @var string $line */
32340 foreach ($codeLines as $line) {
32341 $trClass = '';
32342 $popover = '';
32343 if ($lineData[$i]['includedInBranches'] > 0) {
32344 $lineCss = 'success';
32345 if ($lineData[$i]['includedInHitBranches'] === 0) {
32346 $lineCss = 'danger';
32347 } elseif ($lineData[$i]['includedInHitBranches'] !== $lineData[$i]['includedInBranches']) {
32348 $lineCss = 'warning';
32349 }
32350 $popoverContent = '<ul>';
32351 if (count($lineData[$i]['tests']) === 1) {
32352 $popoverTitle = '1 test covers line ' . $i;
32353 } else {
32354 $popoverTitle = count($lineData[$i]['tests']) . ' tests cover line ' . $i;
32355 }
32356 $popoverTitle .= '. These are covering ' . $lineData[$i]['includedInHitBranches'] . ' out of the ' . $lineData[$i]['includedInBranches'] . ' code branches.';
32357 foreach ($lineData[$i]['tests'] as $test) {
32358 $popoverContent .= $this->createPopoverContentForTest($test, $testData[$test]);
32359 }
32360 $popoverContent .= '</ul>';
32361 $trClass = $lineCss . ' popin';
32362 $popover = sprintf(' data-title="%s" data-content="%s" data-placement="top" data-html="true"', $popoverTitle, htmlspecialchars($popoverContent, $this->htmlSpecialCharsFlags));
32363 }
32364 $lines .= $this->renderLine($singleLineTemplate, $i, $line, $trClass, $popover);
32365 $i++;
32366 }
32367 $linesTemplate->setVar(['lines' => $lines]);
32368 return $linesTemplate->render();
32369 }
32370 private function renderSourceWithPathCoverage(FileNode $node): string
32371 {
32372 $linesTemplate = new Template($this->templatePath . 'lines.html.dist', '{{', '}}');
32373 $singleLineTemplate = new Template($this->templatePath . 'line.html.dist', '{{', '}}');
32374 $functionCoverageData = $node->functionCoverageData();
32375 $testData = $node->testData();
32376 $codeLines = $this->loadFile($node->pathAsString());
32377 $lineData = [];
32378 /** @var int $line */
32379 foreach (array_keys($codeLines) as $line) {
32380 $lineData[$line + 1] = ['includedInPaths' => [], 'includedInHitPaths' => [], 'tests' => []];
32381 }
32382 foreach ($functionCoverageData as $method) {
32383 foreach ($method['paths'] as $pathId => $path) {
32384 foreach ($path['path'] as $branchTaken) {
32385 foreach (range($method['branches'][$branchTaken]['line_start'], $method['branches'][$branchTaken]['line_end']) as $line) {
32386 if (!isset($lineData[$line])) {
32387 continue;
32388 }
32389 $lineData[$line]['includedInPaths'][] = $pathId;
32390 if ($path['hit']) {
32391 $lineData[$line]['includedInHitPaths'][] = $pathId;
32392 $lineData[$line]['tests'] = array_unique(array_merge($lineData[$line]['tests'], $path['hit']));
32393 }
32394 }
32395 }
32396 }
32397 }
32398 $lines = '';
32399 $i = 1;
32400 /** @var string $line */
32401 foreach ($codeLines as $line) {
32402 $trClass = '';
32403 $popover = '';
32404 $includedInPathsCount = count(array_unique($lineData[$i]['includedInPaths']));
32405 $includedInHitPathsCount = count(array_unique($lineData[$i]['includedInHitPaths']));
32406 if ($includedInPathsCount > 0) {
32407 $lineCss = 'success';
32408 if ($includedInHitPathsCount === 0) {
32409 $lineCss = 'danger';
32410 } elseif ($includedInHitPathsCount !== $includedInPathsCount) {
32411 $lineCss = 'warning';
32412 }
32413 $popoverContent = '<ul>';
32414 if (count($lineData[$i]['tests']) === 1) {
32415 $popoverTitle = '1 test covers line ' . $i;
32416 } else {
32417 $popoverTitle = count($lineData[$i]['tests']) . ' tests cover line ' . $i;
32418 }
32419 $popoverTitle .= '. These are covering ' . $includedInHitPathsCount . ' out of the ' . $includedInPathsCount . ' code paths.';
32420 foreach ($lineData[$i]['tests'] as $test) {
32421 $popoverContent .= $this->createPopoverContentForTest($test, $testData[$test]);
32422 }
32423 $popoverContent .= '</ul>';
32424 $trClass = $lineCss . ' popin';
32425 $popover = sprintf(' data-title="%s" data-content="%s" data-placement="top" data-html="true"', $popoverTitle, htmlspecialchars($popoverContent, $this->htmlSpecialCharsFlags));
32426 }
32427 $lines .= $this->renderLine($singleLineTemplate, $i, $line, $trClass, $popover);
32428 $i++;
32429 }
32430 $linesTemplate->setVar(['lines' => $lines]);
32431 return $linesTemplate->render();
32432 }
32433 private function renderBranchStructure(FileNode $node): string
32434 {
32435 $branchesTemplate = new Template($this->templatePath . 'branches.html.dist', '{{', '}}');
32436 $coverageData = $node->functionCoverageData();
32437 $testData = $node->testData();
32438 $codeLines = $this->loadFile($node->pathAsString());
32439 $branches = '';
32440 ksort($coverageData);
32441 foreach ($coverageData as $methodName => $methodData) {
32442 if (!$methodData['branches']) {
32443 continue;
32444 }
32445 $branchStructure = '';
32446 foreach ($methodData['branches'] as $branch) {
32447 $branchStructure .= $this->renderBranchLines($branch, $codeLines, $testData);
32448 }
32449 if ($branchStructure !== '') {
32450 // don't show empty branches
32451 $branches .= '<h5 class="structure-heading"><a name="' . htmlspecialchars($methodName, $this->htmlSpecialCharsFlags) . '">' . $this->abbreviateMethodName($methodName) . '</a></h5>' . "\n";
32452 $branches .= $branchStructure;
32453 }
32454 }
32455 $branchesTemplate->setVar(['branches' => $branches]);
32456 return $branchesTemplate->render();
32457 }
32458 private function renderBranchLines(array $branch, array $codeLines, array $testData): string
32459 {
32460 $linesTemplate = new Template($this->templatePath . 'lines.html.dist', '{{', '}}');
32461 $singleLineTemplate = new Template($this->templatePath . 'line.html.dist', '{{', '}}');
32462 $lines = '';
32463 $branchLines = range($branch['line_start'], $branch['line_end']);
32464 sort($branchLines);
32465 // sometimes end_line < start_line
32466 /** @var int $line */
32467 foreach ($branchLines as $line) {
32468 if (!isset($codeLines[$line])) {
32469 // blank line at end of file is sometimes included here
32470 continue;
32471 }
32472 $popoverContent = '';
32473 $popoverTitle = '';
32474 $numTests = count($branch['hit']);
32475 if ($numTests === 0) {
32476 $trClass = 'danger';
32477 } else {
32478 $lineCss = 'covered-by-large-tests';
32479 $popoverContent = '<ul>';
32480 if ($numTests > 1) {
32481 $popoverTitle = $numTests . ' tests cover this branch';
32482 } else {
32483 $popoverTitle = '1 test covers this branch';
32484 }
32485 foreach ($branch['hit'] as $test) {
32486 if ($lineCss === 'covered-by-large-tests' && $testData[$test]['size'] === 'medium') {
32487 $lineCss = 'covered-by-medium-tests';
32488 } elseif ($testData[$test]['size'] === 'small') {
32489 $lineCss = 'covered-by-small-tests';
32490 }
32491 $popoverContent .= $this->createPopoverContentForTest($test, $testData[$test]);
32492 }
32493 $trClass = $lineCss . ' popin';
32494 }
32495 $popover = '';
32496 if (!empty($popoverTitle)) {
32497 $popover = sprintf(' data-title="%s" data-content="%s" data-placement="top" data-html="true"', $popoverTitle, htmlspecialchars($popoverContent, $this->htmlSpecialCharsFlags));
32498 }
32499 $lines .= $this->renderLine($singleLineTemplate, $line, $codeLines[$line - 1], $trClass, $popover);
32500 }
32501 if ($lines === '') {
32502 return '';
32503 }
32504 $linesTemplate->setVar(['lines' => $lines]);
32505 return $linesTemplate->render();
32506 }
32507 private function renderPathStructure(FileNode $node): string
32508 {
32509 $pathsTemplate = new Template($this->templatePath . 'paths.html.dist', '{{', '}}');
32510 $coverageData = $node->functionCoverageData();
32511 $testData = $node->testData();
32512 $codeLines = $this->loadFile($node->pathAsString());
32513 $paths = '';
32514 ksort($coverageData);
32515 foreach ($coverageData as $methodName => $methodData) {
32516 if (!$methodData['paths']) {
32517 continue;
32518 }
32519 $pathStructure = '';
32520 if (count($methodData['paths']) > 100) {
32521 $pathStructure .= '<p>' . count($methodData['paths']) . ' is too many paths to sensibly render, consider refactoring your code to bring this number down.</p>';
32522 continue;
32523 }
32524 foreach ($methodData['paths'] as $path) {
32525 $pathStructure .= $this->renderPathLines($path, $methodData['branches'], $codeLines, $testData);
32526 }
32527 if ($pathStructure !== '') {
32528 $paths .= '<h5 class="structure-heading"><a name="' . htmlspecialchars($methodName, $this->htmlSpecialCharsFlags) . '">' . $this->abbreviateMethodName($methodName) . '</a></h5>' . "\n";
32529 $paths .= $pathStructure;
32530 }
32531 }
32532 $pathsTemplate->setVar(['paths' => $paths]);
32533 return $pathsTemplate->render();
32534 }
32535 private function renderPathLines(array $path, array $branches, array $codeLines, array $testData): string
32536 {
32537 $linesTemplate = new Template($this->templatePath . 'lines.html.dist', '{{', '}}');
32538 $singleLineTemplate = new Template($this->templatePath . 'line.html.dist', '{{', '}}');
32539 $lines = '';
32540 $first = \true;
32541 foreach ($path['path'] as $branchId) {
32542 if ($first) {
32543 $first = \false;
32544 } else {
32545 $lines .= ' <tr><td colspan="2">&nbsp;</td></tr>' . "\n";
32546 }
32547 $branchLines = range($branches[$branchId]['line_start'], $branches[$branchId]['line_end']);
32548 sort($branchLines);
32549 // sometimes end_line < start_line
32550 /** @var int $line */
32551 foreach ($branchLines as $line) {
32552 if (!isset($codeLines[$line])) {
32553 // blank line at end of file is sometimes included here
32554 continue;
32555 }
32556 $popoverContent = '';
32557 $popoverTitle = '';
32558 $numTests = count($path['hit']);
32559 if ($numTests === 0) {
32560 $trClass = 'danger';
32561 } else {
32562 $lineCss = 'covered-by-large-tests';
32563 $popoverContent = '<ul>';
32564 if ($numTests > 1) {
32565 $popoverTitle = $numTests . ' tests cover this path';
32566 } else {
32567 $popoverTitle = '1 test covers this path';
32568 }
32569 foreach ($path['hit'] as $test) {
32570 if ($lineCss === 'covered-by-large-tests' && $testData[$test]['size'] === 'medium') {
32571 $lineCss = 'covered-by-medium-tests';
32572 } elseif ($testData[$test]['size'] === 'small') {
32573 $lineCss = 'covered-by-small-tests';
32574 }
32575 $popoverContent .= $this->createPopoverContentForTest($test, $testData[$test]);
32576 }
32577 $trClass = $lineCss . ' popin';
32578 }
32579 $popover = '';
32580 if (!empty($popoverTitle)) {
32581 $popover = sprintf(' data-title="%s" data-content="%s" data-placement="top" data-html="true"', $popoverTitle, htmlspecialchars($popoverContent, $this->htmlSpecialCharsFlags));
32582 }
32583 $lines .= $this->renderLine($singleLineTemplate, $line, $codeLines[$line - 1], $trClass, $popover);
32584 }
32585 }
32586 if ($lines === '') {
32587 return '';
32588 }
32589 $linesTemplate->setVar(['lines' => $lines]);
32590 return $linesTemplate->render();
32591 }
32592 private function renderLine(Template $template, int $lineNumber, string $lineContent, string $class, string $popover): string
32593 {
32594 $template->setVar(['lineNumber' => $lineNumber, 'lineContent' => $lineContent, 'class' => $class, 'popover' => $popover]);
32595 return $template->render();
32596 }
32597 private function loadFile(string $file): array
32598 {
32599 if (isset(self::$formattedSourceCache[$file])) {
32600 return self::$formattedSourceCache[$file];
32601 }
32602 $buffer = file_get_contents($file);
32603 $tokens = token_get_all($buffer);
32604 $result = [''];
32605 $i = 0;
32606 $stringFlag = \false;
32607 $fileEndsWithNewLine = str_ends_with($buffer, "\n");
32608 unset($buffer);
32609 foreach ($tokens as $j => $token) {
32610 if (is_string($token)) {
32611 if ($token === '"' && $tokens[$j - 1] !== '\\') {
32612 $result[$i] .= sprintf('<span class="string">%s</span>', htmlspecialchars($token, $this->htmlSpecialCharsFlags));
32613 $stringFlag = !$stringFlag;
32614 } else {
32615 $result[$i] .= sprintf('<span class="keyword">%s</span>', htmlspecialchars($token, $this->htmlSpecialCharsFlags));
32616 }
32617 continue;
32618 }
32619 [$token, $value] = $token;
32620 $value = str_replace(["\t", ' '], ['&nbsp;&nbsp;&nbsp;&nbsp;', '&nbsp;'], htmlspecialchars($value, $this->htmlSpecialCharsFlags));
32621 if ($value === "\n") {
32622 $result[++$i] = '';
32623 } else {
32624 $lines = explode("\n", $value);
32625 foreach ($lines as $jj => $line) {
32626 $line = trim($line);
32627 if ($line !== '') {
32628 if ($stringFlag) {
32629 $colour = 'string';
32630 } else {
32631 $colour = 'default';
32632 if ($this->isInlineHtml($token)) {
32633 $colour = 'html';
32634 } elseif ($this->isComment($token)) {
32635 $colour = 'comment';
32636 } elseif ($this->isKeyword($token)) {
32637 $colour = 'keyword';
32638 }
32639 }
32640 $result[$i] .= sprintf('<span class="%s">%s</span>', $colour, $line);
32641 }
32642 if (isset($lines[$jj + 1])) {
32643 $result[++$i] = '';
32644 }
32645 }
32646 }
32647 }
32648 if ($fileEndsWithNewLine) {
32649 unset($result[count($result) - 1]);
32650 }
32651 self::$formattedSourceCache[$file] = $result;
32652 return $result;
32653 }
32654 private function abbreviateClassName(string $className): string
32655 {
32656 $tmp = explode('\\', $className);
32657 if (count($tmp) > 1) {
32658 $className = sprintf('<abbr title="%s">%s</abbr>', $className, array_pop($tmp));
32659 }
32660 return $className;
32661 }
32662 private function abbreviateMethodName(string $methodName): string
32663 {
32664 $parts = explode('->', $methodName);
32665 if (count($parts) === 2) {
32666 return $this->abbreviateClassName($parts[0]) . '->' . $parts[1];
32667 }
32668 return $methodName;
32669 }
32670 private function createPopoverContentForTest(string $test, array $testData): string
32671 {
32672 $testCSS = '';
32673 switch ($testData['status']) {
32674 case 'success':
32675 $testCSS = match ($testData['size']) {
32676 'small' => ' class="covered-by-small-tests"',
32677 'medium' => ' class="covered-by-medium-tests"',
32678 // no break
32679 default => ' class="covered-by-large-tests"',
32680 };
32681 break;
32682 case 'failure':
32683 $testCSS = ' class="danger"';
32684 break;
32685 }
32686 return sprintf('<li%s>%s</li>', $testCSS, htmlspecialchars($test, $this->htmlSpecialCharsFlags));
32687 }
32688 private function isComment(int $token): bool
32689 {
32690 return $token === T_COMMENT || $token === T_DOC_COMMENT;
32691 }
32692 private function isInlineHtml(int $token): bool
32693 {
32694 return $token === T_INLINE_HTML;
32695 }
32696 private function isKeyword(int $token): bool
32697 {
32698 return isset(self::KEYWORD_TOKENS[$token]);
32699 }
32700 }
32701 <hr/>
32702 <h4>Branches</h4>
32703 <p>
32704 Below are the source code lines that represent each code branch as identified by Xdebug. Please note a branch is not
32705 necessarily coterminous with a line, a line may contain multiple branches and therefore show up more than once.
32706 Please also be aware that some branches may be implicit rather than explicit, e.g. an <code>if</code> statement
32707 <i>always</i> has an <code>else</code> as part of its logical flow even if you didn't write one.
32708 </p>
32709 {{branches}}
32710 <div class="progress">
32711 <div class="progress-bar bg-{{level}}" role="progressbar" aria-valuenow="{{percent}}" aria-valuemin="0" aria-valuemax="100" style="width: {{percent}}%">
32712 <span class="sr-only">{{percent}}% covered ({{level}})</span>
32713 </div>
32714 </div>
32715 <div class="progress">
32716 <div class="progress-bar bg-{{level}}" role="progressbar" aria-valuenow="{{percent}}" aria-valuemin="0" aria-valuemax="100" style="width: {{percent}}%">
32717 <span class="sr-only">{{percent}}% covered ({{level}})</span>
32718 </div>
32719 </div>
32720 /*!
32721 * Bootstrap v4.6.2 (https://getbootstrap.com/)
32722 * Copyright 2011-2022 The Bootstrap Authors
32723 * Copyright 2011-2022 Twitter, Inc.
32724 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
32725 */:root{--blue:#007bff;--indigo:#6610f2;--purple:#6f42c1;--pink:#e83e8c;--red:#dc3545;--orange:#fd7e14;--yellow:#ffc107;--green:#28a745;--teal:#20c997;--cyan:#17a2b8;--white:#fff;--gray:#6c757d;--gray-dark:#343a40;--primary:#007bff;--secondary:#6c757d;--success:#28a745;--info:#17a2b8;--warning:#ffc107;--danger:#dc3545;--light:#f8f9fa;--dark:#343a40;--breakpoint-xs:0;--breakpoint-sm:576px;--breakpoint-md:768px;--breakpoint-lg:992px;--breakpoint-xl:1200px;--font-family-sans-serif:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans","Liberation Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--font-family-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace}*,::after,::before{box-sizing:border-box}html{font-family:sans-serif;line-height:1.15;-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent}article,aside,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}body{margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans","Liberation Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-size:1rem;font-weight:400;line-height:1.5;color:#212529;text-align:left;background-color:#fff}[tabindex="-1"]:focus:not(:focus-visible){outline:0!important}hr{box-sizing:content-box;height:0;overflow:visible}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem}p{margin-top:0;margin-bottom:1rem}abbr[data-original-title],abbr[title]{text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;border-bottom:0;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:#007bff;text-decoration:none;background-color:transparent}a:hover{color:#0056b3;text-decoration:underline}a:not([href]):not([class]){color:inherit;text-decoration:none}a:not([href]):not([class]):hover{color:inherit;text-decoration:none}code,kbd,pre,samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;font-size:1em}pre{margin-top:0;margin-bottom:1rem;overflow:auto;-ms-overflow-style:scrollbar}figure{margin:0 0 1rem}img{vertical-align:middle;border-style:none}svg{overflow:hidden;vertical-align:middle}table{border-collapse:collapse}caption{padding-top:.75rem;padding-bottom:.75rem;color:#6c757d;text-align:left;caption-side:bottom}th{text-align:inherit;text-align:-webkit-match-parent}label{display:inline-block;margin-bottom:.5rem}button{border-radius:0}button:focus:not(:focus-visible){outline:0}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,input{overflow:visible}button,select{text-transform:none}[role=button]{cursor:pointer}select{word-wrap:normal}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled),button:not(:disabled){cursor:pointer}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{padding:0;border-style:none}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}textarea{overflow:auto;resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;max-width:100%;padding:0;margin-bottom:.5rem;font-size:1.5rem;line-height:inherit;color:inherit;white-space:normal}progress{vertical-align:baseline}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:none}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}summary{display:list-item;cursor:pointer}template{display:none}[hidden]{display:none!important}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{margin-bottom:.5rem;font-weight:500;line-height:1.2}.h1,h1{font-size:2.5rem}.h2,h2{font-size:2rem}.h3,h3{font-size:1.75rem}.h4,h4{font-size:1.5rem}.h5,h5{font-size:1.25rem}.h6,h6{font-size:1rem}.lead{font-size:1.25rem;font-weight:300}.display-1{font-size:6rem;font-weight:300;line-height:1.2}.display-2{font-size:5.5rem;font-weight:300;line-height:1.2}.display-3{font-size:4.5rem;font-weight:300;line-height:1.2}.display-4{font-size:3.5rem;font-weight:300;line-height:1.2}hr{margin-top:1rem;margin-bottom:1rem;border:0;border-top:1px solid rgba(0,0,0,.1)}.small,small{font-size:.875em;font-weight:400}.mark,mark{padding:.2em;background-color:#fcf8e3}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;list-style:none}.list-inline-item{display:inline-block}.list-inline-item:not(:last-child){margin-right:.5rem}.initialism{font-size:90%;text-transform:uppercase}.blockquote{margin-bottom:1rem;font-size:1.25rem}.blockquote-footer{display:block;font-size:.875em;color:#6c757d}.blockquote-footer::before{content:"\2014\00A0"}.img-fluid{max-width:100%;height:auto}.img-thumbnail{padding:.25rem;background-color:#fff;border:1px solid #dee2e6;border-radius:.25rem;max-width:100%;height:auto}.figure{display:inline-block}.figure-img{margin-bottom:.5rem;line-height:1}.figure-caption{font-size:90%;color:#6c757d}code{font-size:87.5%;color:#e83e8c;word-wrap:break-word}a>code{color:inherit}kbd{padding:.2rem .4rem;font-size:87.5%;color:#fff;background-color:#212529;border-radius:.2rem}kbd kbd{padding:0;font-size:100%;font-weight:700}pre{display:block;font-size:87.5%;color:#212529}pre code{font-size:inherit;color:inherit;word-break:normal}.pre-scrollable{max-height:340px;overflow-y:scroll}.container,.container-fluid,.container-lg,.container-md,.container-sm,.container-xl{width:100%;padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:576px){.container,.container-sm{max-width:540px}}@media (min-width:768px){.container,.container-md,.container-sm{max-width:720px}}@media (min-width:992px){.container,.container-lg,.container-md,.container-sm{max-width:960px}}@media (min-width:1200px){.container,.container-lg,.container-md,.container-sm,.container-xl{max-width:1140px}}.row{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-right:-15px;margin-left:-15px}.no-gutters{margin-right:0;margin-left:0}.no-gutters>.col,.no-gutters>[class*=col-]{padding-right:0;padding-left:0}.col,.col-1,.col-10,.col-11,.col-12,.col-2,.col-3,.col-4,.col-5,.col-6,.col-7,.col-8,.col-9,.col-auto,.col-lg,.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-auto,.col-md,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-auto,.col-sm,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-auto,.col-xl,.col-xl-1,.col-xl-10,.col-xl-11,.col-xl-12,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9,.col-xl-auto{position:relative;width:100%;padding-right:15px;padding-left:15px}.col{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.row-cols-1>*{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.row-cols-2>*{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.row-cols-3>*{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.row-cols-4>*{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.row-cols-5>*{-ms-flex:0 0 20%;flex:0 0 20%;max-width:20%}.row-cols-6>*{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-first{-ms-flex-order:-1;order:-1}.order-last{-ms-flex-order:13;order:13}.order-0{-ms-flex-order:0;order:0}.order-1{-ms-flex-order:1;order:1}.order-2{-ms-flex-order:2;order:2}.order-3{-ms-flex-order:3;order:3}.order-4{-ms-flex-order:4;order:4}.order-5{-ms-flex-order:5;order:5}.order-6{-ms-flex-order:6;order:6}.order-7{-ms-flex-order:7;order:7}.order-8{-ms-flex-order:8;order:8}.order-9{-ms-flex-order:9;order:9}.order-10{-ms-flex-order:10;order:10}.order-11{-ms-flex-order:11;order:11}.order-12{-ms-flex-order:12;order:12}.offset-1{margin-left:8.333333%}.offset-2{margin-left:16.666667%}.offset-3{margin-left:25%}.offset-4{margin-left:33.333333%}.offset-5{margin-left:41.666667%}.offset-6{margin-left:50%}.offset-7{margin-left:58.333333%}.offset-8{margin-left:66.666667%}.offset-9{margin-left:75%}.offset-10{margin-left:83.333333%}.offset-11{margin-left:91.666667%}@media (min-width:576px){.col-sm{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.row-cols-sm-1>*{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.row-cols-sm-2>*{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.row-cols-sm-3>*{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.row-cols-sm-4>*{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.row-cols-sm-5>*{-ms-flex:0 0 20%;flex:0 0 20%;max-width:20%}.row-cols-sm-6>*{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-sm-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-sm-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-sm-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-sm-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-sm-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-sm-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-sm-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-sm-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-sm-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-sm-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-sm-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-sm-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-sm-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-sm-first{-ms-flex-order:-1;order:-1}.order-sm-last{-ms-flex-order:13;order:13}.order-sm-0{-ms-flex-order:0;order:0}.order-sm-1{-ms-flex-order:1;order:1}.order-sm-2{-ms-flex-order:2;order:2}.order-sm-3{-ms-flex-order:3;order:3}.order-sm-4{-ms-flex-order:4;order:4}.order-sm-5{-ms-flex-order:5;order:5}.order-sm-6{-ms-flex-order:6;order:6}.order-sm-7{-ms-flex-order:7;order:7}.order-sm-8{-ms-flex-order:8;order:8}.order-sm-9{-ms-flex-order:9;order:9}.order-sm-10{-ms-flex-order:10;order:10}.order-sm-11{-ms-flex-order:11;order:11}.order-sm-12{-ms-flex-order:12;order:12}.offset-sm-0{margin-left:0}.offset-sm-1{margin-left:8.333333%}.offset-sm-2{margin-left:16.666667%}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:33.333333%}.offset-sm-5{margin-left:41.666667%}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:58.333333%}.offset-sm-8{margin-left:66.666667%}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:83.333333%}.offset-sm-11{margin-left:91.666667%}}@media (min-width:768px){.col-md{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.row-cols-md-1>*{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.row-cols-md-2>*{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.row-cols-md-3>*{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.row-cols-md-4>*{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.row-cols-md-5>*{-ms-flex:0 0 20%;flex:0 0 20%;max-width:20%}.row-cols-md-6>*{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-md-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-md-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-md-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-md-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-md-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-md-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-md-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-md-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-md-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-md-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-md-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-md-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-md-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-md-first{-ms-flex-order:-1;order:-1}.order-md-last{-ms-flex-order:13;order:13}.order-md-0{-ms-flex-order:0;order:0}.order-md-1{-ms-flex-order:1;order:1}.order-md-2{-ms-flex-order:2;order:2}.order-md-3{-ms-flex-order:3;order:3}.order-md-4{-ms-flex-order:4;order:4}.order-md-5{-ms-flex-order:5;order:5}.order-md-6{-ms-flex-order:6;order:6}.order-md-7{-ms-flex-order:7;order:7}.order-md-8{-ms-flex-order:8;order:8}.order-md-9{-ms-flex-order:9;order:9}.order-md-10{-ms-flex-order:10;order:10}.order-md-11{-ms-flex-order:11;order:11}.order-md-12{-ms-flex-order:12;order:12}.offset-md-0{margin-left:0}.offset-md-1{margin-left:8.333333%}.offset-md-2{margin-left:16.666667%}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:33.333333%}.offset-md-5{margin-left:41.666667%}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:58.333333%}.offset-md-8{margin-left:66.666667%}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:83.333333%}.offset-md-11{margin-left:91.666667%}}@media (min-width:992px){.col-lg{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.row-cols-lg-1>*{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.row-cols-lg-2>*{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.row-cols-lg-3>*{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.row-cols-lg-4>*{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.row-cols-lg-5>*{-ms-flex:0 0 20%;flex:0 0 20%;max-width:20%}.row-cols-lg-6>*{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-lg-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-lg-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-lg-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-lg-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-lg-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-lg-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-lg-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-lg-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-lg-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-lg-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-lg-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-lg-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-lg-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-lg-first{-ms-flex-order:-1;order:-1}.order-lg-last{-ms-flex-order:13;order:13}.order-lg-0{-ms-flex-order:0;order:0}.order-lg-1{-ms-flex-order:1;order:1}.order-lg-2{-ms-flex-order:2;order:2}.order-lg-3{-ms-flex-order:3;order:3}.order-lg-4{-ms-flex-order:4;order:4}.order-lg-5{-ms-flex-order:5;order:5}.order-lg-6{-ms-flex-order:6;order:6}.order-lg-7{-ms-flex-order:7;order:7}.order-lg-8{-ms-flex-order:8;order:8}.order-lg-9{-ms-flex-order:9;order:9}.order-lg-10{-ms-flex-order:10;order:10}.order-lg-11{-ms-flex-order:11;order:11}.order-lg-12{-ms-flex-order:12;order:12}.offset-lg-0{margin-left:0}.offset-lg-1{margin-left:8.333333%}.offset-lg-2{margin-left:16.666667%}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:33.333333%}.offset-lg-5{margin-left:41.666667%}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:58.333333%}.offset-lg-8{margin-left:66.666667%}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:83.333333%}.offset-lg-11{margin-left:91.666667%}}@media (min-width:1200px){.col-xl{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.row-cols-xl-1>*{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.row-cols-xl-2>*{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.row-cols-xl-3>*{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.row-cols-xl-4>*{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.row-cols-xl-5>*{-ms-flex:0 0 20%;flex:0 0 20%;max-width:20%}.row-cols-xl-6>*{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-xl-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-xl-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-xl-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-xl-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-xl-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-xl-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-xl-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-xl-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-xl-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-xl-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-xl-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-xl-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-xl-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-xl-first{-ms-flex-order:-1;order:-1}.order-xl-last{-ms-flex-order:13;order:13}.order-xl-0{-ms-flex-order:0;order:0}.order-xl-1{-ms-flex-order:1;order:1}.order-xl-2{-ms-flex-order:2;order:2}.order-xl-3{-ms-flex-order:3;order:3}.order-xl-4{-ms-flex-order:4;order:4}.order-xl-5{-ms-flex-order:5;order:5}.order-xl-6{-ms-flex-order:6;order:6}.order-xl-7{-ms-flex-order:7;order:7}.order-xl-8{-ms-flex-order:8;order:8}.order-xl-9{-ms-flex-order:9;order:9}.order-xl-10{-ms-flex-order:10;order:10}.order-xl-11{-ms-flex-order:11;order:11}.order-xl-12{-ms-flex-order:12;order:12}.offset-xl-0{margin-left:0}.offset-xl-1{margin-left:8.333333%}.offset-xl-2{margin-left:16.666667%}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:33.333333%}.offset-xl-5{margin-left:41.666667%}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:58.333333%}.offset-xl-8{margin-left:66.666667%}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:83.333333%}.offset-xl-11{margin-left:91.666667%}}.table{width:100%;margin-bottom:1rem;color:#212529}.table td,.table th{padding:.75rem;vertical-align:top;border-top:1px solid #dee2e6}.table thead th{vertical-align:bottom;border-bottom:2px solid #dee2e6}.table tbody+tbody{border-top:2px solid #dee2e6}.table-sm td,.table-sm th{padding:.3rem}.table-bordered{border:1px solid #dee2e6}.table-bordered td,.table-bordered th{border:1px solid #dee2e6}.table-bordered thead td,.table-bordered thead th{border-bottom-width:2px}.table-borderless tbody+tbody,.table-borderless td,.table-borderless th,.table-borderless thead th{border:0}.table-striped tbody tr:nth-of-type(odd){background-color:rgba(0,0,0,.05)}.table-hover tbody tr:hover{color:#212529;background-color:rgba(0,0,0,.075)}.table-primary,.table-primary>td,.table-primary>th{background-color:#b8daff}.table-primary tbody+tbody,.table-primary td,.table-primary th,.table-primary thead th{border-color:#7abaff}.table-hover .table-primary:hover{background-color:#9fcdff}.table-hover .table-primary:hover>td,.table-hover .table-primary:hover>th{background-color:#9fcdff}.table-secondary,.table-secondary>td,.table-secondary>th{background-color:#d6d8db}.table-secondary tbody+tbody,.table-secondary td,.table-secondary th,.table-secondary thead th{border-color:#b3b7bb}.table-hover .table-secondary:hover{background-color:#c8cbcf}.table-hover .table-secondary:hover>td,.table-hover .table-secondary:hover>th{background-color:#c8cbcf}.table-success,.table-success>td,.table-success>th{background-color:#c3e6cb}.table-success tbody+tbody,.table-success td,.table-success th,.table-success thead th{border-color:#8fd19e}.table-hover .table-success:hover{background-color:#b1dfbb}.table-hover .table-success:hover>td,.table-hover .table-success:hover>th{background-color:#b1dfbb}.table-info,.table-info>td,.table-info>th{background-color:#bee5eb}.table-info tbody+tbody,.table-info td,.table-info th,.table-info thead th{border-color:#86cfda}.table-hover .table-info:hover{background-color:#abdde5}.table-hover .table-info:hover>td,.table-hover .table-info:hover>th{background-color:#abdde5}.table-warning,.table-warning>td,.table-warning>th{background-color:#ffeeba}.table-warning tbody+tbody,.table-warning td,.table-warning th,.table-warning thead th{border-color:#ffdf7e}.table-hover .table-warning:hover{background-color:#ffe8a1}.table-hover .table-warning:hover>td,.table-hover .table-warning:hover>th{background-color:#ffe8a1}.table-danger,.table-danger>td,.table-danger>th{background-color:#f5c6cb}.table-danger tbody+tbody,.table-danger td,.table-danger th,.table-danger thead th{border-color:#ed969e}.table-hover .table-danger:hover{background-color:#f1b0b7}.table-hover .table-danger:hover>td,.table-hover .table-danger:hover>th{background-color:#f1b0b7}.table-light,.table-light>td,.table-light>th{background-color:#fdfdfe}.table-light tbody+tbody,.table-light td,.table-light th,.table-light thead th{border-color:#fbfcfc}.table-hover .table-light:hover{background-color:#ececf6}.table-hover .table-light:hover>td,.table-hover .table-light:hover>th{background-color:#ececf6}.table-dark,.table-dark>td,.table-dark>th{background-color:#c6c8ca}.table-dark tbody+tbody,.table-dark td,.table-dark th,.table-dark thead th{border-color:#95999c}.table-hover .table-dark:hover{background-color:#b9bbbe}.table-hover .table-dark:hover>td,.table-hover .table-dark:hover>th{background-color:#b9bbbe}.table-active,.table-active>td,.table-active>th{background-color:rgba(0,0,0,.075)}.table-hover .table-active:hover{background-color:rgba(0,0,0,.075)}.table-hover .table-active:hover>td,.table-hover .table-active:hover>th{background-color:rgba(0,0,0,.075)}.table .thead-dark th{color:#fff;background-color:#343a40;border-color:#454d55}.table .thead-light th{color:#495057;background-color:#e9ecef;border-color:#dee2e6}.table-dark{color:#fff;background-color:#343a40}.table-dark td,.table-dark th,.table-dark thead th{border-color:#454d55}.table-dark.table-bordered{border:0}.table-dark.table-striped tbody tr:nth-of-type(odd){background-color:rgba(255,255,255,.05)}.table-dark.table-hover tbody tr:hover{color:#fff;background-color:rgba(255,255,255,.075)}@media (max-width:575.98px){.table-responsive-sm{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-sm>.table-bordered{border:0}}@media (max-width:767.98px){.table-responsive-md{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-md>.table-bordered{border:0}}@media (max-width:991.98px){.table-responsive-lg{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-lg>.table-bordered{border:0}}@media (max-width:1199.98px){.table-responsive-xl{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-xl>.table-bordered{border:0}}.table-responsive{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive>.table-bordered{border:0}.form-control{display:block;width:100%;height:calc(1.5em + .75rem + 2px);padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;background-color:#fff;background-clip:padding-box;border:1px solid #ced4da;border-radius:.25rem;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-control{transition:none}}.form-control::-ms-expand{background-color:transparent;border:0}.form-control:focus{color:#495057;background-color:#fff;border-color:#80bdff;outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.form-control::-webkit-input-placeholder{color:#6c757d;opacity:1}.form-control::-moz-placeholder{color:#6c757d;opacity:1}.form-control:-ms-input-placeholder{color:#6c757d;opacity:1}.form-control::-ms-input-placeholder{color:#6c757d;opacity:1}.form-control::placeholder{color:#6c757d;opacity:1}.form-control:disabled,.form-control[readonly]{background-color:#e9ecef;opacity:1}input[type=date].form-control,input[type=datetime-local].form-control,input[type=month].form-control,input[type=time].form-control{-webkit-appearance:none;-moz-appearance:none;appearance:none}select.form-control:-moz-focusring{color:transparent;text-shadow:0 0 0 #495057}select.form-control:focus::-ms-value{color:#495057;background-color:#fff}.form-control-file,.form-control-range{display:block;width:100%}.col-form-label{padding-top:calc(.375rem + 1px);padding-bottom:calc(.375rem + 1px);margin-bottom:0;font-size:inherit;line-height:1.5}.col-form-label-lg{padding-top:calc(.5rem + 1px);padding-bottom:calc(.5rem + 1px);font-size:1.25rem;line-height:1.5}.col-form-label-sm{padding-top:calc(.25rem + 1px);padding-bottom:calc(.25rem + 1px);font-size:.875rem;line-height:1.5}.form-control-plaintext{display:block;width:100%;padding:.375rem 0;margin-bottom:0;font-size:1rem;line-height:1.5;color:#212529;background-color:transparent;border:solid transparent;border-width:1px 0}.form-control-plaintext.form-control-lg,.form-control-plaintext.form-control-sm{padding-right:0;padding-left:0}.form-control-sm{height:calc(1.5em + .5rem + 2px);padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.form-control-lg{height:calc(1.5em + 1rem + 2px);padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}select.form-control[multiple],select.form-control[size]{height:auto}textarea.form-control{height:auto}.form-group{margin-bottom:1rem}.form-text{display:block;margin-top:.25rem}.form-row{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-right:-5px;margin-left:-5px}.form-row>.col,.form-row>[class*=col-]{padding-right:5px;padding-left:5px}.form-check{position:relative;display:block;padding-left:1.25rem}.form-check-input{position:absolute;margin-top:.3rem;margin-left:-1.25rem}.form-check-input:disabled~.form-check-label,.form-check-input[disabled]~.form-check-label{color:#6c757d}.form-check-label{margin-bottom:0}.form-check-inline{display:-ms-inline-flexbox;display:inline-flex;-ms-flex-align:center;align-items:center;padding-left:0;margin-right:.75rem}.form-check-inline .form-check-input{position:static;margin-top:0;margin-right:.3125rem;margin-left:0}.valid-feedback{display:none;width:100%;margin-top:.25rem;font-size:.875em;color:#28a745}.valid-tooltip{position:absolute;top:100%;left:0;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;line-height:1.5;color:#fff;background-color:rgba(40,167,69,.9);border-radius:.25rem}.form-row>.col>.valid-tooltip,.form-row>[class*=col-]>.valid-tooltip{left:5px}.is-valid~.valid-feedback,.is-valid~.valid-tooltip,.was-validated :valid~.valid-feedback,.was-validated :valid~.valid-tooltip{display:block}.form-control.is-valid,.was-validated .form-control:valid{border-color:#28a745;padding-right:calc(1.5em + .75rem)!important;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%2328a745' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(.375em + .1875rem) center;background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.form-control.is-valid:focus,.was-validated .form-control:valid:focus{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.was-validated select.form-control:valid,select.form-control.is-valid{padding-right:3rem!important;background-position:right 1.5rem center}.was-validated textarea.form-control:valid,textarea.form-control.is-valid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}.custom-select.is-valid,.was-validated .custom-select:valid{border-color:#28a745;padding-right:calc(.75em + 2.3125rem)!important;background:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") right .75rem center/8px 10px no-repeat,#fff url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%2328a745' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e") center right 1.75rem/calc(.75em + .375rem) calc(.75em + .375rem) no-repeat}.custom-select.is-valid:focus,.was-validated .custom-select:valid:focus{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.form-check-input.is-valid~.form-check-label,.was-validated .form-check-input:valid~.form-check-label{color:#28a745}.form-check-input.is-valid~.valid-feedback,.form-check-input.is-valid~.valid-tooltip,.was-validated .form-check-input:valid~.valid-feedback,.was-validated .form-check-input:valid~.valid-tooltip{display:block}.custom-control-input.is-valid~.custom-control-label,.was-validated .custom-control-input:valid~.custom-control-label{color:#28a745}.custom-control-input.is-valid~.custom-control-label::before,.was-validated .custom-control-input:valid~.custom-control-label::before{border-color:#28a745}.custom-control-input.is-valid:checked~.custom-control-label::before,.was-validated .custom-control-input:valid:checked~.custom-control-label::before{border-color:#34ce57;background-color:#34ce57}.custom-control-input.is-valid:focus~.custom-control-label::before,.was-validated .custom-control-input:valid:focus~.custom-control-label::before{box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.custom-control-input.is-valid:focus:not(:checked)~.custom-control-label::before,.was-validated .custom-control-input:valid:focus:not(:checked)~.custom-control-label::before{border-color:#28a745}.custom-file-input.is-valid~.custom-file-label,.was-validated .custom-file-input:valid~.custom-file-label{border-color:#28a745}.custom-file-input.is-valid:focus~.custom-file-label,.was-validated .custom-file-input:valid:focus~.custom-file-label{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.invalid-feedback{display:none;width:100%;margin-top:.25rem;font-size:.875em;color:#dc3545}.invalid-tooltip{position:absolute;top:100%;left:0;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;line-height:1.5;color:#fff;background-color:rgba(220,53,69,.9);border-radius:.25rem}.form-row>.col>.invalid-tooltip,.form-row>[class*=col-]>.invalid-tooltip{left:5px}.is-invalid~.invalid-feedback,.is-invalid~.invalid-tooltip,.was-validated :invalid~.invalid-feedback,.was-validated :invalid~.invalid-tooltip{display:block}.form-control.is-invalid,.was-validated .form-control:invalid{border-color:#dc3545;padding-right:calc(1.5em + .75rem)!important;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23dc3545' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(.375em + .1875rem) center;background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.form-control.is-invalid:focus,.was-validated .form-control:invalid:focus{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.was-validated select.form-control:invalid,select.form-control.is-invalid{padding-right:3rem!important;background-position:right 1.5rem center}.was-validated textarea.form-control:invalid,textarea.form-control.is-invalid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}.custom-select.is-invalid,.was-validated .custom-select:invalid{border-color:#dc3545;padding-right:calc(.75em + 2.3125rem)!important;background:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") right .75rem center/8px 10px no-repeat,#fff url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23dc3545' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e") center right 1.75rem/calc(.75em + .375rem) calc(.75em + .375rem) no-repeat}.custom-select.is-invalid:focus,.was-validated .custom-select:invalid:focus{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.form-check-input.is-invalid~.form-check-label,.was-validated .form-check-input:invalid~.form-check-label{color:#dc3545}.form-check-input.is-invalid~.invalid-feedback,.form-check-input.is-invalid~.invalid-tooltip,.was-validated .form-check-input:invalid~.invalid-feedback,.was-validated .form-check-input:invalid~.invalid-tooltip{display:block}.custom-control-input.is-invalid~.custom-control-label,.was-validated .custom-control-input:invalid~.custom-control-label{color:#dc3545}.custom-control-input.is-invalid~.custom-control-label::before,.was-validated .custom-control-input:invalid~.custom-control-label::before{border-color:#dc3545}.custom-control-input.is-invalid:checked~.custom-control-label::before,.was-validated .custom-control-input:invalid:checked~.custom-control-label::before{border-color:#e4606d;background-color:#e4606d}.custom-control-input.is-invalid:focus~.custom-control-label::before,.was-validated .custom-control-input:invalid:focus~.custom-control-label::before{box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.custom-control-input.is-invalid:focus:not(:checked)~.custom-control-label::before,.was-validated .custom-control-input:invalid:focus:not(:checked)~.custom-control-label::before{border-color:#dc3545}.custom-file-input.is-invalid~.custom-file-label,.was-validated .custom-file-input:invalid~.custom-file-label{border-color:#dc3545}.custom-file-input.is-invalid:focus~.custom-file-label,.was-validated .custom-file-input:invalid:focus~.custom-file-label{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.form-inline{display:-ms-flexbox;display:flex;-ms-flex-flow:row wrap;flex-flow:row wrap;-ms-flex-align:center;align-items:center}.form-inline .form-check{width:100%}@media (min-width:576px){.form-inline label{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;margin-bottom:0}.form-inline .form-group{display:-ms-flexbox;display:flex;-ms-flex:0 0 auto;flex:0 0 auto;-ms-flex-flow:row wrap;flex-flow:row wrap;-ms-flex-align:center;align-items:center;margin-bottom:0}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-plaintext{display:inline-block}.form-inline .custom-select,.form-inline .input-group{width:auto}.form-inline .form-check{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;width:auto;padding-left:0}.form-inline .form-check-input{position:relative;-ms-flex-negative:0;flex-shrink:0;margin-top:0;margin-right:.25rem;margin-left:0}.form-inline .custom-control{-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center}.form-inline .custom-control-label{margin-bottom:0}}.btn{display:inline-block;font-weight:400;color:#212529;text-align:center;vertical-align:middle;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-color:transparent;border:1px solid transparent;padding:.375rem .75rem;font-size:1rem;line-height:1.5;border-radius:.25rem;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.btn{transition:none}}.btn:hover{color:#212529;text-decoration:none}.btn.focus,.btn:focus{outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.btn.disabled,.btn:disabled{opacity:.65}.btn:not(:disabled):not(.disabled){cursor:pointer}a.btn.disabled,fieldset:disabled a.btn{pointer-events:none}.btn-primary{color:#fff;background-color:#007bff;border-color:#007bff}.btn-primary:hover{color:#fff;background-color:#0069d9;border-color:#0062cc}.btn-primary.focus,.btn-primary:focus{color:#fff;background-color:#0069d9;border-color:#0062cc;box-shadow:0 0 0 .2rem rgba(38,143,255,.5)}.btn-primary.disabled,.btn-primary:disabled{color:#fff;background-color:#007bff;border-color:#007bff}.btn-primary:not(:disabled):not(.disabled).active,.btn-primary:not(:disabled):not(.disabled):active,.show>.btn-primary.dropdown-toggle{color:#fff;background-color:#0062cc;border-color:#005cbf}.btn-primary:not(:disabled):not(.disabled).active:focus,.btn-primary:not(:disabled):not(.disabled):active:focus,.show>.btn-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(38,143,255,.5)}.btn-secondary{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-secondary:hover{color:#fff;background-color:#5a6268;border-color:#545b62}.btn-secondary.focus,.btn-secondary:focus{color:#fff;background-color:#5a6268;border-color:#545b62;box-shadow:0 0 0 .2rem rgba(130,138,145,.5)}.btn-secondary.disabled,.btn-secondary:disabled{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-secondary:not(:disabled):not(.disabled).active,.btn-secondary:not(:disabled):not(.disabled):active,.show>.btn-secondary.dropdown-toggle{color:#fff;background-color:#545b62;border-color:#4e555b}.btn-secondary:not(:disabled):not(.disabled).active:focus,.btn-secondary:not(:disabled):not(.disabled):active:focus,.show>.btn-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(130,138,145,.5)}.btn-success{color:#fff;background-color:#28a745;border-color:#28a745}.btn-success:hover{color:#fff;background-color:#218838;border-color:#1e7e34}.btn-success.focus,.btn-success:focus{color:#fff;background-color:#218838;border-color:#1e7e34;box-shadow:0 0 0 .2rem rgba(72,180,97,.5)}.btn-success.disabled,.btn-success:disabled{color:#fff;background-color:#28a745;border-color:#28a745}.btn-success:not(:disabled):not(.disabled).active,.btn-success:not(:disabled):not(.disabled):active,.show>.btn-success.dropdown-toggle{color:#fff;background-color:#1e7e34;border-color:#1c7430}.btn-success:not(:disabled):not(.disabled).active:focus,.btn-success:not(:disabled):not(.disabled):active:focus,.show>.btn-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(72,180,97,.5)}.btn-info{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-info:hover{color:#fff;background-color:#138496;border-color:#117a8b}.btn-info.focus,.btn-info:focus{color:#fff;background-color:#138496;border-color:#117a8b;box-shadow:0 0 0 .2rem rgba(58,176,195,.5)}.btn-info.disabled,.btn-info:disabled{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-info:not(:disabled):not(.disabled).active,.btn-info:not(:disabled):not(.disabled):active,.show>.btn-info.dropdown-toggle{color:#fff;background-color:#117a8b;border-color:#10707f}.btn-info:not(:disabled):not(.disabled).active:focus,.btn-info:not(:disabled):not(.disabled):active:focus,.show>.btn-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(58,176,195,.5)}.btn-warning{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-warning:hover{color:#212529;background-color:#e0a800;border-color:#d39e00}.btn-warning.focus,.btn-warning:focus{color:#212529;background-color:#e0a800;border-color:#d39e00;box-shadow:0 0 0 .2rem rgba(222,170,12,.5)}.btn-warning.disabled,.btn-warning:disabled{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-warning:not(:disabled):not(.disabled).active,.btn-warning:not(:disabled):not(.disabled):active,.show>.btn-warning.dropdown-toggle{color:#212529;background-color:#d39e00;border-color:#c69500}.btn-warning:not(:disabled):not(.disabled).active:focus,.btn-warning:not(:disabled):not(.disabled):active:focus,.show>.btn-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(222,170,12,.5)}.btn-danger{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-danger:hover{color:#fff;background-color:#c82333;border-color:#bd2130}.btn-danger.focus,.btn-danger:focus{color:#fff;background-color:#c82333;border-color:#bd2130;box-shadow:0 0 0 .2rem rgba(225,83,97,.5)}.btn-danger.disabled,.btn-danger:disabled{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-danger:not(:disabled):not(.disabled).active,.btn-danger:not(:disabled):not(.disabled):active,.show>.btn-danger.dropdown-toggle{color:#fff;background-color:#bd2130;border-color:#b21f2d}.btn-danger:not(:disabled):not(.disabled).active:focus,.btn-danger:not(:disabled):not(.disabled):active:focus,.show>.btn-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(225,83,97,.5)}.btn-light{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-light:hover{color:#212529;background-color:#e2e6ea;border-color:#dae0e5}.btn-light.focus,.btn-light:focus{color:#212529;background-color:#e2e6ea;border-color:#dae0e5;box-shadow:0 0 0 .2rem rgba(216,217,219,.5)}.btn-light.disabled,.btn-light:disabled{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-light:not(:disabled):not(.disabled).active,.btn-light:not(:disabled):not(.disabled):active,.show>.btn-light.dropdown-toggle{color:#212529;background-color:#dae0e5;border-color:#d3d9df}.btn-light:not(:disabled):not(.disabled).active:focus,.btn-light:not(:disabled):not(.disabled):active:focus,.show>.btn-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(216,217,219,.5)}.btn-dark{color:#fff;background-color:#343a40;border-color:#343a40}.btn-dark:hover{color:#fff;background-color:#23272b;border-color:#1d2124}.btn-dark.focus,.btn-dark:focus{color:#fff;background-color:#23272b;border-color:#1d2124;box-shadow:0 0 0 .2rem rgba(82,88,93,.5)}.btn-dark.disabled,.btn-dark:disabled{color:#fff;background-color:#343a40;border-color:#343a40}.btn-dark:not(:disabled):not(.disabled).active,.btn-dark:not(:disabled):not(.disabled):active,.show>.btn-dark.dropdown-toggle{color:#fff;background-color:#1d2124;border-color:#171a1d}.btn-dark:not(:disabled):not(.disabled).active:focus,.btn-dark:not(:disabled):not(.disabled):active:focus,.show>.btn-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(82,88,93,.5)}.btn-outline-primary{color:#007bff;border-color:#007bff}.btn-outline-primary:hover{color:#fff;background-color:#007bff;border-color:#007bff}.btn-outline-primary.focus,.btn-outline-primary:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.btn-outline-primary.disabled,.btn-outline-primary:disabled{color:#007bff;background-color:transparent}.btn-outline-primary:not(:disabled):not(.disabled).active,.btn-outline-primary:not(:disabled):not(.disabled):active,.show>.btn-outline-primary.dropdown-toggle{color:#fff;background-color:#007bff;border-color:#007bff}.btn-outline-primary:not(:disabled):not(.disabled).active:focus,.btn-outline-primary:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.btn-outline-secondary{color:#6c757d;border-color:#6c757d}.btn-outline-secondary:hover{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-outline-secondary.focus,.btn-outline-secondary:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.btn-outline-secondary.disabled,.btn-outline-secondary:disabled{color:#6c757d;background-color:transparent}.btn-outline-secondary:not(:disabled):not(.disabled).active,.btn-outline-secondary:not(:disabled):not(.disabled):active,.show>.btn-outline-secondary.dropdown-toggle{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-outline-secondary:not(:disabled):not(.disabled).active:focus,.btn-outline-secondary:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.btn-outline-success{color:#28a745;border-color:#28a745}.btn-outline-success:hover{color:#fff;background-color:#28a745;border-color:#28a745}.btn-outline-success.focus,.btn-outline-success:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.btn-outline-success.disabled,.btn-outline-success:disabled{color:#28a745;background-color:transparent}.btn-outline-success:not(:disabled):not(.disabled).active,.btn-outline-success:not(:disabled):not(.disabled):active,.show>.btn-outline-success.dropdown-toggle{color:#fff;background-color:#28a745;border-color:#28a745}.btn-outline-success:not(:disabled):not(.disabled).active:focus,.btn-outline-success:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.btn-outline-info{color:#17a2b8;border-color:#17a2b8}.btn-outline-info:hover{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-outline-info.focus,.btn-outline-info:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.btn-outline-info.disabled,.btn-outline-info:disabled{color:#17a2b8;background-color:transparent}.btn-outline-info:not(:disabled):not(.disabled).active,.btn-outline-info:not(:disabled):not(.disabled):active,.show>.btn-outline-info.dropdown-toggle{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-outline-info:not(:disabled):not(.disabled).active:focus,.btn-outline-info:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.btn-outline-warning{color:#ffc107;border-color:#ffc107}.btn-outline-warning:hover{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-outline-warning.focus,.btn-outline-warning:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.btn-outline-warning.disabled,.btn-outline-warning:disabled{color:#ffc107;background-color:transparent}.btn-outline-warning:not(:disabled):not(.disabled).active,.btn-outline-warning:not(:disabled):not(.disabled):active,.show>.btn-outline-warning.dropdown-toggle{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-outline-warning:not(:disabled):not(.disabled).active:focus,.btn-outline-warning:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.btn-outline-danger{color:#dc3545;border-color:#dc3545}.btn-outline-danger:hover{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-outline-danger.focus,.btn-outline-danger:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.btn-outline-danger.disabled,.btn-outline-danger:disabled{color:#dc3545;background-color:transparent}.btn-outline-danger:not(:disabled):not(.disabled).active,.btn-outline-danger:not(:disabled):not(.disabled):active,.show>.btn-outline-danger.dropdown-toggle{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-outline-danger:not(:disabled):not(.disabled).active:focus,.btn-outline-danger:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.btn-outline-light{color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light:hover{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light.focus,.btn-outline-light:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.btn-outline-light.disabled,.btn-outline-light:disabled{color:#f8f9fa;background-color:transparent}.btn-outline-light:not(:disabled):not(.disabled).active,.btn-outline-light:not(:disabled):not(.disabled):active,.show>.btn-outline-light.dropdown-toggle{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light:not(:disabled):not(.disabled).active:focus,.btn-outline-light:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.btn-outline-dark{color:#343a40;border-color:#343a40}.btn-outline-dark:hover{color:#fff;background-color:#343a40;border-color:#343a40}.btn-outline-dark.focus,.btn-outline-dark:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.btn-outline-dark.disabled,.btn-outline-dark:disabled{color:#343a40;background-color:transparent}.btn-outline-dark:not(:disabled):not(.disabled).active,.btn-outline-dark:not(:disabled):not(.disabled):active,.show>.btn-outline-dark.dropdown-toggle{color:#fff;background-color:#343a40;border-color:#343a40}.btn-outline-dark:not(:disabled):not(.disabled).active:focus,.btn-outline-dark:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.btn-link{font-weight:400;color:#007bff;text-decoration:none}.btn-link:hover{color:#0056b3;text-decoration:underline}.btn-link.focus,.btn-link:focus{text-decoration:underline}.btn-link.disabled,.btn-link:disabled{color:#6c757d;pointer-events:none}.btn-group-lg>.btn,.btn-lg{padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}.btn-group-sm>.btn,.btn-sm{padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:.5rem}input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn-block{width:100%}.fade{transition:opacity .15s linear}@media (prefers-reduced-motion:reduce){.fade{transition:none}}.fade:not(.show){opacity:0}.collapse:not(.show){display:none}.collapsing{position:relative;height:0;overflow:hidden;transition:height .35s ease}@media (prefers-reduced-motion:reduce){.collapsing{transition:none}}.collapsing.width{width:0;height:auto;transition:width .35s ease}@media (prefers-reduced-motion:reduce){.collapsing.width{transition:none}}.dropdown,.dropleft,.dropright,.dropup{position:relative}.dropdown-toggle{white-space:nowrap}.dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid;border-right:.3em solid transparent;border-bottom:0;border-left:.3em solid transparent}.dropdown-toggle:empty::after{margin-left:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:10rem;padding:.5rem 0;margin:.125rem 0 0;font-size:1rem;color:#212529;text-align:left;list-style:none;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.15);border-radius:.25rem}.dropdown-menu-left{right:auto;left:0}.dropdown-menu-right{right:0;left:auto}@media (min-width:576px){.dropdown-menu-sm-left{right:auto;left:0}.dropdown-menu-sm-right{right:0;left:auto}}@media (min-width:768px){.dropdown-menu-md-left{right:auto;left:0}.dropdown-menu-md-right{right:0;left:auto}}@media (min-width:992px){.dropdown-menu-lg-left{right:auto;left:0}.dropdown-menu-lg-right{right:0;left:auto}}@media (min-width:1200px){.dropdown-menu-xl-left{right:auto;left:0}.dropdown-menu-xl-right{right:0;left:auto}}.dropup .dropdown-menu{top:auto;bottom:100%;margin-top:0;margin-bottom:.125rem}.dropup .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:0;border-right:.3em solid transparent;border-bottom:.3em solid;border-left:.3em solid transparent}.dropup .dropdown-toggle:empty::after{margin-left:0}.dropright .dropdown-menu{top:0;right:auto;left:100%;margin-top:0;margin-left:.125rem}.dropright .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:0;border-bottom:.3em solid transparent;border-left:.3em solid}.dropright .dropdown-toggle:empty::after{margin-left:0}.dropright .dropdown-toggle::after{vertical-align:0}.dropleft .dropdown-menu{top:0;right:100%;left:auto;margin-top:0;margin-right:.125rem}.dropleft .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:""}.dropleft .dropdown-toggle::after{display:none}.dropleft .dropdown-toggle::before{display:inline-block;margin-right:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:.3em solid;border-bottom:.3em solid transparent}.dropleft .dropdown-toggle:empty::after{margin-left:0}.dropleft .dropdown-toggle::before{vertical-align:0}.dropdown-menu[x-placement^=bottom],.dropdown-menu[x-placement^=left],.dropdown-menu[x-placement^=right],.dropdown-menu[x-placement^=top]{right:auto;bottom:auto}.dropdown-divider{height:0;margin:.5rem 0;overflow:hidden;border-top:1px solid #e9ecef}.dropdown-item{display:block;width:100%;padding:.25rem 1.5rem;clear:both;font-weight:400;color:#212529;text-align:inherit;white-space:nowrap;background-color:transparent;border:0}.dropdown-item:focus,.dropdown-item:hover{color:#16181b;text-decoration:none;background-color:#e9ecef}.dropdown-item.active,.dropdown-item:active{color:#fff;text-decoration:none;background-color:#007bff}.dropdown-item.disabled,.dropdown-item:disabled{color:#adb5bd;pointer-events:none;background-color:transparent}.dropdown-menu.show{display:block}.dropdown-header{display:block;padding:.5rem 1.5rem;margin-bottom:0;font-size:.875rem;color:#6c757d;white-space:nowrap}.dropdown-item-text{display:block;padding:.25rem 1.5rem;color:#212529}.btn-group,.btn-group-vertical{position:relative;display:-ms-inline-flexbox;display:inline-flex;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;-ms-flex:1 1 auto;flex:1 1 auto}.btn-group-vertical>.btn:hover,.btn-group>.btn:hover{z-index:1}.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus{z-index:1}.btn-toolbar{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-pack:start;justify-content:flex-start}.btn-toolbar .input-group{width:auto}.btn-group>.btn-group:not(:first-child),.btn-group>.btn:not(:first-child){margin-left:-1px}.btn-group>.btn-group:not(:last-child)>.btn,.btn-group>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:not(:first-child)>.btn,.btn-group>.btn:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.dropdown-toggle-split{padding-right:.5625rem;padding-left:.5625rem}.dropdown-toggle-split::after,.dropright .dropdown-toggle-split::after,.dropup .dropdown-toggle-split::after{margin-left:0}.dropleft .dropdown-toggle-split::before{margin-right:0}.btn-group-sm>.btn+.dropdown-toggle-split,.btn-sm+.dropdown-toggle-split{padding-right:.375rem;padding-left:.375rem}.btn-group-lg>.btn+.dropdown-toggle-split,.btn-lg+.dropdown-toggle-split{padding-right:.75rem;padding-left:.75rem}.btn-group-vertical{-ms-flex-direction:column;flex-direction:column;-ms-flex-align:start;align-items:flex-start;-ms-flex-pack:center;justify-content:center}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group{width:100%}.btn-group-vertical>.btn-group:not(:first-child),.btn-group-vertical>.btn:not(:first-child){margin-top:-1px}.btn-group-vertical>.btn-group:not(:last-child)>.btn,.btn-group-vertical>.btn:not(:last-child):not(.dropdown-toggle){border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:not(:first-child)>.btn,.btn-group-vertical>.btn:not(:first-child){border-top-left-radius:0;border-top-right-radius:0}.btn-group-toggle>.btn,.btn-group-toggle>.btn-group>.btn{margin-bottom:0}.btn-group-toggle>.btn input[type=checkbox],.btn-group-toggle>.btn input[type=radio],.btn-group-toggle>.btn-group>.btn input[type=checkbox],.btn-group-toggle>.btn-group>.btn input[type=radio]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.input-group{position:relative;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:stretch;align-items:stretch;width:100%}.input-group>.custom-file,.input-group>.custom-select,.input-group>.form-control,.input-group>.form-control-plaintext{position:relative;-ms-flex:1 1 auto;flex:1 1 auto;width:1%;min-width:0;margin-bottom:0}.input-group>.custom-file+.custom-file,.input-group>.custom-file+.custom-select,.input-group>.custom-file+.form-control,.input-group>.custom-select+.custom-file,.input-group>.custom-select+.custom-select,.input-group>.custom-select+.form-control,.input-group>.form-control+.custom-file,.input-group>.form-control+.custom-select,.input-group>.form-control+.form-control,.input-group>.form-control-plaintext+.custom-file,.input-group>.form-control-plaintext+.custom-select,.input-group>.form-control-plaintext+.form-control{margin-left:-1px}.input-group>.custom-file .custom-file-input:focus~.custom-file-label,.input-group>.custom-select:focus,.input-group>.form-control:focus{z-index:3}.input-group>.custom-file .custom-file-input:focus{z-index:4}.input-group>.custom-select:not(:first-child),.input-group>.form-control:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.input-group>.custom-file{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center}.input-group>.custom-file:not(:last-child) .custom-file-label,.input-group>.custom-file:not(:last-child) .custom-file-label::after{border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.custom-file:not(:first-child) .custom-file-label{border-top-left-radius:0;border-bottom-left-radius:0}.input-group:not(.has-validation)>.custom-file:not(:last-child) .custom-file-label,.input-group:not(.has-validation)>.custom-file:not(:last-child) .custom-file-label::after,.input-group:not(.has-validation)>.custom-select:not(:last-child),.input-group:not(.has-validation)>.form-control:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.input-group.has-validation>.custom-file:nth-last-child(n+3) .custom-file-label,.input-group.has-validation>.custom-file:nth-last-child(n+3) .custom-file-label::after,.input-group.has-validation>.custom-select:nth-last-child(n+3),.input-group.has-validation>.form-control:nth-last-child(n+3){border-top-right-radius:0;border-bottom-right-radius:0}.input-group-append,.input-group-prepend{display:-ms-flexbox;display:flex}.input-group-append .btn,.input-group-prepend .btn{position:relative;z-index:2}.input-group-append .btn:focus,.input-group-prepend .btn:focus{z-index:3}.input-group-append .btn+.btn,.input-group-append .btn+.input-group-text,.input-group-append .input-group-text+.btn,.input-group-append .input-group-text+.input-group-text,.input-group-prepend .btn+.btn,.input-group-prepend .btn+.input-group-text,.input-group-prepend .input-group-text+.btn,.input-group-prepend .input-group-text+.input-group-text{margin-left:-1px}.input-group-prepend{margin-right:-1px}.input-group-append{margin-left:-1px}.input-group-text{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;padding:.375rem .75rem;margin-bottom:0;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;text-align:center;white-space:nowrap;background-color:#e9ecef;border:1px solid #ced4da;border-radius:.25rem}.input-group-text input[type=checkbox],.input-group-text input[type=radio]{margin-top:0}.input-group-lg>.custom-select,.input-group-lg>.form-control:not(textarea){height:calc(1.5em + 1rem + 2px)}.input-group-lg>.custom-select,.input-group-lg>.form-control,.input-group-lg>.input-group-append>.btn,.input-group-lg>.input-group-append>.input-group-text,.input-group-lg>.input-group-prepend>.btn,.input-group-lg>.input-group-prepend>.input-group-text{padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}.input-group-sm>.custom-select,.input-group-sm>.form-control:not(textarea){height:calc(1.5em + .5rem + 2px)}.input-group-sm>.custom-select,.input-group-sm>.form-control,.input-group-sm>.input-group-append>.btn,.input-group-sm>.input-group-append>.input-group-text,.input-group-sm>.input-group-prepend>.btn,.input-group-sm>.input-group-prepend>.input-group-text{padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.input-group-lg>.custom-select,.input-group-sm>.custom-select{padding-right:1.75rem}.input-group.has-validation>.input-group-append:nth-last-child(n+3)>.btn,.input-group.has-validation>.input-group-append:nth-last-child(n+3)>.input-group-text,.input-group:not(.has-validation)>.input-group-append:not(:last-child)>.btn,.input-group:not(.has-validation)>.input-group-append:not(:last-child)>.input-group-text,.input-group>.input-group-append:last-child>.btn:not(:last-child):not(.dropdown-toggle),.input-group>.input-group-append:last-child>.input-group-text:not(:last-child),.input-group>.input-group-prepend>.btn,.input-group>.input-group-prepend>.input-group-text{border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.input-group-append>.btn,.input-group>.input-group-append>.input-group-text,.input-group>.input-group-prepend:first-child>.btn:not(:first-child),.input-group>.input-group-prepend:first-child>.input-group-text:not(:first-child),.input-group>.input-group-prepend:not(:first-child)>.btn,.input-group>.input-group-prepend:not(:first-child)>.input-group-text{border-top-left-radius:0;border-bottom-left-radius:0}.custom-control{position:relative;z-index:1;display:block;min-height:1.5rem;padding-left:1.5rem;-webkit-print-color-adjust:exact;color-adjust:exact;print-color-adjust:exact}.custom-control-inline{display:-ms-inline-flexbox;display:inline-flex;margin-right:1rem}.custom-control-input{position:absolute;left:0;z-index:-1;width:1rem;height:1.25rem;opacity:0}.custom-control-input:checked~.custom-control-label::before{color:#fff;border-color:#007bff;background-color:#007bff}.custom-control-input:focus~.custom-control-label::before{box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.custom-control-input:focus:not(:checked)~.custom-control-label::before{border-color:#80bdff}.custom-control-input:not(:disabled):active~.custom-control-label::before{color:#fff;background-color:#b3d7ff;border-color:#b3d7ff}.custom-control-input:disabled~.custom-control-label,.custom-control-input[disabled]~.custom-control-label{color:#6c757d}.custom-control-input:disabled~.custom-control-label::before,.custom-control-input[disabled]~.custom-control-label::before{background-color:#e9ecef}.custom-control-label{position:relative;margin-bottom:0;vertical-align:top}.custom-control-label::before{position:absolute;top:.25rem;left:-1.5rem;display:block;width:1rem;height:1rem;pointer-events:none;content:"";background-color:#fff;border:1px solid #adb5bd}.custom-control-label::after{position:absolute;top:.25rem;left:-1.5rem;display:block;width:1rem;height:1rem;content:"";background:50%/50% 50% no-repeat}.custom-checkbox .custom-control-label::before{border-radius:.25rem}.custom-checkbox .custom-control-input:checked~.custom-control-label::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%23fff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26l2.974 2.99L8 2.193z'/%3e%3c/svg%3e")}.custom-checkbox .custom-control-input:indeterminate~.custom-control-label::before{border-color:#007bff;background-color:#007bff}.custom-checkbox .custom-control-input:indeterminate~.custom-control-label::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='4' viewBox='0 0 4 4'%3e%3cpath stroke='%23fff' d='M0 2h4'/%3e%3c/svg%3e")}.custom-checkbox .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-checkbox .custom-control-input:disabled:indeterminate~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-radio .custom-control-label::before{border-radius:50%}.custom-radio .custom-control-input:checked~.custom-control-label::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23fff'/%3e%3c/svg%3e")}.custom-radio .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-switch{padding-left:2.25rem}.custom-switch .custom-control-label::before{left:-2.25rem;width:1.75rem;pointer-events:all;border-radius:.5rem}.custom-switch .custom-control-label::after{top:calc(.25rem + 2px);left:calc(-2.25rem + 2px);width:calc(1rem - 4px);height:calc(1rem - 4px);background-color:#adb5bd;border-radius:.5rem;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out,-webkit-transform .15s ease-in-out;transition:transform .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:transform .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out,-webkit-transform .15s ease-in-out}@media (prefers-reduced-motion:reduce){.custom-switch .custom-control-label::after{transition:none}}.custom-switch .custom-control-input:checked~.custom-control-label::after{background-color:#fff;-webkit-transform:translateX(.75rem);transform:translateX(.75rem)}.custom-switch .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-select{display:inline-block;width:100%;height:calc(1.5em + .75rem + 2px);padding:.375rem 1.75rem .375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;vertical-align:middle;background:#fff url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") right .75rem center/8px 10px no-repeat;border:1px solid #ced4da;border-radius:.25rem;-webkit-appearance:none;-moz-appearance:none;appearance:none}.custom-select:focus{border-color:#80bdff;outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.custom-select:focus::-ms-value{color:#495057;background-color:#fff}.custom-select[multiple],.custom-select[size]:not([size="1"]){height:auto;padding-right:.75rem;background-image:none}.custom-select:disabled{color:#6c757d;background-color:#e9ecef}.custom-select::-ms-expand{display:none}.custom-select:-moz-focusring{color:transparent;text-shadow:0 0 0 #495057}.custom-select-sm{height:calc(1.5em + .5rem + 2px);padding-top:.25rem;padding-bottom:.25rem;padding-left:.5rem;font-size:.875rem}.custom-select-lg{height:calc(1.5em + 1rem + 2px);padding-top:.5rem;padding-bottom:.5rem;padding-left:1rem;font-size:1.25rem}.custom-file{position:relative;display:inline-block;width:100%;height:calc(1.5em + .75rem + 2px);margin-bottom:0}.custom-file-input{position:relative;z-index:2;width:100%;height:calc(1.5em + .75rem + 2px);margin:0;overflow:hidden;opacity:0}.custom-file-input:focus~.custom-file-label{border-color:#80bdff;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.custom-file-input:disabled~.custom-file-label,.custom-file-input[disabled]~.custom-file-label{background-color:#e9ecef}.custom-file-input:lang(en)~.custom-file-label::after{content:"Browse"}.custom-file-input~.custom-file-label[data-browse]::after{content:attr(data-browse)}.custom-file-label{position:absolute;top:0;right:0;left:0;z-index:1;height:calc(1.5em + .75rem + 2px);padding:.375rem .75rem;overflow:hidden;font-weight:400;line-height:1.5;color:#495057;background-color:#fff;border:1px solid #ced4da;border-radius:.25rem}.custom-file-label::after{position:absolute;top:0;right:0;bottom:0;z-index:3;display:block;height:calc(1.5em + .75rem);padding:.375rem .75rem;line-height:1.5;color:#495057;content:"Browse";background-color:#e9ecef;border-left:inherit;border-radius:0 .25rem .25rem 0}.custom-range{width:100%;height:1.4rem;padding:0;background-color:transparent;-webkit-appearance:none;-moz-appearance:none;appearance:none}.custom-range:focus{outline:0}.custom-range:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.custom-range:focus::-moz-range-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.custom-range:focus::-ms-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.custom-range::-moz-focus-outer{border:0}.custom-range::-webkit-slider-thumb{width:1rem;height:1rem;margin-top:-.25rem;background-color:#007bff;border:0;border-radius:1rem;-webkit-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;-webkit-appearance:none;appearance:none}@media (prefers-reduced-motion:reduce){.custom-range::-webkit-slider-thumb{-webkit-transition:none;transition:none}}.custom-range::-webkit-slider-thumb:active{background-color:#b3d7ff}.custom-range::-webkit-slider-runnable-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.custom-range::-moz-range-thumb{width:1rem;height:1rem;background-color:#007bff;border:0;border-radius:1rem;-moz-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;-moz-appearance:none;appearance:none}@media (prefers-reduced-motion:reduce){.custom-range::-moz-range-thumb{-moz-transition:none;transition:none}}.custom-range::-moz-range-thumb:active{background-color:#b3d7ff}.custom-range::-moz-range-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.custom-range::-ms-thumb{width:1rem;height:1rem;margin-top:0;margin-right:.2rem;margin-left:.2rem;background-color:#007bff;border:0;border-radius:1rem;-ms-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;appearance:none}@media (prefers-reduced-motion:reduce){.custom-range::-ms-thumb{-ms-transition:none;transition:none}}.custom-range::-ms-thumb:active{background-color:#b3d7ff}.custom-range::-ms-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:transparent;border-color:transparent;border-width:.5rem}.custom-range::-ms-fill-lower{background-color:#dee2e6;border-radius:1rem}.custom-range::-ms-fill-upper{margin-right:15px;background-color:#dee2e6;border-radius:1rem}.custom-range:disabled::-webkit-slider-thumb{background-color:#adb5bd}.custom-range:disabled::-webkit-slider-runnable-track{cursor:default}.custom-range:disabled::-moz-range-thumb{background-color:#adb5bd}.custom-range:disabled::-moz-range-track{cursor:default}.custom-range:disabled::-ms-thumb{background-color:#adb5bd}.custom-control-label::before,.custom-file-label,.custom-select{transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.custom-control-label::before,.custom-file-label,.custom-select{transition:none}}.nav{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;padding-left:0;margin-bottom:0;list-style:none}.nav-link{display:block;padding:.5rem 1rem}.nav-link:focus,.nav-link:hover{text-decoration:none}.nav-link.disabled{color:#6c757d;pointer-events:none;cursor:default}.nav-tabs{border-bottom:1px solid #dee2e6}.nav-tabs .nav-link{margin-bottom:-1px;background-color:transparent;border:1px solid transparent;border-top-left-radius:.25rem;border-top-right-radius:.25rem}.nav-tabs .nav-link:focus,.nav-tabs .nav-link:hover{isolation:isolate;border-color:#e9ecef #e9ecef #dee2e6}.nav-tabs .nav-link.disabled{color:#6c757d;background-color:transparent;border-color:transparent}.nav-tabs .nav-item.show .nav-link,.nav-tabs .nav-link.active{color:#495057;background-color:#fff;border-color:#dee2e6 #dee2e6 #fff}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.nav-pills .nav-link{background:0 0;border:0;border-radius:.25rem}.nav-pills .nav-link.active,.nav-pills .show>.nav-link{color:#fff;background-color:#007bff}.nav-fill .nav-item,.nav-fill>.nav-link{-ms-flex:1 1 auto;flex:1 1 auto;text-align:center}.nav-justified .nav-item,.nav-justified>.nav-link{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;text-align:center}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.navbar{position:relative;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:center;align-items:center;-ms-flex-pack:justify;justify-content:space-between;padding:.5rem 1rem}.navbar .container,.navbar .container-fluid,.navbar .container-lg,.navbar .container-md,.navbar .container-sm,.navbar .container-xl{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:center;align-items:center;-ms-flex-pack:justify;justify-content:space-between}.navbar-brand{display:inline-block;padding-top:.3125rem;padding-bottom:.3125rem;margin-right:1rem;font-size:1.25rem;line-height:inherit;white-space:nowrap}.navbar-brand:focus,.navbar-brand:hover{text-decoration:none}.navbar-nav{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;padding-left:0;margin-bottom:0;list-style:none}.navbar-nav .nav-link{padding-right:0;padding-left:0}.navbar-nav .dropdown-menu{position:static;float:none}.navbar-text{display:inline-block;padding-top:.5rem;padding-bottom:.5rem}.navbar-collapse{-ms-flex-preferred-size:100%;flex-basis:100%;-ms-flex-positive:1;flex-grow:1;-ms-flex-align:center;align-items:center}.navbar-toggler{padding:.25rem .75rem;font-size:1.25rem;line-height:1;background-color:transparent;border:1px solid transparent;border-radius:.25rem}.navbar-toggler:focus,.navbar-toggler:hover{text-decoration:none}.navbar-toggler-icon{display:inline-block;width:1.5em;height:1.5em;vertical-align:middle;content:"";background:50%/100% 100% no-repeat}.navbar-nav-scroll{max-height:75vh;overflow-y:auto}@media (max-width:575.98px){.navbar-expand-sm>.container,.navbar-expand-sm>.container-fluid,.navbar-expand-sm>.container-lg,.navbar-expand-sm>.container-md,.navbar-expand-sm>.container-sm,.navbar-expand-sm>.container-xl{padding-right:0;padding-left:0}}@media (min-width:576px){.navbar-expand-sm{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-sm .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-sm .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-sm .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-sm>.container,.navbar-expand-sm>.container-fluid,.navbar-expand-sm>.container-lg,.navbar-expand-sm>.container-md,.navbar-expand-sm>.container-sm,.navbar-expand-sm>.container-xl{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-sm .navbar-nav-scroll{overflow:visible}.navbar-expand-sm .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-sm .navbar-toggler{display:none}}@media (max-width:767.98px){.navbar-expand-md>.container,.navbar-expand-md>.container-fluid,.navbar-expand-md>.container-lg,.navbar-expand-md>.container-md,.navbar-expand-md>.container-sm,.navbar-expand-md>.container-xl{padding-right:0;padding-left:0}}@media (min-width:768px){.navbar-expand-md{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-md .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-md .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-md .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-md>.container,.navbar-expand-md>.container-fluid,.navbar-expand-md>.container-lg,.navbar-expand-md>.container-md,.navbar-expand-md>.container-sm,.navbar-expand-md>.container-xl{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-md .navbar-nav-scroll{overflow:visible}.navbar-expand-md .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-md .navbar-toggler{display:none}}@media (max-width:991.98px){.navbar-expand-lg>.container,.navbar-expand-lg>.container-fluid,.navbar-expand-lg>.container-lg,.navbar-expand-lg>.container-md,.navbar-expand-lg>.container-sm,.navbar-expand-lg>.container-xl{padding-right:0;padding-left:0}}@media (min-width:992px){.navbar-expand-lg{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-lg .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-lg .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-lg .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-lg>.container,.navbar-expand-lg>.container-fluid,.navbar-expand-lg>.container-lg,.navbar-expand-lg>.container-md,.navbar-expand-lg>.container-sm,.navbar-expand-lg>.container-xl{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-lg .navbar-nav-scroll{overflow:visible}.navbar-expand-lg .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-lg .navbar-toggler{display:none}}@media (max-width:1199.98px){.navbar-expand-xl>.container,.navbar-expand-xl>.container-fluid,.navbar-expand-xl>.container-lg,.navbar-expand-xl>.container-md,.navbar-expand-xl>.container-sm,.navbar-expand-xl>.container-xl{padding-right:0;padding-left:0}}@media (min-width:1200px){.navbar-expand-xl{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-xl .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-xl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xl .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-xl>.container,.navbar-expand-xl>.container-fluid,.navbar-expand-xl>.container-lg,.navbar-expand-xl>.container-md,.navbar-expand-xl>.container-sm,.navbar-expand-xl>.container-xl{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-xl .navbar-nav-scroll{overflow:visible}.navbar-expand-xl .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-xl .navbar-toggler{display:none}}.navbar-expand{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand>.container,.navbar-expand>.container-fluid,.navbar-expand>.container-lg,.navbar-expand>.container-md,.navbar-expand>.container-sm,.navbar-expand>.container-xl{padding-right:0;padding-left:0}.navbar-expand .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand .navbar-nav .dropdown-menu{position:absolute}.navbar-expand .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand>.container,.navbar-expand>.container-fluid,.navbar-expand>.container-lg,.navbar-expand>.container-md,.navbar-expand>.container-sm,.navbar-expand>.container-xl{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand .navbar-nav-scroll{overflow:visible}.navbar-expand .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand .navbar-toggler{display:none}.navbar-light .navbar-brand{color:rgba(0,0,0,.9)}.navbar-light .navbar-brand:focus,.navbar-light .navbar-brand:hover{color:rgba(0,0,0,.9)}.navbar-light .navbar-nav .nav-link{color:rgba(0,0,0,.5)}.navbar-light .navbar-nav .nav-link:focus,.navbar-light .navbar-nav .nav-link:hover{color:rgba(0,0,0,.7)}.navbar-light .navbar-nav .nav-link.disabled{color:rgba(0,0,0,.3)}.navbar-light .navbar-nav .active>.nav-link,.navbar-light .navbar-nav .nav-link.active,.navbar-light .navbar-nav .nav-link.show,.navbar-light .navbar-nav .show>.nav-link{color:rgba(0,0,0,.9)}.navbar-light .navbar-toggler{color:rgba(0,0,0,.5);border-color:rgba(0,0,0,.1)}.navbar-light .navbar-toggler-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='30' height='30' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%280, 0, 0, 0.5%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}.navbar-light .navbar-text{color:rgba(0,0,0,.5)}.navbar-light .navbar-text a{color:rgba(0,0,0,.9)}.navbar-light .navbar-text a:focus,.navbar-light .navbar-text a:hover{color:rgba(0,0,0,.9)}.navbar-dark .navbar-brand{color:#fff}.navbar-dark .navbar-brand:focus,.navbar-dark .navbar-brand:hover{color:#fff}.navbar-dark .navbar-nav .nav-link{color:rgba(255,255,255,.5)}.navbar-dark .navbar-nav .nav-link:focus,.navbar-dark .navbar-nav .nav-link:hover{color:rgba(255,255,255,.75)}.navbar-dark .navbar-nav .nav-link.disabled{color:rgba(255,255,255,.25)}.navbar-dark .navbar-nav .active>.nav-link,.navbar-dark .navbar-nav .nav-link.active,.navbar-dark .navbar-nav .nav-link.show,.navbar-dark .navbar-nav .show>.nav-link{color:#fff}.navbar-dark .navbar-toggler{color:rgba(255,255,255,.5);border-color:rgba(255,255,255,.1)}.navbar-dark .navbar-toggler-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='30' height='30' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.5%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}.navbar-dark .navbar-text{color:rgba(255,255,255,.5)}.navbar-dark .navbar-text a{color:#fff}.navbar-dark .navbar-text a:focus,.navbar-dark .navbar-text a:hover{color:#fff}.card{position:relative;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;min-width:0;word-wrap:break-word;background-color:#fff;background-clip:border-box;border:1px solid rgba(0,0,0,.125);border-radius:.25rem}.card>hr{margin-right:0;margin-left:0}.card>.list-group{border-top:inherit;border-bottom:inherit}.card>.list-group:first-child{border-top-width:0;border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px)}.card>.list-group:last-child{border-bottom-width:0;border-bottom-right-radius:calc(.25rem - 1px);border-bottom-left-radius:calc(.25rem - 1px)}.card>.card-header+.list-group,.card>.list-group+.card-footer{border-top:0}.card-body{-ms-flex:1 1 auto;flex:1 1 auto;min-height:1px;padding:1.25rem}.card-title{margin-bottom:.75rem}.card-subtitle{margin-top:-.375rem;margin-bottom:0}.card-text:last-child{margin-bottom:0}.card-link:hover{text-decoration:none}.card-link+.card-link{margin-left:1.25rem}.card-header{padding:.75rem 1.25rem;margin-bottom:0;background-color:rgba(0,0,0,.03);border-bottom:1px solid rgba(0,0,0,.125)}.card-header:first-child{border-radius:calc(.25rem - 1px) calc(.25rem - 1px) 0 0}.card-footer{padding:.75rem 1.25rem;background-color:rgba(0,0,0,.03);border-top:1px solid rgba(0,0,0,.125)}.card-footer:last-child{border-radius:0 0 calc(.25rem - 1px) calc(.25rem - 1px)}.card-header-tabs{margin-right:-.625rem;margin-bottom:-.75rem;margin-left:-.625rem;border-bottom:0}.card-header-pills{margin-right:-.625rem;margin-left:-.625rem}.card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:1.25rem;border-radius:calc(.25rem - 1px)}.card-img,.card-img-bottom,.card-img-top{-ms-flex-negative:0;flex-shrink:0;width:100%}.card-img,.card-img-top{border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px)}.card-img,.card-img-bottom{border-bottom-right-radius:calc(.25rem - 1px);border-bottom-left-radius:calc(.25rem - 1px)}.card-deck .card{margin-bottom:15px}@media (min-width:576px){.card-deck{display:-ms-flexbox;display:flex;-ms-flex-flow:row wrap;flex-flow:row wrap;margin-right:-15px;margin-left:-15px}.card-deck .card{-ms-flex:1 0 0%;flex:1 0 0%;margin-right:15px;margin-bottom:0;margin-left:15px}}.card-group>.card{margin-bottom:15px}@media (min-width:576px){.card-group{display:-ms-flexbox;display:flex;-ms-flex-flow:row wrap;flex-flow:row wrap}.card-group>.card{-ms-flex:1 0 0%;flex:1 0 0%;margin-bottom:0}.card-group>.card+.card{margin-left:0;border-left:0}.card-group>.card:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.card-group>.card:not(:last-child) .card-header,.card-group>.card:not(:last-child) .card-img-top{border-top-right-radius:0}.card-group>.card:not(:last-child) .card-footer,.card-group>.card:not(:last-child) .card-img-bottom{border-bottom-right-radius:0}.card-group>.card:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.card-group>.card:not(:first-child) .card-header,.card-group>.card:not(:first-child) .card-img-top{border-top-left-radius:0}.card-group>.card:not(:first-child) .card-footer,.card-group>.card:not(:first-child) .card-img-bottom{border-bottom-left-radius:0}}.card-columns .card{margin-bottom:.75rem}@media (min-width:576px){.card-columns{-webkit-column-count:3;-moz-column-count:3;column-count:3;-webkit-column-gap:1.25rem;-moz-column-gap:1.25rem;column-gap:1.25rem;orphans:1;widows:1}.card-columns .card{display:inline-block;width:100%}}.accordion{overflow-anchor:none}.accordion>.card{overflow:hidden}.accordion>.card:not(:last-of-type){border-bottom:0;border-bottom-right-radius:0;border-bottom-left-radius:0}.accordion>.card:not(:first-of-type){border-top-left-radius:0;border-top-right-radius:0}.accordion>.card>.card-header{border-radius:0;margin-bottom:-1px}.breadcrumb{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;padding:.75rem 1rem;margin-bottom:1rem;list-style:none;background-color:#e9ecef;border-radius:.25rem}.breadcrumb-item+.breadcrumb-item{padding-left:.5rem}.breadcrumb-item+.breadcrumb-item::before{float:left;padding-right:.5rem;color:#6c757d;content:"/"}.breadcrumb-item+.breadcrumb-item:hover::before{text-decoration:underline}.breadcrumb-item+.breadcrumb-item:hover::before{text-decoration:none}.breadcrumb-item.active{color:#6c757d}.pagination{display:-ms-flexbox;display:flex;padding-left:0;list-style:none;border-radius:.25rem}.page-link{position:relative;display:block;padding:.5rem .75rem;margin-left:-1px;line-height:1.25;color:#007bff;background-color:#fff;border:1px solid #dee2e6}.page-link:hover{z-index:2;color:#0056b3;text-decoration:none;background-color:#e9ecef;border-color:#dee2e6}.page-link:focus{z-index:3;outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.page-item:first-child .page-link{margin-left:0;border-top-left-radius:.25rem;border-bottom-left-radius:.25rem}.page-item:last-child .page-link{border-top-right-radius:.25rem;border-bottom-right-radius:.25rem}.page-item.active .page-link{z-index:3;color:#fff;background-color:#007bff;border-color:#007bff}.page-item.disabled .page-link{color:#6c757d;pointer-events:none;cursor:auto;background-color:#fff;border-color:#dee2e6}.pagination-lg .page-link{padding:.75rem 1.5rem;font-size:1.25rem;line-height:1.5}.pagination-lg .page-item:first-child .page-link{border-top-left-radius:.3rem;border-bottom-left-radius:.3rem}.pagination-lg .page-item:last-child .page-link{border-top-right-radius:.3rem;border-bottom-right-radius:.3rem}.pagination-sm .page-link{padding:.25rem .5rem;font-size:.875rem;line-height:1.5}.pagination-sm .page-item:first-child .page-link{border-top-left-radius:.2rem;border-bottom-left-radius:.2rem}.pagination-sm .page-item:last-child .page-link{border-top-right-radius:.2rem;border-bottom-right-radius:.2rem}.badge{display:inline-block;padding:.25em .4em;font-size:75%;font-weight:700;line-height:1;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25rem;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.badge{transition:none}}a.badge:focus,a.badge:hover{text-decoration:none}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.badge-pill{padding-right:.6em;padding-left:.6em;border-radius:10rem}.badge-primary{color:#fff;background-color:#007bff}a.badge-primary:focus,a.badge-primary:hover{color:#fff;background-color:#0062cc}a.badge-primary.focus,a.badge-primary:focus{outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.badge-secondary{color:#fff;background-color:#6c757d}a.badge-secondary:focus,a.badge-secondary:hover{color:#fff;background-color:#545b62}a.badge-secondary.focus,a.badge-secondary:focus{outline:0;box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.badge-success{color:#fff;background-color:#28a745}a.badge-success:focus,a.badge-success:hover{color:#fff;background-color:#1e7e34}a.badge-success.focus,a.badge-success:focus{outline:0;box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.badge-info{color:#fff;background-color:#17a2b8}a.badge-info:focus,a.badge-info:hover{color:#fff;background-color:#117a8b}a.badge-info.focus,a.badge-info:focus{outline:0;box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.badge-warning{color:#212529;background-color:#ffc107}a.badge-warning:focus,a.badge-warning:hover{color:#212529;background-color:#d39e00}a.badge-warning.focus,a.badge-warning:focus{outline:0;box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.badge-danger{color:#fff;background-color:#dc3545}a.badge-danger:focus,a.badge-danger:hover{color:#fff;background-color:#bd2130}a.badge-danger.focus,a.badge-danger:focus{outline:0;box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.badge-light{color:#212529;background-color:#f8f9fa}a.badge-light:focus,a.badge-light:hover{color:#212529;background-color:#dae0e5}a.badge-light.focus,a.badge-light:focus{outline:0;box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.badge-dark{color:#fff;background-color:#343a40}a.badge-dark:focus,a.badge-dark:hover{color:#fff;background-color:#1d2124}a.badge-dark.focus,a.badge-dark:focus{outline:0;box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.jumbotron{padding:2rem 1rem;margin-bottom:2rem;background-color:#e9ecef;border-radius:.3rem}@media (min-width:576px){.jumbotron{padding:4rem 2rem}}.jumbotron-fluid{padding-right:0;padding-left:0;border-radius:0}.alert{position:relative;padding:.75rem 1.25rem;margin-bottom:1rem;border:1px solid transparent;border-radius:.25rem}.alert-heading{color:inherit}.alert-link{font-weight:700}.alert-dismissible{padding-right:4rem}.alert-dismissible .close{position:absolute;top:0;right:0;z-index:2;padding:.75rem 1.25rem;color:inherit}.alert-primary{color:#004085;background-color:#cce5ff;border-color:#b8daff}.alert-primary hr{border-top-color:#9fcdff}.alert-primary .alert-link{color:#002752}.alert-secondary{color:#383d41;background-color:#e2e3e5;border-color:#d6d8db}.alert-secondary hr{border-top-color:#c8cbcf}.alert-secondary .alert-link{color:#202326}.alert-success{color:#155724;background-color:#d4edda;border-color:#c3e6cb}.alert-success hr{border-top-color:#b1dfbb}.alert-success .alert-link{color:#0b2e13}.alert-info{color:#0c5460;background-color:#d1ecf1;border-color:#bee5eb}.alert-info hr{border-top-color:#abdde5}.alert-info .alert-link{color:#062c33}.alert-warning{color:#856404;background-color:#fff3cd;border-color:#ffeeba}.alert-warning hr{border-top-color:#ffe8a1}.alert-warning .alert-link{color:#533f03}.alert-danger{color:#721c24;background-color:#f8d7da;border-color:#f5c6cb}.alert-danger hr{border-top-color:#f1b0b7}.alert-danger .alert-link{color:#491217}.alert-light{color:#818182;background-color:#fefefe;border-color:#fdfdfe}.alert-light hr{border-top-color:#ececf6}.alert-light .alert-link{color:#686868}.alert-dark{color:#1b1e21;background-color:#d6d8d9;border-color:#c6c8ca}.alert-dark hr{border-top-color:#b9bbbe}.alert-dark .alert-link{color:#040505}@-webkit-keyframes progress-bar-stripes{from{background-position:1rem 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:1rem 0}to{background-position:0 0}}.progress{display:-ms-flexbox;display:flex;height:1rem;overflow:hidden;line-height:0;font-size:.75rem;background-color:#e9ecef;border-radius:.25rem}.progress-bar{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;-ms-flex-pack:center;justify-content:center;overflow:hidden;color:#fff;text-align:center;white-space:nowrap;background-color:#007bff;transition:width .6s ease}@media (prefers-reduced-motion:reduce){.progress-bar{transition:none}}.progress-bar-striped{background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-size:1rem 1rem}.progress-bar-animated{-webkit-animation:1s linear infinite progress-bar-stripes;animation:1s linear infinite progress-bar-stripes}@media (prefers-reduced-motion:reduce){.progress-bar-animated{-webkit-animation:none;animation:none}}.media{display:-ms-flexbox;display:flex;-ms-flex-align:start;align-items:flex-start}.media-body{-ms-flex:1;flex:1}.list-group{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;padding-left:0;margin-bottom:0;border-radius:.25rem}.list-group-item-action{width:100%;color:#495057;text-align:inherit}.list-group-item-action:focus,.list-group-item-action:hover{z-index:1;color:#495057;text-decoration:none;background-color:#f8f9fa}.list-group-item-action:active{color:#212529;background-color:#e9ecef}.list-group-item{position:relative;display:block;padding:.75rem 1.25rem;background-color:#fff;border:1px solid rgba(0,0,0,.125)}.list-group-item:first-child{border-top-left-radius:inherit;border-top-right-radius:inherit}.list-group-item:last-child{border-bottom-right-radius:inherit;border-bottom-left-radius:inherit}.list-group-item.disabled,.list-group-item:disabled{color:#6c757d;pointer-events:none;background-color:#fff}.list-group-item.active{z-index:2;color:#fff;background-color:#007bff;border-color:#007bff}.list-group-item+.list-group-item{border-top-width:0}.list-group-item+.list-group-item.active{margin-top:-1px;border-top-width:1px}.list-group-horizontal{-ms-flex-direction:row;flex-direction:row}.list-group-horizontal>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal>.list-group-item.active{margin-top:0}.list-group-horizontal>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}@media (min-width:576px){.list-group-horizontal-sm{-ms-flex-direction:row;flex-direction:row}.list-group-horizontal-sm>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-sm>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-sm>.list-group-item.active{margin-top:0}.list-group-horizontal-sm>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-sm>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width:768px){.list-group-horizontal-md{-ms-flex-direction:row;flex-direction:row}.list-group-horizontal-md>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-md>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-md>.list-group-item.active{margin-top:0}.list-group-horizontal-md>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-md>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width:992px){.list-group-horizontal-lg{-ms-flex-direction:row;flex-direction:row}.list-group-horizontal-lg>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-lg>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-lg>.list-group-item.active{margin-top:0}.list-group-horizontal-lg>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-lg>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width:1200px){.list-group-horizontal-xl{-ms-flex-direction:row;flex-direction:row}.list-group-horizontal-xl>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-xl>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-xl>.list-group-item.active{margin-top:0}.list-group-horizontal-xl>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-xl>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}.list-group-flush{border-radius:0}.list-group-flush>.list-group-item{border-width:0 0 1px}.list-group-flush>.list-group-item:last-child{border-bottom-width:0}.list-group-item-primary{color:#004085;background-color:#b8daff}.list-group-item-primary.list-group-item-action:focus,.list-group-item-primary.list-group-item-action:hover{color:#004085;background-color:#9fcdff}.list-group-item-primary.list-group-item-action.active{color:#fff;background-color:#004085;border-color:#004085}.list-group-item-secondary{color:#383d41;background-color:#d6d8db}.list-group-item-secondary.list-group-item-action:focus,.list-group-item-secondary.list-group-item-action:hover{color:#383d41;background-color:#c8cbcf}.list-group-item-secondary.list-group-item-action.active{color:#fff;background-color:#383d41;border-color:#383d41}.list-group-item-success{color:#155724;background-color:#c3e6cb}.list-group-item-success.list-group-item-action:focus,.list-group-item-success.list-group-item-action:hover{color:#155724;background-color:#b1dfbb}.list-group-item-success.list-group-item-action.active{color:#fff;background-color:#155724;border-color:#155724}.list-group-item-info{color:#0c5460;background-color:#bee5eb}.list-group-item-info.list-group-item-action:focus,.list-group-item-info.list-group-item-action:hover{color:#0c5460;background-color:#abdde5}.list-group-item-info.list-group-item-action.active{color:#fff;background-color:#0c5460;border-color:#0c5460}.list-group-item-warning{color:#856404;background-color:#ffeeba}.list-group-item-warning.list-group-item-action:focus,.list-group-item-warning.list-group-item-action:hover{color:#856404;background-color:#ffe8a1}.list-group-item-warning.list-group-item-action.active{color:#fff;background-color:#856404;border-color:#856404}.list-group-item-danger{color:#721c24;background-color:#f5c6cb}.list-group-item-danger.list-group-item-action:focus,.list-group-item-danger.list-group-item-action:hover{color:#721c24;background-color:#f1b0b7}.list-group-item-danger.list-group-item-action.active{color:#fff;background-color:#721c24;border-color:#721c24}.list-group-item-light{color:#818182;background-color:#fdfdfe}.list-group-item-light.list-group-item-action:focus,.list-group-item-light.list-group-item-action:hover{color:#818182;background-color:#ececf6}.list-group-item-light.list-group-item-action.active{color:#fff;background-color:#818182;border-color:#818182}.list-group-item-dark{color:#1b1e21;background-color:#c6c8ca}.list-group-item-dark.list-group-item-action:focus,.list-group-item-dark.list-group-item-action:hover{color:#1b1e21;background-color:#b9bbbe}.list-group-item-dark.list-group-item-action.active{color:#fff;background-color:#1b1e21;border-color:#1b1e21}.close{float:right;font-size:1.5rem;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;opacity:.5}.close:hover{color:#000;text-decoration:none}.close:not(:disabled):not(.disabled):focus,.close:not(:disabled):not(.disabled):hover{opacity:.75}button.close{padding:0;background-color:transparent;border:0}a.close.disabled{pointer-events:none}.toast{-ms-flex-preferred-size:350px;flex-basis:350px;max-width:350px;font-size:.875rem;background-color:rgba(255,255,255,.85);background-clip:padding-box;border:1px solid rgba(0,0,0,.1);box-shadow:0 .25rem .75rem rgba(0,0,0,.1);opacity:0;border-radius:.25rem}.toast:not(:last-child){margin-bottom:.75rem}.toast.showing{opacity:1}.toast.show{display:block;opacity:1}.toast.hide{display:none}.toast-header{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;padding:.25rem .75rem;color:#6c757d;background-color:rgba(255,255,255,.85);background-clip:padding-box;border-bottom:1px solid rgba(0,0,0,.05);border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px)}.toast-body{padding:.75rem}.modal-open{overflow:hidden}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal{position:fixed;top:0;left:0;z-index:1050;display:none;width:100%;height:100%;overflow:hidden;outline:0}.modal-dialog{position:relative;width:auto;margin:.5rem;pointer-events:none}.modal.fade .modal-dialog{transition:-webkit-transform .3s ease-out;transition:transform .3s ease-out;transition:transform .3s ease-out,-webkit-transform .3s ease-out;-webkit-transform:translate(0,-50px);transform:translate(0,-50px)}@media (prefers-reduced-motion:reduce){.modal.fade .modal-dialog{transition:none}}.modal.show .modal-dialog{-webkit-transform:none;transform:none}.modal.modal-static .modal-dialog{-webkit-transform:scale(1.02);transform:scale(1.02)}.modal-dialog-scrollable{display:-ms-flexbox;display:flex;max-height:calc(100% - 1rem)}.modal-dialog-scrollable .modal-content{max-height:calc(100vh - 1rem);overflow:hidden}.modal-dialog-scrollable .modal-footer,.modal-dialog-scrollable .modal-header{-ms-flex-negative:0;flex-shrink:0}.modal-dialog-scrollable .modal-body{overflow-y:auto}.modal-dialog-centered{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;min-height:calc(100% - 1rem)}.modal-dialog-centered::before{display:block;height:calc(100vh - 1rem);height:-webkit-min-content;height:-moz-min-content;height:min-content;content:""}.modal-dialog-centered.modal-dialog-scrollable{-ms-flex-direction:column;flex-direction:column;-ms-flex-pack:center;justify-content:center;height:100%}.modal-dialog-centered.modal-dialog-scrollable .modal-content{max-height:none}.modal-dialog-centered.modal-dialog-scrollable::before{content:none}.modal-content{position:relative;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;width:100%;pointer-events:auto;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem;outline:0}.modal-backdrop{position:fixed;top:0;left:0;z-index:1040;width:100vw;height:100vh;background-color:#000}.modal-backdrop.fade{opacity:0}.modal-backdrop.show{opacity:.5}.modal-header{display:-ms-flexbox;display:flex;-ms-flex-align:start;align-items:flex-start;-ms-flex-pack:justify;justify-content:space-between;padding:1rem 1rem;border-bottom:1px solid #dee2e6;border-top-left-radius:calc(.3rem - 1px);border-top-right-radius:calc(.3rem - 1px)}.modal-header .close{padding:1rem 1rem;margin:-1rem -1rem -1rem auto}.modal-title{margin-bottom:0;line-height:1.5}.modal-body{position:relative;-ms-flex:1 1 auto;flex:1 1 auto;padding:1rem}.modal-footer{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:center;align-items:center;-ms-flex-pack:end;justify-content:flex-end;padding:.75rem;border-top:1px solid #dee2e6;border-bottom-right-radius:calc(.3rem - 1px);border-bottom-left-radius:calc(.3rem - 1px)}.modal-footer>*{margin:.25rem}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:576px){.modal-dialog{max-width:500px;margin:1.75rem auto}.modal-dialog-scrollable{max-height:calc(100% - 3.5rem)}.modal-dialog-scrollable .modal-content{max-height:calc(100vh - 3.5rem)}.modal-dialog-centered{min-height:calc(100% - 3.5rem)}.modal-dialog-centered::before{height:calc(100vh - 3.5rem);height:-webkit-min-content;height:-moz-min-content;height:min-content}.modal-sm{max-width:300px}}@media (min-width:992px){.modal-lg,.modal-xl{max-width:800px}}@media (min-width:1200px){.modal-xl{max-width:1140px}}.tooltip{position:absolute;z-index:1070;display:block;margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans","Liberation Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;white-space:normal;word-spacing:normal;line-break:auto;font-size:.875rem;word-wrap:break-word;opacity:0}.tooltip.show{opacity:.9}.tooltip .arrow{position:absolute;display:block;width:.8rem;height:.4rem}.tooltip .arrow::before{position:absolute;content:"";border-color:transparent;border-style:solid}.bs-tooltip-auto[x-placement^=top],.bs-tooltip-top{padding:.4rem 0}.bs-tooltip-auto[x-placement^=top] .arrow,.bs-tooltip-top .arrow{bottom:0}.bs-tooltip-auto[x-placement^=top] .arrow::before,.bs-tooltip-top .arrow::before{top:0;border-width:.4rem .4rem 0;border-top-color:#000}.bs-tooltip-auto[x-placement^=right],.bs-tooltip-right{padding:0 .4rem}.bs-tooltip-auto[x-placement^=right] .arrow,.bs-tooltip-right .arrow{left:0;width:.4rem;height:.8rem}.bs-tooltip-auto[x-placement^=right] .arrow::before,.bs-tooltip-right .arrow::before{right:0;border-width:.4rem .4rem .4rem 0;border-right-color:#000}.bs-tooltip-auto[x-placement^=bottom],.bs-tooltip-bottom{padding:.4rem 0}.bs-tooltip-auto[x-placement^=bottom] .arrow,.bs-tooltip-bottom .arrow{top:0}.bs-tooltip-auto[x-placement^=bottom] .arrow::before,.bs-tooltip-bottom .arrow::before{bottom:0;border-width:0 .4rem .4rem;border-bottom-color:#000}.bs-tooltip-auto[x-placement^=left],.bs-tooltip-left{padding:0 .4rem}.bs-tooltip-auto[x-placement^=left] .arrow,.bs-tooltip-left .arrow{right:0;width:.4rem;height:.8rem}.bs-tooltip-auto[x-placement^=left] .arrow::before,.bs-tooltip-left .arrow::before{left:0;border-width:.4rem 0 .4rem .4rem;border-left-color:#000}.tooltip-inner{max-width:200px;padding:.25rem .5rem;color:#fff;text-align:center;background-color:#000;border-radius:.25rem}.popover{position:absolute;top:0;left:0;z-index:1060;display:block;max-width:276px;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans","Liberation Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;white-space:normal;word-spacing:normal;line-break:auto;font-size:.875rem;word-wrap:break-word;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem}.popover .arrow{position:absolute;display:block;width:1rem;height:.5rem;margin:0 .3rem}.popover .arrow::after,.popover .arrow::before{position:absolute;display:block;content:"";border-color:transparent;border-style:solid}.bs-popover-auto[x-placement^=top],.bs-popover-top{margin-bottom:.5rem}.bs-popover-auto[x-placement^=top]>.arrow,.bs-popover-top>.arrow{bottom:calc(-.5rem - 1px)}.bs-popover-auto[x-placement^=top]>.arrow::before,.bs-popover-top>.arrow::before{bottom:0;border-width:.5rem .5rem 0;border-top-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=top]>.arrow::after,.bs-popover-top>.arrow::after{bottom:1px;border-width:.5rem .5rem 0;border-top-color:#fff}.bs-popover-auto[x-placement^=right],.bs-popover-right{margin-left:.5rem}.bs-popover-auto[x-placement^=right]>.arrow,.bs-popover-right>.arrow{left:calc(-.5rem - 1px);width:.5rem;height:1rem;margin:.3rem 0}.bs-popover-auto[x-placement^=right]>.arrow::before,.bs-popover-right>.arrow::before{left:0;border-width:.5rem .5rem .5rem 0;border-right-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=right]>.arrow::after,.bs-popover-right>.arrow::after{left:1px;border-width:.5rem .5rem .5rem 0;border-right-color:#fff}.bs-popover-auto[x-placement^=bottom],.bs-popover-bottom{margin-top:.5rem}.bs-popover-auto[x-placement^=bottom]>.arrow,.bs-popover-bottom>.arrow{top:calc(-.5rem - 1px)}.bs-popover-auto[x-placement^=bottom]>.arrow::before,.bs-popover-bottom>.arrow::before{top:0;border-width:0 .5rem .5rem .5rem;border-bottom-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=bottom]>.arrow::after,.bs-popover-bottom>.arrow::after{top:1px;border-width:0 .5rem .5rem .5rem;border-bottom-color:#fff}.bs-popover-auto[x-placement^=bottom] .popover-header::before,.bs-popover-bottom .popover-header::before{position:absolute;top:0;left:50%;display:block;width:1rem;margin-left:-.5rem;content:"";border-bottom:1px solid #f7f7f7}.bs-popover-auto[x-placement^=left],.bs-popover-left{margin-right:.5rem}.bs-popover-auto[x-placement^=left]>.arrow,.bs-popover-left>.arrow{right:calc(-.5rem - 1px);width:.5rem;height:1rem;margin:.3rem 0}.bs-popover-auto[x-placement^=left]>.arrow::before,.bs-popover-left>.arrow::before{right:0;border-width:.5rem 0 .5rem .5rem;border-left-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=left]>.arrow::after,.bs-popover-left>.arrow::after{right:1px;border-width:.5rem 0 .5rem .5rem;border-left-color:#fff}.popover-header{padding:.5rem .75rem;margin-bottom:0;font-size:1rem;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-top-left-radius:calc(.3rem - 1px);border-top-right-radius:calc(.3rem - 1px)}.popover-header:empty{display:none}.popover-body{padding:.5rem .75rem;color:#212529}.carousel{position:relative}.carousel.pointer-event{-ms-touch-action:pan-y;touch-action:pan-y}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner::after{display:block;clear:both;content:""}.carousel-item{position:relative;display:none;float:left;width:100%;margin-right:-100%;-webkit-backface-visibility:hidden;backface-visibility:hidden;transition:-webkit-transform .6s ease-in-out;transition:transform .6s ease-in-out;transition:transform .6s ease-in-out,-webkit-transform .6s ease-in-out}@media (prefers-reduced-motion:reduce){.carousel-item{transition:none}}.carousel-item-next,.carousel-item-prev,.carousel-item.active{display:block}.active.carousel-item-right,.carousel-item-next:not(.carousel-item-left){-webkit-transform:translateX(100%);transform:translateX(100%)}.active.carousel-item-left,.carousel-item-prev:not(.carousel-item-right){-webkit-transform:translateX(-100%);transform:translateX(-100%)}.carousel-fade .carousel-item{opacity:0;transition-property:opacity;-webkit-transform:none;transform:none}.carousel-fade .carousel-item-next.carousel-item-left,.carousel-fade .carousel-item-prev.carousel-item-right,.carousel-fade .carousel-item.active{z-index:1;opacity:1}.carousel-fade .active.carousel-item-left,.carousel-fade .active.carousel-item-right{z-index:0;opacity:0;transition:opacity 0s .6s}@media (prefers-reduced-motion:reduce){.carousel-fade .active.carousel-item-left,.carousel-fade .active.carousel-item-right{transition:none}}.carousel-control-next,.carousel-control-prev{position:absolute;top:0;bottom:0;z-index:1;display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;width:15%;padding:0;color:#fff;text-align:center;background:0 0;border:0;opacity:.5;transition:opacity .15s ease}@media (prefers-reduced-motion:reduce){.carousel-control-next,.carousel-control-prev{transition:none}}.carousel-control-next:focus,.carousel-control-next:hover,.carousel-control-prev:focus,.carousel-control-prev:hover{color:#fff;text-decoration:none;outline:0;opacity:.9}.carousel-control-prev{left:0}.carousel-control-next{right:0}.carousel-control-next-icon,.carousel-control-prev-icon{display:inline-block;width:20px;height:20px;background:50%/100% 100% no-repeat}.carousel-control-prev-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath d='M5.25 0l-4 4 4 4 1.5-1.5L4.25 4l2.5-2.5L5.25 0z'/%3e%3c/svg%3e")}.carousel-control-next-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath d='M2.75 0l-1.5 1.5L3.75 4l-2.5 2.5L2.75 8l4-4-4-4z'/%3e%3c/svg%3e")}.carousel-indicators{position:absolute;right:0;bottom:0;left:0;z-index:15;display:-ms-flexbox;display:flex;-ms-flex-pack:center;justify-content:center;padding-left:0;margin-right:15%;margin-left:15%;list-style:none}.carousel-indicators li{box-sizing:content-box;-ms-flex:0 1 auto;flex:0 1 auto;width:30px;height:3px;margin-right:3px;margin-left:3px;text-indent:-999px;cursor:pointer;background-color:#fff;background-clip:padding-box;border-top:10px solid transparent;border-bottom:10px solid transparent;opacity:.5;transition:opacity .6s ease}@media (prefers-reduced-motion:reduce){.carousel-indicators li{transition:none}}.carousel-indicators .active{opacity:1}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center}@-webkit-keyframes spinner-border{to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes spinner-border{to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}.spinner-border{display:inline-block;width:2rem;height:2rem;vertical-align:-.125em;border:.25em solid currentcolor;border-right-color:transparent;border-radius:50%;-webkit-animation:.75s linear infinite spinner-border;animation:.75s linear infinite spinner-border}.spinner-border-sm{width:1rem;height:1rem;border-width:.2em}@-webkit-keyframes spinner-grow{0%{-webkit-transform:scale(0);transform:scale(0)}50%{opacity:1;-webkit-transform:none;transform:none}}@keyframes spinner-grow{0%{-webkit-transform:scale(0);transform:scale(0)}50%{opacity:1;-webkit-transform:none;transform:none}}.spinner-grow{display:inline-block;width:2rem;height:2rem;vertical-align:-.125em;background-color:currentcolor;border-radius:50%;opacity:0;-webkit-animation:.75s linear infinite spinner-grow;animation:.75s linear infinite spinner-grow}.spinner-grow-sm{width:1rem;height:1rem}@media (prefers-reduced-motion:reduce){.spinner-border,.spinner-grow{-webkit-animation-duration:1.5s;animation-duration:1.5s}}.align-baseline{vertical-align:baseline!important}.align-top{vertical-align:top!important}.align-middle{vertical-align:middle!important}.align-bottom{vertical-align:bottom!important}.align-text-bottom{vertical-align:text-bottom!important}.align-text-top{vertical-align:text-top!important}.bg-primary{background-color:#007bff!important}a.bg-primary:focus,a.bg-primary:hover,button.bg-primary:focus,button.bg-primary:hover{background-color:#0062cc!important}.bg-secondary{background-color:#6c757d!important}a.bg-secondary:focus,a.bg-secondary:hover,button.bg-secondary:focus,button.bg-secondary:hover{background-color:#545b62!important}.bg-success{background-color:#28a745!important}a.bg-success:focus,a.bg-success:hover,button.bg-success:focus,button.bg-success:hover{background-color:#1e7e34!important}.bg-info{background-color:#17a2b8!important}a.bg-info:focus,a.bg-info:hover,button.bg-info:focus,button.bg-info:hover{background-color:#117a8b!important}.bg-warning{background-color:#ffc107!important}a.bg-warning:focus,a.bg-warning:hover,button.bg-warning:focus,button.bg-warning:hover{background-color:#d39e00!important}.bg-danger{background-color:#dc3545!important}a.bg-danger:focus,a.bg-danger:hover,button.bg-danger:focus,button.bg-danger:hover{background-color:#bd2130!important}.bg-light{background-color:#f8f9fa!important}a.bg-light:focus,a.bg-light:hover,button.bg-light:focus,button.bg-light:hover{background-color:#dae0e5!important}.bg-dark{background-color:#343a40!important}a.bg-dark:focus,a.bg-dark:hover,button.bg-dark:focus,button.bg-dark:hover{background-color:#1d2124!important}.bg-white{background-color:#fff!important}.bg-transparent{background-color:transparent!important}.border{border:1px solid #dee2e6!important}.border-top{border-top:1px solid #dee2e6!important}.border-right{border-right:1px solid #dee2e6!important}.border-bottom{border-bottom:1px solid #dee2e6!important}.border-left{border-left:1px solid #dee2e6!important}.border-0{border:0!important}.border-top-0{border-top:0!important}.border-right-0{border-right:0!important}.border-bottom-0{border-bottom:0!important}.border-left-0{border-left:0!important}.border-primary{border-color:#007bff!important}.border-secondary{border-color:#6c757d!important}.border-success{border-color:#28a745!important}.border-info{border-color:#17a2b8!important}.border-warning{border-color:#ffc107!important}.border-danger{border-color:#dc3545!important}.border-light{border-color:#f8f9fa!important}.border-dark{border-color:#343a40!important}.border-white{border-color:#fff!important}.rounded-sm{border-radius:.2rem!important}.rounded{border-radius:.25rem!important}.rounded-top{border-top-left-radius:.25rem!important;border-top-right-radius:.25rem!important}.rounded-right{border-top-right-radius:.25rem!important;border-bottom-right-radius:.25rem!important}.rounded-bottom{border-bottom-right-radius:.25rem!important;border-bottom-left-radius:.25rem!important}.rounded-left{border-top-left-radius:.25rem!important;border-bottom-left-radius:.25rem!important}.rounded-lg{border-radius:.3rem!important}.rounded-circle{border-radius:50%!important}.rounded-pill{border-radius:50rem!important}.rounded-0{border-radius:0!important}.clearfix::after{display:block;clear:both;content:""}.d-none{display:none!important}.d-inline{display:inline!important}.d-inline-block{display:inline-block!important}.d-block{display:block!important}.d-table{display:table!important}.d-table-row{display:table-row!important}.d-table-cell{display:table-cell!important}.d-flex{display:-ms-flexbox!important;display:flex!important}.d-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}@media (min-width:576px){.d-sm-none{display:none!important}.d-sm-inline{display:inline!important}.d-sm-inline-block{display:inline-block!important}.d-sm-block{display:block!important}.d-sm-table{display:table!important}.d-sm-table-row{display:table-row!important}.d-sm-table-cell{display:table-cell!important}.d-sm-flex{display:-ms-flexbox!important;display:flex!important}.d-sm-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:768px){.d-md-none{display:none!important}.d-md-inline{display:inline!important}.d-md-inline-block{display:inline-block!important}.d-md-block{display:block!important}.d-md-table{display:table!important}.d-md-table-row{display:table-row!important}.d-md-table-cell{display:table-cell!important}.d-md-flex{display:-ms-flexbox!important;display:flex!important}.d-md-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:992px){.d-lg-none{display:none!important}.d-lg-inline{display:inline!important}.d-lg-inline-block{display:inline-block!important}.d-lg-block{display:block!important}.d-lg-table{display:table!important}.d-lg-table-row{display:table-row!important}.d-lg-table-cell{display:table-cell!important}.d-lg-flex{display:-ms-flexbox!important;display:flex!important}.d-lg-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:1200px){.d-xl-none{display:none!important}.d-xl-inline{display:inline!important}.d-xl-inline-block{display:inline-block!important}.d-xl-block{display:block!important}.d-xl-table{display:table!important}.d-xl-table-row{display:table-row!important}.d-xl-table-cell{display:table-cell!important}.d-xl-flex{display:-ms-flexbox!important;display:flex!important}.d-xl-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media print{.d-print-none{display:none!important}.d-print-inline{display:inline!important}.d-print-inline-block{display:inline-block!important}.d-print-block{display:block!important}.d-print-table{display:table!important}.d-print-table-row{display:table-row!important}.d-print-table-cell{display:table-cell!important}.d-print-flex{display:-ms-flexbox!important;display:flex!important}.d-print-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}.embed-responsive{position:relative;display:block;width:100%;padding:0;overflow:hidden}.embed-responsive::before{display:block;content:""}.embed-responsive .embed-responsive-item,.embed-responsive embed,.embed-responsive iframe,.embed-responsive object,.embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.embed-responsive-21by9::before{padding-top:42.857143%}.embed-responsive-16by9::before{padding-top:56.25%}.embed-responsive-4by3::before{padding-top:75%}.embed-responsive-1by1::before{padding-top:100%}.flex-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-center{-ms-flex-align:center!important;align-items:center!important}.align-items-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}@media (min-width:576px){.flex-sm-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-sm-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-sm-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-sm-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-sm-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-sm-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-sm-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-sm-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-sm-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-sm-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-sm-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-sm-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-sm-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-sm-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-sm-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-sm-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-sm-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-sm-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-sm-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-sm-center{-ms-flex-align:center!important;align-items:center!important}.align-items-sm-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-sm-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-sm-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-sm-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-sm-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-sm-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-sm-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-sm-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-sm-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-sm-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-sm-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-sm-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-sm-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-sm-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}@media (min-width:768px){.flex-md-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-md-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-md-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-md-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-md-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-md-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-md-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-md-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-md-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-md-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-md-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-md-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-md-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-md-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-md-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-md-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-md-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-md-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-md-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-md-center{-ms-flex-align:center!important;align-items:center!important}.align-items-md-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-md-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-md-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-md-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-md-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-md-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-md-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-md-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-md-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-md-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-md-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-md-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-md-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-md-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}@media (min-width:992px){.flex-lg-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-lg-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-lg-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-lg-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-lg-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-lg-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-lg-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-lg-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-lg-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-lg-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-lg-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-lg-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-lg-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-lg-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-lg-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-lg-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-lg-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-lg-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-lg-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-lg-center{-ms-flex-align:center!important;align-items:center!important}.align-items-lg-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-lg-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-lg-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-lg-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-lg-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-lg-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-lg-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-lg-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-lg-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-lg-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-lg-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-lg-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-lg-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-lg-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}@media (min-width:1200px){.flex-xl-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-xl-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-xl-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-xl-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-xl-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-xl-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-xl-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-xl-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-xl-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-xl-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-xl-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-xl-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-xl-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-xl-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-xl-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-xl-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-xl-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-xl-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-xl-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-xl-center{-ms-flex-align:center!important;align-items:center!important}.align-items-xl-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-xl-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-xl-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-xl-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-xl-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-xl-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-xl-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-xl-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-xl-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-xl-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-xl-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-xl-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-xl-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-xl-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}.float-left{float:left!important}.float-right{float:right!important}.float-none{float:none!important}@media (min-width:576px){.float-sm-left{float:left!important}.float-sm-right{float:right!important}.float-sm-none{float:none!important}}@media (min-width:768px){.float-md-left{float:left!important}.float-md-right{float:right!important}.float-md-none{float:none!important}}@media (min-width:992px){.float-lg-left{float:left!important}.float-lg-right{float:right!important}.float-lg-none{float:none!important}}@media (min-width:1200px){.float-xl-left{float:left!important}.float-xl-right{float:right!important}.float-xl-none{float:none!important}}.user-select-all{-webkit-user-select:all!important;-moz-user-select:all!important;user-select:all!important}.user-select-auto{-webkit-user-select:auto!important;-moz-user-select:auto!important;-ms-user-select:auto!important;user-select:auto!important}.user-select-none{-webkit-user-select:none!important;-moz-user-select:none!important;-ms-user-select:none!important;user-select:none!important}.overflow-auto{overflow:auto!important}.overflow-hidden{overflow:hidden!important}.position-static{position:static!important}.position-relative{position:relative!important}.position-absolute{position:absolute!important}.position-fixed{position:fixed!important}.position-sticky{position:-webkit-sticky!important;position:sticky!important}.fixed-top{position:fixed;top:0;right:0;left:0;z-index:1030}.fixed-bottom{position:fixed;right:0;bottom:0;left:0;z-index:1030}@supports ((position:-webkit-sticky) or (position:sticky)){.sticky-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;overflow:visible;clip:auto;white-space:normal}.shadow-sm{box-shadow:0 .125rem .25rem rgba(0,0,0,.075)!important}.shadow{box-shadow:0 .5rem 1rem rgba(0,0,0,.15)!important}.shadow-lg{box-shadow:0 1rem 3rem rgba(0,0,0,.175)!important}.shadow-none{box-shadow:none!important}.w-25{width:25%!important}.w-50{width:50%!important}.w-75{width:75%!important}.w-100{width:100%!important}.w-auto{width:auto!important}.h-25{height:25%!important}.h-50{height:50%!important}.h-75{height:75%!important}.h-100{height:100%!important}.h-auto{height:auto!important}.mw-100{max-width:100%!important}.mh-100{max-height:100%!important}.min-vw-100{min-width:100vw!important}.min-vh-100{min-height:100vh!important}.vw-100{width:100vw!important}.vh-100{height:100vh!important}.m-0{margin:0!important}.mt-0,.my-0{margin-top:0!important}.mr-0,.mx-0{margin-right:0!important}.mb-0,.my-0{margin-bottom:0!important}.ml-0,.mx-0{margin-left:0!important}.m-1{margin:.25rem!important}.mt-1,.my-1{margin-top:.25rem!important}.mr-1,.mx-1{margin-right:.25rem!important}.mb-1,.my-1{margin-bottom:.25rem!important}.ml-1,.mx-1{margin-left:.25rem!important}.m-2{margin:.5rem!important}.mt-2,.my-2{margin-top:.5rem!important}.mr-2,.mx-2{margin-right:.5rem!important}.mb-2,.my-2{margin-bottom:.5rem!important}.ml-2,.mx-2{margin-left:.5rem!important}.m-3{margin:1rem!important}.mt-3,.my-3{margin-top:1rem!important}.mr-3,.mx-3{margin-right:1rem!important}.mb-3,.my-3{margin-bottom:1rem!important}.ml-3,.mx-3{margin-left:1rem!important}.m-4{margin:1.5rem!important}.mt-4,.my-4{margin-top:1.5rem!important}.mr-4,.mx-4{margin-right:1.5rem!important}.mb-4,.my-4{margin-bottom:1.5rem!important}.ml-4,.mx-4{margin-left:1.5rem!important}.m-5{margin:3rem!important}.mt-5,.my-5{margin-top:3rem!important}.mr-5,.mx-5{margin-right:3rem!important}.mb-5,.my-5{margin-bottom:3rem!important}.ml-5,.mx-5{margin-left:3rem!important}.p-0{padding:0!important}.pt-0,.py-0{padding-top:0!important}.pr-0,.px-0{padding-right:0!important}.pb-0,.py-0{padding-bottom:0!important}.pl-0,.px-0{padding-left:0!important}.p-1{padding:.25rem!important}.pt-1,.py-1{padding-top:.25rem!important}.pr-1,.px-1{padding-right:.25rem!important}.pb-1,.py-1{padding-bottom:.25rem!important}.pl-1,.px-1{padding-left:.25rem!important}.p-2{padding:.5rem!important}.pt-2,.py-2{padding-top:.5rem!important}.pr-2,.px-2{padding-right:.5rem!important}.pb-2,.py-2{padding-bottom:.5rem!important}.pl-2,.px-2{padding-left:.5rem!important}.p-3{padding:1rem!important}.pt-3,.py-3{padding-top:1rem!important}.pr-3,.px-3{padding-right:1rem!important}.pb-3,.py-3{padding-bottom:1rem!important}.pl-3,.px-3{padding-left:1rem!important}.p-4{padding:1.5rem!important}.pt-4,.py-4{padding-top:1.5rem!important}.pr-4,.px-4{padding-right:1.5rem!important}.pb-4,.py-4{padding-bottom:1.5rem!important}.pl-4,.px-4{padding-left:1.5rem!important}.p-5{padding:3rem!important}.pt-5,.py-5{padding-top:3rem!important}.pr-5,.px-5{padding-right:3rem!important}.pb-5,.py-5{padding-bottom:3rem!important}.pl-5,.px-5{padding-left:3rem!important}.m-n1{margin:-.25rem!important}.mt-n1,.my-n1{margin-top:-.25rem!important}.mr-n1,.mx-n1{margin-right:-.25rem!important}.mb-n1,.my-n1{margin-bottom:-.25rem!important}.ml-n1,.mx-n1{margin-left:-.25rem!important}.m-n2{margin:-.5rem!important}.mt-n2,.my-n2{margin-top:-.5rem!important}.mr-n2,.mx-n2{margin-right:-.5rem!important}.mb-n2,.my-n2{margin-bottom:-.5rem!important}.ml-n2,.mx-n2{margin-left:-.5rem!important}.m-n3{margin:-1rem!important}.mt-n3,.my-n3{margin-top:-1rem!important}.mr-n3,.mx-n3{margin-right:-1rem!important}.mb-n3,.my-n3{margin-bottom:-1rem!important}.ml-n3,.mx-n3{margin-left:-1rem!important}.m-n4{margin:-1.5rem!important}.mt-n4,.my-n4{margin-top:-1.5rem!important}.mr-n4,.mx-n4{margin-right:-1.5rem!important}.mb-n4,.my-n4{margin-bottom:-1.5rem!important}.ml-n4,.mx-n4{margin-left:-1.5rem!important}.m-n5{margin:-3rem!important}.mt-n5,.my-n5{margin-top:-3rem!important}.mr-n5,.mx-n5{margin-right:-3rem!important}.mb-n5,.my-n5{margin-bottom:-3rem!important}.ml-n5,.mx-n5{margin-left:-3rem!important}.m-auto{margin:auto!important}.mt-auto,.my-auto{margin-top:auto!important}.mr-auto,.mx-auto{margin-right:auto!important}.mb-auto,.my-auto{margin-bottom:auto!important}.ml-auto,.mx-auto{margin-left:auto!important}@media (min-width:576px){.m-sm-0{margin:0!important}.mt-sm-0,.my-sm-0{margin-top:0!important}.mr-sm-0,.mx-sm-0{margin-right:0!important}.mb-sm-0,.my-sm-0{margin-bottom:0!important}.ml-sm-0,.mx-sm-0{margin-left:0!important}.m-sm-1{margin:.25rem!important}.mt-sm-1,.my-sm-1{margin-top:.25rem!important}.mr-sm-1,.mx-sm-1{margin-right:.25rem!important}.mb-sm-1,.my-sm-1{margin-bottom:.25rem!important}.ml-sm-1,.mx-sm-1{margin-left:.25rem!important}.m-sm-2{margin:.5rem!important}.mt-sm-2,.my-sm-2{margin-top:.5rem!important}.mr-sm-2,.mx-sm-2{margin-right:.5rem!important}.mb-sm-2,.my-sm-2{margin-bottom:.5rem!important}.ml-sm-2,.mx-sm-2{margin-left:.5rem!important}.m-sm-3{margin:1rem!important}.mt-sm-3,.my-sm-3{margin-top:1rem!important}.mr-sm-3,.mx-sm-3{margin-right:1rem!important}.mb-sm-3,.my-sm-3{margin-bottom:1rem!important}.ml-sm-3,.mx-sm-3{margin-left:1rem!important}.m-sm-4{margin:1.5rem!important}.mt-sm-4,.my-sm-4{margin-top:1.5rem!important}.mr-sm-4,.mx-sm-4{margin-right:1.5rem!important}.mb-sm-4,.my-sm-4{margin-bottom:1.5rem!important}.ml-sm-4,.mx-sm-4{margin-left:1.5rem!important}.m-sm-5{margin:3rem!important}.mt-sm-5,.my-sm-5{margin-top:3rem!important}.mr-sm-5,.mx-sm-5{margin-right:3rem!important}.mb-sm-5,.my-sm-5{margin-bottom:3rem!important}.ml-sm-5,.mx-sm-5{margin-left:3rem!important}.p-sm-0{padding:0!important}.pt-sm-0,.py-sm-0{padding-top:0!important}.pr-sm-0,.px-sm-0{padding-right:0!important}.pb-sm-0,.py-sm-0{padding-bottom:0!important}.pl-sm-0,.px-sm-0{padding-left:0!important}.p-sm-1{padding:.25rem!important}.pt-sm-1,.py-sm-1{padding-top:.25rem!important}.pr-sm-1,.px-sm-1{padding-right:.25rem!important}.pb-sm-1,.py-sm-1{padding-bottom:.25rem!important}.pl-sm-1,.px-sm-1{padding-left:.25rem!important}.p-sm-2{padding:.5rem!important}.pt-sm-2,.py-sm-2{padding-top:.5rem!important}.pr-sm-2,.px-sm-2{padding-right:.5rem!important}.pb-sm-2,.py-sm-2{padding-bottom:.5rem!important}.pl-sm-2,.px-sm-2{padding-left:.5rem!important}.p-sm-3{padding:1rem!important}.pt-sm-3,.py-sm-3{padding-top:1rem!important}.pr-sm-3,.px-sm-3{padding-right:1rem!important}.pb-sm-3,.py-sm-3{padding-bottom:1rem!important}.pl-sm-3,.px-sm-3{padding-left:1rem!important}.p-sm-4{padding:1.5rem!important}.pt-sm-4,.py-sm-4{padding-top:1.5rem!important}.pr-sm-4,.px-sm-4{padding-right:1.5rem!important}.pb-sm-4,.py-sm-4{padding-bottom:1.5rem!important}.pl-sm-4,.px-sm-4{padding-left:1.5rem!important}.p-sm-5{padding:3rem!important}.pt-sm-5,.py-sm-5{padding-top:3rem!important}.pr-sm-5,.px-sm-5{padding-right:3rem!important}.pb-sm-5,.py-sm-5{padding-bottom:3rem!important}.pl-sm-5,.px-sm-5{padding-left:3rem!important}.m-sm-n1{margin:-.25rem!important}.mt-sm-n1,.my-sm-n1{margin-top:-.25rem!important}.mr-sm-n1,.mx-sm-n1{margin-right:-.25rem!important}.mb-sm-n1,.my-sm-n1{margin-bottom:-.25rem!important}.ml-sm-n1,.mx-sm-n1{margin-left:-.25rem!important}.m-sm-n2{margin:-.5rem!important}.mt-sm-n2,.my-sm-n2{margin-top:-.5rem!important}.mr-sm-n2,.mx-sm-n2{margin-right:-.5rem!important}.mb-sm-n2,.my-sm-n2{margin-bottom:-.5rem!important}.ml-sm-n2,.mx-sm-n2{margin-left:-.5rem!important}.m-sm-n3{margin:-1rem!important}.mt-sm-n3,.my-sm-n3{margin-top:-1rem!important}.mr-sm-n3,.mx-sm-n3{margin-right:-1rem!important}.mb-sm-n3,.my-sm-n3{margin-bottom:-1rem!important}.ml-sm-n3,.mx-sm-n3{margin-left:-1rem!important}.m-sm-n4{margin:-1.5rem!important}.mt-sm-n4,.my-sm-n4{margin-top:-1.5rem!important}.mr-sm-n4,.mx-sm-n4{margin-right:-1.5rem!important}.mb-sm-n4,.my-sm-n4{margin-bottom:-1.5rem!important}.ml-sm-n4,.mx-sm-n4{margin-left:-1.5rem!important}.m-sm-n5{margin:-3rem!important}.mt-sm-n5,.my-sm-n5{margin-top:-3rem!important}.mr-sm-n5,.mx-sm-n5{margin-right:-3rem!important}.mb-sm-n5,.my-sm-n5{margin-bottom:-3rem!important}.ml-sm-n5,.mx-sm-n5{margin-left:-3rem!important}.m-sm-auto{margin:auto!important}.mt-sm-auto,.my-sm-auto{margin-top:auto!important}.mr-sm-auto,.mx-sm-auto{margin-right:auto!important}.mb-sm-auto,.my-sm-auto{margin-bottom:auto!important}.ml-sm-auto,.mx-sm-auto{margin-left:auto!important}}@media (min-width:768px){.m-md-0{margin:0!important}.mt-md-0,.my-md-0{margin-top:0!important}.mr-md-0,.mx-md-0{margin-right:0!important}.mb-md-0,.my-md-0{margin-bottom:0!important}.ml-md-0,.mx-md-0{margin-left:0!important}.m-md-1{margin:.25rem!important}.mt-md-1,.my-md-1{margin-top:.25rem!important}.mr-md-1,.mx-md-1{margin-right:.25rem!important}.mb-md-1,.my-md-1{margin-bottom:.25rem!important}.ml-md-1,.mx-md-1{margin-left:.25rem!important}.m-md-2{margin:.5rem!important}.mt-md-2,.my-md-2{margin-top:.5rem!important}.mr-md-2,.mx-md-2{margin-right:.5rem!important}.mb-md-2,.my-md-2{margin-bottom:.5rem!important}.ml-md-2,.mx-md-2{margin-left:.5rem!important}.m-md-3{margin:1rem!important}.mt-md-3,.my-md-3{margin-top:1rem!important}.mr-md-3,.mx-md-3{margin-right:1rem!important}.mb-md-3,.my-md-3{margin-bottom:1rem!important}.ml-md-3,.mx-md-3{margin-left:1rem!important}.m-md-4{margin:1.5rem!important}.mt-md-4,.my-md-4{margin-top:1.5rem!important}.mr-md-4,.mx-md-4{margin-right:1.5rem!important}.mb-md-4,.my-md-4{margin-bottom:1.5rem!important}.ml-md-4,.mx-md-4{margin-left:1.5rem!important}.m-md-5{margin:3rem!important}.mt-md-5,.my-md-5{margin-top:3rem!important}.mr-md-5,.mx-md-5{margin-right:3rem!important}.mb-md-5,.my-md-5{margin-bottom:3rem!important}.ml-md-5,.mx-md-5{margin-left:3rem!important}.p-md-0{padding:0!important}.pt-md-0,.py-md-0{padding-top:0!important}.pr-md-0,.px-md-0{padding-right:0!important}.pb-md-0,.py-md-0{padding-bottom:0!important}.pl-md-0,.px-md-0{padding-left:0!important}.p-md-1{padding:.25rem!important}.pt-md-1,.py-md-1{padding-top:.25rem!important}.pr-md-1,.px-md-1{padding-right:.25rem!important}.pb-md-1,.py-md-1{padding-bottom:.25rem!important}.pl-md-1,.px-md-1{padding-left:.25rem!important}.p-md-2{padding:.5rem!important}.pt-md-2,.py-md-2{padding-top:.5rem!important}.pr-md-2,.px-md-2{padding-right:.5rem!important}.pb-md-2,.py-md-2{padding-bottom:.5rem!important}.pl-md-2,.px-md-2{padding-left:.5rem!important}.p-md-3{padding:1rem!important}.pt-md-3,.py-md-3{padding-top:1rem!important}.pr-md-3,.px-md-3{padding-right:1rem!important}.pb-md-3,.py-md-3{padding-bottom:1rem!important}.pl-md-3,.px-md-3{padding-left:1rem!important}.p-md-4{padding:1.5rem!important}.pt-md-4,.py-md-4{padding-top:1.5rem!important}.pr-md-4,.px-md-4{padding-right:1.5rem!important}.pb-md-4,.py-md-4{padding-bottom:1.5rem!important}.pl-md-4,.px-md-4{padding-left:1.5rem!important}.p-md-5{padding:3rem!important}.pt-md-5,.py-md-5{padding-top:3rem!important}.pr-md-5,.px-md-5{padding-right:3rem!important}.pb-md-5,.py-md-5{padding-bottom:3rem!important}.pl-md-5,.px-md-5{padding-left:3rem!important}.m-md-n1{margin:-.25rem!important}.mt-md-n1,.my-md-n1{margin-top:-.25rem!important}.mr-md-n1,.mx-md-n1{margin-right:-.25rem!important}.mb-md-n1,.my-md-n1{margin-bottom:-.25rem!important}.ml-md-n1,.mx-md-n1{margin-left:-.25rem!important}.m-md-n2{margin:-.5rem!important}.mt-md-n2,.my-md-n2{margin-top:-.5rem!important}.mr-md-n2,.mx-md-n2{margin-right:-.5rem!important}.mb-md-n2,.my-md-n2{margin-bottom:-.5rem!important}.ml-md-n2,.mx-md-n2{margin-left:-.5rem!important}.m-md-n3{margin:-1rem!important}.mt-md-n3,.my-md-n3{margin-top:-1rem!important}.mr-md-n3,.mx-md-n3{margin-right:-1rem!important}.mb-md-n3,.my-md-n3{margin-bottom:-1rem!important}.ml-md-n3,.mx-md-n3{margin-left:-1rem!important}.m-md-n4{margin:-1.5rem!important}.mt-md-n4,.my-md-n4{margin-top:-1.5rem!important}.mr-md-n4,.mx-md-n4{margin-right:-1.5rem!important}.mb-md-n4,.my-md-n4{margin-bottom:-1.5rem!important}.ml-md-n4,.mx-md-n4{margin-left:-1.5rem!important}.m-md-n5{margin:-3rem!important}.mt-md-n5,.my-md-n5{margin-top:-3rem!important}.mr-md-n5,.mx-md-n5{margin-right:-3rem!important}.mb-md-n5,.my-md-n5{margin-bottom:-3rem!important}.ml-md-n5,.mx-md-n5{margin-left:-3rem!important}.m-md-auto{margin:auto!important}.mt-md-auto,.my-md-auto{margin-top:auto!important}.mr-md-auto,.mx-md-auto{margin-right:auto!important}.mb-md-auto,.my-md-auto{margin-bottom:auto!important}.ml-md-auto,.mx-md-auto{margin-left:auto!important}}@media (min-width:992px){.m-lg-0{margin:0!important}.mt-lg-0,.my-lg-0{margin-top:0!important}.mr-lg-0,.mx-lg-0{margin-right:0!important}.mb-lg-0,.my-lg-0{margin-bottom:0!important}.ml-lg-0,.mx-lg-0{margin-left:0!important}.m-lg-1{margin:.25rem!important}.mt-lg-1,.my-lg-1{margin-top:.25rem!important}.mr-lg-1,.mx-lg-1{margin-right:.25rem!important}.mb-lg-1,.my-lg-1{margin-bottom:.25rem!important}.ml-lg-1,.mx-lg-1{margin-left:.25rem!important}.m-lg-2{margin:.5rem!important}.mt-lg-2,.my-lg-2{margin-top:.5rem!important}.mr-lg-2,.mx-lg-2{margin-right:.5rem!important}.mb-lg-2,.my-lg-2{margin-bottom:.5rem!important}.ml-lg-2,.mx-lg-2{margin-left:.5rem!important}.m-lg-3{margin:1rem!important}.mt-lg-3,.my-lg-3{margin-top:1rem!important}.mr-lg-3,.mx-lg-3{margin-right:1rem!important}.mb-lg-3,.my-lg-3{margin-bottom:1rem!important}.ml-lg-3,.mx-lg-3{margin-left:1rem!important}.m-lg-4{margin:1.5rem!important}.mt-lg-4,.my-lg-4{margin-top:1.5rem!important}.mr-lg-4,.mx-lg-4{margin-right:1.5rem!important}.mb-lg-4,.my-lg-4{margin-bottom:1.5rem!important}.ml-lg-4,.mx-lg-4{margin-left:1.5rem!important}.m-lg-5{margin:3rem!important}.mt-lg-5,.my-lg-5{margin-top:3rem!important}.mr-lg-5,.mx-lg-5{margin-right:3rem!important}.mb-lg-5,.my-lg-5{margin-bottom:3rem!important}.ml-lg-5,.mx-lg-5{margin-left:3rem!important}.p-lg-0{padding:0!important}.pt-lg-0,.py-lg-0{padding-top:0!important}.pr-lg-0,.px-lg-0{padding-right:0!important}.pb-lg-0,.py-lg-0{padding-bottom:0!important}.pl-lg-0,.px-lg-0{padding-left:0!important}.p-lg-1{padding:.25rem!important}.pt-lg-1,.py-lg-1{padding-top:.25rem!important}.pr-lg-1,.px-lg-1{padding-right:.25rem!important}.pb-lg-1,.py-lg-1{padding-bottom:.25rem!important}.pl-lg-1,.px-lg-1{padding-left:.25rem!important}.p-lg-2{padding:.5rem!important}.pt-lg-2,.py-lg-2{padding-top:.5rem!important}.pr-lg-2,.px-lg-2{padding-right:.5rem!important}.pb-lg-2,.py-lg-2{padding-bottom:.5rem!important}.pl-lg-2,.px-lg-2{padding-left:.5rem!important}.p-lg-3{padding:1rem!important}.pt-lg-3,.py-lg-3{padding-top:1rem!important}.pr-lg-3,.px-lg-3{padding-right:1rem!important}.pb-lg-3,.py-lg-3{padding-bottom:1rem!important}.pl-lg-3,.px-lg-3{padding-left:1rem!important}.p-lg-4{padding:1.5rem!important}.pt-lg-4,.py-lg-4{padding-top:1.5rem!important}.pr-lg-4,.px-lg-4{padding-right:1.5rem!important}.pb-lg-4,.py-lg-4{padding-bottom:1.5rem!important}.pl-lg-4,.px-lg-4{padding-left:1.5rem!important}.p-lg-5{padding:3rem!important}.pt-lg-5,.py-lg-5{padding-top:3rem!important}.pr-lg-5,.px-lg-5{padding-right:3rem!important}.pb-lg-5,.py-lg-5{padding-bottom:3rem!important}.pl-lg-5,.px-lg-5{padding-left:3rem!important}.m-lg-n1{margin:-.25rem!important}.mt-lg-n1,.my-lg-n1{margin-top:-.25rem!important}.mr-lg-n1,.mx-lg-n1{margin-right:-.25rem!important}.mb-lg-n1,.my-lg-n1{margin-bottom:-.25rem!important}.ml-lg-n1,.mx-lg-n1{margin-left:-.25rem!important}.m-lg-n2{margin:-.5rem!important}.mt-lg-n2,.my-lg-n2{margin-top:-.5rem!important}.mr-lg-n2,.mx-lg-n2{margin-right:-.5rem!important}.mb-lg-n2,.my-lg-n2{margin-bottom:-.5rem!important}.ml-lg-n2,.mx-lg-n2{margin-left:-.5rem!important}.m-lg-n3{margin:-1rem!important}.mt-lg-n3,.my-lg-n3{margin-top:-1rem!important}.mr-lg-n3,.mx-lg-n3{margin-right:-1rem!important}.mb-lg-n3,.my-lg-n3{margin-bottom:-1rem!important}.ml-lg-n3,.mx-lg-n3{margin-left:-1rem!important}.m-lg-n4{margin:-1.5rem!important}.mt-lg-n4,.my-lg-n4{margin-top:-1.5rem!important}.mr-lg-n4,.mx-lg-n4{margin-right:-1.5rem!important}.mb-lg-n4,.my-lg-n4{margin-bottom:-1.5rem!important}.ml-lg-n4,.mx-lg-n4{margin-left:-1.5rem!important}.m-lg-n5{margin:-3rem!important}.mt-lg-n5,.my-lg-n5{margin-top:-3rem!important}.mr-lg-n5,.mx-lg-n5{margin-right:-3rem!important}.mb-lg-n5,.my-lg-n5{margin-bottom:-3rem!important}.ml-lg-n5,.mx-lg-n5{margin-left:-3rem!important}.m-lg-auto{margin:auto!important}.mt-lg-auto,.my-lg-auto{margin-top:auto!important}.mr-lg-auto,.mx-lg-auto{margin-right:auto!important}.mb-lg-auto,.my-lg-auto{margin-bottom:auto!important}.ml-lg-auto,.mx-lg-auto{margin-left:auto!important}}@media (min-width:1200px){.m-xl-0{margin:0!important}.mt-xl-0,.my-xl-0{margin-top:0!important}.mr-xl-0,.mx-xl-0{margin-right:0!important}.mb-xl-0,.my-xl-0{margin-bottom:0!important}.ml-xl-0,.mx-xl-0{margin-left:0!important}.m-xl-1{margin:.25rem!important}.mt-xl-1,.my-xl-1{margin-top:.25rem!important}.mr-xl-1,.mx-xl-1{margin-right:.25rem!important}.mb-xl-1,.my-xl-1{margin-bottom:.25rem!important}.ml-xl-1,.mx-xl-1{margin-left:.25rem!important}.m-xl-2{margin:.5rem!important}.mt-xl-2,.my-xl-2{margin-top:.5rem!important}.mr-xl-2,.mx-xl-2{margin-right:.5rem!important}.mb-xl-2,.my-xl-2{margin-bottom:.5rem!important}.ml-xl-2,.mx-xl-2{margin-left:.5rem!important}.m-xl-3{margin:1rem!important}.mt-xl-3,.my-xl-3{margin-top:1rem!important}.mr-xl-3,.mx-xl-3{margin-right:1rem!important}.mb-xl-3,.my-xl-3{margin-bottom:1rem!important}.ml-xl-3,.mx-xl-3{margin-left:1rem!important}.m-xl-4{margin:1.5rem!important}.mt-xl-4,.my-xl-4{margin-top:1.5rem!important}.mr-xl-4,.mx-xl-4{margin-right:1.5rem!important}.mb-xl-4,.my-xl-4{margin-bottom:1.5rem!important}.ml-xl-4,.mx-xl-4{margin-left:1.5rem!important}.m-xl-5{margin:3rem!important}.mt-xl-5,.my-xl-5{margin-top:3rem!important}.mr-xl-5,.mx-xl-5{margin-right:3rem!important}.mb-xl-5,.my-xl-5{margin-bottom:3rem!important}.ml-xl-5,.mx-xl-5{margin-left:3rem!important}.p-xl-0{padding:0!important}.pt-xl-0,.py-xl-0{padding-top:0!important}.pr-xl-0,.px-xl-0{padding-right:0!important}.pb-xl-0,.py-xl-0{padding-bottom:0!important}.pl-xl-0,.px-xl-0{padding-left:0!important}.p-xl-1{padding:.25rem!important}.pt-xl-1,.py-xl-1{padding-top:.25rem!important}.pr-xl-1,.px-xl-1{padding-right:.25rem!important}.pb-xl-1,.py-xl-1{padding-bottom:.25rem!important}.pl-xl-1,.px-xl-1{padding-left:.25rem!important}.p-xl-2{padding:.5rem!important}.pt-xl-2,.py-xl-2{padding-top:.5rem!important}.pr-xl-2,.px-xl-2{padding-right:.5rem!important}.pb-xl-2,.py-xl-2{padding-bottom:.5rem!important}.pl-xl-2,.px-xl-2{padding-left:.5rem!important}.p-xl-3{padding:1rem!important}.pt-xl-3,.py-xl-3{padding-top:1rem!important}.pr-xl-3,.px-xl-3{padding-right:1rem!important}.pb-xl-3,.py-xl-3{padding-bottom:1rem!important}.pl-xl-3,.px-xl-3{padding-left:1rem!important}.p-xl-4{padding:1.5rem!important}.pt-xl-4,.py-xl-4{padding-top:1.5rem!important}.pr-xl-4,.px-xl-4{padding-right:1.5rem!important}.pb-xl-4,.py-xl-4{padding-bottom:1.5rem!important}.pl-xl-4,.px-xl-4{padding-left:1.5rem!important}.p-xl-5{padding:3rem!important}.pt-xl-5,.py-xl-5{padding-top:3rem!important}.pr-xl-5,.px-xl-5{padding-right:3rem!important}.pb-xl-5,.py-xl-5{padding-bottom:3rem!important}.pl-xl-5,.px-xl-5{padding-left:3rem!important}.m-xl-n1{margin:-.25rem!important}.mt-xl-n1,.my-xl-n1{margin-top:-.25rem!important}.mr-xl-n1,.mx-xl-n1{margin-right:-.25rem!important}.mb-xl-n1,.my-xl-n1{margin-bottom:-.25rem!important}.ml-xl-n1,.mx-xl-n1{margin-left:-.25rem!important}.m-xl-n2{margin:-.5rem!important}.mt-xl-n2,.my-xl-n2{margin-top:-.5rem!important}.mr-xl-n2,.mx-xl-n2{margin-right:-.5rem!important}.mb-xl-n2,.my-xl-n2{margin-bottom:-.5rem!important}.ml-xl-n2,.mx-xl-n2{margin-left:-.5rem!important}.m-xl-n3{margin:-1rem!important}.mt-xl-n3,.my-xl-n3{margin-top:-1rem!important}.mr-xl-n3,.mx-xl-n3{margin-right:-1rem!important}.mb-xl-n3,.my-xl-n3{margin-bottom:-1rem!important}.ml-xl-n3,.mx-xl-n3{margin-left:-1rem!important}.m-xl-n4{margin:-1.5rem!important}.mt-xl-n4,.my-xl-n4{margin-top:-1.5rem!important}.mr-xl-n4,.mx-xl-n4{margin-right:-1.5rem!important}.mb-xl-n4,.my-xl-n4{margin-bottom:-1.5rem!important}.ml-xl-n4,.mx-xl-n4{margin-left:-1.5rem!important}.m-xl-n5{margin:-3rem!important}.mt-xl-n5,.my-xl-n5{margin-top:-3rem!important}.mr-xl-n5,.mx-xl-n5{margin-right:-3rem!important}.mb-xl-n5,.my-xl-n5{margin-bottom:-3rem!important}.ml-xl-n5,.mx-xl-n5{margin-left:-3rem!important}.m-xl-auto{margin:auto!important}.mt-xl-auto,.my-xl-auto{margin-top:auto!important}.mr-xl-auto,.mx-xl-auto{margin-right:auto!important}.mb-xl-auto,.my-xl-auto{margin-bottom:auto!important}.ml-xl-auto,.mx-xl-auto{margin-left:auto!important}}.stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;pointer-events:auto;content:"";background-color:rgba(0,0,0,0)}.text-monospace{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace!important}.text-justify{text-align:justify!important}.text-wrap{white-space:normal!important}.text-nowrap{white-space:nowrap!important}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.text-left{text-align:left!important}.text-right{text-align:right!important}.text-center{text-align:center!important}@media (min-width:576px){.text-sm-left{text-align:left!important}.text-sm-right{text-align:right!important}.text-sm-center{text-align:center!important}}@media (min-width:768px){.text-md-left{text-align:left!important}.text-md-right{text-align:right!important}.text-md-center{text-align:center!important}}@media (min-width:992px){.text-lg-left{text-align:left!important}.text-lg-right{text-align:right!important}.text-lg-center{text-align:center!important}}@media (min-width:1200px){.text-xl-left{text-align:left!important}.text-xl-right{text-align:right!important}.text-xl-center{text-align:center!important}}.text-lowercase{text-transform:lowercase!important}.text-uppercase{text-transform:uppercase!important}.text-capitalize{text-transform:capitalize!important}.font-weight-light{font-weight:300!important}.font-weight-lighter{font-weight:lighter!important}.font-weight-normal{font-weight:400!important}.font-weight-bold{font-weight:700!important}.font-weight-bolder{font-weight:bolder!important}.font-italic{font-style:italic!important}.text-white{color:#fff!important}.text-primary{color:#007bff!important}a.text-primary:focus,a.text-primary:hover{color:#0056b3!important}.text-secondary{color:#6c757d!important}a.text-secondary:focus,a.text-secondary:hover{color:#494f54!important}.text-success{color:#28a745!important}a.text-success:focus,a.text-success:hover{color:#19692c!important}.text-info{color:#17a2b8!important}a.text-info:focus,a.text-info:hover{color:#0f6674!important}.text-warning{color:#ffc107!important}a.text-warning:focus,a.text-warning:hover{color:#ba8b00!important}.text-danger{color:#dc3545!important}a.text-danger:focus,a.text-danger:hover{color:#a71d2a!important}.text-light{color:#f8f9fa!important}a.text-light:focus,a.text-light:hover{color:#cbd3da!important}.text-dark{color:#343a40!important}a.text-dark:focus,a.text-dark:hover{color:#121416!important}.text-body{color:#212529!important}.text-muted{color:#6c757d!important}.text-black-50{color:rgba(0,0,0,.5)!important}.text-white-50{color:rgba(255,255,255,.5)!important}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.text-decoration-none{text-decoration:none!important}.text-break{word-break:break-word!important;word-wrap:break-word!important}.text-reset{color:inherit!important}.visible{visibility:visible!important}.invisible{visibility:hidden!important}@media print{*,::after,::before{text-shadow:none!important;box-shadow:none!important}a:not(.btn){text-decoration:underline}abbr[title]::after{content:" (" attr(title) ")"}pre{white-space:pre-wrap!important}blockquote,pre{border:1px solid #adb5bd;page-break-inside:avoid}img,tr{page-break-inside:avoid}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}@page{size:a3}body{min-width:992px!important}.container{min-width:992px!important}.navbar{display:none}.badge{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered td,.table-bordered th{border:1px solid #dee2e6!important}.table-dark{color:inherit}.table-dark tbody+tbody,.table-dark td,.table-dark th,.table-dark thead th{border-color:#dee2e6}.table .thead-dark th{color:inherit;border-color:#dee2e6}}
32726 /*# sourceMappingURL=bootstrap.min.css.map */.nvd3 .nv-axis{pointer-events:none;opacity:1}.nvd3 .nv-axis path{fill:none;stroke:#000;stroke-opacity:.75;shape-rendering:crispEdges}.nvd3 .nv-axis path.domain{stroke-opacity:.75}.nvd3 .nv-axis.nv-x path.domain{stroke-opacity:0}.nvd3 .nv-axis line{fill:none;stroke:#e5e5e5;shape-rendering:crispEdges}.nvd3 .nv-axis .zero line,.nvd3 .nv-axis line.zero{stroke-opacity:.75}.nvd3 .nv-axis .nv-axisMaxMin text{font-weight:700}.nvd3 .x .nv-axis .nv-axisMaxMin text,.nvd3 .x2 .nv-axis .nv-axisMaxMin text,.nvd3 .x3 .nv-axis .nv-axisMaxMin text{text-anchor:middle}.nvd3 .nv-axis.nv-disabled{opacity:0}.nvd3 .nv-bars rect{fill-opacity:.75;transition:fill-opacity 250ms linear;-moz-transition:fill-opacity 250ms linear;-webkit-transition:fill-opacity 250ms linear}.nvd3 .nv-bars rect.hover{fill-opacity:1}.nvd3 .nv-bars .hover rect{fill:#add8e6}.nvd3 .nv-bars text{fill:rgba(0,0,0,0)}.nvd3 .nv-bars .hover text{fill:rgba(0,0,0,1)}.nvd3 .nv-multibar .nv-groups rect,.nvd3 .nv-multibarHorizontal .nv-groups rect,.nvd3 .nv-discretebar .nv-groups rect{stroke-opacity:0;transition:fill-opacity 250ms linear;-moz-transition:fill-opacity 250ms linear;-webkit-transition:fill-opacity 250ms linear}.nvd3 .nv-multibar .nv-groups rect:hover,.nvd3 .nv-multibarHorizontal .nv-groups rect:hover,.nvd3 .nv-candlestickBar .nv-ticks rect:hover,.nvd3 .nv-discretebar .nv-groups rect:hover{fill-opacity:1}.nvd3 .nv-discretebar .nv-groups text,.nvd3 .nv-multibarHorizontal .nv-groups text{font-weight:700;fill:rgba(0,0,0,1);stroke:rgba(0,0,0,0)}.nvd3 .nv-boxplot circle{fill-opacity:.5}.nvd3 .nv-boxplot circle:hover{fill-opacity:1}.nvd3 .nv-boxplot rect:hover{fill-opacity:1}.nvd3 line.nv-boxplot-median{stroke:#000}.nv-boxplot-tick:hover{stroke-width:2.5px}.nvd3.nv-bullet{font:10px sans-serif}.nvd3.nv-bullet .nv-measure{fill-opacity:.8}.nvd3.nv-bullet .nv-measure:hover{fill-opacity:1}.nvd3.nv-bullet .nv-marker{stroke:#000;stroke-width:2px}.nvd3.nv-bullet .nv-markerTriangle{stroke:#000;fill:#fff;stroke-width:1.5px}.nvd3.nv-bullet .nv-tick line{stroke:#666;stroke-width:.5px}.nvd3.nv-bullet .nv-range.nv-s0{fill:#eee}.nvd3.nv-bullet .nv-range.nv-s1{fill:#ddd}.nvd3.nv-bullet .nv-range.nv-s2{fill:#ccc}.nvd3.nv-bullet .nv-title{font-size:14px;font-weight:700}.nvd3.nv-bullet .nv-subtitle{fill:#999}.nvd3.nv-bullet .nv-range{fill:#bababa;fill-opacity:.4}.nvd3.nv-bullet .nv-range:hover{fill-opacity:.7}.nvd3.nv-candlestickBar .nv-ticks .nv-tick{stroke-width:1px}.nvd3.nv-candlestickBar .nv-ticks .nv-tick.hover{stroke-width:2px}.nvd3.nv-candlestickBar .nv-ticks .nv-tick.positive rect{stroke:#2ca02c;fill:#2ca02c}.nvd3.nv-candlestickBar .nv-ticks .nv-tick.negative rect{stroke:#d62728;fill:#d62728}.with-transitions .nv-candlestickBar .nv-ticks .nv-tick{transition:stroke-width 250ms linear,stroke-opacity 250ms linear;-moz-transition:stroke-width 250ms linear,stroke-opacity 250ms linear;-webkit-transition:stroke-width 250ms linear,stroke-opacity 250ms linear}.nvd3.nv-candlestickBar .nv-ticks line{stroke:#333}.nvd3 .nv-legend .nv-disabled rect{}.nvd3 .nv-check-box .nv-box{fill-opacity:0;stroke-width:2}.nvd3 .nv-check-box .nv-check{fill-opacity:0;stroke-width:4}.nvd3 .nv-series.nv-disabled .nv-check-box .nv-check{fill-opacity:0;stroke-opacity:0}.nvd3 .nv-controlsWrap .nv-legend .nv-check-box .nv-check{opacity:0}.nvd3.nv-linePlusBar .nv-bar rect{fill-opacity:.75}.nvd3.nv-linePlusBar .nv-bar rect:hover{fill-opacity:1}.nvd3 .nv-groups path.nv-line{fill:none}.nvd3 .nv-groups path.nv-area{stroke:none}.nvd3.nv-line .nvd3.nv-scatter .nv-groups .nv-point{fill-opacity:0;stroke-opacity:0}.nvd3.nv-scatter.nv-single-point .nv-groups .nv-point{fill-opacity:.5!important;stroke-opacity:.5!important}.with-transitions .nvd3 .nv-groups .nv-point{transition:stroke-width 250ms linear,stroke-opacity 250ms linear;-moz-transition:stroke-width 250ms linear,stroke-opacity 250ms linear;-webkit-transition:stroke-width 250ms linear,stroke-opacity 250ms linear}.nvd3.nv-scatter .nv-groups .nv-point.hover,.nvd3 .nv-groups .nv-point.hover{stroke-width:7px;fill-opacity:.95!important;stroke-opacity:.95!important}.nvd3 .nv-point-paths path{stroke:#aaa;stroke-opacity:0;fill:#eee;fill-opacity:0}.nvd3 .nv-indexLine{cursor:ew-resize}svg.nvd3-svg{-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-ms-user-select:none;-moz-user-select:none;user-select:none;display:block;width:100%;height:100%}.nvtooltip.with-3d-shadow,.with-3d-shadow .nvtooltip{-moz-box-shadow:0 5px 10px rgba(0,0,0,.2);-webkit-box-shadow:0 5px 10px rgba(0,0,0,.2);box-shadow:0 5px 10px rgba(0,0,0,.2);-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px}.nvd3 text{font:400 12px Arial}.nvd3 .title{font:700 14px Arial}.nvd3 .nv-background{fill:#fff;fill-opacity:0}.nvd3.nv-noData{font-size:18px;font-weight:700}.nv-brush .extent{fill-opacity:.125;shape-rendering:crispEdges}.nv-brush .resize path{fill:#eee;stroke:#666}.nvd3 .nv-legend .nv-series{cursor:pointer}.nvd3 .nv-legend .nv-disabled circle{fill-opacity:0}.nvd3 .nv-brush .extent{fill-opacity:0!important}.nvd3 .nv-brushBackground rect{stroke:#000;stroke-width:.4;fill:#fff;fill-opacity:.7}.nvd3.nv-ohlcBar .nv-ticks .nv-tick{stroke-width:1px}.nvd3.nv-ohlcBar .nv-ticks .nv-tick.hover{stroke-width:2px}.nvd3.nv-ohlcBar .nv-ticks .nv-tick.positive{stroke:#2ca02c}.nvd3.nv-ohlcBar .nv-ticks .nv-tick.negative{stroke:#d62728}.nvd3 .background path{fill:none;stroke:#EEE;stroke-opacity:.4;shape-rendering:crispEdges}.nvd3 .foreground path{fill:none;stroke-opacity:.7}.nvd3 .nv-parallelCoordinates-brush .extent{fill:#fff;fill-opacity:.6;stroke:gray;shape-rendering:crispEdges}.nvd3 .nv-parallelCoordinates .hover{fill-opacity:1;stroke-width:3px}.nvd3 .missingValuesline line{fill:none;stroke:#000;stroke-width:1;stroke-opacity:1;stroke-dasharray:5,5}.nvd3.nv-pie path{stroke-opacity:0;transition:fill-opacity 250ms linear,stroke-width 250ms linear,stroke-opacity 250ms linear;-moz-transition:fill-opacity 250ms linear,stroke-width 250ms linear,stroke-opacity 250ms linear;-webkit-transition:fill-opacity 250ms linear,stroke-width 250ms linear,stroke-opacity 250ms linear}.nvd3.nv-pie .nv-pie-title{font-size:24px;fill:rgba(19,196,249,.59)}.nvd3.nv-pie .nv-slice text{stroke:#000;stroke-width:0}.nvd3.nv-pie path{stroke:#fff;stroke-width:1px;stroke-opacity:1}.nvd3.nv-pie .hover path{fill-opacity:.7}.nvd3.nv-pie .nv-label{pointer-events:none}.nvd3.nv-pie .nv-label rect{fill-opacity:0;stroke-opacity:0}.nvd3 .nv-groups .nv-point.hover{stroke-width:20px;stroke-opacity:.5}.nvd3 .nv-scatter .nv-point.hover{fill-opacity:1}.nv-noninteractive{pointer-events:none}.nv-distx,.nv-disty{pointer-events:none}.nvd3.nv-sparkline path{fill:none}.nvd3.nv-sparklineplus g.nv-hoverValue{pointer-events:none}.nvd3.nv-sparklineplus .nv-hoverValue line{stroke:#333;stroke-width:1.5px}.nvd3.nv-sparklineplus,.nvd3.nv-sparklineplus g{pointer-events:all}.nvd3 .nv-hoverArea{fill-opacity:0;stroke-opacity:0}.nvd3.nv-sparklineplus .nv-xValue,.nvd3.nv-sparklineplus .nv-yValue{stroke-width:0;font-size:.9em;font-weight:400}.nvd3.nv-sparklineplus .nv-yValue{stroke:#f66}.nvd3.nv-sparklineplus .nv-maxValue{stroke:#2ca02c;fill:#2ca02c}.nvd3.nv-sparklineplus .nv-minValue{stroke:#d62728;fill:#d62728}.nvd3.nv-sparklineplus .nv-currentValue{font-weight:700;font-size:1.1em}.nvd3.nv-stackedarea path.nv-area{fill-opacity:.7;stroke-opacity:0;transition:fill-opacity 250ms linear,stroke-opacity 250ms linear;-moz-transition:fill-opacity 250ms linear,stroke-opacity 250ms linear;-webkit-transition:fill-opacity 250ms linear,stroke-opacity 250ms linear}.nvd3.nv-stackedarea path.nv-area.hover{fill-opacity:.9}.nvd3.nv-stackedarea .nv-groups .nv-point{stroke-opacity:0;fill-opacity:0}.nvtooltip{position:absolute;background-color:rgba(255,255,255,1);color:rgba(0,0,0,1);padding:1px;border:1px solid rgba(0,0,0,.2);z-index:10000;display:block;font-family:Arial;font-size:13px;text-align:left;pointer-events:none;white-space:nowrap;-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.nvtooltip{background:rgba(255,255,255,.8);border:1px solid rgba(0,0,0,.5);border-radius:4px}.nvtooltip.with-transitions,.with-transitions .nvtooltip{transition:opacity 50ms linear;-moz-transition:opacity 50ms linear;-webkit-transition:opacity 50ms linear;transition-delay:200ms;-moz-transition-delay:200ms;-webkit-transition-delay:200ms}.nvtooltip.x-nvtooltip,.nvtooltip.y-nvtooltip{padding:8px}.nvtooltip h3{margin:0;padding:4px 14px;line-height:18px;font-weight:400;background-color:rgba(247,247,247,.75);color:rgba(0,0,0,1);text-align:center;border-bottom:1px solid #ebebeb;-webkit-border-radius:5px 5px 0 0;-moz-border-radius:5px 5px 0 0;border-radius:5px 5px 0 0}.nvtooltip p{margin:0;padding:5px 14px;text-align:center}.nvtooltip span{display:inline-block;margin:2px 0}.nvtooltip table{margin:6px;border-spacing:0}.nvtooltip table td{padding:2px 9px 2px 0;vertical-align:middle}.nvtooltip table td.key{font-weight:400}.nvtooltip table td.value{text-align:right;font-weight:700}.nvtooltip table tr.highlight td{padding:1px 9px 1px 0;border-bottom-style:solid;border-bottom-width:1px;border-top-style:solid;border-top-width:1px}.nvtooltip table td.legend-color-guide div{width:8px;height:8px;vertical-align:middle}.nvtooltip table td.legend-color-guide div{width:12px;height:12px;border:1px solid #999}.nvtooltip .footer{padding:3px;text-align:center}.nvtooltip-pending-removal{pointer-events:none;display:none}.nvd3 .nv-interactiveGuideLine{pointer-events:none}.nvd3 line.nv-guideline{stroke:#ccc}.octicon {
32727 display: inline-block;
32728 vertical-align: text-top;
32729 fill: currentColor;
32730 }
32731 body {
32732 font-family: sans-serif;
32733 font-size: 1em;
32734 font-kerning: normal;
32735 font-variant-ligatures: common-ligatures;
32736 text-rendering: optimizeLegibility;
32737 padding-top: 10px;
32738 }
32739
32740 .popover {
32741 max-width: none;
32742 }
32743
32744 .octicon {
32745 margin-right:.25em;
32746 vertical-align: baseline;
32747 width: 0.75em;
32748 }
32749
32750 .table-bordered>thead>tr>td {
32751 border-bottom-width: 1px;
32752 }
32753
32754 .table tbody>tr>td, .table thead>tr>td {
32755 padding-top: 3px;
32756 padding-bottom: 3px;
32757 }
32758
32759 .table-condensed tbody>tr>td {
32760 padding-top: 0;
32761 padding-bottom: 0;
32762 }
32763
32764 .table .progress {
32765 margin-bottom: inherit;
32766 }
32767
32768 .table-borderless th, .table-borderless td {
32769 border: 0 !important;
32770 }
32771
32772 .table tbody tr.covered-by-large-tests, li.covered-by-large-tests, tr.success, td.success, li.success, span.success {
32773 background-color: {{success-low}};
32774 }
32775
32776 .table tbody tr.covered-by-medium-tests, li.covered-by-medium-tests {
32777 background-color: {{success-medium}};
32778 }
32779
32780 .table tbody tr.covered-by-small-tests, li.covered-by-small-tests {
32781 background-color: {{success-high}};
32782 }
32783
32784 .table tbody tr.warning, .table tbody td.warning, li.warning, span.warning {
32785 background-color: {{warning}};
32786 }
32787
32788 .table tbody tr.danger, .table tbody td.danger, li.danger, span.danger {
32789 background-color: {{danger}};
32790 }
32791
32792 .table tbody td.info {
32793 background-color: #d9edf7;
32794 }
32795
32796 td.big {
32797 vertical-align: middle;
32798 width: 117px;
32799 }
32800
32801 td.small {
32802 }
32803
32804 td.codeLine {
32805 font-family: "Source Code Pro", "SFMono-Regular", Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
32806 white-space: pre-wrap;
32807 }
32808
32809 td span.comment {
32810 color: #888a85;
32811 }
32812
32813 td span.default {
32814 color: #2e3436;
32815 }
32816
32817 td span.html {
32818 color: #888a85;
32819 }
32820
32821 td span.keyword {
32822 color: #2e3436;
32823 font-weight: bold;
32824 }
32825
32826 pre span.string {
32827 color: #2e3436;
32828 }
32829
32830 span.success, span.warning, span.danger {
32831 margin-right: 2px;
32832 padding-left: 10px;
32833 padding-right: 10px;
32834 text-align: center;
32835 }
32836
32837 #toplink {
32838 position: fixed;
32839 left: 5px;
32840 bottom: 5px;
32841 outline: 0;
32842 }
32843
32844 svg text {
32845 font-family: "Lucida Grande", "Lucida Sans Unicode", Verdana, Arial, Helvetica, sans-serif;
32846 font-size: 11px;
32847 color: #666;
32848 fill: #666;
32849 }
32850
32851 .scrollbox {
32852 height:245px;
32853 overflow-x:scroll;
32854 overflow-y:scroll;
32855 }
32856
32857 table + .structure-heading {
32858 border-top: 1px solid lightgrey;
32859 padding-top: 0.5em;
32860 }
32861
32862 .legend {
32863 font-weight: bold;
32864 margin-right: 2px;
32865 padding-left: 10px;
32866 padding-right: 10px;
32867 text-align: center;
32868 }
32869
32870 .covered-by-small-tests {
32871 background-color: {{success-high}};
32872 }
32873
32874 .covered-by-medium-tests {
32875 background-color: {{success-medium}};
32876 }
32877
32878 .covered-by-large-tests {
32879 background-color: {{success-low}};
32880 }
32881
32882 .not-covered {
32883 background-color: {{danger}};
32884 }
32885
32886 .not-coverable {
32887 background-color: {{warning}};
32888 }
32889 <!DOCTYPE html>
32890 <html lang="en">
32891 <head>
32892 <meta charset="UTF-8">
32893 <title>Dashboard for {{full_path}}</title>
32894 <meta name="viewport" content="width=device-width, initial-scale=1.0">
32895 <link href="{{path_to_root}}_css/bootstrap.min.css?v={{version}}" rel="stylesheet" type="text/css">
32896 <link href="{{path_to_root}}_css/nv.d3.min.css?v={{version}}" rel="stylesheet" type="text/css">
32897 <link href="{{path_to_root}}_css/style.css?v={{version}}" rel="stylesheet" type="text/css">
32898 <link href="{{path_to_root}}_css/custom.css" rel="stylesheet" type="text/css">
32899 </head>
32900 <body>
32901 <header>
32902 <div class="container-fluid">
32903 <div class="row">
32904 <div class="col-md-12">
32905 <nav aria-label="breadcrumb">
32906 <ol class="breadcrumb">
32907 {{breadcrumbs}}
32908 </ol>
32909 </nav>
32910 </div>
32911 </div>
32912 </div>
32913 </header>
32914 <div class="container-fluid">
32915 <div class="row">
32916 <div class="col-md-12">
32917 <h2>Classes</h2>
32918 </div>
32919 </div>
32920 <div class="row">
32921 <div class="col-md-6">
32922 <h3>Coverage Distribution</h3>
32923 <div id="classCoverageDistribution" style="height: 300px;">
32924 <svg></svg>
32925 </div>
32926 </div>
32927 <div class="col-md-6">
32928 <h3>Complexity</h3>
32929 <div id="classComplexity" style="height: 300px;">
32930 <svg></svg>
32931 </div>
32932 </div>
32933 </div>
32934 <div class="row">
32935 <div class="col-md-6">
32936 <h3>Insufficient Coverage</h3>
32937 <div class="scrollbox">
32938 <table class="table">
32939 <thead>
32940 <tr>
32941 <th>Class</th>
32942 <th class="text-right">Coverage</th>
32943 </tr>
32944 </thead>
32945 <tbody>
32946 {{insufficient_coverage_classes}}
32947 </tbody>
32948 </table>
32949 </div>
32950 </div>
32951 <div class="col-md-6">
32952 <h3>Project Risks</h3>
32953 <div class="scrollbox">
32954 <table class="table">
32955 <thead>
32956 <tr>
32957 <th>Class</th>
32958 <th class="text-right"><abbr title="Change Risk Anti-Patterns (CRAP) Index">CRAP</abbr></th>
32959 </tr>
32960 </thead>
32961 <tbody>
32962 {{project_risks_classes}}
32963 </tbody>
32964 </table>
32965 </div>
32966 </div>
32967 </div>
32968 <div class="row">
32969 <div class="col-md-12">
32970 <h2>Methods</h2>
32971 </div>
32972 </div>
32973 <div class="row">
32974 <div class="col-md-6">
32975 <h3>Coverage Distribution</h3>
32976 <div id="methodCoverageDistribution" style="height: 300px;">
32977 <svg></svg>
32978 </div>
32979 </div>
32980 <div class="col-md-6">
32981 <h3>Complexity</h3>
32982 <div id="methodComplexity" style="height: 300px;">
32983 <svg></svg>
32984 </div>
32985 </div>
32986 </div>
32987 <div class="row">
32988 <div class="col-md-6">
32989 <h3>Insufficient Coverage</h3>
32990 <div class="scrollbox">
32991 <table class="table">
32992 <thead>
32993 <tr>
32994 <th>Method</th>
32995 <th class="text-right">Coverage</th>
32996 </tr>
32997 </thead>
32998 <tbody>
32999 {{insufficient_coverage_methods}}
33000 </tbody>
33001 </table>
33002 </div>
33003 </div>
33004 <div class="col-md-6">
33005 <h3>Project Risks</h3>
33006 <div class="scrollbox">
33007 <table class="table">
33008 <thead>
33009 <tr>
33010 <th>Method</th>
33011 <th class="text-right"><abbr title="Change Risk Anti-Patterns (CRAP) Index">CRAP</abbr></th>
33012 </tr>
33013 </thead>
33014 <tbody>
33015 {{project_risks_methods}}
33016 </tbody>
33017 </table>
33018 </div>
33019 </div>
33020 </div>
33021 <footer>
33022 <hr/>
33023 <p>
33024 <small>Generated by <a href="https://github.com/sebastianbergmann/php-code-coverage" target="_top">php-code-coverage {{version}}</a> using {{runtime}}{{generator}} at {{date}}.</small>
33025 </p>
33026 </footer>
33027 </div>
33028 <script src="{{path_to_root}}_js/jquery.min.js?v={{version}}" type="text/javascript"></script>
33029 <script src="{{path_to_root}}_js/d3.min.js?v={{version}}" type="text/javascript"></script>
33030 <script src="{{path_to_root}}_js/nv.d3.min.js?v={{version}}" type="text/javascript"></script>
33031 <script type="text/javascript">
33032 $(document).ready(function() {
33033 nv.addGraph(function() {
33034 var chart = nv.models.multiBarChart();
33035 chart.tooltips(false)
33036 .showControls(false)
33037 .showLegend(false)
33038 .reduceXTicks(false)
33039 .staggerLabels(true)
33040 .yAxis.tickFormat(d3.format('d'));
33041
33042 d3.select('#classCoverageDistribution svg')
33043 .datum(getCoverageDistributionData({{class_coverage_distribution}}, "Class Coverage"))
33044 .transition().duration(500).call(chart);
33045
33046 nv.utils.windowResize(chart.update);
33047
33048 return chart;
33049 });
33050
33051 nv.addGraph(function() {
33052 var chart = nv.models.multiBarChart();
33053 chart.tooltips(false)
33054 .showControls(false)
33055 .showLegend(false)
33056 .reduceXTicks(false)
33057 .staggerLabels(true)
33058 .yAxis.tickFormat(d3.format('d'));
33059
33060 d3.select('#methodCoverageDistribution svg')
33061 .datum(getCoverageDistributionData({{method_coverage_distribution}}, "Method Coverage"))
33062 .transition().duration(500).call(chart);
33063
33064 nv.utils.windowResize(chart.update);
33065
33066 return chart;
33067 });
33068
33069 function getCoverageDistributionData(data, label) {
33070 var labels = [
33071 '0%',
33072 '0-10%',
33073 '10-20%',
33074 '20-30%',
33075 '30-40%',
33076 '40-50%',
33077 '50-60%',
33078 '60-70%',
33079 '70-80%',
33080 '80-90%',
33081 '90-100%',
33082 '100%'
33083 ];
33084 var values = [];
33085 $.each(labels, function(key) {
33086 values.push({x: labels[key], y: data[key]});
33087 });
33088
33089 return [
33090 {
33091 key: label,
33092 values: values,
33093 color: "#4572A7"
33094 }
33095 ];
33096 }
33097 nv.addGraph(function() {
33098 var chart = nv.models.scatterChart()
33099 .showDistX(true)
33100 .showDistY(true)
33101 .showLegend(false)
33102 .forceX([0, 100]);
33103 chart.tooltipContent(function(graph) {
33104 return '<p>' + graph.point.class + '</p>';
33105 });
33106
33107 chart.xAxis.axisLabel('Code Coverage (in percent)');
33108 chart.yAxis.axisLabel('Cyclomatic Complexity');
33109
33110 d3.select('#classComplexity svg')
33111 .datum(getComplexityData({{complexity_class}}, 'Class Complexity'))
33112 .transition()
33113 .duration(500)
33114 .call(chart);
33115
33116 nv.utils.windowResize(chart.update);
33117
33118 return chart;
33119 });
33120
33121 nv.addGraph(function() {
33122 var chart = nv.models.scatterChart()
33123 .showDistX(true)
33124 .showDistY(true)
33125 .showLegend(false)
33126 .forceX([0, 100]);
33127 chart.tooltipContent(function(graph) {
33128 return '<p>' + graph.point.class + '</p>';
33129 });
33130
33131 chart.xAxis.axisLabel('Code Coverage (in percent)');
33132 chart.yAxis.axisLabel('Method Complexity');
33133
33134 d3.select('#methodComplexity svg')
33135 .datum(getComplexityData({{complexity_method}}, 'Method Complexity'))
33136 .transition()
33137 .duration(500)
33138 .call(chart);
33139
33140 nv.utils.windowResize(chart.update);
33141
33142 return chart;
33143 });
33144
33145 function getComplexityData(data, label) {
33146 var values = [];
33147 $.each(data, function(key) {
33148 var value = Math.round(data[key][0]*100) / 100;
33149 values.push({
33150 x: value,
33151 y: data[key][1],
33152 class: data[key][2],
33153 size: 0.05,
33154 shape: 'diamond'
33155 });
33156 });
33157
33158 return [
33159 {
33160 key: label,
33161 values: values,
33162 color: "#4572A7"
33163 }
33164 ];
33165 }
33166 });
33167 </script>
33168 </body>
33169 </html>
33170 <!DOCTYPE html>
33171 <html lang="en">
33172 <head>
33173 <meta charset="UTF-8">
33174 <title>Dashboard for {{full_path}}</title>
33175 <meta name="viewport" content="width=device-width, initial-scale=1.0">
33176 <link href="{{path_to_root}}_css/bootstrap.min.css?v={{version}}" rel="stylesheet" type="text/css">
33177 <link href="{{path_to_root}}_css/nv.d3.min.css?v={{version}}" rel="stylesheet" type="text/css">
33178 <link href="{{path_to_root}}_css/style.css?v={{version}}" rel="stylesheet" type="text/css">
33179 <link href="{{path_to_root}}_css/custom.css" rel="stylesheet" type="text/css">
33180 </head>
33181 <body>
33182 <header>
33183 <div class="container-fluid">
33184 <div class="row">
33185 <div class="col-md-12">
33186 <nav aria-label="breadcrumb">
33187 <ol class="breadcrumb">
33188 {{breadcrumbs}}
33189 </ol>
33190 </nav>
33191 </div>
33192 </div>
33193 </div>
33194 </header>
33195 <div class="container-fluid">
33196 <div class="row">
33197 <div class="col-md-12">
33198 <h2>Classes</h2>
33199 </div>
33200 </div>
33201 <div class="row">
33202 <div class="col-md-6">
33203 <h3>Coverage Distribution</h3>
33204 <div id="classCoverageDistribution" style="height: 300px;">
33205 <svg></svg>
33206 </div>
33207 </div>
33208 <div class="col-md-6">
33209 <h3>Complexity</h3>
33210 <div id="classComplexity" style="height: 300px;">
33211 <svg></svg>
33212 </div>
33213 </div>
33214 </div>
33215 <div class="row">
33216 <div class="col-md-6">
33217 <h3>Insufficient Coverage</h3>
33218 <div class="scrollbox">
33219 <table class="table">
33220 <thead>
33221 <tr>
33222 <th>Class</th>
33223 <th class="text-right">Coverage</th>
33224 </tr>
33225 </thead>
33226 <tbody>
33227 {{insufficient_coverage_classes}}
33228 </tbody>
33229 </table>
33230 </div>
33231 </div>
33232 <div class="col-md-6">
33233 <h3>Project Risks</h3>
33234 <div class="scrollbox">
33235 <table class="table">
33236 <thead>
33237 <tr>
33238 <th>Class</th>
33239 <th class="text-right"><abbr title="Change Risk Anti-Patterns (CRAP) Index">CRAP</abbr></th>
33240 </tr>
33241 </thead>
33242 <tbody>
33243 {{project_risks_classes}}
33244 </tbody>
33245 </table>
33246 </div>
33247 </div>
33248 </div>
33249 <div class="row">
33250 <div class="col-md-12">
33251 <h2>Methods</h2>
33252 </div>
33253 </div>
33254 <div class="row">
33255 <div class="col-md-6">
33256 <h3>Coverage Distribution</h3>
33257 <div id="methodCoverageDistribution" style="height: 300px;">
33258 <svg></svg>
33259 </div>
33260 </div>
33261 <div class="col-md-6">
33262 <h3>Complexity</h3>
33263 <div id="methodComplexity" style="height: 300px;">
33264 <svg></svg>
33265 </div>
33266 </div>
33267 </div>
33268 <div class="row">
33269 <div class="col-md-6">
33270 <h3>Insufficient Coverage</h3>
33271 <div class="scrollbox">
33272 <table class="table">
33273 <thead>
33274 <tr>
33275 <th>Method</th>
33276 <th class="text-right">Coverage</th>
33277 </tr>
33278 </thead>
33279 <tbody>
33280 {{insufficient_coverage_methods}}
33281 </tbody>
33282 </table>
33283 </div>
33284 </div>
33285 <div class="col-md-6">
33286 <h3>Project Risks</h3>
33287 <div class="scrollbox">
33288 <table class="table">
33289 <thead>
33290 <tr>
33291 <th>Method</th>
33292 <th class="text-right"><abbr title="Change Risk Anti-Patterns (CRAP) Index">CRAP</abbr></th>
33293 </tr>
33294 </thead>
33295 <tbody>
33296 {{project_risks_methods}}
33297 </tbody>
33298 </table>
33299 </div>
33300 </div>
33301 </div>
33302 <footer>
33303 <hr/>
33304 <p>
33305 <small>Generated by <a href="https://github.com/sebastianbergmann/php-code-coverage" target="_top">php-code-coverage {{version}}</a> using {{runtime}}{{generator}} at {{date}}.</small>
33306 </p>
33307 </footer>
33308 </div>
33309 <script src="{{path_to_root}}_js/jquery.min.js?v={{version}}" type="text/javascript"></script>
33310 <script src="{{path_to_root}}_js/d3.min.js?v={{version}}" type="text/javascript"></script>
33311 <script src="{{path_to_root}}_js/nv.d3.min.js?v={{version}}" type="text/javascript"></script>
33312 <script type="text/javascript">
33313 $(document).ready(function() {
33314 nv.addGraph(function() {
33315 var chart = nv.models.multiBarChart();
33316 chart.tooltips(false)
33317 .showControls(false)
33318 .showLegend(false)
33319 .reduceXTicks(false)
33320 .staggerLabels(true)
33321 .yAxis.tickFormat(d3.format('d'));
33322
33323 d3.select('#classCoverageDistribution svg')
33324 .datum(getCoverageDistributionData({{class_coverage_distribution}}, "Class Coverage"))
33325 .transition().duration(500).call(chart);
33326
33327 nv.utils.windowResize(chart.update);
33328
33329 return chart;
33330 });
33331
33332 nv.addGraph(function() {
33333 var chart = nv.models.multiBarChart();
33334 chart.tooltips(false)
33335 .showControls(false)
33336 .showLegend(false)
33337 .reduceXTicks(false)
33338 .staggerLabels(true)
33339 .yAxis.tickFormat(d3.format('d'));
33340
33341 d3.select('#methodCoverageDistribution svg')
33342 .datum(getCoverageDistributionData({{method_coverage_distribution}}, "Method Coverage"))
33343 .transition().duration(500).call(chart);
33344
33345 nv.utils.windowResize(chart.update);
33346
33347 return chart;
33348 });
33349
33350 function getCoverageDistributionData(data, label) {
33351 var labels = [
33352 '0%',
33353 '0-10%',
33354 '10-20%',
33355 '20-30%',
33356 '30-40%',
33357 '40-50%',
33358 '50-60%',
33359 '60-70%',
33360 '70-80%',
33361 '80-90%',
33362 '90-100%',
33363 '100%'
33364 ];
33365 var values = [];
33366 $.each(labels, function(key) {
33367 values.push({x: labels[key], y: data[key]});
33368 });
33369
33370 return [
33371 {
33372 key: label,
33373 values: values,
33374 color: "#4572A7"
33375 }
33376 ];
33377 }
33378 nv.addGraph(function() {
33379 var chart = nv.models.scatterChart()
33380 .showDistX(true)
33381 .showDistY(true)
33382 .showLegend(false)
33383 .forceX([0, 100]);
33384 chart.tooltipContent(function(graph) {
33385 return '<p>' + graph.point.class + '</p>';
33386 });
33387
33388 chart.xAxis.axisLabel('Code Coverage (in percent)');
33389 chart.yAxis.axisLabel('Cyclomatic Complexity');
33390
33391 d3.select('#classComplexity svg')
33392 .datum(getComplexityData({{complexity_class}}, 'Class Complexity'))
33393 .transition()
33394 .duration(500)
33395 .call(chart);
33396
33397 nv.utils.windowResize(chart.update);
33398
33399 return chart;
33400 });
33401
33402 nv.addGraph(function() {
33403 var chart = nv.models.scatterChart()
33404 .showDistX(true)
33405 .showDistY(true)
33406 .showLegend(false)
33407 .forceX([0, 100]);
33408 chart.tooltipContent(function(graph) {
33409 return '<p>' + graph.point.class + '</p>';
33410 });
33411
33412 chart.xAxis.axisLabel('Code Coverage (in percent)');
33413 chart.yAxis.axisLabel('Method Complexity');
33414
33415 d3.select('#methodComplexity svg')
33416 .datum(getComplexityData({{complexity_method}}, 'Method Complexity'))
33417 .transition()
33418 .duration(500)
33419 .call(chart);
33420
33421 nv.utils.windowResize(chart.update);
33422
33423 return chart;
33424 });
33425
33426 function getComplexityData(data, label) {
33427 var values = [];
33428 $.each(data, function(key) {
33429 var value = Math.round(data[key][0]*100) / 100;
33430 values.push({
33431 x: value,
33432 y: data[key][1],
33433 class: data[key][2],
33434 size: 0.05,
33435 shape: 'diamond'
33436 });
33437 });
33438
33439 return [
33440 {
33441 key: label,
33442 values: values,
33443 color: "#4572A7"
33444 }
33445 ];
33446 }
33447 });
33448 </script>
33449 </body>
33450 </html>
33451 <!DOCTYPE html>
33452 <html lang="en">
33453 <head>
33454 <meta charset="UTF-8">
33455 <title>Code Coverage for {{full_path}}</title>
33456 <meta name="viewport" content="width=device-width, initial-scale=1.0">
33457 <link href="{{path_to_root}}_css/bootstrap.min.css?v={{version}}" rel="stylesheet" type="text/css">
33458 <link href="{{path_to_root}}_css/octicons.css?v={{version}}" rel="stylesheet" type="text/css">
33459 <link href="{{path_to_root}}_css/style.css?v={{version}}" rel="stylesheet" type="text/css">
33460 <link href="{{path_to_root}}_css/custom.css" rel="stylesheet" type="text/css">
33461 </head>
33462 <body>
33463 <header>
33464 <div class="container-fluid">
33465 <div class="row">
33466 <div class="col-md-12">
33467 <nav aria-label="breadcrumb">
33468 <ol class="breadcrumb">
33469 {{breadcrumbs}}
33470 </ol>
33471 </nav>
33472 </div>
33473 </div>
33474 </div>
33475 </header>
33476 <div class="container-fluid">
33477 <div class="table-responsive">
33478 <table class="table table-bordered">
33479 <thead>
33480 <tr>
33481 <td>&nbsp;</td>
33482 <td colspan="9"><div align="center"><strong>Code Coverage</strong></div></td>
33483 </tr>
33484 <tr>
33485 <td>&nbsp;</td>
33486 <td colspan="3"><div align="center"><strong>Lines</strong></div></td>
33487 <td colspan="3"><div align="center"><strong>Functions and Methods</strong></div></td>
33488 <td colspan="3"><div align="center"><strong>Classes and Traits</strong></div></td>
33489 </tr>
33490 </thead>
33491 <tbody>
33492 {{items}}
33493 </tbody>
33494 </table>
33495 </div>
33496 <footer>
33497 <hr/>
33498 <h4>Legend</h4>
33499 <p>
33500 <span class="danger"><strong>Low</strong>: 0% to {{low_upper_bound}}%</span>
33501 <span class="warning"><strong>Medium</strong>: {{low_upper_bound}}% to {{high_lower_bound}}%</span>
33502 <span class="success"><strong>High</strong>: {{high_lower_bound}}% to 100%</span>
33503 </p>
33504 <p>
33505 <small>Generated by <a href="https://github.com/sebastianbergmann/php-code-coverage" target="_top">php-code-coverage {{version}}</a> using {{runtime}}{{generator}} at {{date}}.</small>
33506 </p>
33507 </footer>
33508 </div>
33509 </body>
33510 </html>
33511 <!DOCTYPE html>
33512 <html lang="en">
33513 <head>
33514 <meta charset="UTF-8">
33515 <title>Code Coverage for {{full_path}}</title>
33516 <meta name="viewport" content="width=device-width, initial-scale=1.0">
33517 <link href="{{path_to_root}}_css/bootstrap.min.css?v={{version}}" rel="stylesheet" type="text/css">
33518 <link href="{{path_to_root}}_css/octicons.css?v={{version}}" rel="stylesheet" type="text/css">
33519 <link href="{{path_to_root}}_css/style.css?v={{version}}" rel="stylesheet" type="text/css">
33520 <link href="{{path_to_root}}_css/custom.css" rel="stylesheet" type="text/css">
33521 </head>
33522 <body>
33523 <header>
33524 <div class="container-fluid">
33525 <div class="row">
33526 <div class="col-md-12">
33527 <nav aria-label="breadcrumb">
33528 <ol class="breadcrumb">
33529 {{breadcrumbs}}
33530 </ol>
33531 </nav>
33532 </div>
33533 </div>
33534 </div>
33535 </header>
33536 <div class="container-fluid">
33537 <div class="table-responsive">
33538 <table class="table table-bordered">
33539 <thead>
33540 <tr>
33541 <td>&nbsp;</td>
33542 <td colspan="15"><div align="center"><strong>Code Coverage</strong></div></td>
33543 </tr>
33544 <tr>
33545 <td>&nbsp;</td>
33546 <td colspan="3"><div align="center"><strong>Lines</strong></div></td>
33547 <td colspan="3"><div align="center"><strong>Branches</strong></div></td>
33548 <td colspan="3"><div align="center"><strong>Paths</strong></div></td>
33549 <td colspan="3"><div align="center"><strong>Functions and Methods</strong></div></td>
33550 <td colspan="3"><div align="center"><strong>Classes and Traits</strong></div></td>
33551 </tr>
33552 </thead>
33553 <tbody>
33554 {{items}}
33555 </tbody>
33556 </table>
33557 </div>
33558 <footer>
33559 <hr/>
33560 <h4>Legend</h4>
33561 <p>
33562 <span class="danger"><strong>Low</strong>: 0% to {{low_upper_bound}}%</span>
33563 <span class="warning"><strong>Medium</strong>: {{low_upper_bound}}% to {{high_lower_bound}}%</span>
33564 <span class="success"><strong>High</strong>: {{high_lower_bound}}% to 100%</span>
33565 </p>
33566 <p>
33567 <small>Generated by <a href="https://github.com/sebastianbergmann/php-code-coverage" target="_top">php-code-coverage {{version}}</a> using {{runtime}}{{generator}} at {{date}}.</small>
33568 </p>
33569 </footer>
33570 </div>
33571 </body>
33572 </html>
33573 <tr>
33574 <td class="{{lines_level}}">{{icon}}{{name}}</td>
33575 <td class="{{lines_level}} big">{{lines_bar}}</td>
33576 <td class="{{lines_level}} small"><div align="right">{{lines_executed_percent}}</div></td>
33577 <td class="{{lines_level}} small"><div align="right">{{lines_number}}</div></td>
33578 <td class="{{methods_level}} big">{{methods_bar}}</td>
33579 <td class="{{methods_level}} small"><div align="right">{{methods_tested_percent}}</div></td>
33580 <td class="{{methods_level}} small"><div align="right">{{methods_number}}</div></td>
33581 <td class="{{classes_level}} big">{{classes_bar}}</td>
33582 <td class="{{classes_level}} small"><div align="right">{{classes_tested_percent}}</div></td>
33583 <td class="{{classes_level}} small"><div align="right">{{classes_number}}</div></td>
33584 </tr>
33585
33586 <tr>
33587 <td class="{{lines_level}}">{{icon}}{{name}}</td>
33588 <td class="{{lines_level}} big">{{lines_bar}}</td>
33589 <td class="{{lines_level}} small"><div align="right">{{lines_executed_percent}}</div></td>
33590 <td class="{{lines_level}} small"><div align="right">{{lines_number}}</div></td>
33591 <td class="{{branches_level}} big">{{branches_bar}}</td>
33592 <td class="{{branches_level}} small"><div align="right">{{branches_executed_percent}}</div></td>
33593 <td class="{{branches_level}} small"><div align="right">{{branches_number}}</div></td>
33594 <td class="{{paths_level}} big">{{paths_bar}}</td>
33595 <td class="{{paths_level}} small"><div align="right">{{paths_executed_percent}}</div></td>
33596 <td class="{{paths_level}} small"><div align="right">{{paths_number}}</div></td>
33597 <td class="{{methods_level}} big">{{methods_bar}}</td>
33598 <td class="{{methods_level}} small"><div align="right">{{methods_tested_percent}}</div></td>
33599 <td class="{{methods_level}} small"><div align="right">{{methods_number}}</div></td>
33600 <td class="{{classes_level}} big">{{classes_bar}}</td>
33601 <td class="{{classes_level}} small"><div align="right">{{classes_tested_percent}}</div></td>
33602 <td class="{{classes_level}} small"><div align="right">{{classes_number}}</div></td>
33603 </tr>
33604
33605 <!DOCTYPE html>
33606 <html lang="en">
33607 <head>
33608 <meta charset="UTF-8">
33609 <title>Code Coverage for {{full_path}}</title>
33610 <meta name="viewport" content="width=device-width, initial-scale=1.0">
33611 <link href="{{path_to_root}}_css/bootstrap.min.css?v={{version}}" rel="stylesheet" type="text/css">
33612 <link href="{{path_to_root}}_css/octicons.css?v={{version}}" rel="stylesheet" type="text/css">
33613 <link href="{{path_to_root}}_css/style.css?v={{version}}" rel="stylesheet" type="text/css">
33614 <link href="{{path_to_root}}_css/custom.css" rel="stylesheet" type="text/css">
33615 </head>
33616 <body>
33617 <header>
33618 <div class="container-fluid">
33619 <div class="row">
33620 <div class="col-md-12">
33621 <nav aria-label="breadcrumb">
33622 <ol class="breadcrumb">
33623 {{breadcrumbs}}
33624 </ol>
33625 </nav>
33626 </div>
33627 </div>
33628 </div>
33629 </header>
33630 <div class="container-fluid">
33631 <div class="table-responsive">
33632 <table class="table table-bordered">
33633 <thead>
33634 <tr>
33635 <td>&nbsp;</td>
33636 <td colspan="10"><div align="center"><strong>Code Coverage</strong></div></td>
33637 </tr>
33638 <tr>
33639 <td>&nbsp;</td>
33640 <td colspan="3"><div align="center"><strong>Lines</strong></div></td>
33641 <td colspan="4"><div align="center"><strong>Functions and Methods</strong></div></td>
33642 <td colspan="3"><div align="center"><strong>Classes and Traits</strong></div></td>
33643 </tr>
33644 </thead>
33645 <tbody>
33646 {{items}}
33647 </tbody>
33648 </table>
33649 </div>
33650 {{lines}}
33651 {{structure}}
33652 <footer>
33653 <hr/>
33654 <h4>Legend</h4>
33655 {{legend}}
33656 <p>
33657 <small>Generated by <a href="https://github.com/sebastianbergmann/php-code-coverage" target="_top">php-code-coverage {{version}}</a> using {{runtime}}{{generator}} at {{date}}.</small>
33658 </p>
33659 <a title="Back to the top" id="toplink" href="#">
33660 <svg xmlns="http://www.w3.org/2000/svg" width="12" height="16" viewBox="0 0 12 16"><path fill-rule="evenodd" d="M12 11L6 5l-6 6h12z"/></svg>
33661 </a>
33662 </footer>
33663 </div>
33664 <script src="{{path_to_root}}_js/jquery.min.js?v={{version}}" type="text/javascript"></script>
33665 <script src="{{path_to_root}}_js/popper.min.js?v={{version}}" type="text/javascript"></script>
33666 <script src="{{path_to_root}}_js/bootstrap.min.js?v={{version}}" type="text/javascript"></script>
33667 <script src="{{path_to_root}}_js/file.js?v={{version}}" type="text/javascript"></script>
33668 </body>
33669 </html>
33670 <!DOCTYPE html>
33671 <html lang="en">
33672 <head>
33673 <meta charset="UTF-8">
33674 <title>Code Coverage for {{full_path}}</title>
33675 <meta name="viewport" content="width=device-width, initial-scale=1.0">
33676 <link href="{{path_to_root}}_css/bootstrap.min.css?v={{version}}" rel="stylesheet" type="text/css">
33677 <link href="{{path_to_root}}_css/octicons.css?v={{version}}" rel="stylesheet" type="text/css">
33678 <link href="{{path_to_root}}_css/style.css?v={{version}}" rel="stylesheet" type="text/css">
33679 <link href="{{path_to_root}}_css/custom.css" rel="stylesheet" type="text/css">
33680 </head>
33681 <body>
33682 <header>
33683 <div class="container-fluid">
33684 <div class="row">
33685 <div class="col-md-12">
33686 <nav aria-label="breadcrumb">
33687 <ol class="breadcrumb">
33688 {{breadcrumbs}}
33689 </ol>
33690 </nav>
33691 </div>
33692 </div>
33693 </div>
33694 </header>
33695 <div class="container-fluid">
33696 <div class="table-responsive">
33697 <table class="table table-bordered">
33698 <thead>
33699 <tr>
33700 <td>&nbsp;</td>
33701 <td colspan="16"><div align="center"><strong>Code Coverage</strong></div></td>
33702 </tr>
33703 <tr>
33704 <td>&nbsp;</td>
33705 <td colspan="3"><div align="center"><strong>Lines</strong></div></td>
33706 <td colspan="3"><div align="center"><strong>Branches</strong></div></td>
33707 <td colspan="3"><div align="center"><strong>Paths</strong></div></td>
33708 <td colspan="4"><div align="center"><strong>Functions and Methods</strong></div></td>
33709 <td colspan="3"><div align="center"><strong>Classes and Traits</strong></div></td>
33710 </tr>
33711 </thead>
33712 <tbody>
33713 {{items}}
33714 </tbody>
33715 </table>
33716 </div>
33717 {{lines}}
33718 {{structure}}
33719 <footer>
33720 <hr/>
33721 <h4>Legend</h4>
33722 {{legend}}
33723 <p>
33724 <small>Generated by <a href="https://github.com/sebastianbergmann/php-code-coverage" target="_top">php-code-coverage {{version}}</a> using {{runtime}}{{generator}} at {{date}}.</small>
33725 </p>
33726 <a title="Back to the top" id="toplink" href="#">
33727 <svg xmlns="http://www.w3.org/2000/svg" width="12" height="16" viewBox="0 0 12 16"><path fill-rule="evenodd" d="M12 11L6 5l-6 6h12z"/></svg>
33728 </a>
33729 </footer>
33730 </div>
33731 <script src="{{path_to_root}}_js/jquery.min.js?v={{version}}" type="text/javascript"></script>
33732 <script src="{{path_to_root}}_js/popper.min.js?v={{version}}" type="text/javascript"></script>
33733 <script src="{{path_to_root}}_js/bootstrap.min.js?v={{version}}" type="text/javascript"></script>
33734 <script src="{{path_to_root}}_js/file.js?v={{version}}" type="text/javascript"></script>
33735 </body>
33736 </html>
33737 <tr>
33738 <td class="{{lines_level}}">{{name}}</td>
33739 <td class="{{lines_level}} big">{{lines_bar}}</td>
33740 <td class="{{lines_level}} small"><div align="right">{{lines_executed_percent}}</div></td>
33741 <td class="{{lines_level}} small"><div align="right">{{lines_number}}</div></td>
33742 <td class="{{methods_level}} big">{{methods_bar}}</td>
33743 <td class="{{methods_level}} small"><div align="right">{{methods_tested_percent}}</div></td>
33744 <td class="{{methods_level}} small"><div align="right">{{methods_number}}</div></td>
33745 <td class="{{methods_level}} small">{{crap}}</td>
33746 <td class="{{classes_level}} big">{{classes_bar}}</td>
33747 <td class="{{classes_level}} small"><div align="right">{{classes_tested_percent}}</div></td>
33748 <td class="{{classes_level}} small"><div align="right">{{classes_number}}</div></td>
33749 </tr>
33750
33751 <tr>
33752 <td class="{{lines_level}}">{{name}}</td>
33753 <td class="{{lines_level}} big">{{lines_bar}}</td>
33754 <td class="{{lines_level}} small"><div align="right">{{lines_executed_percent}}</div></td>
33755 <td class="{{lines_level}} small"><div align="right">{{lines_number}}</div></td>
33756 <td class="{{branches_level}} big">{{branches_bar}}</td>
33757 <td class="{{branches_level}} small"><div align="right">{{branches_executed_percent}}</div></td>
33758 <td class="{{branches_level}} small"><div align="right">{{branches_number}}</div></td>
33759 <td class="{{paths_level}} big">{{paths_bar}}</td>
33760 <td class="{{paths_level}} small"><div align="right">{{paths_executed_percent}}</div></td>
33761 <td class="{{paths_level}} small"><div align="right">{{paths_number}}</div></td>
33762 <td class="{{methods_level}} big">{{methods_bar}}</td>
33763 <td class="{{methods_level}} small"><div align="right">{{methods_tested_percent}}</div></td>
33764 <td class="{{methods_level}} small"><div align="right">{{methods_number}}</div></td>
33765 <td class="{{methods_level}} small">{{crap}}</td>
33766 <td class="{{classes_level}} big">{{classes_bar}}</td>
33767 <td class="{{classes_level}} small"><div align="right">{{classes_tested_percent}}</div></td>
33768 <td class="{{classes_level}} small"><div align="right">{{classes_number}}</div></td>
33769 </tr>
33770
33771 <svg xmlns="http://www.w3.org/2000/svg" width="12" height="16" viewBox="0 0 12 16"><path fill-rule="evenodd" d="M8.5 1H1c-.55 0-1 .45-1 1v12c0 .55.45 1 1 1h10c.55 0 1-.45 1-1V4.5L8.5 1zM11 14H1V2h7l3 3v9zM5 6.98L3.5 8.5 5 10l-.5 1L2 8.5 4.5 6l.5.98zM7.5 6L10 8.5 7.5 11l-.5-.98L8.5 8.5 7 7l.5-1z"/></svg><svg xmlns="http://www.w3.org/2000/svg" width="14" height="16" viewBox="0 0 14 16"><path fill-rule="evenodd" d="M13 4H7V3c0-.66-.31-1-1-1H1c-.55 0-1 .45-1 1v10c0 .55.45 1 1 1h12c.55 0 1-.45 1-1V5c0-.55-.45-1-1-1zM6 4H1V3h5v1z"/></svg>/*!
33772 * Bootstrap v4.6.2 (https://getbootstrap.com/)
33773 * Copyright 2011-2022 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
33774 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
33775 */
33776 !function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("jquery"),require("popper.js")):"function"==typeof define&&define.amd?define(["exports","jquery","popper.js"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).bootstrap={},t.jQuery,t.Popper)}(this,(function(t,e,n){"use strict";function i(t){return t&&"object"==typeof t&&"default"in t?t:{default:t}}var o=i(e),a=i(n);function s(t,e){for(var n=0;n<e.length;n++){var i=e[n];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(t,i.key,i)}}function l(t,e,n){return e&&s(t.prototype,e),n&&s(t,n),Object.defineProperty(t,"prototype",{writable:!1}),t}function r(){return r=Object.assign?Object.assign.bind():function(t){for(var e=1;e<arguments.length;e++){var n=arguments[e];for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])}return t},r.apply(this,arguments)}function u(t,e){return u=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(t,e){return t.__proto__=e,t},u(t,e)}var f="transitionend";var d={TRANSITION_END:"bsTransitionEnd",getUID:function(t){do{t+=~~(1e6*Math.random())}while(document.getElementById(t));return t},getSelectorFromElement:function(t){var e=t.getAttribute("data-target");if(!e||"#"===e){var n=t.getAttribute("href");e=n&&"#"!==n?n.trim():""}try{return document.querySelector(e)?e:null}catch(t){return null}},getTransitionDurationFromElement:function(t){if(!t)return 0;var e=o.default(t).css("transition-duration"),n=o.default(t).css("transition-delay"),i=parseFloat(e),a=parseFloat(n);return i||a?(e=e.split(",")[0],n=n.split(",")[0],1e3*(parseFloat(e)+parseFloat(n))):0},reflow:function(t){return t.offsetHeight},triggerTransitionEnd:function(t){o.default(t).trigger(f)},supportsTransitionEnd:function(){return Boolean(f)},isElement:function(t){return(t[0]||t).nodeType},typeCheckConfig:function(t,e,n){for(var i in n)if(Object.prototype.hasOwnProperty.call(n,i)){var o=n[i],a=e[i],s=a&&d.isElement(a)?"element":null===(l=a)||"undefined"==typeof l?""+l:{}.toString.call(l).match(/\s([a-z]+)/i)[1].toLowerCase();if(!new RegExp(o).test(s))throw new Error(t.toUpperCase()+': Option "'+i+'" provided type "'+s+'" but expected type "'+o+'".')}var l},findShadowRoot:function(t){if(!document.documentElement.attachShadow)return null;if("function"==typeof t.getRootNode){var e=t.getRootNode();return e instanceof ShadowRoot?e:null}return t instanceof ShadowRoot?t:t.parentNode?d.findShadowRoot(t.parentNode):null},jQueryDetection:function(){if("undefined"==typeof o.default)throw new TypeError("Bootstrap's JavaScript requires jQuery. jQuery must be included before Bootstrap's JavaScript.");var t=o.default.fn.jquery.split(" ")[0].split(".");if(t[0]<2&&t[1]<9||1===t[0]&&9===t[1]&&t[2]<1||t[0]>=4)throw new Error("Bootstrap's JavaScript requires at least jQuery v1.9.1 but less than v4.0.0")}};d.jQueryDetection(),o.default.fn.emulateTransitionEnd=function(t){var e=this,n=!1;return o.default(this).one(d.TRANSITION_END,(function(){n=!0})),setTimeout((function(){n||d.triggerTransitionEnd(e)}),t),this},o.default.event.special[d.TRANSITION_END]={bindType:f,delegateType:f,handle:function(t){if(o.default(t.target).is(this))return t.handleObj.handler.apply(this,arguments)}};var c="bs.alert",h=o.default.fn.alert,g=function(){function t(t){this._element=t}var e=t.prototype;return e.close=function(t){var e=this._element;t&&(e=this._getRootElement(t)),this._triggerCloseEvent(e).isDefaultPrevented()||this._removeElement(e)},e.dispose=function(){o.default.removeData(this._element,c),this._element=null},e._getRootElement=function(t){var e=d.getSelectorFromElement(t),n=!1;return e&&(n=document.querySelector(e)),n||(n=o.default(t).closest(".alert")[0]),n},e._triggerCloseEvent=function(t){var e=o.default.Event("close.bs.alert");return o.default(t).trigger(e),e},e._removeElement=function(t){var e=this;if(o.default(t).removeClass("show"),o.default(t).hasClass("fade")){var n=d.getTransitionDurationFromElement(t);o.default(t).one(d.TRANSITION_END,(function(n){return e._destroyElement(t,n)})).emulateTransitionEnd(n)}else this._destroyElement(t)},e._destroyElement=function(t){o.default(t).detach().trigger("closed.bs.alert").remove()},t._jQueryInterface=function(e){return this.each((function(){var n=o.default(this),i=n.data(c);i||(i=new t(this),n.data(c,i)),"close"===e&&i[e](this)}))},t._handleDismiss=function(t){return function(e){e&&e.preventDefault(),t.close(this)}},l(t,null,[{key:"VERSION",get:function(){return"4.6.2"}}]),t}();o.default(document).on("click.bs.alert.data-api",'[data-dismiss="alert"]',g._handleDismiss(new g)),o.default.fn.alert=g._jQueryInterface,o.default.fn.alert.Constructor=g,o.default.fn.alert.noConflict=function(){return o.default.fn.alert=h,g._jQueryInterface};var m="bs.button",p=o.default.fn.button,_="active",v='[data-toggle^="button"]',y='input:not([type="hidden"])',b=".btn",E=function(){function t(t){this._element=t,this.shouldAvoidTriggerChange=!1}var e=t.prototype;return e.toggle=function(){var t=!0,e=!0,n=o.default(this._element).closest('[data-toggle="buttons"]')[0];if(n){var i=this._element.querySelector(y);if(i){if("radio"===i.type)if(i.checked&&this._element.classList.contains(_))t=!1;else{var a=n.querySelector(".active");a&&o.default(a).removeClass(_)}t&&("checkbox"!==i.type&&"radio"!==i.type||(i.checked=!this._element.classList.contains(_)),this.shouldAvoidTriggerChange||o.default(i).trigger("change")),i.focus(),e=!1}}this._element.hasAttribute("disabled")||this._element.classList.contains("disabled")||(e&&this._element.setAttribute("aria-pressed",!this._element.classList.contains(_)),t&&o.default(this._element).toggleClass(_))},e.dispose=function(){o.default.removeData(this._element,m),this._element=null},t._jQueryInterface=function(e,n){return this.each((function(){var i=o.default(this),a=i.data(m);a||(a=new t(this),i.data(m,a)),a.shouldAvoidTriggerChange=n,"toggle"===e&&a[e]()}))},l(t,null,[{key:"VERSION",get:function(){return"4.6.2"}}]),t}();o.default(document).on("click.bs.button.data-api",v,(function(t){var e=t.target,n=e;if(o.default(e).hasClass("btn")||(e=o.default(e).closest(b)[0]),!e||e.hasAttribute("disabled")||e.classList.contains("disabled"))t.preventDefault();else{var i=e.querySelector(y);if(i&&(i.hasAttribute("disabled")||i.classList.contains("disabled")))return void t.preventDefault();"INPUT"!==n.tagName&&"LABEL"===e.tagName||E._jQueryInterface.call(o.default(e),"toggle","INPUT"===n.tagName)}})).on("focus.bs.button.data-api blur.bs.button.data-api",v,(function(t){var e=o.default(t.target).closest(b)[0];o.default(e).toggleClass("focus",/^focus(in)?$/.test(t.type))})),o.default(window).on("load.bs.button.data-api",(function(){for(var t=[].slice.call(document.querySelectorAll('[data-toggle="buttons"] .btn')),e=0,n=t.length;e<n;e++){var i=t[e],o=i.querySelector(y);o.checked||o.hasAttribute("checked")?i.classList.add(_):i.classList.remove(_)}for(var a=0,s=(t=[].slice.call(document.querySelectorAll('[data-toggle="button"]'))).length;a<s;a++){var l=t[a];"true"===l.getAttribute("aria-pressed")?l.classList.add(_):l.classList.remove(_)}})),o.default.fn.button=E._jQueryInterface,o.default.fn.button.Constructor=E,o.default.fn.button.noConflict=function(){return o.default.fn.button=p,E._jQueryInterface};var T="carousel",w="bs.carousel",C=o.default.fn[T],S="active",N="next",D="prev",A="slid.bs.carousel",I=".active.carousel-item",k={interval:5e3,keyboard:!0,slide:!1,pause:"hover",wrap:!0,touch:!0},O={interval:"(number|boolean)",keyboard:"boolean",slide:"(boolean|string)",pause:"(string|boolean)",wrap:"boolean",touch:"boolean"},j={TOUCH:"touch",PEN:"pen"},P=function(){function t(t,e){this._items=null,this._interval=null,this._activeElement=null,this._isPaused=!1,this._isSliding=!1,this.touchTimeout=null,this.touchStartX=0,this.touchDeltaX=0,this._config=this._getConfig(e),this._element=t,this._indicatorsElement=this._element.querySelector(".carousel-indicators"),this._touchSupported="ontouchstart"in document.documentElement||navigator.maxTouchPoints>0,this._pointerEvent=Boolean(window.PointerEvent||window.MSPointerEvent),this._addEventListeners()}var e=t.prototype;return e.next=function(){this._isSliding||this._slide(N)},e.nextWhenVisible=function(){var t=o.default(this._element);!document.hidden&&t.is(":visible")&&"hidden"!==t.css("visibility")&&this.next()},e.prev=function(){this._isSliding||this._slide(D)},e.pause=function(t){t||(this._isPaused=!0),this._element.querySelector(".carousel-item-next, .carousel-item-prev")&&(d.triggerTransitionEnd(this._element),this.cycle(!0)),clearInterval(this._interval),this._interval=null},e.cycle=function(t){t||(this._isPaused=!1),this._interval&&(clearInterval(this._interval),this._interval=null),this._config.interval&&!this._isPaused&&(this._updateInterval(),this._interval=setInterval((document.visibilityState?this.nextWhenVisible:this.next).bind(this),this._config.interval))},e.to=function(t){var e=this;this._activeElement=this._element.querySelector(I);var n=this._getItemIndex(this._activeElement);if(!(t>this._items.length-1||t<0))if(this._isSliding)o.default(this._element).one(A,(function(){return e.to(t)}));else{if(n===t)return this.pause(),void this.cycle();var i=t>n?N:D;this._slide(i,this._items[t])}},e.dispose=function(){o.default(this._element).off(".bs.carousel"),o.default.removeData(this._element,w),this._items=null,this._config=null,this._element=null,this._interval=null,this._isPaused=null,this._isSliding=null,this._activeElement=null,this._indicatorsElement=null},e._getConfig=function(t){return t=r({},k,t),d.typeCheckConfig(T,t,O),t},e._handleSwipe=function(){var t=Math.abs(this.touchDeltaX);if(!(t<=40)){var e=t/this.touchDeltaX;this.touchDeltaX=0,e>0&&this.prev(),e<0&&this.next()}},e._addEventListeners=function(){var t=this;this._config.keyboard&&o.default(this._element).on("keydown.bs.carousel",(function(e){return t._keydown(e)})),"hover"===this._config.pause&&o.default(this._element).on("mouseenter.bs.carousel",(function(e){return t.pause(e)})).on("mouseleave.bs.carousel",(function(e){return t.cycle(e)})),this._config.touch&&this._addTouchEventListeners()},e._addTouchEventListeners=function(){var t=this;if(this._touchSupported){var e=function(e){t._pointerEvent&&j[e.originalEvent.pointerType.toUpperCase()]?t.touchStartX=e.originalEvent.clientX:t._pointerEvent||(t.touchStartX=e.originalEvent.touches[0].clientX)},n=function(e){t._pointerEvent&&j[e.originalEvent.pointerType.toUpperCase()]&&(t.touchDeltaX=e.originalEvent.clientX-t.touchStartX),t._handleSwipe(),"hover"===t._config.pause&&(t.pause(),t.touchTimeout&&clearTimeout(t.touchTimeout),t.touchTimeout=setTimeout((function(e){return t.cycle(e)}),500+t._config.interval))};o.default(this._element.querySelectorAll(".carousel-item img")).on("dragstart.bs.carousel",(function(t){return t.preventDefault()})),this._pointerEvent?(o.default(this._element).on("pointerdown.bs.carousel",(function(t){return e(t)})),o.default(this._element).on("pointerup.bs.carousel",(function(t){return n(t)})),this._element.classList.add("pointer-event")):(o.default(this._element).on("touchstart.bs.carousel",(function(t){return e(t)})),o.default(this._element).on("touchmove.bs.carousel",(function(e){return function(e){t.touchDeltaX=e.originalEvent.touches&&e.originalEvent.touches.length>1?0:e.originalEvent.touches[0].clientX-t.touchStartX}(e)})),o.default(this._element).on("touchend.bs.carousel",(function(t){return n(t)})))}},e._keydown=function(t){if(!/input|textarea/i.test(t.target.tagName))switch(t.which){case 37:t.preventDefault(),this.prev();break;case 39:t.preventDefault(),this.next()}},e._getItemIndex=function(t){return this._items=t&&t.parentNode?[].slice.call(t.parentNode.querySelectorAll(".carousel-item")):[],this._items.indexOf(t)},e._getItemByDirection=function(t,e){var n=t===N,i=t===D,o=this._getItemIndex(e),a=this._items.length-1;if((i&&0===o||n&&o===a)&&!this._config.wrap)return e;var s=(o+(t===D?-1:1))%this._items.length;return-1===s?this._items[this._items.length-1]:this._items[s]},e._triggerSlideEvent=function(t,e){var n=this._getItemIndex(t),i=this._getItemIndex(this._element.querySelector(I)),a=o.default.Event("slide.bs.carousel",{relatedTarget:t,direction:e,from:i,to:n});return o.default(this._element).trigger(a),a},e._setActiveIndicatorElement=function(t){if(this._indicatorsElement){var e=[].slice.call(this._indicatorsElement.querySelectorAll(".active"));o.default(e).removeClass(S);var n=this._indicatorsElement.children[this._getItemIndex(t)];n&&o.default(n).addClass(S)}},e._updateInterval=function(){var t=this._activeElement||this._element.querySelector(I);if(t){var e=parseInt(t.getAttribute("data-interval"),10);e?(this._config.defaultInterval=this._config.defaultInterval||this._config.interval,this._config.interval=e):this._config.interval=this._config.defaultInterval||this._config.interval}},e._slide=function(t,e){var n,i,a,s=this,l=this._element.querySelector(I),r=this._getItemIndex(l),u=e||l&&this._getItemByDirection(t,l),f=this._getItemIndex(u),c=Boolean(this._interval);if(t===N?(n="carousel-item-left",i="carousel-item-next",a="left"):(n="carousel-item-right",i="carousel-item-prev",a="right"),u&&o.default(u).hasClass(S))this._isSliding=!1;else if(!this._triggerSlideEvent(u,a).isDefaultPrevented()&&l&&u){this._isSliding=!0,c&&this.pause(),this._setActiveIndicatorElement(u),this._activeElement=u;var h=o.default.Event(A,{relatedTarget:u,direction:a,from:r,to:f});if(o.default(this._element).hasClass("slide")){o.default(u).addClass(i),d.reflow(u),o.default(l).addClass(n),o.default(u).addClass(n);var g=d.getTransitionDurationFromElement(l);o.default(l).one(d.TRANSITION_END,(function(){o.default(u).removeClass(n+" "+i).addClass(S),o.default(l).removeClass("active "+i+" "+n),s._isSliding=!1,setTimeout((function(){return o.default(s._element).trigger(h)}),0)})).emulateTransitionEnd(g)}else o.default(l).removeClass(S),o.default(u).addClass(S),this._isSliding=!1,o.default(this._element).trigger(h);c&&this.cycle()}},t._jQueryInterface=function(e){return this.each((function(){var n=o.default(this).data(w),i=r({},k,o.default(this).data());"object"==typeof e&&(i=r({},i,e));var a="string"==typeof e?e:i.slide;if(n||(n=new t(this,i),o.default(this).data(w,n)),"number"==typeof e)n.to(e);else if("string"==typeof a){if("undefined"==typeof n[a])throw new TypeError('No method named "'+a+'"');n[a]()}else i.interval&&i.ride&&(n.pause(),n.cycle())}))},t._dataApiClickHandler=function(e){var n=d.getSelectorFromElement(this);if(n){var i=o.default(n)[0];if(i&&o.default(i).hasClass("carousel")){var a=r({},o.default(i).data(),o.default(this).data()),s=this.getAttribute("data-slide-to");s&&(a.interval=!1),t._jQueryInterface.call(o.default(i),a),s&&o.default(i).data(w).to(s),e.preventDefault()}}},l(t,null,[{key:"VERSION",get:function(){return"4.6.2"}},{key:"Default",get:function(){return k}}]),t}();o.default(document).on("click.bs.carousel.data-api","[data-slide], [data-slide-to]",P._dataApiClickHandler),o.default(window).on("load.bs.carousel.data-api",(function(){for(var t=[].slice.call(document.querySelectorAll('[data-ride="carousel"]')),e=0,n=t.length;e<n;e++){var i=o.default(t[e]);P._jQueryInterface.call(i,i.data())}})),o.default.fn[T]=P._jQueryInterface,o.default.fn[T].Constructor=P,o.default.fn[T].noConflict=function(){return o.default.fn[T]=C,P._jQueryInterface};var L="collapse",R="bs.collapse",x=o.default.fn[L],q="show",F="collapse",Q="collapsing",B="collapsed",H="width",U='[data-toggle="collapse"]',M={toggle:!0,parent:""},W={toggle:"boolean",parent:"(string|element)"},V=function(){function t(t,e){this._isTransitioning=!1,this._element=t,this._config=this._getConfig(e),this._triggerArray=[].slice.call(document.querySelectorAll('[data-toggle="collapse"][href="#'+t.id+'"],[data-toggle="collapse"][data-target="#'+t.id+'"]'));for(var n=[].slice.call(document.querySelectorAll(U)),i=0,o=n.length;i<o;i++){var a=n[i],s=d.getSelectorFromElement(a),l=[].slice.call(document.querySelectorAll(s)).filter((function(e){return e===t}));null!==s&&l.length>0&&(this._selector=s,this._triggerArray.push(a))}this._parent=this._config.parent?this._getParent():null,this._config.parent||this._addAriaAndCollapsedClass(this._element,this._triggerArray),this._config.toggle&&this.toggle()}var e=t.prototype;return e.toggle=function(){o.default(this._element).hasClass(q)?this.hide():this.show()},e.show=function(){var e,n,i=this;if(!(this._isTransitioning||o.default(this._element).hasClass(q)||(this._parent&&0===(e=[].slice.call(this._parent.querySelectorAll(".show, .collapsing")).filter((function(t){return"string"==typeof i._config.parent?t.getAttribute("data-parent")===i._config.parent:t.classList.contains(F)}))).length&&(e=null),e&&(n=o.default(e).not(this._selector).data(R))&&n._isTransitioning))){var a=o.default.Event("show.bs.collapse");if(o.default(this._element).trigger(a),!a.isDefaultPrevented()){e&&(t._jQueryInterface.call(o.default(e).not(this._selector),"hide"),n||o.default(e).data(R,null));var s=this._getDimension();o.default(this._element).removeClass(F).addClass(Q),this._element.style[s]=0,this._triggerArray.length&&o.default(this._triggerArray).removeClass(B).attr("aria-expanded",!0),this.setTransitioning(!0);var l="scroll"+(s[0].toUpperCase()+s.slice(1)),r=d.getTransitionDurationFromElement(this._element);o.default(this._element).one(d.TRANSITION_END,(function(){o.default(i._element).removeClass(Q).addClass("collapse show"),i._element.style[s]="",i.setTransitioning(!1),o.default(i._element).trigger("shown.bs.collapse")})).emulateTransitionEnd(r),this._element.style[s]=this._element[l]+"px"}}},e.hide=function(){var t=this;if(!this._isTransitioning&&o.default(this._element).hasClass(q)){var e=o.default.Event("hide.bs.collapse");if(o.default(this._element).trigger(e),!e.isDefaultPrevented()){var n=this._getDimension();this._element.style[n]=this._element.getBoundingClientRect()[n]+"px",d.reflow(this._element),o.default(this._element).addClass(Q).removeClass("collapse show");var i=this._triggerArray.length;if(i>0)for(var a=0;a<i;a++){var s=this._triggerArray[a],l=d.getSelectorFromElement(s);null!==l&&(o.default([].slice.call(document.querySelectorAll(l))).hasClass(q)||o.default(s).addClass(B).attr("aria-expanded",!1))}this.setTransitioning(!0),this._element.style[n]="";var r=d.getTransitionDurationFromElement(this._element);o.default(this._element).one(d.TRANSITION_END,(function(){t.setTransitioning(!1),o.default(t._element).removeClass(Q).addClass(F).trigger("hidden.bs.collapse")})).emulateTransitionEnd(r)}}},e.setTransitioning=function(t){this._isTransitioning=t},e.dispose=function(){o.default.removeData(this._element,R),this._config=null,this._parent=null,this._element=null,this._triggerArray=null,this._isTransitioning=null},e._getConfig=function(t){return(t=r({},M,t)).toggle=Boolean(t.toggle),d.typeCheckConfig(L,t,W),t},e._getDimension=function(){return o.default(this._element).hasClass(H)?H:"height"},e._getParent=function(){var e,n=this;d.isElement(this._config.parent)?(e=this._config.parent,"undefined"!=typeof this._config.parent.jquery&&(e=this._config.parent[0])):e=document.querySelector(this._config.parent);var i='[data-toggle="collapse"][data-parent="'+this._config.parent+'"]',a=[].slice.call(e.querySelectorAll(i));return o.default(a).each((function(e,i){n._addAriaAndCollapsedClass(t._getTargetFromElement(i),[i])})),e},e._addAriaAndCollapsedClass=function(t,e){var n=o.default(t).hasClass(q);e.length&&o.default(e).toggleClass(B,!n).attr("aria-expanded",n)},t._getTargetFromElement=function(t){var e=d.getSelectorFromElement(t);return e?document.querySelector(e):null},t._jQueryInterface=function(e){return this.each((function(){var n=o.default(this),i=n.data(R),a=r({},M,n.data(),"object"==typeof e&&e?e:{});if(!i&&a.toggle&&"string"==typeof e&&/show|hide/.test(e)&&(a.toggle=!1),i||(i=new t(this,a),n.data(R,i)),"string"==typeof e){if("undefined"==typeof i[e])throw new TypeError('No method named "'+e+'"');i[e]()}}))},l(t,null,[{key:"VERSION",get:function(){return"4.6.2"}},{key:"Default",get:function(){return M}}]),t}();o.default(document).on("click.bs.collapse.data-api",U,(function(t){"A"===t.currentTarget.tagName&&t.preventDefault();var e=o.default(this),n=d.getSelectorFromElement(this),i=[].slice.call(document.querySelectorAll(n));o.default(i).each((function(){var t=o.default(this),n=t.data(R)?"toggle":e.data();V._jQueryInterface.call(t,n)}))})),o.default.fn[L]=V._jQueryInterface,o.default.fn[L].Constructor=V,o.default.fn[L].noConflict=function(){return o.default.fn[L]=x,V._jQueryInterface};var z="dropdown",K="bs.dropdown",X=o.default.fn[z],Y=new RegExp("38|40|27"),$="disabled",J="show",G="dropdown-menu-right",Z="hide.bs.dropdown",tt="hidden.bs.dropdown",et="click.bs.dropdown.data-api",nt="keydown.bs.dropdown.data-api",it='[data-toggle="dropdown"]',ot=".dropdown-menu",at={offset:0,flip:!0,boundary:"scrollParent",reference:"toggle",display:"dynamic",popperConfig:null},st={offset:"(number|string|function)",flip:"boolean",boundary:"(string|element)",reference:"(string|element)",display:"string",popperConfig:"(null|object)"},lt=function(){function t(t,e){this._element=t,this._popper=null,this._config=this._getConfig(e),this._menu=this._getMenuElement(),this._inNavbar=this._detectNavbar(),this._addEventListeners()}var e=t.prototype;return e.toggle=function(){if(!this._element.disabled&&!o.default(this._element).hasClass($)){var e=o.default(this._menu).hasClass(J);t._clearMenus(),e||this.show(!0)}},e.show=function(e){if(void 0===e&&(e=!1),!(this._element.disabled||o.default(this._element).hasClass($)||o.default(this._menu).hasClass(J))){var n={relatedTarget:this._element},i=o.default.Event("show.bs.dropdown",n),s=t._getParentFromElement(this._element);if(o.default(s).trigger(i),!i.isDefaultPrevented()){if(!this._inNavbar&&e){if("undefined"==typeof a.default)throw new TypeError("Bootstrap's dropdowns require Popper (https://popper.js.org)");var l=this._element;"parent"===this._config.reference?l=s:d.isElement(this._config.reference)&&(l=this._config.reference,"undefined"!=typeof this._config.reference.jquery&&(l=this._config.reference[0])),"scrollParent"!==this._config.boundary&&o.default(s).addClass("position-static"),this._popper=new a.default(l,this._menu,this._getPopperConfig())}"ontouchstart"in document.documentElement&&0===o.default(s).closest(".navbar-nav").length&&o.default(document.body).children().on("mouseover",null,o.default.noop),this._element.focus(),this._element.setAttribute("aria-expanded",!0),o.default(this._menu).toggleClass(J),o.default(s).toggleClass(J).trigger(o.default.Event("shown.bs.dropdown",n))}}},e.hide=function(){if(!this._element.disabled&&!o.default(this._element).hasClass($)&&o.default(this._menu).hasClass(J)){var e={relatedTarget:this._element},n=o.default.Event(Z,e),i=t._getParentFromElement(this._element);o.default(i).trigger(n),n.isDefaultPrevented()||(this._popper&&this._popper.destroy(),o.default(this._menu).toggleClass(J),o.default(i).toggleClass(J).trigger(o.default.Event(tt,e)))}},e.dispose=function(){o.default.removeData(this._element,K),o.default(this._element).off(".bs.dropdown"),this._element=null,this._menu=null,null!==this._popper&&(this._popper.destroy(),this._popper=null)},e.update=function(){this._inNavbar=this._detectNavbar(),null!==this._popper&&this._popper.scheduleUpdate()},e._addEventListeners=function(){var t=this;o.default(this._element).on("click.bs.dropdown",(function(e){e.preventDefault(),e.stopPropagation(),t.toggle()}))},e._getConfig=function(t){return t=r({},this.constructor.Default,o.default(this._element).data(),t),d.typeCheckConfig(z,t,this.constructor.DefaultType),t},e._getMenuElement=function(){if(!this._menu){var e=t._getParentFromElement(this._element);e&&(this._menu=e.querySelector(ot))}return this._menu},e._getPlacement=function(){var t=o.default(this._element.parentNode),e="bottom-start";return t.hasClass("dropup")?e=o.default(this._menu).hasClass(G)?"top-end":"top-start":t.hasClass("dropright")?e="right-start":t.hasClass("dropleft")?e="left-start":o.default(this._menu).hasClass(G)&&(e="bottom-end"),e},e._detectNavbar=function(){return o.default(this._element).closest(".navbar").length>0},e._getOffset=function(){var t=this,e={};return"function"==typeof this._config.offset?e.fn=function(e){return e.offsets=r({},e.offsets,t._config.offset(e.offsets,t._element)),e}:e.offset=this._config.offset,e},e._getPopperConfig=function(){var t={placement:this._getPlacement(),modifiers:{offset:this._getOffset(),flip:{enabled:this._config.flip},preventOverflow:{boundariesElement:this._config.boundary}}};return"static"===this._config.display&&(t.modifiers.applyStyle={enabled:!1}),r({},t,this._config.popperConfig)},t._jQueryInterface=function(e){return this.each((function(){var n=o.default(this).data(K);if(n||(n=new t(this,"object"==typeof e?e:null),o.default(this).data(K,n)),"string"==typeof e){if("undefined"==typeof n[e])throw new TypeError('No method named "'+e+'"');n[e]()}}))},t._clearMenus=function(e){if(!e||3!==e.which&&("keyup"!==e.type||9===e.which))for(var n=[].slice.call(document.querySelectorAll(it)),i=0,a=n.length;i<a;i++){var s=t._getParentFromElement(n[i]),l=o.default(n[i]).data(K),r={relatedTarget:n[i]};if(e&&"click"===e.type&&(r.clickEvent=e),l){var u=l._menu;if(o.default(s).hasClass(J)&&!(e&&("click"===e.type&&/input|textarea/i.test(e.target.tagName)||"keyup"===e.type&&9===e.which)&&o.default.contains(s,e.target))){var f=o.default.Event(Z,r);o.default(s).trigger(f),f.isDefaultPrevented()||("ontouchstart"in document.documentElement&&o.default(document.body).children().off("mouseover",null,o.default.noop),n[i].setAttribute("aria-expanded","false"),l._popper&&l._popper.destroy(),o.default(u).removeClass(J),o.default(s).removeClass(J).trigger(o.default.Event(tt,r)))}}}},t._getParentFromElement=function(t){var e,n=d.getSelectorFromElement(t);return n&&(e=document.querySelector(n)),e||t.parentNode},t._dataApiKeydownHandler=function(e){if(!(/input|textarea/i.test(e.target.tagName)?32===e.which||27!==e.which&&(40!==e.which&&38!==e.which||o.default(e.target).closest(ot).length):!Y.test(e.which))&&!this.disabled&&!o.default(this).hasClass($)){var n=t._getParentFromElement(this),i=o.default(n).hasClass(J);if(i||27!==e.which){if(e.preventDefault(),e.stopPropagation(),!i||27===e.which||32===e.which)return 27===e.which&&o.default(n.querySelector(it)).trigger("focus"),void o.default(this).trigger("click");var a=[].slice.call(n.querySelectorAll(".dropdown-menu .dropdown-item:not(.disabled):not(:disabled)")).filter((function(t){return o.default(t).is(":visible")}));if(0!==a.length){var s=a.indexOf(e.target);38===e.which&&s>0&&s--,40===e.which&&s<a.length-1&&s++,s<0&&(s=0),a[s].focus()}}}},l(t,null,[{key:"VERSION",get:function(){return"4.6.2"}},{key:"Default",get:function(){return at}},{key:"DefaultType",get:function(){return st}}]),t}();o.default(document).on(nt,it,lt._dataApiKeydownHandler).on(nt,ot,lt._dataApiKeydownHandler).on(et+" keyup.bs.dropdown.data-api",lt._clearMenus).on(et,it,(function(t){t.preventDefault(),t.stopPropagation(),lt._jQueryInterface.call(o.default(this),"toggle")})).on(et,".dropdown form",(function(t){t.stopPropagation()})),o.default.fn[z]=lt._jQueryInterface,o.default.fn[z].Constructor=lt,o.default.fn[z].noConflict=function(){return o.default.fn[z]=X,lt._jQueryInterface};var rt="bs.modal",ut=o.default.fn.modal,ft="modal-open",dt="fade",ct="show",ht="modal-static",gt="hidden.bs.modal",mt="show.bs.modal",pt="focusin.bs.modal",_t="resize.bs.modal",vt="click.dismiss.bs.modal",yt="keydown.dismiss.bs.modal",bt="mousedown.dismiss.bs.modal",Et=".fixed-top, .fixed-bottom, .is-fixed, .sticky-top",Tt={backdrop:!0,keyboard:!0,focus:!0,show:!0},wt={backdrop:"(boolean|string)",keyboard:"boolean",focus:"boolean",show:"boolean"},Ct=function(){function t(t,e){this._config=this._getConfig(e),this._element=t,this._dialog=t.querySelector(".modal-dialog"),this._backdrop=null,this._isShown=!1,this._isBodyOverflowing=!1,this._ignoreBackdropClick=!1,this._isTransitioning=!1,this._scrollbarWidth=0}var e=t.prototype;return e.toggle=function(t){return this._isShown?this.hide():this.show(t)},e.show=function(t){var e=this;if(!this._isShown&&!this._isTransitioning){var n=o.default.Event(mt,{relatedTarget:t});o.default(this._element).trigger(n),n.isDefaultPrevented()||(this._isShown=!0,o.default(this._element).hasClass(dt)&&(this._isTransitioning=!0),this._checkScrollbar(),this._setScrollbar(),this._adjustDialog(),this._setEscapeEvent(),this._setResizeEvent(),o.default(this._element).on(vt,'[data-dismiss="modal"]',(function(t){return e.hide(t)})),o.default(this._dialog).on(bt,(function(){o.default(e._element).one("mouseup.dismiss.bs.modal",(function(t){o.default(t.target).is(e._element)&&(e._ignoreBackdropClick=!0)}))})),this._showBackdrop((function(){return e._showElement(t)})))}},e.hide=function(t){var e=this;if(t&&t.preventDefault(),this._isShown&&!this._isTransitioning){var n=o.default.Event("hide.bs.modal");if(o.default(this._element).trigger(n),this._isShown&&!n.isDefaultPrevented()){this._isShown=!1;var i=o.default(this._element).hasClass(dt);if(i&&(this._isTransitioning=!0),this._setEscapeEvent(),this._setResizeEvent(),o.default(document).off(pt),o.default(this._element).removeClass(ct),o.default(this._element).off(vt),o.default(this._dialog).off(bt),i){var a=d.getTransitionDurationFromElement(this._element);o.default(this._element).one(d.TRANSITION_END,(function(t){return e._hideModal(t)})).emulateTransitionEnd(a)}else this._hideModal()}}},e.dispose=function(){[window,this._element,this._dialog].forEach((function(t){return o.default(t).off(".bs.modal")})),o.default(document).off(pt),o.default.removeData(this._element,rt),this._config=null,this._element=null,this._dialog=null,this._backdrop=null,this._isShown=null,this._isBodyOverflowing=null,this._ignoreBackdropClick=null,this._isTransitioning=null,this._scrollbarWidth=null},e.handleUpdate=function(){this._adjustDialog()},e._getConfig=function(t){return t=r({},Tt,t),d.typeCheckConfig("modal",t,wt),t},e._triggerBackdropTransition=function(){var t=this,e=o.default.Event("hidePrevented.bs.modal");if(o.default(this._element).trigger(e),!e.isDefaultPrevented()){var n=this._element.scrollHeight>document.documentElement.clientHeight;n||(this._element.style.overflowY="hidden"),this._element.classList.add(ht);var i=d.getTransitionDurationFromElement(this._dialog);o.default(this._element).off(d.TRANSITION_END),o.default(this._element).one(d.TRANSITION_END,(function(){t._element.classList.remove(ht),n||o.default(t._element).one(d.TRANSITION_END,(function(){t._element.style.overflowY=""})).emulateTransitionEnd(t._element,i)})).emulateTransitionEnd(i),this._element.focus()}},e._showElement=function(t){var e=this,n=o.default(this._element).hasClass(dt),i=this._dialog?this._dialog.querySelector(".modal-body"):null;this._element.parentNode&&this._element.parentNode.nodeType===Node.ELEMENT_NODE||document.body.appendChild(this._element),this._element.style.display="block",this._element.removeAttribute("aria-hidden"),this._element.setAttribute("aria-modal",!0),this._element.setAttribute("role","dialog"),o.default(this._dialog).hasClass("modal-dialog-scrollable")&&i?i.scrollTop=0:this._element.scrollTop=0,n&&d.reflow(this._element),o.default(this._element).addClass(ct),this._config.focus&&this._enforceFocus();var a=o.default.Event("shown.bs.modal",{relatedTarget:t}),s=function(){e._config.focus&&e._element.focus(),e._isTransitioning=!1,o.default(e._element).trigger(a)};if(n){var l=d.getTransitionDurationFromElement(this._dialog);o.default(this._dialog).one(d.TRANSITION_END,s).emulateTransitionEnd(l)}else s()},e._enforceFocus=function(){var t=this;o.default(document).off(pt).on(pt,(function(e){document!==e.target&&t._element!==e.target&&0===o.default(t._element).has(e.target).length&&t._element.focus()}))},e._setEscapeEvent=function(){var t=this;this._isShown?o.default(this._element).on(yt,(function(e){t._config.keyboard&&27===e.which?(e.preventDefault(),t.hide()):t._config.keyboard||27!==e.which||t._triggerBackdropTransition()})):this._isShown||o.default(this._element).off(yt)},e._setResizeEvent=function(){var t=this;this._isShown?o.default(window).on(_t,(function(e){return t.handleUpdate(e)})):o.default(window).off(_t)},e._hideModal=function(){var t=this;this._element.style.display="none",this._element.setAttribute("aria-hidden",!0),this._element.removeAttribute("aria-modal"),this._element.removeAttribute("role"),this._isTransitioning=!1,this._showBackdrop((function(){o.default(document.body).removeClass(ft),t._resetAdjustments(),t._resetScrollbar(),o.default(t._element).trigger(gt)}))},e._removeBackdrop=function(){this._backdrop&&(o.default(this._backdrop).remove(),this._backdrop=null)},e._showBackdrop=function(t){var e=this,n=o.default(this._element).hasClass(dt)?dt:"";if(this._isShown&&this._config.backdrop){if(this._backdrop=document.createElement("div"),this._backdrop.className="modal-backdrop",n&&this._backdrop.classList.add(n),o.default(this._backdrop).appendTo(document.body),o.default(this._element).on(vt,(function(t){e._ignoreBackdropClick?e._ignoreBackdropClick=!1:t.target===t.currentTarget&&("static"===e._config.backdrop?e._triggerBackdropTransition():e.hide())})),n&&d.reflow(this._backdrop),o.default(this._backdrop).addClass(ct),!t)return;if(!n)return void t();var i=d.getTransitionDurationFromElement(this._backdrop);o.default(this._backdrop).one(d.TRANSITION_END,t).emulateTransitionEnd(i)}else if(!this._isShown&&this._backdrop){o.default(this._backdrop).removeClass(ct);var a=function(){e._removeBackdrop(),t&&t()};if(o.default(this._element).hasClass(dt)){var s=d.getTransitionDurationFromElement(this._backdrop);o.default(this._backdrop).one(d.TRANSITION_END,a).emulateTransitionEnd(s)}else a()}else t&&t()},e._adjustDialog=function(){var t=this._element.scrollHeight>document.documentElement.clientHeight;!this._isBodyOverflowing&&t&&(this._element.style.paddingLeft=this._scrollbarWidth+"px"),this._isBodyOverflowing&&!t&&(this._element.style.paddingRight=this._scrollbarWidth+"px")},e._resetAdjustments=function(){this._element.style.paddingLeft="",this._element.style.paddingRight=""},e._checkScrollbar=function(){var t=document.body.getBoundingClientRect();this._isBodyOverflowing=Math.round(t.left+t.right)<window.innerWidth,this._scrollbarWidth=this._getScrollbarWidth()},e._setScrollbar=function(){var t=this;if(this._isBodyOverflowing){var e=[].slice.call(document.querySelectorAll(Et)),n=[].slice.call(document.querySelectorAll(".sticky-top"));o.default(e).each((function(e,n){var i=n.style.paddingRight,a=o.default(n).css("padding-right");o.default(n).data("padding-right",i).css("padding-right",parseFloat(a)+t._scrollbarWidth+"px")})),o.default(n).each((function(e,n){var i=n.style.marginRight,a=o.default(n).css("margin-right");o.default(n).data("margin-right",i).css("margin-right",parseFloat(a)-t._scrollbarWidth+"px")}));var i=document.body.style.paddingRight,a=o.default(document.body).css("padding-right");o.default(document.body).data("padding-right",i).css("padding-right",parseFloat(a)+this._scrollbarWidth+"px")}o.default(document.body).addClass(ft)},e._resetScrollbar=function(){var t=[].slice.call(document.querySelectorAll(Et));o.default(t).each((function(t,e){var n=o.default(e).data("padding-right");o.default(e).removeData("padding-right"),e.style.paddingRight=n||""}));var e=[].slice.call(document.querySelectorAll(".sticky-top"));o.default(e).each((function(t,e){var n=o.default(e).data("margin-right");"undefined"!=typeof n&&o.default(e).css("margin-right",n).removeData("margin-right")}));var n=o.default(document.body).data("padding-right");o.default(document.body).removeData("padding-right"),document.body.style.paddingRight=n||""},e._getScrollbarWidth=function(){var t=document.createElement("div");t.className="modal-scrollbar-measure",document.body.appendChild(t);var e=t.getBoundingClientRect().width-t.clientWidth;return document.body.removeChild(t),e},t._jQueryInterface=function(e,n){return this.each((function(){var i=o.default(this).data(rt),a=r({},Tt,o.default(this).data(),"object"==typeof e&&e?e:{});if(i||(i=new t(this,a),o.default(this).data(rt,i)),"string"==typeof e){if("undefined"==typeof i[e])throw new TypeError('No method named "'+e+'"');i[e](n)}else a.show&&i.show(n)}))},l(t,null,[{key:"VERSION",get:function(){return"4.6.2"}},{key:"Default",get:function(){return Tt}}]),t}();o.default(document).on("click.bs.modal.data-api",'[data-toggle="modal"]',(function(t){var e,n=this,i=d.getSelectorFromElement(this);i&&(e=document.querySelector(i));var a=o.default(e).data(rt)?"toggle":r({},o.default(e).data(),o.default(this).data());"A"!==this.tagName&&"AREA"!==this.tagName||t.preventDefault();var s=o.default(e).one(mt,(function(t){t.isDefaultPrevented()||s.one(gt,(function(){o.default(n).is(":visible")&&n.focus()}))}));Ct._jQueryInterface.call(o.default(e),a,this)})),o.default.fn.modal=Ct._jQueryInterface,o.default.fn.modal.Constructor=Ct,o.default.fn.modal.noConflict=function(){return o.default.fn.modal=ut,Ct._jQueryInterface};var St=["background","cite","href","itemtype","longdesc","poster","src","xlink:href"],Nt=/^(?:(?:https?|mailto|ftp|tel|file|sms):|[^#&/:?]*(?:[#/?]|$))/i,Dt=/^data:(?:image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\/(?:mpeg|mp4|ogg|webm)|audio\/(?:mp3|oga|ogg|opus));base64,[\d+/a-z]+=*$/i;function At(t,e,n){if(0===t.length)return t;if(n&&"function"==typeof n)return n(t);for(var i=(new window.DOMParser).parseFromString(t,"text/html"),o=Object.keys(e),a=[].slice.call(i.body.querySelectorAll("*")),s=function(t,n){var i=a[t],s=i.nodeName.toLowerCase();if(-1===o.indexOf(i.nodeName.toLowerCase()))return i.parentNode.removeChild(i),"continue";var l=[].slice.call(i.attributes),r=[].concat(e["*"]||[],e[s]||[]);l.forEach((function(t){(function(t,e){var n=t.nodeName.toLowerCase();if(-1!==e.indexOf(n))return-1===St.indexOf(n)||Boolean(Nt.test(t.nodeValue)||Dt.test(t.nodeValue));for(var i=e.filter((function(t){return t instanceof RegExp})),o=0,a=i.length;o<a;o++)if(i[o].test(n))return!0;return!1})(t,r)||i.removeAttribute(t.nodeName)}))},l=0,r=a.length;l<r;l++)s(l);return i.body.innerHTML}var It="tooltip",kt="bs.tooltip",Ot=o.default.fn.tooltip,jt=new RegExp("(^|\\s)bs-tooltip\\S+","g"),Pt=["sanitize","whiteList","sanitizeFn"],Lt="fade",Rt="show",xt="show",qt="out",Ft="hover",Qt="focus",Bt={AUTO:"auto",TOP:"top",RIGHT:"right",BOTTOM:"bottom",LEFT:"left"},Ht={animation:!0,template:'<div class="tooltip" role="tooltip"><div class="arrow"></div><div class="tooltip-inner"></div></div>',trigger:"hover focus",title:"",delay:0,html:!1,selector:!1,placement:"top",offset:0,container:!1,fallbackPlacement:"flip",boundary:"scrollParent",customClass:"",sanitize:!0,sanitizeFn:null,whiteList:{"*":["class","dir","id","lang","role",/^aria-[\w-]*$/i],a:["target","href","title","rel"],area:[],b:[],br:[],col:[],code:[],div:[],em:[],hr:[],h1:[],h2:[],h3:[],h4:[],h5:[],h6:[],i:[],img:["src","srcset","alt","title","width","height"],li:[],ol:[],p:[],pre:[],s:[],small:[],span:[],sub:[],sup:[],strong:[],u:[],ul:[]},popperConfig:null},Ut={animation:"boolean",template:"string",title:"(string|element|function)",trigger:"string",delay:"(number|object)",html:"boolean",selector:"(string|boolean)",placement:"(string|function)",offset:"(number|string|function)",container:"(string|element|boolean)",fallbackPlacement:"(string|array)",boundary:"(string|element)",customClass:"(string|function)",sanitize:"boolean",sanitizeFn:"(null|function)",whiteList:"object",popperConfig:"(null|object)"},Mt={HIDE:"hide.bs.tooltip",HIDDEN:"hidden.bs.tooltip",SHOW:"show.bs.tooltip",SHOWN:"shown.bs.tooltip",INSERTED:"inserted.bs.tooltip",CLICK:"click.bs.tooltip",FOCUSIN:"focusin.bs.tooltip",FOCUSOUT:"focusout.bs.tooltip",MOUSEENTER:"mouseenter.bs.tooltip",MOUSELEAVE:"mouseleave.bs.tooltip"},Wt=function(){function t(t,e){if("undefined"==typeof a.default)throw new TypeError("Bootstrap's tooltips require Popper (https://popper.js.org)");this._isEnabled=!0,this._timeout=0,this._hoverState="",this._activeTrigger={},this._popper=null,this.element=t,this.config=this._getConfig(e),this.tip=null,this._setListeners()}var e=t.prototype;return e.enable=function(){this._isEnabled=!0},e.disable=function(){this._isEnabled=!1},e.toggleEnabled=function(){this._isEnabled=!this._isEnabled},e.toggle=function(t){if(this._isEnabled)if(t){var e=this.constructor.DATA_KEY,n=o.default(t.currentTarget).data(e);n||(n=new this.constructor(t.currentTarget,this._getDelegateConfig()),o.default(t.currentTarget).data(e,n)),n._activeTrigger.click=!n._activeTrigger.click,n._isWithActiveTrigger()?n._enter(null,n):n._leave(null,n)}else{if(o.default(this.getTipElement()).hasClass(Rt))return void this._leave(null,this);this._enter(null,this)}},e.dispose=function(){clearTimeout(this._timeout),o.default.removeData(this.element,this.constructor.DATA_KEY),o.default(this.element).off(this.constructor.EVENT_KEY),o.default(this.element).closest(".modal").off("hide.bs.modal",this._hideModalHandler),this.tip&&o.default(this.tip).remove(),this._isEnabled=null,this._timeout=null,this._hoverState=null,this._activeTrigger=null,this._popper&&this._popper.destroy(),this._popper=null,this.element=null,this.config=null,this.tip=null},e.show=function(){var t=this;if("none"===o.default(this.element).css("display"))throw new Error("Please use show on visible elements");var e=o.default.Event(this.constructor.Event.SHOW);if(this.isWithContent()&&this._isEnabled){o.default(this.element).trigger(e);var n=d.findShadowRoot(this.element),i=o.default.contains(null!==n?n:this.element.ownerDocument.documentElement,this.element);if(e.isDefaultPrevented()||!i)return;var s=this.getTipElement(),l=d.getUID(this.constructor.NAME);s.setAttribute("id",l),this.element.setAttribute("aria-describedby",l),this.setContent(),this.config.animation&&o.default(s).addClass(Lt);var r="function"==typeof this.config.placement?this.config.placement.call(this,s,this.element):this.config.placement,u=this._getAttachment(r);this.addAttachmentClass(u);var f=this._getContainer();o.default(s).data(this.constructor.DATA_KEY,this),o.default.contains(this.element.ownerDocument.documentElement,this.tip)||o.default(s).appendTo(f),o.default(this.element).trigger(this.constructor.Event.INSERTED),this._popper=new a.default(this.element,s,this._getPopperConfig(u)),o.default(s).addClass(Rt),o.default(s).addClass(this.config.customClass),"ontouchstart"in document.documentElement&&o.default(document.body).children().on("mouseover",null,o.default.noop);var c=function(){t.config.animation&&t._fixTransition();var e=t._hoverState;t._hoverState=null,o.default(t.element).trigger(t.constructor.Event.SHOWN),e===qt&&t._leave(null,t)};if(o.default(this.tip).hasClass(Lt)){var h=d.getTransitionDurationFromElement(this.tip);o.default(this.tip).one(d.TRANSITION_END,c).emulateTransitionEnd(h)}else c()}},e.hide=function(t){var e=this,n=this.getTipElement(),i=o.default.Event(this.constructor.Event.HIDE),a=function(){e._hoverState!==xt&&n.parentNode&&n.parentNode.removeChild(n),e._cleanTipClass(),e.element.removeAttribute("aria-describedby"),o.default(e.element).trigger(e.constructor.Event.HIDDEN),null!==e._popper&&e._popper.destroy(),t&&t()};if(o.default(this.element).trigger(i),!i.isDefaultPrevented()){if(o.default(n).removeClass(Rt),"ontouchstart"in document.documentElement&&o.default(document.body).children().off("mouseover",null,o.default.noop),this._activeTrigger.click=!1,this._activeTrigger.focus=!1,this._activeTrigger.hover=!1,o.default(this.tip).hasClass(Lt)){var s=d.getTransitionDurationFromElement(n);o.default(n).one(d.TRANSITION_END,a).emulateTransitionEnd(s)}else a();this._hoverState=""}},e.update=function(){null!==this._popper&&this._popper.scheduleUpdate()},e.isWithContent=function(){return Boolean(this.getTitle())},e.addAttachmentClass=function(t){o.default(this.getTipElement()).addClass("bs-tooltip-"+t)},e.getTipElement=function(){return this.tip=this.tip||o.default(this.config.template)[0],this.tip},e.setContent=function(){var t=this.getTipElement();this.setElementContent(o.default(t.querySelectorAll(".tooltip-inner")),this.getTitle()),o.default(t).removeClass("fade show")},e.setElementContent=function(t,e){"object"!=typeof e||!e.nodeType&&!e.jquery?this.config.html?(this.config.sanitize&&(e=At(e,this.config.whiteList,this.config.sanitizeFn)),t.html(e)):t.text(e):this.config.html?o.default(e).parent().is(t)||t.empty().append(e):t.text(o.default(e).text())},e.getTitle=function(){var t=this.element.getAttribute("data-original-title");return t||(t="function"==typeof this.config.title?this.config.title.call(this.element):this.config.title),t},e._getPopperConfig=function(t){var e=this;return r({},{placement:t,modifiers:{offset:this._getOffset(),flip:{behavior:this.config.fallbackPlacement},arrow:{element:".arrow"},preventOverflow:{boundariesElement:this.config.boundary}},onCreate:function(t){t.originalPlacement!==t.placement&&e._handlePopperPlacementChange(t)},onUpdate:function(t){return e._handlePopperPlacementChange(t)}},this.config.popperConfig)},e._getOffset=function(){var t=this,e={};return"function"==typeof this.config.offset?e.fn=function(e){return e.offsets=r({},e.offsets,t.config.offset(e.offsets,t.element)),e}:e.offset=this.config.offset,e},e._getContainer=function(){return!1===this.config.container?document.body:d.isElement(this.config.container)?o.default(this.config.container):o.default(document).find(this.config.container)},e._getAttachment=function(t){return Bt[t.toUpperCase()]},e._setListeners=function(){var t=this;this.config.trigger.split(" ").forEach((function(e){if("click"===e)o.default(t.element).on(t.constructor.Event.CLICK,t.config.selector,(function(e){return t.toggle(e)}));else if("manual"!==e){var n=e===Ft?t.constructor.Event.MOUSEENTER:t.constructor.Event.FOCUSIN,i=e===Ft?t.constructor.Event.MOUSELEAVE:t.constructor.Event.FOCUSOUT;o.default(t.element).on(n,t.config.selector,(function(e){return t._enter(e)})).on(i,t.config.selector,(function(e){return t._leave(e)}))}})),this._hideModalHandler=function(){t.element&&t.hide()},o.default(this.element).closest(".modal").on("hide.bs.modal",this._hideModalHandler),this.config.selector?this.config=r({},this.config,{trigger:"manual",selector:""}):this._fixTitle()},e._fixTitle=function(){var t=typeof this.element.getAttribute("data-original-title");(this.element.getAttribute("title")||"string"!==t)&&(this.element.setAttribute("data-original-title",this.element.getAttribute("title")||""),this.element.setAttribute("title",""))},e._enter=function(t,e){var n=this.constructor.DATA_KEY;(e=e||o.default(t.currentTarget).data(n))||(e=new this.constructor(t.currentTarget,this._getDelegateConfig()),o.default(t.currentTarget).data(n,e)),t&&(e._activeTrigger["focusin"===t.type?Qt:Ft]=!0),o.default(e.getTipElement()).hasClass(Rt)||e._hoverState===xt?e._hoverState=xt:(clearTimeout(e._timeout),e._hoverState=xt,e.config.delay&&e.config.delay.show?e._timeout=setTimeout((function(){e._hoverState===xt&&e.show()}),e.config.delay.show):e.show())},e._leave=function(t,e){var n=this.constructor.DATA_KEY;(e=e||o.default(t.currentTarget).data(n))||(e=new this.constructor(t.currentTarget,this._getDelegateConfig()),o.default(t.currentTarget).data(n,e)),t&&(e._activeTrigger["focusout"===t.type?Qt:Ft]=!1),e._isWithActiveTrigger()||(clearTimeout(e._timeout),e._hoverState=qt,e.config.delay&&e.config.delay.hide?e._timeout=setTimeout((function(){e._hoverState===qt&&e.hide()}),e.config.delay.hide):e.hide())},e._isWithActiveTrigger=function(){for(var t in this._activeTrigger)if(this._activeTrigger[t])return!0;return!1},e._getConfig=function(t){var e=o.default(this.element).data();return Object.keys(e).forEach((function(t){-1!==Pt.indexOf(t)&&delete e[t]})),"number"==typeof(t=r({},this.constructor.Default,e,"object"==typeof t&&t?t:{})).delay&&(t.delay={show:t.delay,hide:t.delay}),"number"==typeof t.title&&(t.title=t.title.toString()),"number"==typeof t.content&&(t.content=t.content.toString()),d.typeCheckConfig(It,t,this.constructor.DefaultType),t.sanitize&&(t.template=At(t.template,t.whiteList,t.sanitizeFn)),t},e._getDelegateConfig=function(){var t={};if(this.config)for(var e in this.config)this.constructor.Default[e]!==this.config[e]&&(t[e]=this.config[e]);return t},e._cleanTipClass=function(){var t=o.default(this.getTipElement()),e=t.attr("class").match(jt);null!==e&&e.length&&t.removeClass(e.join(""))},e._handlePopperPlacementChange=function(t){this.tip=t.instance.popper,this._cleanTipClass(),this.addAttachmentClass(this._getAttachment(t.placement))},e._fixTransition=function(){var t=this.getTipElement(),e=this.config.animation;null===t.getAttribute("x-placement")&&(o.default(t).removeClass(Lt),this.config.animation=!1,this.hide(),this.show(),this.config.animation=e)},t._jQueryInterface=function(e){return this.each((function(){var n=o.default(this),i=n.data(kt),a="object"==typeof e&&e;if((i||!/dispose|hide/.test(e))&&(i||(i=new t(this,a),n.data(kt,i)),"string"==typeof e)){if("undefined"==typeof i[e])throw new TypeError('No method named "'+e+'"');i[e]()}}))},l(t,null,[{key:"VERSION",get:function(){return"4.6.2"}},{key:"Default",get:function(){return Ht}},{key:"NAME",get:function(){return It}},{key:"DATA_KEY",get:function(){return kt}},{key:"Event",get:function(){return Mt}},{key:"EVENT_KEY",get:function(){return".bs.tooltip"}},{key:"DefaultType",get:function(){return Ut}}]),t}();o.default.fn.tooltip=Wt._jQueryInterface,o.default.fn.tooltip.Constructor=Wt,o.default.fn.tooltip.noConflict=function(){return o.default.fn.tooltip=Ot,Wt._jQueryInterface};var Vt="bs.popover",zt=o.default.fn.popover,Kt=new RegExp("(^|\\s)bs-popover\\S+","g"),Xt=r({},Wt.Default,{placement:"right",trigger:"click",content:"",template:'<div class="popover" role="tooltip"><div class="arrow"></div><h3 class="popover-header"></h3><div class="popover-body"></div></div>'}),Yt=r({},Wt.DefaultType,{content:"(string|element|function)"}),$t={HIDE:"hide.bs.popover",HIDDEN:"hidden.bs.popover",SHOW:"show.bs.popover",SHOWN:"shown.bs.popover",INSERTED:"inserted.bs.popover",CLICK:"click.bs.popover",FOCUSIN:"focusin.bs.popover",FOCUSOUT:"focusout.bs.popover",MOUSEENTER:"mouseenter.bs.popover",MOUSELEAVE:"mouseleave.bs.popover"},Jt=function(t){var e,n;function i(){return t.apply(this,arguments)||this}n=t,(e=i).prototype=Object.create(n.prototype),e.prototype.constructor=e,u(e,n);var a=i.prototype;return a.isWithContent=function(){return this.getTitle()||this._getContent()},a.addAttachmentClass=function(t){o.default(this.getTipElement()).addClass("bs-popover-"+t)},a.getTipElement=function(){return this.tip=this.tip||o.default(this.config.template)[0],this.tip},a.setContent=function(){var t=o.default(this.getTipElement());this.setElementContent(t.find(".popover-header"),this.getTitle());var e=this._getContent();"function"==typeof e&&(e=e.call(this.element)),this.setElementContent(t.find(".popover-body"),e),t.removeClass("fade show")},a._getContent=function(){return this.element.getAttribute("data-content")||this.config.content},a._cleanTipClass=function(){var t=o.default(this.getTipElement()),e=t.attr("class").match(Kt);null!==e&&e.length>0&&t.removeClass(e.join(""))},i._jQueryInterface=function(t){return this.each((function(){var e=o.default(this).data(Vt),n="object"==typeof t?t:null;if((e||!/dispose|hide/.test(t))&&(e||(e=new i(this,n),o.default(this).data(Vt,e)),"string"==typeof t)){if("undefined"==typeof e[t])throw new TypeError('No method named "'+t+'"');e[t]()}}))},l(i,null,[{key:"VERSION",get:function(){return"4.6.2"}},{key:"Default",get:function(){return Xt}},{key:"NAME",get:function(){return"popover"}},{key:"DATA_KEY",get:function(){return Vt}},{key:"Event",get:function(){return $t}},{key:"EVENT_KEY",get:function(){return".bs.popover"}},{key:"DefaultType",get:function(){return Yt}}]),i}(Wt);o.default.fn.popover=Jt._jQueryInterface,o.default.fn.popover.Constructor=Jt,o.default.fn.popover.noConflict=function(){return o.default.fn.popover=zt,Jt._jQueryInterface};var Gt="scrollspy",Zt="bs.scrollspy",te=o.default.fn[Gt],ee="active",ne="position",ie=".nav, .list-group",oe={offset:10,method:"auto",target:""},ae={offset:"number",method:"string",target:"(string|element)"},se=function(){function t(t,e){var n=this;this._element=t,this._scrollElement="BODY"===t.tagName?window:t,this._config=this._getConfig(e),this._selector=this._config.target+" .nav-link,"+this._config.target+" .list-group-item,"+this._config.target+" .dropdown-item",this._offsets=[],this._targets=[],this._activeTarget=null,this._scrollHeight=0,o.default(this._scrollElement).on("scroll.bs.scrollspy",(function(t){return n._process(t)})),this.refresh(),this._process()}var e=t.prototype;return e.refresh=function(){var t=this,e=this._scrollElement===this._scrollElement.window?"offset":ne,n="auto"===this._config.method?e:this._config.method,i=n===ne?this._getScrollTop():0;this._offsets=[],this._targets=[],this._scrollHeight=this._getScrollHeight(),[].slice.call(document.querySelectorAll(this._selector)).map((function(t){var e,a=d.getSelectorFromElement(t);if(a&&(e=document.querySelector(a)),e){var s=e.getBoundingClientRect();if(s.width||s.height)return[o.default(e)[n]().top+i,a]}return null})).filter(Boolean).sort((function(t,e){return t[0]-e[0]})).forEach((function(e){t._offsets.push(e[0]),t._targets.push(e[1])}))},e.dispose=function(){o.default.removeData(this._element,Zt),o.default(this._scrollElement).off(".bs.scrollspy"),this._element=null,this._scrollElement=null,this._config=null,this._selector=null,this._offsets=null,this._targets=null,this._activeTarget=null,this._scrollHeight=null},e._getConfig=function(t){if("string"!=typeof(t=r({},oe,"object"==typeof t&&t?t:{})).target&&d.isElement(t.target)){var e=o.default(t.target).attr("id");e||(e=d.getUID(Gt),o.default(t.target).attr("id",e)),t.target="#"+e}return d.typeCheckConfig(Gt,t,ae),t},e._getScrollTop=function(){return this._scrollElement===window?this._scrollElement.pageYOffset:this._scrollElement.scrollTop},e._getScrollHeight=function(){return this._scrollElement.scrollHeight||Math.max(document.body.scrollHeight,document.documentElement.scrollHeight)},e._getOffsetHeight=function(){return this._scrollElement===window?window.innerHeight:this._scrollElement.getBoundingClientRect().height},e._process=function(){var t=this._getScrollTop()+this._config.offset,e=this._getScrollHeight(),n=this._config.offset+e-this._getOffsetHeight();if(this._scrollHeight!==e&&this.refresh(),t>=n){var i=this._targets[this._targets.length-1];this._activeTarget!==i&&this._activate(i)}else{if(this._activeTarget&&t<this._offsets[0]&&this._offsets[0]>0)return this._activeTarget=null,void this._clear();for(var o=this._offsets.length;o--;)this._activeTarget!==this._targets[o]&&t>=this._offsets[o]&&("undefined"==typeof this._offsets[o+1]||t<this._offsets[o+1])&&this._activate(this._targets[o])}},e._activate=function(t){this._activeTarget=t,this._clear();var e=this._selector.split(",").map((function(e){return e+'[data-target="'+t+'"],'+e+'[href="'+t+'"]'})),n=o.default([].slice.call(document.querySelectorAll(e.join(","))));n.hasClass("dropdown-item")?(n.closest(".dropdown").find(".dropdown-toggle").addClass(ee),n.addClass(ee)):(n.addClass(ee),n.parents(ie).prev(".nav-link, .list-group-item").addClass(ee),n.parents(ie).prev(".nav-item").children(".nav-link").addClass(ee)),o.default(this._scrollElement).trigger("activate.bs.scrollspy",{relatedTarget:t})},e._clear=function(){[].slice.call(document.querySelectorAll(this._selector)).filter((function(t){return t.classList.contains(ee)})).forEach((function(t){return t.classList.remove(ee)}))},t._jQueryInterface=function(e){return this.each((function(){var n=o.default(this).data(Zt);if(n||(n=new t(this,"object"==typeof e&&e),o.default(this).data(Zt,n)),"string"==typeof e){if("undefined"==typeof n[e])throw new TypeError('No method named "'+e+'"');n[e]()}}))},l(t,null,[{key:"VERSION",get:function(){return"4.6.2"}},{key:"Default",get:function(){return oe}}]),t}();o.default(window).on("load.bs.scrollspy.data-api",(function(){for(var t=[].slice.call(document.querySelectorAll('[data-spy="scroll"]')),e=t.length;e--;){var n=o.default(t[e]);se._jQueryInterface.call(n,n.data())}})),o.default.fn[Gt]=se._jQueryInterface,o.default.fn[Gt].Constructor=se,o.default.fn[Gt].noConflict=function(){return o.default.fn[Gt]=te,se._jQueryInterface};var le="bs.tab",re=o.default.fn.tab,ue="active",fe="fade",de="show",ce=".active",he="> li > .active",ge=function(){function t(t){this._element=t}var e=t.prototype;return e.show=function(){var t=this;if(!(this._element.parentNode&&this._element.parentNode.nodeType===Node.ELEMENT_NODE&&o.default(this._element).hasClass(ue)||o.default(this._element).hasClass("disabled")||this._element.hasAttribute("disabled"))){var e,n,i=o.default(this._element).closest(".nav, .list-group")[0],a=d.getSelectorFromElement(this._element);if(i){var s="UL"===i.nodeName||"OL"===i.nodeName?he:ce;n=(n=o.default.makeArray(o.default(i).find(s)))[n.length-1]}var l=o.default.Event("hide.bs.tab",{relatedTarget:this._element}),r=o.default.Event("show.bs.tab",{relatedTarget:n});if(n&&o.default(n).trigger(l),o.default(this._element).trigger(r),!r.isDefaultPrevented()&&!l.isDefaultPrevented()){a&&(e=document.querySelector(a)),this._activate(this._element,i);var u=function(){var e=o.default.Event("hidden.bs.tab",{relatedTarget:t._element}),i=o.default.Event("shown.bs.tab",{relatedTarget:n});o.default(n).trigger(e),o.default(t._element).trigger(i)};e?this._activate(e,e.parentNode,u):u()}}},e.dispose=function(){o.default.removeData(this._element,le),this._element=null},e._activate=function(t,e,n){var i=this,a=(!e||"UL"!==e.nodeName&&"OL"!==e.nodeName?o.default(e).children(ce):o.default(e).find(he))[0],s=n&&a&&o.default(a).hasClass(fe),l=function(){return i._transitionComplete(t,a,n)};if(a&&s){var r=d.getTransitionDurationFromElement(a);o.default(a).removeClass(de).one(d.TRANSITION_END,l).emulateTransitionEnd(r)}else l()},e._transitionComplete=function(t,e,n){if(e){o.default(e).removeClass(ue);var i=o.default(e.parentNode).find("> .dropdown-menu .active")[0];i&&o.default(i).removeClass(ue),"tab"===e.getAttribute("role")&&e.setAttribute("aria-selected",!1)}o.default(t).addClass(ue),"tab"===t.getAttribute("role")&&t.setAttribute("aria-selected",!0),d.reflow(t),t.classList.contains(fe)&&t.classList.add(de);var a=t.parentNode;if(a&&"LI"===a.nodeName&&(a=a.parentNode),a&&o.default(a).hasClass("dropdown-menu")){var s=o.default(t).closest(".dropdown")[0];if(s){var l=[].slice.call(s.querySelectorAll(".dropdown-toggle"));o.default(l).addClass(ue)}t.setAttribute("aria-expanded",!0)}n&&n()},t._jQueryInterface=function(e){return this.each((function(){var n=o.default(this),i=n.data(le);if(i||(i=new t(this),n.data(le,i)),"string"==typeof e){if("undefined"==typeof i[e])throw new TypeError('No method named "'+e+'"');i[e]()}}))},l(t,null,[{key:"VERSION",get:function(){return"4.6.2"}}]),t}();o.default(document).on("click.bs.tab.data-api",'[data-toggle="tab"], [data-toggle="pill"], [data-toggle="list"]',(function(t){t.preventDefault(),ge._jQueryInterface.call(o.default(this),"show")})),o.default.fn.tab=ge._jQueryInterface,o.default.fn.tab.Constructor=ge,o.default.fn.tab.noConflict=function(){return o.default.fn.tab=re,ge._jQueryInterface};var me="bs.toast",pe=o.default.fn.toast,_e="hide",ve="show",ye="showing",be="click.dismiss.bs.toast",Ee={animation:!0,autohide:!0,delay:500},Te={animation:"boolean",autohide:"boolean",delay:"number"},we=function(){function t(t,e){this._element=t,this._config=this._getConfig(e),this._timeout=null,this._setListeners()}var e=t.prototype;return e.show=function(){var t=this,e=o.default.Event("show.bs.toast");if(o.default(this._element).trigger(e),!e.isDefaultPrevented()){this._clearTimeout(),this._config.animation&&this._element.classList.add("fade");var n=function(){t._element.classList.remove(ye),t._element.classList.add(ve),o.default(t._element).trigger("shown.bs.toast"),t._config.autohide&&(t._timeout=setTimeout((function(){t.hide()}),t._config.delay))};if(this._element.classList.remove(_e),d.reflow(this._element),this._element.classList.add(ye),this._config.animation){var i=d.getTransitionDurationFromElement(this._element);o.default(this._element).one(d.TRANSITION_END,n).emulateTransitionEnd(i)}else n()}},e.hide=function(){if(this._element.classList.contains(ve)){var t=o.default.Event("hide.bs.toast");o.default(this._element).trigger(t),t.isDefaultPrevented()||this._close()}},e.dispose=function(){this._clearTimeout(),this._element.classList.contains(ve)&&this._element.classList.remove(ve),o.default(this._element).off(be),o.default.removeData(this._element,me),this._element=null,this._config=null},e._getConfig=function(t){return t=r({},Ee,o.default(this._element).data(),"object"==typeof t&&t?t:{}),d.typeCheckConfig("toast",t,this.constructor.DefaultType),t},e._setListeners=function(){var t=this;o.default(this._element).on(be,'[data-dismiss="toast"]',(function(){return t.hide()}))},e._close=function(){var t=this,e=function(){t._element.classList.add(_e),o.default(t._element).trigger("hidden.bs.toast")};if(this._element.classList.remove(ve),this._config.animation){var n=d.getTransitionDurationFromElement(this._element);o.default(this._element).one(d.TRANSITION_END,e).emulateTransitionEnd(n)}else e()},e._clearTimeout=function(){clearTimeout(this._timeout),this._timeout=null},t._jQueryInterface=function(e){return this.each((function(){var n=o.default(this),i=n.data(me);if(i||(i=new t(this,"object"==typeof e&&e),n.data(me,i)),"string"==typeof e){if("undefined"==typeof i[e])throw new TypeError('No method named "'+e+'"');i[e](this)}}))},l(t,null,[{key:"VERSION",get:function(){return"4.6.2"}},{key:"DefaultType",get:function(){return Te}},{key:"Default",get:function(){return Ee}}]),t}();o.default.fn.toast=we._jQueryInterface,o.default.fn.toast.Constructor=we,o.default.fn.toast.noConflict=function(){return o.default.fn.toast=pe,we._jQueryInterface},t.Alert=g,t.Button=E,t.Carousel=P,t.Collapse=V,t.Dropdown=lt,t.Modal=Ct,t.Popover=Jt,t.Scrollspy=se,t.Tab=ge,t.Toast=we,t.Tooltip=Wt,t.Util=d,Object.defineProperty(t,"__esModule",{value:!0})}));
33777 //# sourceMappingURL=bootstrap.min.js.map!function(){function n(n){return n&&(n.ownerDocument||n.document||n).documentElement}function t(n){return n&&(n.ownerDocument&&n.ownerDocument.defaultView||n.document&&n||n.defaultView)}function e(n,t){return t>n?-1:n>t?1:n>=t?0:NaN}function r(n){return null===n?NaN:+n}function i(n){return!isNaN(n)}function u(n){return{left:function(t,e,r,i){for(arguments.length<3&&(r=0),arguments.length<4&&(i=t.length);i>r;){var u=r+i>>>1;n(t[u],e)<0?r=u+1:i=u}return r},right:function(t,e,r,i){for(arguments.length<3&&(r=0),arguments.length<4&&(i=t.length);i>r;){var u=r+i>>>1;n(t[u],e)>0?i=u:r=u+1}return r}}}function o(n){return n.length}function a(n){for(var t=1;n*t%1;)t*=10;return t}function l(n,t){for(var e in t)Object.defineProperty(n.prototype,e,{value:t[e],enumerable:!1})}function c(){this._=Object.create(null)}function f(n){return(n+="")===bo||n[0]===_o?_o+n:n}function s(n){return(n+="")[0]===_o?n.slice(1):n}function h(n){return f(n)in this._}function p(n){return(n=f(n))in this._&&delete this._[n]}function g(){var n=[];for(var t in this._)n.push(s(t));return n}function v(){var n=0;for(var t in this._)++n;return n}function d(){for(var n in this._)return!1;return!0}function y(){this._=Object.create(null)}function m(n){return n}function M(n,t,e){return function(){var r=e.apply(t,arguments);return r===t?n:r}}function x(n,t){if(t in n)return t;t=t.charAt(0).toUpperCase()+t.slice(1);for(var e=0,r=wo.length;r>e;++e){var i=wo[e]+t;if(i in n)return i}}function b(){}function _(){}function w(n){function t(){for(var t,r=e,i=-1,u=r.length;++i<u;)(t=r[i].on)&&t.apply(this,arguments);return n}var e=[],r=new c;return t.on=function(t,i){var u,o=r.get(t);return arguments.length<2?o&&o.on:(o&&(o.on=null,e=e.slice(0,u=e.indexOf(o)).concat(e.slice(u+1)),r.remove(t)),i&&e.push(r.set(t,{on:i})),n)},t}function S(){ao.event.preventDefault()}function k(){for(var n,t=ao.event;n=t.sourceEvent;)t=n;return t}function N(n){for(var t=new _,e=0,r=arguments.length;++e<r;)t[arguments[e]]=w(t);return t.of=function(e,r){return function(i){try{var u=i.sourceEvent=ao.event;i.target=n,ao.event=i,t[i.type].apply(e,r)}finally{ao.event=u}}},t}function E(n){return ko(n,Co),n}function A(n){return"function"==typeof n?n:function(){return No(n,this)}}function C(n){return"function"==typeof n?n:function(){return Eo(n,this)}}function z(n,t){function e(){this.removeAttribute(n)}function r(){this.removeAttributeNS(n.space,n.local)}function i(){this.setAttribute(n,t)}function u(){this.setAttributeNS(n.space,n.local,t)}function o(){var e=t.apply(this,arguments);null==e?this.removeAttribute(n):this.setAttribute(n,e)}function a(){var e=t.apply(this,arguments);null==e?this.removeAttributeNS(n.space,n.local):this.setAttributeNS(n.space,n.local,e)}return n=ao.ns.qualify(n),null==t?n.local?r:e:"function"==typeof t?n.local?a:o:n.local?u:i}function L(n){return n.trim().replace(/\s+/g," ")}function q(n){return new RegExp("(?:^|\\s+)"+ao.requote(n)+"(?:\\s+|$)","g")}function T(n){return(n+"").trim().split(/^|\s+/)}function R(n,t){function e(){for(var e=-1;++e<i;)n[e](this,t)}function r(){for(var e=-1,r=t.apply(this,arguments);++e<i;)n[e](this,r)}n=T(n).map(D);var i=n.length;return"function"==typeof t?r:e}function D(n){var t=q(n);return function(e,r){if(i=e.classList)return r?i.add(n):i.remove(n);var i=e.getAttribute("class")||"";r?(t.lastIndex=0,t.test(i)||e.setAttribute("class",L(i+" "+n))):e.setAttribute("class",L(i.replace(t," ")))}}function P(n,t,e){function r(){this.style.removeProperty(n)}function i(){this.style.setProperty(n,t,e)}function u(){var r=t.apply(this,arguments);null==r?this.style.removeProperty(n):this.style.setProperty(n,r,e)}return null==t?r:"function"==typeof t?u:i}function U(n,t){function e(){delete this[n]}function r(){this[n]=t}function i(){var e=t.apply(this,arguments);null==e?delete this[n]:this[n]=e}return null==t?e:"function"==typeof t?i:r}function j(n){function t(){var t=this.ownerDocument,e=this.namespaceURI;return e===zo&&t.documentElement.namespaceURI===zo?t.createElement(n):t.createElementNS(e,n)}function e(){return this.ownerDocument.createElementNS(n.space,n.local)}return"function"==typeof n?n:(n=ao.ns.qualify(n)).local?e:t}function F(){var n=this.parentNode;n&&n.removeChild(this)}function H(n){return{__data__:n}}function O(n){return function(){return Ao(this,n)}}function I(n){return arguments.length||(n=e),function(t,e){return t&&e?n(t.__data__,e.__data__):!t-!e}}function Y(n,t){for(var e=0,r=n.length;r>e;e++)for(var i,u=n[e],o=0,a=u.length;a>o;o++)(i=u[o])&&t(i,o,e);return n}function Z(n){return ko(n,qo),n}function V(n){var t,e;return function(r,i,u){var o,a=n[u].update,l=a.length;for(u!=e&&(e=u,t=0),i>=t&&(t=i+1);!(o=a[t])&&++t<l;);return o}}function X(n,t,e){function r(){var t=this[o];t&&(this.removeEventListener(n,t,t.$),delete this[o])}function i(){var i=l(t,co(arguments));r.call(this),this.addEventListener(n,this[o]=i,i.$=e),i._=t}function u(){var t,e=new RegExp("^__on([^.]+)"+ao.requote(n)+"$");for(var r in this)if(t=r.match(e)){var i=this[r];this.removeEventListener(t[1],i,i.$),delete this[r]}}var o="__on"+n,a=n.indexOf("."),l=$;a>0&&(n=n.slice(0,a));var c=To.get(n);return c&&(n=c,l=B),a?t?i:r:t?b:u}function $(n,t){return function(e){var r=ao.event;ao.event=e,t[0]=this.__data__;try{n.apply(this,t)}finally{ao.event=r}}}function B(n,t){var e=$(n,t);return function(n){var t=this,r=n.relatedTarget;r&&(r===t||8&r.compareDocumentPosition(t))||e.call(t,n)}}function W(e){var r=".dragsuppress-"+ ++Do,i="click"+r,u=ao.select(t(e)).on("touchmove"+r,S).on("dragstart"+r,S).on("selectstart"+r,S);if(null==Ro&&(Ro="onselectstart"in e?!1:x(e.style,"userSelect")),Ro){var o=n(e).style,a=o[Ro];o[Ro]="none"}return function(n){if(u.on(r,null),Ro&&(o[Ro]=a),n){var t=function(){u.on(i,null)};u.on(i,function(){S(),t()},!0),setTimeout(t,0)}}}function J(n,e){e.changedTouches&&(e=e.changedTouches[0]);var r=n.ownerSVGElement||n;if(r.createSVGPoint){var i=r.createSVGPoint();if(0>Po){var u=t(n);if(u.scrollX||u.scrollY){r=ao.select("body").append("svg").style({position:"absolute",top:0,left:0,margin:0,padding:0,border:"none"},"important");var o=r[0][0].getScreenCTM();Po=!(o.f||o.e),r.remove()}}return Po?(i.x=e.pageX,i.y=e.pageY):(i.x=e.clientX,i.y=e.clientY),i=i.matrixTransform(n.getScreenCTM().inverse()),[i.x,i.y]}var a=n.getBoundingClientRect();return[e.clientX-a.left-n.clientLeft,e.clientY-a.top-n.clientTop]}function G(){return ao.event.changedTouches[0].identifier}function K(n){return n>0?1:0>n?-1:0}function Q(n,t,e){return(t[0]-n[0])*(e[1]-n[1])-(t[1]-n[1])*(e[0]-n[0])}function nn(n){return n>1?0:-1>n?Fo:Math.acos(n)}function tn(n){return n>1?Io:-1>n?-Io:Math.asin(n)}function en(n){return((n=Math.exp(n))-1/n)/2}function rn(n){return((n=Math.exp(n))+1/n)/2}function un(n){return((n=Math.exp(2*n))-1)/(n+1)}function on(n){return(n=Math.sin(n/2))*n}function an(){}function ln(n,t,e){return this instanceof ln?(this.h=+n,this.s=+t,void(this.l=+e)):arguments.length<2?n instanceof ln?new ln(n.h,n.s,n.l):_n(""+n,wn,ln):new ln(n,t,e)}function cn(n,t,e){function r(n){return n>360?n-=360:0>n&&(n+=360),60>n?u+(o-u)*n/60:180>n?o:240>n?u+(o-u)*(240-n)/60:u}function i(n){return Math.round(255*r(n))}var u,o;return n=isNaN(n)?0:(n%=360)<0?n+360:n,t=isNaN(t)?0:0>t?0:t>1?1:t,e=0>e?0:e>1?1:e,o=.5>=e?e*(1+t):e+t-e*t,u=2*e-o,new mn(i(n+120),i(n),i(n-120))}function fn(n,t,e){return this instanceof fn?(this.h=+n,this.c=+t,void(this.l=+e)):arguments.length<2?n instanceof fn?new fn(n.h,n.c,n.l):n instanceof hn?gn(n.l,n.a,n.b):gn((n=Sn((n=ao.rgb(n)).r,n.g,n.b)).l,n.a,n.b):new fn(n,t,e)}function sn(n,t,e){return isNaN(n)&&(n=0),isNaN(t)&&(t=0),new hn(e,Math.cos(n*=Yo)*t,Math.sin(n)*t)}function hn(n,t,e){return this instanceof hn?(this.l=+n,this.a=+t,void(this.b=+e)):arguments.length<2?n instanceof hn?new hn(n.l,n.a,n.b):n instanceof fn?sn(n.h,n.c,n.l):Sn((n=mn(n)).r,n.g,n.b):new hn(n,t,e)}function pn(n,t,e){var r=(n+16)/116,i=r+t/500,u=r-e/200;return i=vn(i)*na,r=vn(r)*ta,u=vn(u)*ea,new mn(yn(3.2404542*i-1.5371385*r-.4985314*u),yn(-.969266*i+1.8760108*r+.041556*u),yn(.0556434*i-.2040259*r+1.0572252*u))}function gn(n,t,e){return n>0?new fn(Math.atan2(e,t)*Zo,Math.sqrt(t*t+e*e),n):new fn(NaN,NaN,n)}function vn(n){return n>.206893034?n*n*n:(n-4/29)/7.787037}function dn(n){return n>.008856?Math.pow(n,1/3):7.787037*n+4/29}function yn(n){return Math.round(255*(.00304>=n?12.92*n:1.055*Math.pow(n,1/2.4)-.055))}function mn(n,t,e){return this instanceof mn?(this.r=~~n,this.g=~~t,void(this.b=~~e)):arguments.length<2?n instanceof mn?new mn(n.r,n.g,n.b):_n(""+n,mn,cn):new mn(n,t,e)}function Mn(n){return new mn(n>>16,n>>8&255,255&n)}function xn(n){return Mn(n)+""}function bn(n){return 16>n?"0"+Math.max(0,n).toString(16):Math.min(255,n).toString(16)}function _n(n,t,e){var r,i,u,o=0,a=0,l=0;if(r=/([a-z]+)\((.*)\)/.exec(n=n.toLowerCase()))switch(i=r[2].split(","),r[1]){case"hsl":return e(parseFloat(i[0]),parseFloat(i[1])/100,parseFloat(i[2])/100);case"rgb":return t(Nn(i[0]),Nn(i[1]),Nn(i[2]))}return(u=ua.get(n))?t(u.r,u.g,u.b):(null==n||"#"!==n.charAt(0)||isNaN(u=parseInt(n.slice(1),16))||(4===n.length?(o=(3840&u)>>4,o=o>>4|o,a=240&u,a=a>>4|a,l=15&u,l=l<<4|l):7===n.length&&(o=(16711680&u)>>16,a=(65280&u)>>8,l=255&u)),t(o,a,l))}function wn(n,t,e){var r,i,u=Math.min(n/=255,t/=255,e/=255),o=Math.max(n,t,e),a=o-u,l=(o+u)/2;return a?(i=.5>l?a/(o+u):a/(2-o-u),r=n==o?(t-e)/a+(e>t?6:0):t==o?(e-n)/a+2:(n-t)/a+4,r*=60):(r=NaN,i=l>0&&1>l?0:r),new ln(r,i,l)}function Sn(n,t,e){n=kn(n),t=kn(t),e=kn(e);var r=dn((.4124564*n+.3575761*t+.1804375*e)/na),i=dn((.2126729*n+.7151522*t+.072175*e)/ta),u=dn((.0193339*n+.119192*t+.9503041*e)/ea);return hn(116*i-16,500*(r-i),200*(i-u))}function kn(n){return(n/=255)<=.04045?n/12.92:Math.pow((n+.055)/1.055,2.4)}function Nn(n){var t=parseFloat(n);return"%"===n.charAt(n.length-1)?Math.round(2.55*t):t}function En(n){return"function"==typeof n?n:function(){return n}}function An(n){return function(t,e,r){return 2===arguments.length&&"function"==typeof e&&(r=e,e=null),Cn(t,e,n,r)}}function Cn(n,t,e,r){function i(){var n,t=l.status;if(!t&&Ln(l)||t>=200&&300>t||304===t){try{n=e.call(u,l)}catch(r){return void o.error.call(u,r)}o.load.call(u,n)}else o.error.call(u,l)}var u={},o=ao.dispatch("beforesend","progress","load","error"),a={},l=new XMLHttpRequest,c=null;return!this.XDomainRequest||"withCredentials"in l||!/^(http(s)?:)?\/\//.test(n)||(l=new XDomainRequest),"onload"in l?l.onload=l.onerror=i:l.onreadystatechange=function(){l.readyState>3&&i()},l.onprogress=function(n){var t=ao.event;ao.event=n;try{o.progress.call(u,l)}finally{ao.event=t}},u.header=function(n,t){return n=(n+"").toLowerCase(),arguments.length<2?a[n]:(null==t?delete a[n]:a[n]=t+"",u)},u.mimeType=function(n){return arguments.length?(t=null==n?null:n+"",u):t},u.responseType=function(n){return arguments.length?(c=n,u):c},u.response=function(n){return e=n,u},["get","post"].forEach(function(n){u[n]=function(){return u.send.apply(u,[n].concat(co(arguments)))}}),u.send=function(e,r,i){if(2===arguments.length&&"function"==typeof r&&(i=r,r=null),l.open(e,n,!0),null==t||"accept"in a||(a.accept=t+",*/*"),l.setRequestHeader)for(var f in a)l.setRequestHeader(f,a[f]);return null!=t&&l.overrideMimeType&&l.overrideMimeType(t),null!=c&&(l.responseType=c),null!=i&&u.on("error",i).on("load",function(n){i(null,n)}),o.beforesend.call(u,l),l.send(null==r?null:r),u},u.abort=function(){return l.abort(),u},ao.rebind(u,o,"on"),null==r?u:u.get(zn(r))}function zn(n){return 1===n.length?function(t,e){n(null==t?e:null)}:n}function Ln(n){var t=n.responseType;return t&&"text"!==t?n.response:n.responseText}function qn(n,t,e){var r=arguments.length;2>r&&(t=0),3>r&&(e=Date.now());var i=e+t,u={c:n,t:i,n:null};return aa?aa.n=u:oa=u,aa=u,la||(ca=clearTimeout(ca),la=1,fa(Tn)),u}function Tn(){var n=Rn(),t=Dn()-n;t>24?(isFinite(t)&&(clearTimeout(ca),ca=setTimeout(Tn,t)),la=0):(la=1,fa(Tn))}function Rn(){for(var n=Date.now(),t=oa;t;)n>=t.t&&t.c(n-t.t)&&(t.c=null),t=t.n;return n}function Dn(){for(var n,t=oa,e=1/0;t;)t.c?(t.t<e&&(e=t.t),t=(n=t).n):t=n?n.n=t.n:oa=t.n;return aa=n,e}function Pn(n,t){return t-(n?Math.ceil(Math.log(n)/Math.LN10):1)}function Un(n,t){var e=Math.pow(10,3*xo(8-t));return{scale:t>8?function(n){return n/e}:function(n){return n*e},symbol:n}}function jn(n){var t=n.decimal,e=n.thousands,r=n.grouping,i=n.currency,u=r&&e?function(n,t){for(var i=n.length,u=[],o=0,a=r[0],l=0;i>0&&a>0&&(l+a+1>t&&(a=Math.max(1,t-l)),u.push(n.substring(i-=a,i+a)),!((l+=a+1)>t));)a=r[o=(o+1)%r.length];return u.reverse().join(e)}:m;return function(n){var e=ha.exec(n),r=e[1]||" ",o=e[2]||">",a=e[3]||"-",l=e[4]||"",c=e[5],f=+e[6],s=e[7],h=e[8],p=e[9],g=1,v="",d="",y=!1,m=!0;switch(h&&(h=+h.substring(1)),(c||"0"===r&&"="===o)&&(c=r="0",o="="),p){case"n":s=!0,p="g";break;case"%":g=100,d="%",p="f";break;case"p":g=100,d="%",p="r";break;case"b":case"o":case"x":case"X":"#"===l&&(v="0"+p.toLowerCase());case"c":m=!1;case"d":y=!0,h=0;break;case"s":g=-1,p="r"}"$"===l&&(v=i[0],d=i[1]),"r"!=p||h||(p="g"),null!=h&&("g"==p?h=Math.max(1,Math.min(21,h)):"e"!=p&&"f"!=p||(h=Math.max(0,Math.min(20,h)))),p=pa.get(p)||Fn;var M=c&&s;return function(n){var e=d;if(y&&n%1)return"";var i=0>n||0===n&&0>1/n?(n=-n,"-"):"-"===a?"":a;if(0>g){var l=ao.formatPrefix(n,h);n=l.scale(n),e=l.symbol+d}else n*=g;n=p(n,h);var x,b,_=n.lastIndexOf(".");if(0>_){var w=m?n.lastIndexOf("e"):-1;0>w?(x=n,b=""):(x=n.substring(0,w),b=n.substring(w))}else x=n.substring(0,_),b=t+n.substring(_+1);!c&&s&&(x=u(x,1/0));var S=v.length+x.length+b.length+(M?0:i.length),k=f>S?new Array(S=f-S+1).join(r):"";return M&&(x=u(k+x,k.length?f-b.length:1/0)),i+=v,n=x+b,("<"===o?i+n+k:">"===o?k+i+n:"^"===o?k.substring(0,S>>=1)+i+n+k.substring(S):i+(M?n:k+n))+e}}}function Fn(n){return n+""}function Hn(){this._=new Date(arguments.length>1?Date.UTC.apply(this,arguments):arguments[0])}function On(n,t,e){function r(t){var e=n(t),r=u(e,1);return r-t>t-e?e:r}function i(e){return t(e=n(new va(e-1)),1),e}function u(n,e){return t(n=new va(+n),e),n}function o(n,r,u){var o=i(n),a=[];if(u>1)for(;r>o;)e(o)%u||a.push(new Date(+o)),t(o,1);else for(;r>o;)a.push(new Date(+o)),t(o,1);return a}function a(n,t,e){try{va=Hn;var r=new Hn;return r._=n,o(r,t,e)}finally{va=Date}}n.floor=n,n.round=r,n.ceil=i,n.offset=u,n.range=o;var l=n.utc=In(n);return l.floor=l,l.round=In(r),l.ceil=In(i),l.offset=In(u),l.range=a,n}function In(n){return function(t,e){try{va=Hn;var r=new Hn;return r._=t,n(r,e)._}finally{va=Date}}}function Yn(n){function t(n){function t(t){for(var e,i,u,o=[],a=-1,l=0;++a<r;)37===n.charCodeAt(a)&&(o.push(n.slice(l,a)),null!=(i=ya[e=n.charAt(++a)])&&(e=n.charAt(++a)),(u=A[e])&&(e=u(t,null==i?"e"===e?" ":"0":i)),o.push(e),l=a+1);return o.push(n.slice(l,a)),o.join("")}var r=n.length;return t.parse=function(t){var r={y:1900,m:0,d:1,H:0,M:0,S:0,L:0,Z:null},i=e(r,n,t,0);if(i!=t.length)return null;"p"in r&&(r.H=r.H%12+12*r.p);var u=null!=r.Z&&va!==Hn,o=new(u?Hn:va);return"j"in r?o.setFullYear(r.y,0,r.j):"W"in r||"U"in r?("w"in r||(r.w="W"in r?1:0),o.setFullYear(r.y,0,1),o.setFullYear(r.y,0,"W"in r?(r.w+6)%7+7*r.W-(o.getDay()+5)%7:r.w+7*r.U-(o.getDay()+6)%7)):o.setFullYear(r.y,r.m,r.d),o.setHours(r.H+(r.Z/100|0),r.M+r.Z%100,r.S,r.L),u?o._:o},t.toString=function(){return n},t}function e(n,t,e,r){for(var i,u,o,a=0,l=t.length,c=e.length;l>a;){if(r>=c)return-1;if(i=t.charCodeAt(a++),37===i){if(o=t.charAt(a++),u=C[o in ya?t.charAt(a++):o],!u||(r=u(n,e,r))<0)return-1}else if(i!=e.charCodeAt(r++))return-1}return r}function r(n,t,e){_.lastIndex=0;var r=_.exec(t.slice(e));return r?(n.w=w.get(r[0].toLowerCase()),e+r[0].length):-1}function i(n,t,e){x.lastIndex=0;var r=x.exec(t.slice(e));return r?(n.w=b.get(r[0].toLowerCase()),e+r[0].length):-1}function u(n,t,e){N.lastIndex=0;var r=N.exec(t.slice(e));return r?(n.m=E.get(r[0].toLowerCase()),e+r[0].length):-1}function o(n,t,e){S.lastIndex=0;var r=S.exec(t.slice(e));return r?(n.m=k.get(r[0].toLowerCase()),e+r[0].length):-1}function a(n,t,r){return e(n,A.c.toString(),t,r)}function l(n,t,r){return e(n,A.x.toString(),t,r)}function c(n,t,r){return e(n,A.X.toString(),t,r)}function f(n,t,e){var r=M.get(t.slice(e,e+=2).toLowerCase());return null==r?-1:(n.p=r,e)}var s=n.dateTime,h=n.date,p=n.time,g=n.periods,v=n.days,d=n.shortDays,y=n.months,m=n.shortMonths;t.utc=function(n){function e(n){try{va=Hn;var t=new va;return t._=n,r(t)}finally{va=Date}}var r=t(n);return e.parse=function(n){try{va=Hn;var t=r.parse(n);return t&&t._}finally{va=Date}},e.toString=r.toString,e},t.multi=t.utc.multi=ct;var M=ao.map(),x=Vn(v),b=Xn(v),_=Vn(d),w=Xn(d),S=Vn(y),k=Xn(y),N=Vn(m),E=Xn(m);g.forEach(function(n,t){M.set(n.toLowerCase(),t)});var A={a:function(n){return d[n.getDay()]},A:function(n){return v[n.getDay()]},b:function(n){return m[n.getMonth()]},B:function(n){return y[n.getMonth()]},c:t(s),d:function(n,t){return Zn(n.getDate(),t,2)},e:function(n,t){return Zn(n.getDate(),t,2)},H:function(n,t){return Zn(n.getHours(),t,2)},I:function(n,t){return Zn(n.getHours()%12||12,t,2)},j:function(n,t){return Zn(1+ga.dayOfYear(n),t,3)},L:function(n,t){return Zn(n.getMilliseconds(),t,3)},m:function(n,t){return Zn(n.getMonth()+1,t,2)},M:function(n,t){return Zn(n.getMinutes(),t,2)},p:function(n){return g[+(n.getHours()>=12)]},S:function(n,t){return Zn(n.getSeconds(),t,2)},U:function(n,t){return Zn(ga.sundayOfYear(n),t,2)},w:function(n){return n.getDay()},W:function(n,t){return Zn(ga.mondayOfYear(n),t,2)},x:t(h),X:t(p),y:function(n,t){return Zn(n.getFullYear()%100,t,2)},Y:function(n,t){return Zn(n.getFullYear()%1e4,t,4)},Z:at,"%":function(){return"%"}},C={a:r,A:i,b:u,B:o,c:a,d:tt,e:tt,H:rt,I:rt,j:et,L:ot,m:nt,M:it,p:f,S:ut,U:Bn,w:$n,W:Wn,x:l,X:c,y:Gn,Y:Jn,Z:Kn,"%":lt};return t}function Zn(n,t,e){var r=0>n?"-":"",i=(r?-n:n)+"",u=i.length;return r+(e>u?new Array(e-u+1).join(t)+i:i)}function Vn(n){return new RegExp("^(?:"+n.map(ao.requote).join("|")+")","i")}function Xn(n){for(var t=new c,e=-1,r=n.length;++e<r;)t.set(n[e].toLowerCase(),e);return t}function $n(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+1));return r?(n.w=+r[0],e+r[0].length):-1}function Bn(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e));return r?(n.U=+r[0],e+r[0].length):-1}function Wn(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e));return r?(n.W=+r[0],e+r[0].length):-1}function Jn(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+4));return r?(n.y=+r[0],e+r[0].length):-1}function Gn(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+2));return r?(n.y=Qn(+r[0]),e+r[0].length):-1}function Kn(n,t,e){return/^[+-]\d{4}$/.test(t=t.slice(e,e+5))?(n.Z=-t,e+5):-1}function Qn(n){return n+(n>68?1900:2e3)}function nt(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+2));return r?(n.m=r[0]-1,e+r[0].length):-1}function tt(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+2));return r?(n.d=+r[0],e+r[0].length):-1}function et(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+3));return r?(n.j=+r[0],e+r[0].length):-1}function rt(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+2));return r?(n.H=+r[0],e+r[0].length):-1}function it(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+2));return r?(n.M=+r[0],e+r[0].length):-1}function ut(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+2));return r?(n.S=+r[0],e+r[0].length):-1}function ot(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+3));return r?(n.L=+r[0],e+r[0].length):-1}function at(n){var t=n.getTimezoneOffset(),e=t>0?"-":"+",r=xo(t)/60|0,i=xo(t)%60;return e+Zn(r,"0",2)+Zn(i,"0",2)}function lt(n,t,e){Ma.lastIndex=0;var r=Ma.exec(t.slice(e,e+1));return r?e+r[0].length:-1}function ct(n){for(var t=n.length,e=-1;++e<t;)n[e][0]=this(n[e][0]);return function(t){for(var e=0,r=n[e];!r[1](t);)r=n[++e];return r[0](t)}}function ft(){}function st(n,t,e){var r=e.s=n+t,i=r-n,u=r-i;e.t=n-u+(t-i)}function ht(n,t){n&&wa.hasOwnProperty(n.type)&&wa[n.type](n,t)}function pt(n,t,e){var r,i=-1,u=n.length-e;for(t.lineStart();++i<u;)r=n[i],t.point(r[0],r[1],r[2]);t.lineEnd()}function gt(n,t){var e=-1,r=n.length;for(t.polygonStart();++e<r;)pt(n[e],t,1);t.polygonEnd()}function vt(){function n(n,t){n*=Yo,t=t*Yo/2+Fo/4;var e=n-r,o=e>=0?1:-1,a=o*e,l=Math.cos(t),c=Math.sin(t),f=u*c,s=i*l+f*Math.cos(a),h=f*o*Math.sin(a);ka.add(Math.atan2(h,s)),r=n,i=l,u=c}var t,e,r,i,u;Na.point=function(o,a){Na.point=n,r=(t=o)*Yo,i=Math.cos(a=(e=a)*Yo/2+Fo/4),u=Math.sin(a)},Na.lineEnd=function(){n(t,e)}}function dt(n){var t=n[0],e=n[1],r=Math.cos(e);return[r*Math.cos(t),r*Math.sin(t),Math.sin(e)]}function yt(n,t){return n[0]*t[0]+n[1]*t[1]+n[2]*t[2]}function mt(n,t){return[n[1]*t[2]-n[2]*t[1],n[2]*t[0]-n[0]*t[2],n[0]*t[1]-n[1]*t[0]]}function Mt(n,t){n[0]+=t[0],n[1]+=t[1],n[2]+=t[2]}function xt(n,t){return[n[0]*t,n[1]*t,n[2]*t]}function bt(n){var t=Math.sqrt(n[0]*n[0]+n[1]*n[1]+n[2]*n[2]);n[0]/=t,n[1]/=t,n[2]/=t}function _t(n){return[Math.atan2(n[1],n[0]),tn(n[2])]}function wt(n,t){return xo(n[0]-t[0])<Uo&&xo(n[1]-t[1])<Uo}function St(n,t){n*=Yo;var e=Math.cos(t*=Yo);kt(e*Math.cos(n),e*Math.sin(n),Math.sin(t))}function kt(n,t,e){++Ea,Ca+=(n-Ca)/Ea,za+=(t-za)/Ea,La+=(e-La)/Ea}function Nt(){function n(n,i){n*=Yo;var u=Math.cos(i*=Yo),o=u*Math.cos(n),a=u*Math.sin(n),l=Math.sin(i),c=Math.atan2(Math.sqrt((c=e*l-r*a)*c+(c=r*o-t*l)*c+(c=t*a-e*o)*c),t*o+e*a+r*l);Aa+=c,qa+=c*(t+(t=o)),Ta+=c*(e+(e=a)),Ra+=c*(r+(r=l)),kt(t,e,r)}var t,e,r;ja.point=function(i,u){i*=Yo;var o=Math.cos(u*=Yo);t=o*Math.cos(i),e=o*Math.sin(i),r=Math.sin(u),ja.point=n,kt(t,e,r)}}function Et(){ja.point=St}function At(){function n(n,t){n*=Yo;var e=Math.cos(t*=Yo),o=e*Math.cos(n),a=e*Math.sin(n),l=Math.sin(t),c=i*l-u*a,f=u*o-r*l,s=r*a-i*o,h=Math.sqrt(c*c+f*f+s*s),p=r*o+i*a+u*l,g=h&&-nn(p)/h,v=Math.atan2(h,p);Da+=g*c,Pa+=g*f,Ua+=g*s,Aa+=v,qa+=v*(r+(r=o)),Ta+=v*(i+(i=a)),Ra+=v*(u+(u=l)),kt(r,i,u)}var t,e,r,i,u;ja.point=function(o,a){t=o,e=a,ja.point=n,o*=Yo;var l=Math.cos(a*=Yo);r=l*Math.cos(o),i=l*Math.sin(o),u=Math.sin(a),kt(r,i,u)},ja.lineEnd=function(){n(t,e),ja.lineEnd=Et,ja.point=St}}function Ct(n,t){function e(e,r){return e=n(e,r),t(e[0],e[1])}return n.invert&&t.invert&&(e.invert=function(e,r){return e=t.invert(e,r),e&&n.invert(e[0],e[1])}),e}function zt(){return!0}function Lt(n,t,e,r,i){var u=[],o=[];if(n.forEach(function(n){if(!((t=n.length-1)<=0)){var t,e=n[0],r=n[t];if(wt(e,r)){i.lineStart();for(var a=0;t>a;++a)i.point((e=n[a])[0],e[1]);return void i.lineEnd()}var l=new Tt(e,n,null,!0),c=new Tt(e,null,l,!1);l.o=c,u.push(l),o.push(c),l=new Tt(r,n,null,!1),c=new Tt(r,null,l,!0),l.o=c,u.push(l),o.push(c)}}),o.sort(t),qt(u),qt(o),u.length){for(var a=0,l=e,c=o.length;c>a;++a)o[a].e=l=!l;for(var f,s,h=u[0];;){for(var p=h,g=!0;p.v;)if((p=p.n)===h)return;f=p.z,i.lineStart();do{if(p.v=p.o.v=!0,p.e){if(g)for(var a=0,c=f.length;c>a;++a)i.point((s=f[a])[0],s[1]);else r(p.x,p.n.x,1,i);p=p.n}else{if(g){f=p.p.z;for(var a=f.length-1;a>=0;--a)i.point((s=f[a])[0],s[1])}else r(p.x,p.p.x,-1,i);p=p.p}p=p.o,f=p.z,g=!g}while(!p.v);i.lineEnd()}}}function qt(n){if(t=n.length){for(var t,e,r=0,i=n[0];++r<t;)i.n=e=n[r],e.p=i,i=e;i.n=e=n[0],e.p=i}}function Tt(n,t,e,r){this.x=n,this.z=t,this.o=e,this.e=r,this.v=!1,this.n=this.p=null}function Rt(n,t,e,r){return function(i,u){function o(t,e){var r=i(t,e);n(t=r[0],e=r[1])&&u.point(t,e)}function a(n,t){var e=i(n,t);d.point(e[0],e[1])}function l(){m.point=a,d.lineStart()}function c(){m.point=o,d.lineEnd()}function f(n,t){v.push([n,t]);var e=i(n,t);x.point(e[0],e[1])}function s(){x.lineStart(),v=[]}function h(){f(v[0][0],v[0][1]),x.lineEnd();var n,t=x.clean(),e=M.buffer(),r=e.length;if(v.pop(),g.push(v),v=null,r)if(1&t){n=e[0];var i,r=n.length-1,o=-1;if(r>0){for(b||(u.polygonStart(),b=!0),u.lineStart();++o<r;)u.point((i=n[o])[0],i[1]);u.lineEnd()}}else r>1&&2&t&&e.push(e.pop().concat(e.shift())),p.push(e.filter(Dt))}var p,g,v,d=t(u),y=i.invert(r[0],r[1]),m={point:o,lineStart:l,lineEnd:c,polygonStart:function(){m.point=f,m.lineStart=s,m.lineEnd=h,p=[],g=[]},polygonEnd:function(){m.point=o,m.lineStart=l,m.lineEnd=c,p=ao.merge(p);var n=Ot(y,g);p.length?(b||(u.polygonStart(),b=!0),Lt(p,Ut,n,e,u)):n&&(b||(u.polygonStart(),b=!0),u.lineStart(),e(null,null,1,u),u.lineEnd()),b&&(u.polygonEnd(),b=!1),p=g=null},sphere:function(){u.polygonStart(),u.lineStart(),e(null,null,1,u),u.lineEnd(),u.polygonEnd()}},M=Pt(),x=t(M),b=!1;return m}}function Dt(n){return n.length>1}function Pt(){var n,t=[];return{lineStart:function(){t.push(n=[])},point:function(t,e){n.push([t,e])},lineEnd:b,buffer:function(){var e=t;return t=[],n=null,e},rejoin:function(){t.length>1&&t.push(t.pop().concat(t.shift()))}}}function Ut(n,t){return((n=n.x)[0]<0?n[1]-Io-Uo:Io-n[1])-((t=t.x)[0]<0?t[1]-Io-Uo:Io-t[1])}function jt(n){var t,e=NaN,r=NaN,i=NaN;return{lineStart:function(){n.lineStart(),t=1},point:function(u,o){var a=u>0?Fo:-Fo,l=xo(u-e);xo(l-Fo)<Uo?(n.point(e,r=(r+o)/2>0?Io:-Io),n.point(i,r),n.lineEnd(),n.lineStart(),n.point(a,r),n.point(u,r),t=0):i!==a&&l>=Fo&&(xo(e-i)<Uo&&(e-=i*Uo),xo(u-a)<Uo&&(u-=a*Uo),r=Ft(e,r,u,o),n.point(i,r),n.lineEnd(),n.lineStart(),n.point(a,r),t=0),n.point(e=u,r=o),i=a},lineEnd:function(){n.lineEnd(),e=r=NaN},clean:function(){return 2-t}}}function Ft(n,t,e,r){var i,u,o=Math.sin(n-e);return xo(o)>Uo?Math.atan((Math.sin(t)*(u=Math.cos(r))*Math.sin(e)-Math.sin(r)*(i=Math.cos(t))*Math.sin(n))/(i*u*o)):(t+r)/2}function Ht(n,t,e,r){var i;if(null==n)i=e*Io,r.point(-Fo,i),r.point(0,i),r.point(Fo,i),r.point(Fo,0),r.point(Fo,-i),r.point(0,-i),r.point(-Fo,-i),r.point(-Fo,0),r.point(-Fo,i);else if(xo(n[0]-t[0])>Uo){var u=n[0]<t[0]?Fo:-Fo;i=e*u/2,r.point(-u,i),r.point(0,i),r.point(u,i)}else r.point(t[0],t[1])}function Ot(n,t){var e=n[0],r=n[1],i=[Math.sin(e),-Math.cos(e),0],u=0,o=0;ka.reset();for(var a=0,l=t.length;l>a;++a){var c=t[a],f=c.length;if(f)for(var s=c[0],h=s[0],p=s[1]/2+Fo/4,g=Math.sin(p),v=Math.cos(p),d=1;;){d===f&&(d=0),n=c[d];var y=n[0],m=n[1]/2+Fo/4,M=Math.sin(m),x=Math.cos(m),b=y-h,_=b>=0?1:-1,w=_*b,S=w>Fo,k=g*M;if(ka.add(Math.atan2(k*_*Math.sin(w),v*x+k*Math.cos(w))),u+=S?b+_*Ho:b,S^h>=e^y>=e){var N=mt(dt(s),dt(n));bt(N);var E=mt(i,N);bt(E);var A=(S^b>=0?-1:1)*tn(E[2]);(r>A||r===A&&(N[0]||N[1]))&&(o+=S^b>=0?1:-1)}if(!d++)break;h=y,g=M,v=x,s=n}}return(-Uo>u||Uo>u&&-Uo>ka)^1&o}function It(n){function t(n,t){return Math.cos(n)*Math.cos(t)>u}function e(n){var e,u,l,c,f;return{lineStart:function(){c=l=!1,f=1},point:function(s,h){var p,g=[s,h],v=t(s,h),d=o?v?0:i(s,h):v?i(s+(0>s?Fo:-Fo),h):0;if(!e&&(c=l=v)&&n.lineStart(),v!==l&&(p=r(e,g),(wt(e,p)||wt(g,p))&&(g[0]+=Uo,g[1]+=Uo,v=t(g[0],g[1]))),v!==l)f=0,v?(n.lineStart(),p=r(g,e),n.point(p[0],p[1])):(p=r(e,g),n.point(p[0],p[1]),n.lineEnd()),e=p;else if(a&&e&&o^v){var y;d&u||!(y=r(g,e,!0))||(f=0,o?(n.lineStart(),n.point(y[0][0],y[0][1]),n.point(y[1][0],y[1][1]),n.lineEnd()):(n.point(y[1][0],y[1][1]),n.lineEnd(),n.lineStart(),n.point(y[0][0],y[0][1])))}!v||e&&wt(e,g)||n.point(g[0],g[1]),e=g,l=v,u=d},lineEnd:function(){l&&n.lineEnd(),e=null},clean:function(){return f|(c&&l)<<1}}}function r(n,t,e){var r=dt(n),i=dt(t),o=[1,0,0],a=mt(r,i),l=yt(a,a),c=a[0],f=l-c*c;if(!f)return!e&&n;var s=u*l/f,h=-u*c/f,p=mt(o,a),g=xt(o,s),v=xt(a,h);Mt(g,v);var d=p,y=yt(g,d),m=yt(d,d),M=y*y-m*(yt(g,g)-1);if(!(0>M)){var x=Math.sqrt(M),b=xt(d,(-y-x)/m);if(Mt(b,g),b=_t(b),!e)return b;var _,w=n[0],S=t[0],k=n[1],N=t[1];w>S&&(_=w,w=S,S=_);var E=S-w,A=xo(E-Fo)<Uo,C=A||Uo>E;if(!A&&k>N&&(_=k,k=N,N=_),C?A?k+N>0^b[1]<(xo(b[0]-w)<Uo?k:N):k<=b[1]&&b[1]<=N:E>Fo^(w<=b[0]&&b[0]<=S)){var z=xt(d,(-y+x)/m);return Mt(z,g),[b,_t(z)]}}}function i(t,e){var r=o?n:Fo-n,i=0;return-r>t?i|=1:t>r&&(i|=2),-r>e?i|=4:e>r&&(i|=8),i}var u=Math.cos(n),o=u>0,a=xo(u)>Uo,l=ve(n,6*Yo);return Rt(t,e,l,o?[0,-n]:[-Fo,n-Fo])}function Yt(n,t,e,r){return function(i){var u,o=i.a,a=i.b,l=o.x,c=o.y,f=a.x,s=a.y,h=0,p=1,g=f-l,v=s-c;if(u=n-l,g||!(u>0)){if(u/=g,0>g){if(h>u)return;p>u&&(p=u)}else if(g>0){if(u>p)return;u>h&&(h=u)}if(u=e-l,g||!(0>u)){if(u/=g,0>g){if(u>p)return;u>h&&(h=u)}else if(g>0){if(h>u)return;p>u&&(p=u)}if(u=t-c,v||!(u>0)){if(u/=v,0>v){if(h>u)return;p>u&&(p=u)}else if(v>0){if(u>p)return;u>h&&(h=u)}if(u=r-c,v||!(0>u)){if(u/=v,0>v){if(u>p)return;u>h&&(h=u)}else if(v>0){if(h>u)return;p>u&&(p=u)}return h>0&&(i.a={x:l+h*g,y:c+h*v}),1>p&&(i.b={x:l+p*g,y:c+p*v}),i}}}}}}function Zt(n,t,e,r){function i(r,i){return xo(r[0]-n)<Uo?i>0?0:3:xo(r[0]-e)<Uo?i>0?2:1:xo(r[1]-t)<Uo?i>0?1:0:i>0?3:2}function u(n,t){return o(n.x,t.x)}function o(n,t){var e=i(n,1),r=i(t,1);return e!==r?e-r:0===e?t[1]-n[1]:1===e?n[0]-t[0]:2===e?n[1]-t[1]:t[0]-n[0]}return function(a){function l(n){for(var t=0,e=d.length,r=n[1],i=0;e>i;++i)for(var u,o=1,a=d[i],l=a.length,c=a[0];l>o;++o)u=a[o],c[1]<=r?u[1]>r&&Q(c,u,n)>0&&++t:u[1]<=r&&Q(c,u,n)<0&&--t,c=u;return 0!==t}function c(u,a,l,c){var f=0,s=0;if(null==u||(f=i(u,l))!==(s=i(a,l))||o(u,a)<0^l>0){do c.point(0===f||3===f?n:e,f>1?r:t);while((f=(f+l+4)%4)!==s)}else c.point(a[0],a[1])}function f(i,u){return i>=n&&e>=i&&u>=t&&r>=u}function s(n,t){f(n,t)&&a.point(n,t)}function h(){C.point=g,d&&d.push(y=[]),S=!0,w=!1,b=_=NaN}function p(){v&&(g(m,M),x&&w&&E.rejoin(),v.push(E.buffer())),C.point=s,w&&a.lineEnd()}function g(n,t){n=Math.max(-Ha,Math.min(Ha,n)),t=Math.max(-Ha,Math.min(Ha,t));var e=f(n,t);if(d&&y.push([n,t]),S)m=n,M=t,x=e,S=!1,e&&(a.lineStart(),a.point(n,t));else if(e&&w)a.point(n,t);else{var r={a:{x:b,y:_},b:{x:n,y:t}};A(r)?(w||(a.lineStart(),a.point(r.a.x,r.a.y)),a.point(r.b.x,r.b.y),e||a.lineEnd(),k=!1):e&&(a.lineStart(),a.point(n,t),k=!1)}b=n,_=t,w=e}var v,d,y,m,M,x,b,_,w,S,k,N=a,E=Pt(),A=Yt(n,t,e,r),C={point:s,lineStart:h,lineEnd:p,polygonStart:function(){a=E,v=[],d=[],k=!0},polygonEnd:function(){a=N,v=ao.merge(v);var t=l([n,r]),e=k&&t,i=v.length;(e||i)&&(a.polygonStart(),e&&(a.lineStart(),c(null,null,1,a),a.lineEnd()),i&&Lt(v,u,t,c,a),a.polygonEnd()),v=d=y=null}};return C}}function Vt(n){var t=0,e=Fo/3,r=ae(n),i=r(t,e);return i.parallels=function(n){return arguments.length?r(t=n[0]*Fo/180,e=n[1]*Fo/180):[t/Fo*180,e/Fo*180]},i}function Xt(n,t){function e(n,t){var e=Math.sqrt(u-2*i*Math.sin(t))/i;return[e*Math.sin(n*=i),o-e*Math.cos(n)]}var r=Math.sin(n),i=(r+Math.sin(t))/2,u=1+r*(2*i-r),o=Math.sqrt(u)/i;return e.invert=function(n,t){var e=o-t;return[Math.atan2(n,e)/i,tn((u-(n*n+e*e)*i*i)/(2*i))]},e}function $t(){function n(n,t){Ia+=i*n-r*t,r=n,i=t}var t,e,r,i;$a.point=function(u,o){$a.point=n,t=r=u,e=i=o},$a.lineEnd=function(){n(t,e)}}function Bt(n,t){Ya>n&&(Ya=n),n>Va&&(Va=n),Za>t&&(Za=t),t>Xa&&(Xa=t)}function Wt(){function n(n,t){o.push("M",n,",",t,u)}function t(n,t){o.push("M",n,",",t),a.point=e}function e(n,t){o.push("L",n,",",t)}function r(){a.point=n}function i(){o.push("Z")}var u=Jt(4.5),o=[],a={point:n,lineStart:function(){a.point=t},lineEnd:r,polygonStart:function(){a.lineEnd=i},polygonEnd:function(){a.lineEnd=r,a.point=n},pointRadius:function(n){return u=Jt(n),a},result:function(){if(o.length){var n=o.join("");return o=[],n}}};return a}function Jt(n){return"m0,"+n+"a"+n+","+n+" 0 1,1 0,"+-2*n+"a"+n+","+n+" 0 1,1 0,"+2*n+"z"}function Gt(n,t){Ca+=n,za+=t,++La}function Kt(){function n(n,r){var i=n-t,u=r-e,o=Math.sqrt(i*i+u*u);qa+=o*(t+n)/2,Ta+=o*(e+r)/2,Ra+=o,Gt(t=n,e=r)}var t,e;Wa.point=function(r,i){Wa.point=n,Gt(t=r,e=i)}}function Qt(){Wa.point=Gt}function ne(){function n(n,t){var e=n-r,u=t-i,o=Math.sqrt(e*e+u*u);qa+=o*(r+n)/2,Ta+=o*(i+t)/2,Ra+=o,o=i*n-r*t,Da+=o*(r+n),Pa+=o*(i+t),Ua+=3*o,Gt(r=n,i=t)}var t,e,r,i;Wa.point=function(u,o){Wa.point=n,Gt(t=r=u,e=i=o)},Wa.lineEnd=function(){n(t,e)}}function te(n){function t(t,e){n.moveTo(t+o,e),n.arc(t,e,o,0,Ho)}function e(t,e){n.moveTo(t,e),a.point=r}function r(t,e){n.lineTo(t,e)}function i(){a.point=t}function u(){n.closePath()}var o=4.5,a={point:t,lineStart:function(){a.point=e},lineEnd:i,polygonStart:function(){a.lineEnd=u},polygonEnd:function(){a.lineEnd=i,a.point=t},pointRadius:function(n){return o=n,a},result:b};return a}function ee(n){function t(n){return(a?r:e)(n)}function e(t){return ue(t,function(e,r){e=n(e,r),t.point(e[0],e[1])})}function r(t){function e(e,r){e=n(e,r),t.point(e[0],e[1])}function r(){M=NaN,S.point=u,t.lineStart()}function u(e,r){var u=dt([e,r]),o=n(e,r);i(M,x,m,b,_,w,M=o[0],x=o[1],m=e,b=u[0],_=u[1],w=u[2],a,t),t.point(M,x)}function o(){S.point=e,t.lineEnd()}function l(){
33778 r(),S.point=c,S.lineEnd=f}function c(n,t){u(s=n,h=t),p=M,g=x,v=b,d=_,y=w,S.point=u}function f(){i(M,x,m,b,_,w,p,g,s,v,d,y,a,t),S.lineEnd=o,o()}var s,h,p,g,v,d,y,m,M,x,b,_,w,S={point:e,lineStart:r,lineEnd:o,polygonStart:function(){t.polygonStart(),S.lineStart=l},polygonEnd:function(){t.polygonEnd(),S.lineStart=r}};return S}function i(t,e,r,a,l,c,f,s,h,p,g,v,d,y){var m=f-t,M=s-e,x=m*m+M*M;if(x>4*u&&d--){var b=a+p,_=l+g,w=c+v,S=Math.sqrt(b*b+_*_+w*w),k=Math.asin(w/=S),N=xo(xo(w)-1)<Uo||xo(r-h)<Uo?(r+h)/2:Math.atan2(_,b),E=n(N,k),A=E[0],C=E[1],z=A-t,L=C-e,q=M*z-m*L;(q*q/x>u||xo((m*z+M*L)/x-.5)>.3||o>a*p+l*g+c*v)&&(i(t,e,r,a,l,c,A,C,N,b/=S,_/=S,w,d,y),y.point(A,C),i(A,C,N,b,_,w,f,s,h,p,g,v,d,y))}}var u=.5,o=Math.cos(30*Yo),a=16;return t.precision=function(n){return arguments.length?(a=(u=n*n)>0&&16,t):Math.sqrt(u)},t}function re(n){var t=ee(function(t,e){return n([t*Zo,e*Zo])});return function(n){return le(t(n))}}function ie(n){this.stream=n}function ue(n,t){return{point:t,sphere:function(){n.sphere()},lineStart:function(){n.lineStart()},lineEnd:function(){n.lineEnd()},polygonStart:function(){n.polygonStart()},polygonEnd:function(){n.polygonEnd()}}}function oe(n){return ae(function(){return n})()}function ae(n){function t(n){return n=a(n[0]*Yo,n[1]*Yo),[n[0]*h+l,c-n[1]*h]}function e(n){return n=a.invert((n[0]-l)/h,(c-n[1])/h),n&&[n[0]*Zo,n[1]*Zo]}function r(){a=Ct(o=se(y,M,x),u);var n=u(v,d);return l=p-n[0]*h,c=g+n[1]*h,i()}function i(){return f&&(f.valid=!1,f=null),t}var u,o,a,l,c,f,s=ee(function(n,t){return n=u(n,t),[n[0]*h+l,c-n[1]*h]}),h=150,p=480,g=250,v=0,d=0,y=0,M=0,x=0,b=Fa,_=m,w=null,S=null;return t.stream=function(n){return f&&(f.valid=!1),f=le(b(o,s(_(n)))),f.valid=!0,f},t.clipAngle=function(n){return arguments.length?(b=null==n?(w=n,Fa):It((w=+n)*Yo),i()):w},t.clipExtent=function(n){return arguments.length?(S=n,_=n?Zt(n[0][0],n[0][1],n[1][0],n[1][1]):m,i()):S},t.scale=function(n){return arguments.length?(h=+n,r()):h},t.translate=function(n){return arguments.length?(p=+n[0],g=+n[1],r()):[p,g]},t.center=function(n){return arguments.length?(v=n[0]%360*Yo,d=n[1]%360*Yo,r()):[v*Zo,d*Zo]},t.rotate=function(n){return arguments.length?(y=n[0]%360*Yo,M=n[1]%360*Yo,x=n.length>2?n[2]%360*Yo:0,r()):[y*Zo,M*Zo,x*Zo]},ao.rebind(t,s,"precision"),function(){return u=n.apply(this,arguments),t.invert=u.invert&&e,r()}}function le(n){return ue(n,function(t,e){n.point(t*Yo,e*Yo)})}function ce(n,t){return[n,t]}function fe(n,t){return[n>Fo?n-Ho:-Fo>n?n+Ho:n,t]}function se(n,t,e){return n?t||e?Ct(pe(n),ge(t,e)):pe(n):t||e?ge(t,e):fe}function he(n){return function(t,e){return t+=n,[t>Fo?t-Ho:-Fo>t?t+Ho:t,e]}}function pe(n){var t=he(n);return t.invert=he(-n),t}function ge(n,t){function e(n,t){var e=Math.cos(t),a=Math.cos(n)*e,l=Math.sin(n)*e,c=Math.sin(t),f=c*r+a*i;return[Math.atan2(l*u-f*o,a*r-c*i),tn(f*u+l*o)]}var r=Math.cos(n),i=Math.sin(n),u=Math.cos(t),o=Math.sin(t);return e.invert=function(n,t){var e=Math.cos(t),a=Math.cos(n)*e,l=Math.sin(n)*e,c=Math.sin(t),f=c*u-l*o;return[Math.atan2(l*u+c*o,a*r+f*i),tn(f*r-a*i)]},e}function ve(n,t){var e=Math.cos(n),r=Math.sin(n);return function(i,u,o,a){var l=o*t;null!=i?(i=de(e,i),u=de(e,u),(o>0?u>i:i>u)&&(i+=o*Ho)):(i=n+o*Ho,u=n-.5*l);for(var c,f=i;o>0?f>u:u>f;f-=l)a.point((c=_t([e,-r*Math.cos(f),-r*Math.sin(f)]))[0],c[1])}}function de(n,t){var e=dt(t);e[0]-=n,bt(e);var r=nn(-e[1]);return((-e[2]<0?-r:r)+2*Math.PI-Uo)%(2*Math.PI)}function ye(n,t,e){var r=ao.range(n,t-Uo,e).concat(t);return function(n){return r.map(function(t){return[n,t]})}}function me(n,t,e){var r=ao.range(n,t-Uo,e).concat(t);return function(n){return r.map(function(t){return[t,n]})}}function Me(n){return n.source}function xe(n){return n.target}function be(n,t,e,r){var i=Math.cos(t),u=Math.sin(t),o=Math.cos(r),a=Math.sin(r),l=i*Math.cos(n),c=i*Math.sin(n),f=o*Math.cos(e),s=o*Math.sin(e),h=2*Math.asin(Math.sqrt(on(r-t)+i*o*on(e-n))),p=1/Math.sin(h),g=h?function(n){var t=Math.sin(n*=h)*p,e=Math.sin(h-n)*p,r=e*l+t*f,i=e*c+t*s,o=e*u+t*a;return[Math.atan2(i,r)*Zo,Math.atan2(o,Math.sqrt(r*r+i*i))*Zo]}:function(){return[n*Zo,t*Zo]};return g.distance=h,g}function _e(){function n(n,i){var u=Math.sin(i*=Yo),o=Math.cos(i),a=xo((n*=Yo)-t),l=Math.cos(a);Ja+=Math.atan2(Math.sqrt((a=o*Math.sin(a))*a+(a=r*u-e*o*l)*a),e*u+r*o*l),t=n,e=u,r=o}var t,e,r;Ga.point=function(i,u){t=i*Yo,e=Math.sin(u*=Yo),r=Math.cos(u),Ga.point=n},Ga.lineEnd=function(){Ga.point=Ga.lineEnd=b}}function we(n,t){function e(t,e){var r=Math.cos(t),i=Math.cos(e),u=n(r*i);return[u*i*Math.sin(t),u*Math.sin(e)]}return e.invert=function(n,e){var r=Math.sqrt(n*n+e*e),i=t(r),u=Math.sin(i),o=Math.cos(i);return[Math.atan2(n*u,r*o),Math.asin(r&&e*u/r)]},e}function Se(n,t){function e(n,t){o>0?-Io+Uo>t&&(t=-Io+Uo):t>Io-Uo&&(t=Io-Uo);var e=o/Math.pow(i(t),u);return[e*Math.sin(u*n),o-e*Math.cos(u*n)]}var r=Math.cos(n),i=function(n){return Math.tan(Fo/4+n/2)},u=n===t?Math.sin(n):Math.log(r/Math.cos(t))/Math.log(i(t)/i(n)),o=r*Math.pow(i(n),u)/u;return u?(e.invert=function(n,t){var e=o-t,r=K(u)*Math.sqrt(n*n+e*e);return[Math.atan2(n,e)/u,2*Math.atan(Math.pow(o/r,1/u))-Io]},e):Ne}function ke(n,t){function e(n,t){var e=u-t;return[e*Math.sin(i*n),u-e*Math.cos(i*n)]}var r=Math.cos(n),i=n===t?Math.sin(n):(r-Math.cos(t))/(t-n),u=r/i+n;return xo(i)<Uo?ce:(e.invert=function(n,t){var e=u-t;return[Math.atan2(n,e)/i,u-K(i)*Math.sqrt(n*n+e*e)]},e)}function Ne(n,t){return[n,Math.log(Math.tan(Fo/4+t/2))]}function Ee(n){var t,e=oe(n),r=e.scale,i=e.translate,u=e.clipExtent;return e.scale=function(){var n=r.apply(e,arguments);return n===e?t?e.clipExtent(null):e:n},e.translate=function(){var n=i.apply(e,arguments);return n===e?t?e.clipExtent(null):e:n},e.clipExtent=function(n){var o=u.apply(e,arguments);if(o===e){if(t=null==n){var a=Fo*r(),l=i();u([[l[0]-a,l[1]-a],[l[0]+a,l[1]+a]])}}else t&&(o=null);return o},e.clipExtent(null)}function Ae(n,t){return[Math.log(Math.tan(Fo/4+t/2)),-n]}function Ce(n){return n[0]}function ze(n){return n[1]}function Le(n){for(var t=n.length,e=[0,1],r=2,i=2;t>i;i++){for(;r>1&&Q(n[e[r-2]],n[e[r-1]],n[i])<=0;)--r;e[r++]=i}return e.slice(0,r)}function qe(n,t){return n[0]-t[0]||n[1]-t[1]}function Te(n,t,e){return(e[0]-t[0])*(n[1]-t[1])<(e[1]-t[1])*(n[0]-t[0])}function Re(n,t,e,r){var i=n[0],u=e[0],o=t[0]-i,a=r[0]-u,l=n[1],c=e[1],f=t[1]-l,s=r[1]-c,h=(a*(l-c)-s*(i-u))/(s*o-a*f);return[i+h*o,l+h*f]}function De(n){var t=n[0],e=n[n.length-1];return!(t[0]-e[0]||t[1]-e[1])}function Pe(){rr(this),this.edge=this.site=this.circle=null}function Ue(n){var t=cl.pop()||new Pe;return t.site=n,t}function je(n){Be(n),ol.remove(n),cl.push(n),rr(n)}function Fe(n){var t=n.circle,e=t.x,r=t.cy,i={x:e,y:r},u=n.P,o=n.N,a=[n];je(n);for(var l=u;l.circle&&xo(e-l.circle.x)<Uo&&xo(r-l.circle.cy)<Uo;)u=l.P,a.unshift(l),je(l),l=u;a.unshift(l),Be(l);for(var c=o;c.circle&&xo(e-c.circle.x)<Uo&&xo(r-c.circle.cy)<Uo;)o=c.N,a.push(c),je(c),c=o;a.push(c),Be(c);var f,s=a.length;for(f=1;s>f;++f)c=a[f],l=a[f-1],nr(c.edge,l.site,c.site,i);l=a[0],c=a[s-1],c.edge=Ke(l.site,c.site,null,i),$e(l),$e(c)}function He(n){for(var t,e,r,i,u=n.x,o=n.y,a=ol._;a;)if(r=Oe(a,o)-u,r>Uo)a=a.L;else{if(i=u-Ie(a,o),!(i>Uo)){r>-Uo?(t=a.P,e=a):i>-Uo?(t=a,e=a.N):t=e=a;break}if(!a.R){t=a;break}a=a.R}var l=Ue(n);if(ol.insert(t,l),t||e){if(t===e)return Be(t),e=Ue(t.site),ol.insert(l,e),l.edge=e.edge=Ke(t.site,l.site),$e(t),void $e(e);if(!e)return void(l.edge=Ke(t.site,l.site));Be(t),Be(e);var c=t.site,f=c.x,s=c.y,h=n.x-f,p=n.y-s,g=e.site,v=g.x-f,d=g.y-s,y=2*(h*d-p*v),m=h*h+p*p,M=v*v+d*d,x={x:(d*m-p*M)/y+f,y:(h*M-v*m)/y+s};nr(e.edge,c,g,x),l.edge=Ke(c,n,null,x),e.edge=Ke(n,g,null,x),$e(t),$e(e)}}function Oe(n,t){var e=n.site,r=e.x,i=e.y,u=i-t;if(!u)return r;var o=n.P;if(!o)return-(1/0);e=o.site;var a=e.x,l=e.y,c=l-t;if(!c)return a;var f=a-r,s=1/u-1/c,h=f/c;return s?(-h+Math.sqrt(h*h-2*s*(f*f/(-2*c)-l+c/2+i-u/2)))/s+r:(r+a)/2}function Ie(n,t){var e=n.N;if(e)return Oe(e,t);var r=n.site;return r.y===t?r.x:1/0}function Ye(n){this.site=n,this.edges=[]}function Ze(n){for(var t,e,r,i,u,o,a,l,c,f,s=n[0][0],h=n[1][0],p=n[0][1],g=n[1][1],v=ul,d=v.length;d--;)if(u=v[d],u&&u.prepare())for(a=u.edges,l=a.length,o=0;l>o;)f=a[o].end(),r=f.x,i=f.y,c=a[++o%l].start(),t=c.x,e=c.y,(xo(r-t)>Uo||xo(i-e)>Uo)&&(a.splice(o,0,new tr(Qe(u.site,f,xo(r-s)<Uo&&g-i>Uo?{x:s,y:xo(t-s)<Uo?e:g}:xo(i-g)<Uo&&h-r>Uo?{x:xo(e-g)<Uo?t:h,y:g}:xo(r-h)<Uo&&i-p>Uo?{x:h,y:xo(t-h)<Uo?e:p}:xo(i-p)<Uo&&r-s>Uo?{x:xo(e-p)<Uo?t:s,y:p}:null),u.site,null)),++l)}function Ve(n,t){return t.angle-n.angle}function Xe(){rr(this),this.x=this.y=this.arc=this.site=this.cy=null}function $e(n){var t=n.P,e=n.N;if(t&&e){var r=t.site,i=n.site,u=e.site;if(r!==u){var o=i.x,a=i.y,l=r.x-o,c=r.y-a,f=u.x-o,s=u.y-a,h=2*(l*s-c*f);if(!(h>=-jo)){var p=l*l+c*c,g=f*f+s*s,v=(s*p-c*g)/h,d=(l*g-f*p)/h,s=d+a,y=fl.pop()||new Xe;y.arc=n,y.site=i,y.x=v+o,y.y=s+Math.sqrt(v*v+d*d),y.cy=s,n.circle=y;for(var m=null,M=ll._;M;)if(y.y<M.y||y.y===M.y&&y.x<=M.x){if(!M.L){m=M.P;break}M=M.L}else{if(!M.R){m=M;break}M=M.R}ll.insert(m,y),m||(al=y)}}}}function Be(n){var t=n.circle;t&&(t.P||(al=t.N),ll.remove(t),fl.push(t),rr(t),n.circle=null)}function We(n){for(var t,e=il,r=Yt(n[0][0],n[0][1],n[1][0],n[1][1]),i=e.length;i--;)t=e[i],(!Je(t,n)||!r(t)||xo(t.a.x-t.b.x)<Uo&&xo(t.a.y-t.b.y)<Uo)&&(t.a=t.b=null,e.splice(i,1))}function Je(n,t){var e=n.b;if(e)return!0;var r,i,u=n.a,o=t[0][0],a=t[1][0],l=t[0][1],c=t[1][1],f=n.l,s=n.r,h=f.x,p=f.y,g=s.x,v=s.y,d=(h+g)/2,y=(p+v)/2;if(v===p){if(o>d||d>=a)return;if(h>g){if(u){if(u.y>=c)return}else u={x:d,y:l};e={x:d,y:c}}else{if(u){if(u.y<l)return}else u={x:d,y:c};e={x:d,y:l}}}else if(r=(h-g)/(v-p),i=y-r*d,-1>r||r>1)if(h>g){if(u){if(u.y>=c)return}else u={x:(l-i)/r,y:l};e={x:(c-i)/r,y:c}}else{if(u){if(u.y<l)return}else u={x:(c-i)/r,y:c};e={x:(l-i)/r,y:l}}else if(v>p){if(u){if(u.x>=a)return}else u={x:o,y:r*o+i};e={x:a,y:r*a+i}}else{if(u){if(u.x<o)return}else u={x:a,y:r*a+i};e={x:o,y:r*o+i}}return n.a=u,n.b=e,!0}function Ge(n,t){this.l=n,this.r=t,this.a=this.b=null}function Ke(n,t,e,r){var i=new Ge(n,t);return il.push(i),e&&nr(i,n,t,e),r&&nr(i,t,n,r),ul[n.i].edges.push(new tr(i,n,t)),ul[t.i].edges.push(new tr(i,t,n)),i}function Qe(n,t,e){var r=new Ge(n,null);return r.a=t,r.b=e,il.push(r),r}function nr(n,t,e,r){n.a||n.b?n.l===e?n.b=r:n.a=r:(n.a=r,n.l=t,n.r=e)}function tr(n,t,e){var r=n.a,i=n.b;this.edge=n,this.site=t,this.angle=e?Math.atan2(e.y-t.y,e.x-t.x):n.l===t?Math.atan2(i.x-r.x,r.y-i.y):Math.atan2(r.x-i.x,i.y-r.y)}function er(){this._=null}function rr(n){n.U=n.C=n.L=n.R=n.P=n.N=null}function ir(n,t){var e=t,r=t.R,i=e.U;i?i.L===e?i.L=r:i.R=r:n._=r,r.U=i,e.U=r,e.R=r.L,e.R&&(e.R.U=e),r.L=e}function ur(n,t){var e=t,r=t.L,i=e.U;i?i.L===e?i.L=r:i.R=r:n._=r,r.U=i,e.U=r,e.L=r.R,e.L&&(e.L.U=e),r.R=e}function or(n){for(;n.L;)n=n.L;return n}function ar(n,t){var e,r,i,u=n.sort(lr).pop();for(il=[],ul=new Array(n.length),ol=new er,ll=new er;;)if(i=al,u&&(!i||u.y<i.y||u.y===i.y&&u.x<i.x))u.x===e&&u.y===r||(ul[u.i]=new Ye(u),He(u),e=u.x,r=u.y),u=n.pop();else{if(!i)break;Fe(i.arc)}t&&(We(t),Ze(t));var o={cells:ul,edges:il};return ol=ll=il=ul=null,o}function lr(n,t){return t.y-n.y||t.x-n.x}function cr(n,t,e){return(n.x-e.x)*(t.y-n.y)-(n.x-t.x)*(e.y-n.y)}function fr(n){return n.x}function sr(n){return n.y}function hr(){return{leaf:!0,nodes:[],point:null,x:null,y:null}}function pr(n,t,e,r,i,u){if(!n(t,e,r,i,u)){var o=.5*(e+i),a=.5*(r+u),l=t.nodes;l[0]&&pr(n,l[0],e,r,o,a),l[1]&&pr(n,l[1],o,r,i,a),l[2]&&pr(n,l[2],e,a,o,u),l[3]&&pr(n,l[3],o,a,i,u)}}function gr(n,t,e,r,i,u,o){var a,l=1/0;return function c(n,f,s,h,p){if(!(f>u||s>o||r>h||i>p)){if(g=n.point){var g,v=t-n.x,d=e-n.y,y=v*v+d*d;if(l>y){var m=Math.sqrt(l=y);r=t-m,i=e-m,u=t+m,o=e+m,a=g}}for(var M=n.nodes,x=.5*(f+h),b=.5*(s+p),_=t>=x,w=e>=b,S=w<<1|_,k=S+4;k>S;++S)if(n=M[3&S])switch(3&S){case 0:c(n,f,s,x,b);break;case 1:c(n,x,s,h,b);break;case 2:c(n,f,b,x,p);break;case 3:c(n,x,b,h,p)}}}(n,r,i,u,o),a}function vr(n,t){n=ao.rgb(n),t=ao.rgb(t);var e=n.r,r=n.g,i=n.b,u=t.r-e,o=t.g-r,a=t.b-i;return function(n){return"#"+bn(Math.round(e+u*n))+bn(Math.round(r+o*n))+bn(Math.round(i+a*n))}}function dr(n,t){var e,r={},i={};for(e in n)e in t?r[e]=Mr(n[e],t[e]):i[e]=n[e];for(e in t)e in n||(i[e]=t[e]);return function(n){for(e in r)i[e]=r[e](n);return i}}function yr(n,t){return n=+n,t=+t,function(e){return n*(1-e)+t*e}}function mr(n,t){var e,r,i,u=hl.lastIndex=pl.lastIndex=0,o=-1,a=[],l=[];for(n+="",t+="";(e=hl.exec(n))&&(r=pl.exec(t));)(i=r.index)>u&&(i=t.slice(u,i),a[o]?a[o]+=i:a[++o]=i),(e=e[0])===(r=r[0])?a[o]?a[o]+=r:a[++o]=r:(a[++o]=null,l.push({i:o,x:yr(e,r)})),u=pl.lastIndex;return u<t.length&&(i=t.slice(u),a[o]?a[o]+=i:a[++o]=i),a.length<2?l[0]?(t=l[0].x,function(n){return t(n)+""}):function(){return t}:(t=l.length,function(n){for(var e,r=0;t>r;++r)a[(e=l[r]).i]=e.x(n);return a.join("")})}function Mr(n,t){for(var e,r=ao.interpolators.length;--r>=0&&!(e=ao.interpolators[r](n,t)););return e}function xr(n,t){var e,r=[],i=[],u=n.length,o=t.length,a=Math.min(n.length,t.length);for(e=0;a>e;++e)r.push(Mr(n[e],t[e]));for(;u>e;++e)i[e]=n[e];for(;o>e;++e)i[e]=t[e];return function(n){for(e=0;a>e;++e)i[e]=r[e](n);return i}}function br(n){return function(t){return 0>=t?0:t>=1?1:n(t)}}function _r(n){return function(t){return 1-n(1-t)}}function wr(n){return function(t){return.5*(.5>t?n(2*t):2-n(2-2*t))}}function Sr(n){return n*n}function kr(n){return n*n*n}function Nr(n){if(0>=n)return 0;if(n>=1)return 1;var t=n*n,e=t*n;return 4*(.5>n?e:3*(n-t)+e-.75)}function Er(n){return function(t){return Math.pow(t,n)}}function Ar(n){return 1-Math.cos(n*Io)}function Cr(n){return Math.pow(2,10*(n-1))}function zr(n){return 1-Math.sqrt(1-n*n)}function Lr(n,t){var e;return arguments.length<2&&(t=.45),arguments.length?e=t/Ho*Math.asin(1/n):(n=1,e=t/4),function(r){return 1+n*Math.pow(2,-10*r)*Math.sin((r-e)*Ho/t)}}function qr(n){return n||(n=1.70158),function(t){return t*t*((n+1)*t-n)}}function Tr(n){return 1/2.75>n?7.5625*n*n:2/2.75>n?7.5625*(n-=1.5/2.75)*n+.75:2.5/2.75>n?7.5625*(n-=2.25/2.75)*n+.9375:7.5625*(n-=2.625/2.75)*n+.984375}function Rr(n,t){n=ao.hcl(n),t=ao.hcl(t);var e=n.h,r=n.c,i=n.l,u=t.h-e,o=t.c-r,a=t.l-i;return isNaN(o)&&(o=0,r=isNaN(r)?t.c:r),isNaN(u)?(u=0,e=isNaN(e)?t.h:e):u>180?u-=360:-180>u&&(u+=360),function(n){return sn(e+u*n,r+o*n,i+a*n)+""}}function Dr(n,t){n=ao.hsl(n),t=ao.hsl(t);var e=n.h,r=n.s,i=n.l,u=t.h-e,o=t.s-r,a=t.l-i;return isNaN(o)&&(o=0,r=isNaN(r)?t.s:r),isNaN(u)?(u=0,e=isNaN(e)?t.h:e):u>180?u-=360:-180>u&&(u+=360),function(n){return cn(e+u*n,r+o*n,i+a*n)+""}}function Pr(n,t){n=ao.lab(n),t=ao.lab(t);var e=n.l,r=n.a,i=n.b,u=t.l-e,o=t.a-r,a=t.b-i;return function(n){return pn(e+u*n,r+o*n,i+a*n)+""}}function Ur(n,t){return t-=n,function(e){return Math.round(n+t*e)}}function jr(n){var t=[n.a,n.b],e=[n.c,n.d],r=Hr(t),i=Fr(t,e),u=Hr(Or(e,t,-i))||0;t[0]*e[1]<e[0]*t[1]&&(t[0]*=-1,t[1]*=-1,r*=-1,i*=-1),this.rotate=(r?Math.atan2(t[1],t[0]):Math.atan2(-e[0],e[1]))*Zo,this.translate=[n.e,n.f],this.scale=[r,u],this.skew=u?Math.atan2(i,u)*Zo:0}function Fr(n,t){return n[0]*t[0]+n[1]*t[1]}function Hr(n){var t=Math.sqrt(Fr(n,n));return t&&(n[0]/=t,n[1]/=t),t}function Or(n,t,e){return n[0]+=e*t[0],n[1]+=e*t[1],n}function Ir(n){return n.length?n.pop()+",":""}function Yr(n,t,e,r){if(n[0]!==t[0]||n[1]!==t[1]){var i=e.push("translate(",null,",",null,")");r.push({i:i-4,x:yr(n[0],t[0])},{i:i-2,x:yr(n[1],t[1])})}else(t[0]||t[1])&&e.push("translate("+t+")")}function Zr(n,t,e,r){n!==t?(n-t>180?t+=360:t-n>180&&(n+=360),r.push({i:e.push(Ir(e)+"rotate(",null,")")-2,x:yr(n,t)})):t&&e.push(Ir(e)+"rotate("+t+")")}function Vr(n,t,e,r){n!==t?r.push({i:e.push(Ir(e)+"skewX(",null,")")-2,x:yr(n,t)}):t&&e.push(Ir(e)+"skewX("+t+")")}function Xr(n,t,e,r){if(n[0]!==t[0]||n[1]!==t[1]){var i=e.push(Ir(e)+"scale(",null,",",null,")");r.push({i:i-4,x:yr(n[0],t[0])},{i:i-2,x:yr(n[1],t[1])})}else 1===t[0]&&1===t[1]||e.push(Ir(e)+"scale("+t+")")}function $r(n,t){var e=[],r=[];return n=ao.transform(n),t=ao.transform(t),Yr(n.translate,t.translate,e,r),Zr(n.rotate,t.rotate,e,r),Vr(n.skew,t.skew,e,r),Xr(n.scale,t.scale,e,r),n=t=null,function(n){for(var t,i=-1,u=r.length;++i<u;)e[(t=r[i]).i]=t.x(n);return e.join("")}}function Br(n,t){return t=(t-=n=+n)||1/t,function(e){return(e-n)/t}}function Wr(n,t){return t=(t-=n=+n)||1/t,function(e){return Math.max(0,Math.min(1,(e-n)/t))}}function Jr(n){for(var t=n.source,e=n.target,r=Kr(t,e),i=[t];t!==r;)t=t.parent,i.push(t);for(var u=i.length;e!==r;)i.splice(u,0,e),e=e.parent;return i}function Gr(n){for(var t=[],e=n.parent;null!=e;)t.push(n),n=e,e=e.parent;return t.push(n),t}function Kr(n,t){if(n===t)return n;for(var e=Gr(n),r=Gr(t),i=e.pop(),u=r.pop(),o=null;i===u;)o=i,i=e.pop(),u=r.pop();return o}function Qr(n){n.fixed|=2}function ni(n){n.fixed&=-7}function ti(n){n.fixed|=4,n.px=n.x,n.py=n.y}function ei(n){n.fixed&=-5}function ri(n,t,e){var r=0,i=0;if(n.charge=0,!n.leaf)for(var u,o=n.nodes,a=o.length,l=-1;++l<a;)u=o[l],null!=u&&(ri(u,t,e),n.charge+=u.charge,r+=u.charge*u.cx,i+=u.charge*u.cy);if(n.point){n.leaf||(n.point.x+=Math.random()-.5,n.point.y+=Math.random()-.5);var c=t*e[n.point.index];n.charge+=n.pointCharge=c,r+=c*n.point.x,i+=c*n.point.y}n.cx=r/n.charge,n.cy=i/n.charge}function ii(n,t){return ao.rebind(n,t,"sort","children","value"),n.nodes=n,n.links=fi,n}function ui(n,t){for(var e=[n];null!=(n=e.pop());)if(t(n),(i=n.children)&&(r=i.length))for(var r,i;--r>=0;)e.push(i[r])}function oi(n,t){for(var e=[n],r=[];null!=(n=e.pop());)if(r.push(n),(u=n.children)&&(i=u.length))for(var i,u,o=-1;++o<i;)e.push(u[o]);for(;null!=(n=r.pop());)t(n)}function ai(n){return n.children}function li(n){return n.value}function ci(n,t){return t.value-n.value}function fi(n){return ao.merge(n.map(function(n){return(n.children||[]).map(function(t){return{source:n,target:t}})}))}function si(n){return n.x}function hi(n){return n.y}function pi(n,t,e){n.y0=t,n.y=e}function gi(n){return ao.range(n.length)}function vi(n){for(var t=-1,e=n[0].length,r=[];++t<e;)r[t]=0;return r}function di(n){for(var t,e=1,r=0,i=n[0][1],u=n.length;u>e;++e)(t=n[e][1])>i&&(r=e,i=t);return r}function yi(n){return n.reduce(mi,0)}function mi(n,t){return n+t[1]}function Mi(n,t){return xi(n,Math.ceil(Math.log(t.length)/Math.LN2+1))}function xi(n,t){for(var e=-1,r=+n[0],i=(n[1]-r)/t,u=[];++e<=t;)u[e]=i*e+r;return u}function bi(n){return[ao.min(n),ao.max(n)]}function _i(n,t){return n.value-t.value}function wi(n,t){var e=n._pack_next;n._pack_next=t,t._pack_prev=n,t._pack_next=e,e._pack_prev=t}function Si(n,t){n._pack_next=t,t._pack_prev=n}function ki(n,t){var e=t.x-n.x,r=t.y-n.y,i=n.r+t.r;return.999*i*i>e*e+r*r}function Ni(n){function t(n){f=Math.min(n.x-n.r,f),s=Math.max(n.x+n.r,s),h=Math.min(n.y-n.r,h),p=Math.max(n.y+n.r,p)}if((e=n.children)&&(c=e.length)){var e,r,i,u,o,a,l,c,f=1/0,s=-(1/0),h=1/0,p=-(1/0);if(e.forEach(Ei),r=e[0],r.x=-r.r,r.y=0,t(r),c>1&&(i=e[1],i.x=i.r,i.y=0,t(i),c>2))for(u=e[2],zi(r,i,u),t(u),wi(r,u),r._pack_prev=u,wi(u,i),i=r._pack_next,o=3;c>o;o++){zi(r,i,u=e[o]);var g=0,v=1,d=1;for(a=i._pack_next;a!==i;a=a._pack_next,v++)if(ki(a,u)){g=1;break}if(1==g)for(l=r._pack_prev;l!==a._pack_prev&&!ki(l,u);l=l._pack_prev,d++);g?(d>v||v==d&&i.r<r.r?Si(r,i=a):Si(r=l,i),o--):(wi(r,u),i=u,t(u))}var y=(f+s)/2,m=(h+p)/2,M=0;for(o=0;c>o;o++)u=e[o],u.x-=y,u.y-=m,M=Math.max(M,u.r+Math.sqrt(u.x*u.x+u.y*u.y));n.r=M,e.forEach(Ai)}}function Ei(n){n._pack_next=n._pack_prev=n}function Ai(n){delete n._pack_next,delete n._pack_prev}function Ci(n,t,e,r){var i=n.children;if(n.x=t+=r*n.x,n.y=e+=r*n.y,n.r*=r,i)for(var u=-1,o=i.length;++u<o;)Ci(i[u],t,e,r)}function zi(n,t,e){var r=n.r+e.r,i=t.x-n.x,u=t.y-n.y;if(r&&(i||u)){var o=t.r+e.r,a=i*i+u*u;o*=o,r*=r;var l=.5+(r-o)/(2*a),c=Math.sqrt(Math.max(0,2*o*(r+a)-(r-=a)*r-o*o))/(2*a);e.x=n.x+l*i+c*u,e.y=n.y+l*u-c*i}else e.x=n.x+r,e.y=n.y}function Li(n,t){return n.parent==t.parent?1:2}function qi(n){var t=n.children;return t.length?t[0]:n.t}function Ti(n){var t,e=n.children;return(t=e.length)?e[t-1]:n.t}function Ri(n,t,e){var r=e/(t.i-n.i);t.c-=r,t.s+=e,n.c+=r,t.z+=e,t.m+=e}function Di(n){for(var t,e=0,r=0,i=n.children,u=i.length;--u>=0;)t=i[u],t.z+=e,t.m+=e,e+=t.s+(r+=t.c)}function Pi(n,t,e){return n.a.parent===t.parent?n.a:e}function Ui(n){return 1+ao.max(n,function(n){return n.y})}function ji(n){return n.reduce(function(n,t){return n+t.x},0)/n.length}function Fi(n){var t=n.children;return t&&t.length?Fi(t[0]):n}function Hi(n){var t,e=n.children;return e&&(t=e.length)?Hi(e[t-1]):n}function Oi(n){return{x:n.x,y:n.y,dx:n.dx,dy:n.dy}}function Ii(n,t){var e=n.x+t[3],r=n.y+t[0],i=n.dx-t[1]-t[3],u=n.dy-t[0]-t[2];return 0>i&&(e+=i/2,i=0),0>u&&(r+=u/2,u=0),{x:e,y:r,dx:i,dy:u}}function Yi(n){var t=n[0],e=n[n.length-1];return e>t?[t,e]:[e,t]}function Zi(n){return n.rangeExtent?n.rangeExtent():Yi(n.range())}function Vi(n,t,e,r){var i=e(n[0],n[1]),u=r(t[0],t[1]);return function(n){return u(i(n))}}function Xi(n,t){var e,r=0,i=n.length-1,u=n[r],o=n[i];return u>o&&(e=r,r=i,i=e,e=u,u=o,o=e),n[r]=t.floor(u),n[i]=t.ceil(o),n}function $i(n){return n?{floor:function(t){return Math.floor(t/n)*n},ceil:function(t){return Math.ceil(t/n)*n}}:Sl}function Bi(n,t,e,r){var i=[],u=[],o=0,a=Math.min(n.length,t.length)-1;for(n[a]<n[0]&&(n=n.slice().reverse(),t=t.slice().reverse());++o<=a;)i.push(e(n[o-1],n[o])),u.push(r(t[o-1],t[o]));return function(t){var e=ao.bisect(n,t,1,a)-1;return u[e](i[e](t))}}function Wi(n,t,e,r){function i(){var i=Math.min(n.length,t.length)>2?Bi:Vi,l=r?Wr:Br;return o=i(n,t,l,e),a=i(t,n,l,Mr),u}function u(n){return o(n)}var o,a;return u.invert=function(n){return a(n)},u.domain=function(t){return arguments.length?(n=t.map(Number),i()):n},u.range=function(n){return arguments.length?(t=n,i()):t},u.rangeRound=function(n){return u.range(n).interpolate(Ur)},u.clamp=function(n){return arguments.length?(r=n,i()):r},u.interpolate=function(n){return arguments.length?(e=n,i()):e},u.ticks=function(t){return Qi(n,t)},u.tickFormat=function(t,e){return nu(n,t,e)},u.nice=function(t){return Gi(n,t),i()},u.copy=function(){return Wi(n,t,e,r)},i()}function Ji(n,t){return ao.rebind(n,t,"range","rangeRound","interpolate","clamp")}function Gi(n,t){return Xi(n,$i(Ki(n,t)[2])),Xi(n,$i(Ki(n,t)[2])),n}function Ki(n,t){null==t&&(t=10);var e=Yi(n),r=e[1]-e[0],i=Math.pow(10,Math.floor(Math.log(r/t)/Math.LN10)),u=t/r*i;return.15>=u?i*=10:.35>=u?i*=5:.75>=u&&(i*=2),e[0]=Math.ceil(e[0]/i)*i,e[1]=Math.floor(e[1]/i)*i+.5*i,e[2]=i,e}function Qi(n,t){return ao.range.apply(ao,Ki(n,t))}function nu(n,t,e){var r=Ki(n,t);if(e){var i=ha.exec(e);if(i.shift(),"s"===i[8]){var u=ao.formatPrefix(Math.max(xo(r[0]),xo(r[1])));return i[7]||(i[7]="."+tu(u.scale(r[2]))),i[8]="f",e=ao.format(i.join("")),function(n){return e(u.scale(n))+u.symbol}}i[7]||(i[7]="."+eu(i[8],r)),e=i.join("")}else e=",."+tu(r[2])+"f";return ao.format(e)}function tu(n){return-Math.floor(Math.log(n)/Math.LN10+.01)}function eu(n,t){var e=tu(t[2]);return n in kl?Math.abs(e-tu(Math.max(xo(t[0]),xo(t[1]))))+ +("e"!==n):e-2*("%"===n)}function ru(n,t,e,r){function i(n){return(e?Math.log(0>n?0:n):-Math.log(n>0?0:-n))/Math.log(t)}function u(n){return e?Math.pow(t,n):-Math.pow(t,-n)}function o(t){return n(i(t))}return o.invert=function(t){return u(n.invert(t))},o.domain=function(t){return arguments.length?(e=t[0]>=0,n.domain((r=t.map(Number)).map(i)),o):r},o.base=function(e){return arguments.length?(t=+e,n.domain(r.map(i)),o):t},o.nice=function(){var t=Xi(r.map(i),e?Math:El);return n.domain(t),r=t.map(u),o},o.ticks=function(){var n=Yi(r),o=[],a=n[0],l=n[1],c=Math.floor(i(a)),f=Math.ceil(i(l)),s=t%1?2:t;if(isFinite(f-c)){if(e){for(;f>c;c++)for(var h=1;s>h;h++)o.push(u(c)*h);o.push(u(c))}else for(o.push(u(c));c++<f;)for(var h=s-1;h>0;h--)o.push(u(c)*h);for(c=0;o[c]<a;c++);for(f=o.length;o[f-1]>l;f--);o=o.slice(c,f)}return o},o.tickFormat=function(n,e){if(!arguments.length)return Nl;arguments.length<2?e=Nl:"function"!=typeof e&&(e=ao.format(e));var r=Math.max(1,t*n/o.ticks().length);return function(n){var o=n/u(Math.round(i(n)));return t-.5>o*t&&(o*=t),r>=o?e(n):""}},o.copy=function(){return ru(n.copy(),t,e,r)},Ji(o,n)}function iu(n,t,e){function r(t){return n(i(t))}var i=uu(t),u=uu(1/t);return r.invert=function(t){return u(n.invert(t))},r.domain=function(t){return arguments.length?(n.domain((e=t.map(Number)).map(i)),r):e},r.ticks=function(n){return Qi(e,n)},r.tickFormat=function(n,t){return nu(e,n,t)},r.nice=function(n){return r.domain(Gi(e,n))},r.exponent=function(o){return arguments.length?(i=uu(t=o),u=uu(1/t),n.domain(e.map(i)),r):t},r.copy=function(){return iu(n.copy(),t,e)},Ji(r,n)}function uu(n){return function(t){return 0>t?-Math.pow(-t,n):Math.pow(t,n)}}function ou(n,t){function e(e){return u[((i.get(e)||("range"===t.t?i.set(e,n.push(e)):NaN))-1)%u.length]}function r(t,e){return ao.range(n.length).map(function(n){return t+e*n})}var i,u,o;return e.domain=function(r){if(!arguments.length)return n;n=[],i=new c;for(var u,o=-1,a=r.length;++o<a;)i.has(u=r[o])||i.set(u,n.push(u));return e[t.t].apply(e,t.a)},e.range=function(n){return arguments.length?(u=n,o=0,t={t:"range",a:arguments},e):u},e.rangePoints=function(i,a){arguments.length<2&&(a=0);var l=i[0],c=i[1],f=n.length<2?(l=(l+c)/2,0):(c-l)/(n.length-1+a);return u=r(l+f*a/2,f),o=0,t={t:"rangePoints",a:arguments},e},e.rangeRoundPoints=function(i,a){arguments.length<2&&(a=0);var l=i[0],c=i[1],f=n.length<2?(l=c=Math.round((l+c)/2),0):(c-l)/(n.length-1+a)|0;return u=r(l+Math.round(f*a/2+(c-l-(n.length-1+a)*f)/2),f),o=0,t={t:"rangeRoundPoints",a:arguments},e},e.rangeBands=function(i,a,l){arguments.length<2&&(a=0),arguments.length<3&&(l=a);var c=i[1]<i[0],f=i[c-0],s=i[1-c],h=(s-f)/(n.length-a+2*l);return u=r(f+h*l,h),c&&u.reverse(),o=h*(1-a),t={t:"rangeBands",a:arguments},e},e.rangeRoundBands=function(i,a,l){arguments.length<2&&(a=0),arguments.length<3&&(l=a);var c=i[1]<i[0],f=i[c-0],s=i[1-c],h=Math.floor((s-f)/(n.length-a+2*l));return u=r(f+Math.round((s-f-(n.length-a)*h)/2),h),c&&u.reverse(),o=Math.round(h*(1-a)),t={t:"rangeRoundBands",a:arguments},e},e.rangeBand=function(){return o},e.rangeExtent=function(){return Yi(t.a[0])},e.copy=function(){return ou(n,t)},e.domain(n)}function au(n,t){function u(){var e=0,r=t.length;for(a=[];++e<r;)a[e-1]=ao.quantile(n,e/r);return o}function o(n){return isNaN(n=+n)?void 0:t[ao.bisect(a,n)]}var a;return o.domain=function(t){return arguments.length?(n=t.map(r).filter(i).sort(e),u()):n},o.range=function(n){return arguments.length?(t=n,u()):t},o.quantiles=function(){return a},o.invertExtent=function(e){return e=t.indexOf(e),0>e?[NaN,NaN]:[e>0?a[e-1]:n[0],e<a.length?a[e]:n[n.length-1]]},o.copy=function(){return au(n,t)},u()}function lu(n,t,e){function r(t){return e[Math.max(0,Math.min(o,Math.floor(u*(t-n))))]}function i(){return u=e.length/(t-n),o=e.length-1,r}var u,o;return r.domain=function(e){return arguments.length?(n=+e[0],t=+e[e.length-1],i()):[n,t]},r.range=function(n){return arguments.length?(e=n,i()):e},r.invertExtent=function(t){return t=e.indexOf(t),t=0>t?NaN:t/u+n,[t,t+1/u]},r.copy=function(){return lu(n,t,e)},i()}function cu(n,t){function e(e){return e>=e?t[ao.bisect(n,e)]:void 0}return e.domain=function(t){return arguments.length?(n=t,e):n},e.range=function(n){return arguments.length?(t=n,e):t},e.invertExtent=function(e){return e=t.indexOf(e),[n[e-1],n[e]]},e.copy=function(){return cu(n,t)},e}function fu(n){function t(n){return+n}return t.invert=t,t.domain=t.range=function(e){return arguments.length?(n=e.map(t),t):n},t.ticks=function(t){return Qi(n,t)},t.tickFormat=function(t,e){return nu(n,t,e)},t.copy=function(){return fu(n)},t}function su(){return 0}function hu(n){return n.innerRadius}function pu(n){return n.outerRadius}function gu(n){return n.startAngle}function vu(n){return n.endAngle}function du(n){return n&&n.padAngle}function yu(n,t,e,r){return(n-e)*t-(t-r)*n>0?0:1}function mu(n,t,e,r,i){var u=n[0]-t[0],o=n[1]-t[1],a=(i?r:-r)/Math.sqrt(u*u+o*o),l=a*o,c=-a*u,f=n[0]+l,s=n[1]+c,h=t[0]+l,p=t[1]+c,g=(f+h)/2,v=(s+p)/2,d=h-f,y=p-s,m=d*d+y*y,M=e-r,x=f*p-h*s,b=(0>y?-1:1)*Math.sqrt(Math.max(0,M*M*m-x*x)),_=(x*y-d*b)/m,w=(-x*d-y*b)/m,S=(x*y+d*b)/m,k=(-x*d+y*b)/m,N=_-g,E=w-v,A=S-g,C=k-v;return N*N+E*E>A*A+C*C&&(_=S,w=k),[[_-l,w-c],[_*e/M,w*e/M]]}function Mu(n){function t(t){function o(){c.push("M",u(n(f),a))}for(var l,c=[],f=[],s=-1,h=t.length,p=En(e),g=En(r);++s<h;)i.call(this,l=t[s],s)?f.push([+p.call(this,l,s),+g.call(this,l,s)]):f.length&&(o(),f=[]);return f.length&&o(),c.length?c.join(""):null}var e=Ce,r=ze,i=zt,u=xu,o=u.key,a=.7;return t.x=function(n){return arguments.length?(e=n,t):e},t.y=function(n){return arguments.length?(r=n,t):r},t.defined=function(n){return arguments.length?(i=n,t):i},t.interpolate=function(n){return arguments.length?(o="function"==typeof n?u=n:(u=Tl.get(n)||xu).key,t):o},t.tension=function(n){return arguments.length?(a=n,t):a},t}function xu(n){return n.length>1?n.join("L"):n+"Z"}function bu(n){return n.join("L")+"Z"}function _u(n){for(var t=0,e=n.length,r=n[0],i=[r[0],",",r[1]];++t<e;)i.push("H",(r[0]+(r=n[t])[0])/2,"V",r[1]);return e>1&&i.push("H",r[0]),i.join("")}function wu(n){for(var t=0,e=n.length,r=n[0],i=[r[0],",",r[1]];++t<e;)i.push("V",(r=n[t])[1],"H",r[0]);return i.join("")}function Su(n){for(var t=0,e=n.length,r=n[0],i=[r[0],",",r[1]];++t<e;)i.push("H",(r=n[t])[0],"V",r[1]);return i.join("")}function ku(n,t){return n.length<4?xu(n):n[1]+Au(n.slice(1,-1),Cu(n,t))}function Nu(n,t){return n.length<3?bu(n):n[0]+Au((n.push(n[0]),n),Cu([n[n.length-2]].concat(n,[n[1]]),t))}function Eu(n,t){return n.length<3?xu(n):n[0]+Au(n,Cu(n,t))}function Au(n,t){if(t.length<1||n.length!=t.length&&n.length!=t.length+2)return xu(n);var e=n.length!=t.length,r="",i=n[0],u=n[1],o=t[0],a=o,l=1;if(e&&(r+="Q"+(u[0]-2*o[0]/3)+","+(u[1]-2*o[1]/3)+","+u[0]+","+u[1],i=n[1],l=2),t.length>1){a=t[1],u=n[l],l++,r+="C"+(i[0]+o[0])+","+(i[1]+o[1])+","+(u[0]-a[0])+","+(u[1]-a[1])+","+u[0]+","+u[1];for(var c=2;c<t.length;c++,l++)u=n[l],a=t[c],r+="S"+(u[0]-a[0])+","+(u[1]-a[1])+","+u[0]+","+u[1]}if(e){var f=n[l];r+="Q"+(u[0]+2*a[0]/3)+","+(u[1]+2*a[1]/3)+","+f[0]+","+f[1]}return r}function Cu(n,t){for(var e,r=[],i=(1-t)/2,u=n[0],o=n[1],a=1,l=n.length;++a<l;)e=u,u=o,o=n[a],r.push([i*(o[0]-e[0]),i*(o[1]-e[1])]);return r}function zu(n){if(n.length<3)return xu(n);var t=1,e=n.length,r=n[0],i=r[0],u=r[1],o=[i,i,i,(r=n[1])[0]],a=[u,u,u,r[1]],l=[i,",",u,"L",Ru(Pl,o),",",Ru(Pl,a)];for(n.push(n[e-1]);++t<=e;)r=n[t],o.shift(),o.push(r[0]),a.shift(),a.push(r[1]),Du(l,o,a);return n.pop(),l.push("L",r),l.join("")}function Lu(n){if(n.length<4)return xu(n);for(var t,e=[],r=-1,i=n.length,u=[0],o=[0];++r<3;)t=n[r],u.push(t[0]),o.push(t[1]);for(e.push(Ru(Pl,u)+","+Ru(Pl,o)),--r;++r<i;)t=n[r],u.shift(),u.push(t[0]),o.shift(),o.push(t[1]),Du(e,u,o);return e.join("")}function qu(n){for(var t,e,r=-1,i=n.length,u=i+4,o=[],a=[];++r<4;)e=n[r%i],o.push(e[0]),a.push(e[1]);for(t=[Ru(Pl,o),",",Ru(Pl,a)],--r;++r<u;)e=n[r%i],o.shift(),o.push(e[0]),a.shift(),a.push(e[1]),Du(t,o,a);return t.join("")}function Tu(n,t){var e=n.length-1;if(e)for(var r,i,u=n[0][0],o=n[0][1],a=n[e][0]-u,l=n[e][1]-o,c=-1;++c<=e;)r=n[c],i=c/e,r[0]=t*r[0]+(1-t)*(u+i*a),r[1]=t*r[1]+(1-t)*(o+i*l);return zu(n)}function Ru(n,t){return n[0]*t[0]+n[1]*t[1]+n[2]*t[2]+n[3]*t[3]}function Du(n,t,e){n.push("C",Ru(Rl,t),",",Ru(Rl,e),",",Ru(Dl,t),",",Ru(Dl,e),",",Ru(Pl,t),",",Ru(Pl,e))}function Pu(n,t){return(t[1]-n[1])/(t[0]-n[0])}function Uu(n){for(var t=0,e=n.length-1,r=[],i=n[0],u=n[1],o=r[0]=Pu(i,u);++t<e;)r[t]=(o+(o=Pu(i=u,u=n[t+1])))/2;return r[t]=o,r}function ju(n){for(var t,e,r,i,u=[],o=Uu(n),a=-1,l=n.length-1;++a<l;)t=Pu(n[a],n[a+1]),xo(t)<Uo?o[a]=o[a+1]=0:(e=o[a]/t,r=o[a+1]/t,i=e*e+r*r,i>9&&(i=3*t/Math.sqrt(i),o[a]=i*e,o[a+1]=i*r));for(a=-1;++a<=l;)i=(n[Math.min(l,a+1)][0]-n[Math.max(0,a-1)][0])/(6*(1+o[a]*o[a])),u.push([i||0,o[a]*i||0]);return u}function Fu(n){return n.length<3?xu(n):n[0]+Au(n,ju(n))}function Hu(n){for(var t,e,r,i=-1,u=n.length;++i<u;)t=n[i],e=t[0],r=t[1]-Io,t[0]=e*Math.cos(r),t[1]=e*Math.sin(r);return n}function Ou(n){function t(t){function l(){v.push("M",a(n(y),s),f,c(n(d.reverse()),s),"Z")}for(var h,p,g,v=[],d=[],y=[],m=-1,M=t.length,x=En(e),b=En(i),_=e===r?function(){
33779 return p}:En(r),w=i===u?function(){return g}:En(u);++m<M;)o.call(this,h=t[m],m)?(d.push([p=+x.call(this,h,m),g=+b.call(this,h,m)]),y.push([+_.call(this,h,m),+w.call(this,h,m)])):d.length&&(l(),d=[],y=[]);return d.length&&l(),v.length?v.join(""):null}var e=Ce,r=Ce,i=0,u=ze,o=zt,a=xu,l=a.key,c=a,f="L",s=.7;return t.x=function(n){return arguments.length?(e=r=n,t):r},t.x0=function(n){return arguments.length?(e=n,t):e},t.x1=function(n){return arguments.length?(r=n,t):r},t.y=function(n){return arguments.length?(i=u=n,t):u},t.y0=function(n){return arguments.length?(i=n,t):i},t.y1=function(n){return arguments.length?(u=n,t):u},t.defined=function(n){return arguments.length?(o=n,t):o},t.interpolate=function(n){return arguments.length?(l="function"==typeof n?a=n:(a=Tl.get(n)||xu).key,c=a.reverse||a,f=a.closed?"M":"L",t):l},t.tension=function(n){return arguments.length?(s=n,t):s},t}function Iu(n){return n.radius}function Yu(n){return[n.x,n.y]}function Zu(n){return function(){var t=n.apply(this,arguments),e=t[0],r=t[1]-Io;return[e*Math.cos(r),e*Math.sin(r)]}}function Vu(){return 64}function Xu(){return"circle"}function $u(n){var t=Math.sqrt(n/Fo);return"M0,"+t+"A"+t+","+t+" 0 1,1 0,"+-t+"A"+t+","+t+" 0 1,1 0,"+t+"Z"}function Bu(n){return function(){var t,e,r;(t=this[n])&&(r=t[e=t.active])&&(r.timer.c=null,r.timer.t=NaN,--t.count?delete t[e]:delete this[n],t.active+=.5,r.event&&r.event.interrupt.call(this,this.__data__,r.index))}}function Wu(n,t,e){return ko(n,Yl),n.namespace=t,n.id=e,n}function Ju(n,t,e,r){var i=n.id,u=n.namespace;return Y(n,"function"==typeof e?function(n,o,a){n[u][i].tween.set(t,r(e.call(n,n.__data__,o,a)))}:(e=r(e),function(n){n[u][i].tween.set(t,e)}))}function Gu(n){return null==n&&(n=""),function(){this.textContent=n}}function Ku(n){return null==n?"__transition__":"__transition_"+n+"__"}function Qu(n,t,e,r,i){function u(n){var t=v.delay;return f.t=t+l,n>=t?o(n-t):void(f.c=o)}function o(e){var i=g.active,u=g[i];u&&(u.timer.c=null,u.timer.t=NaN,--g.count,delete g[i],u.event&&u.event.interrupt.call(n,n.__data__,u.index));for(var o in g)if(r>+o){var c=g[o];c.timer.c=null,c.timer.t=NaN,--g.count,delete g[o]}f.c=a,qn(function(){return f.c&&a(e||1)&&(f.c=null,f.t=NaN),1},0,l),g.active=r,v.event&&v.event.start.call(n,n.__data__,t),p=[],v.tween.forEach(function(e,r){(r=r.call(n,n.__data__,t))&&p.push(r)}),h=v.ease,s=v.duration}function a(i){for(var u=i/s,o=h(u),a=p.length;a>0;)p[--a].call(n,o);return u>=1?(v.event&&v.event.end.call(n,n.__data__,t),--g.count?delete g[r]:delete n[e],1):void 0}var l,f,s,h,p,g=n[e]||(n[e]={active:0,count:0}),v=g[r];v||(l=i.time,f=qn(u,0,l),v=g[r]={tween:new c,time:l,timer:f,delay:i.delay,duration:i.duration,ease:i.ease,index:t},i=null,++g.count)}function no(n,t,e){n.attr("transform",function(n){var r=t(n);return"translate("+(isFinite(r)?r:e(n))+",0)"})}function to(n,t,e){n.attr("transform",function(n){var r=t(n);return"translate(0,"+(isFinite(r)?r:e(n))+")"})}function eo(n){return n.toISOString()}function ro(n,t,e){function r(t){return n(t)}function i(n,e){var r=n[1]-n[0],i=r/e,u=ao.bisect(Kl,i);return u==Kl.length?[t.year,Ki(n.map(function(n){return n/31536e6}),e)[2]]:u?t[i/Kl[u-1]<Kl[u]/i?u-1:u]:[tc,Ki(n,e)[2]]}return r.invert=function(t){return io(n.invert(t))},r.domain=function(t){return arguments.length?(n.domain(t),r):n.domain().map(io)},r.nice=function(n,t){function e(e){return!isNaN(e)&&!n.range(e,io(+e+1),t).length}var u=r.domain(),o=Yi(u),a=null==n?i(o,10):"number"==typeof n&&i(o,n);return a&&(n=a[0],t=a[1]),r.domain(Xi(u,t>1?{floor:function(t){for(;e(t=n.floor(t));)t=io(t-1);return t},ceil:function(t){for(;e(t=n.ceil(t));)t=io(+t+1);return t}}:n))},r.ticks=function(n,t){var e=Yi(r.domain()),u=null==n?i(e,10):"number"==typeof n?i(e,n):!n.range&&[{range:n},t];return u&&(n=u[0],t=u[1]),n.range(e[0],io(+e[1]+1),1>t?1:t)},r.tickFormat=function(){return e},r.copy=function(){return ro(n.copy(),t,e)},Ji(r,n)}function io(n){return new Date(n)}function uo(n){return JSON.parse(n.responseText)}function oo(n){var t=fo.createRange();return t.selectNode(fo.body),t.createContextualFragment(n.responseText)}var ao={version:"3.5.17"},lo=[].slice,co=function(n){return lo.call(n)},fo=this.document;if(fo)try{co(fo.documentElement.childNodes)[0].nodeType}catch(so){co=function(n){for(var t=n.length,e=new Array(t);t--;)e[t]=n[t];return e}}if(Date.now||(Date.now=function(){return+new Date}),fo)try{fo.createElement("DIV").style.setProperty("opacity",0,"")}catch(ho){var po=this.Element.prototype,go=po.setAttribute,vo=po.setAttributeNS,yo=this.CSSStyleDeclaration.prototype,mo=yo.setProperty;po.setAttribute=function(n,t){go.call(this,n,t+"")},po.setAttributeNS=function(n,t,e){vo.call(this,n,t,e+"")},yo.setProperty=function(n,t,e){mo.call(this,n,t+"",e)}}ao.ascending=e,ao.descending=function(n,t){return n>t?-1:t>n?1:t>=n?0:NaN},ao.min=function(n,t){var e,r,i=-1,u=n.length;if(1===arguments.length){for(;++i<u;)if(null!=(r=n[i])&&r>=r){e=r;break}for(;++i<u;)null!=(r=n[i])&&e>r&&(e=r)}else{for(;++i<u;)if(null!=(r=t.call(n,n[i],i))&&r>=r){e=r;break}for(;++i<u;)null!=(r=t.call(n,n[i],i))&&e>r&&(e=r)}return e},ao.max=function(n,t){var e,r,i=-1,u=n.length;if(1===arguments.length){for(;++i<u;)if(null!=(r=n[i])&&r>=r){e=r;break}for(;++i<u;)null!=(r=n[i])&&r>e&&(e=r)}else{for(;++i<u;)if(null!=(r=t.call(n,n[i],i))&&r>=r){e=r;break}for(;++i<u;)null!=(r=t.call(n,n[i],i))&&r>e&&(e=r)}return e},ao.extent=function(n,t){var e,r,i,u=-1,o=n.length;if(1===arguments.length){for(;++u<o;)if(null!=(r=n[u])&&r>=r){e=i=r;break}for(;++u<o;)null!=(r=n[u])&&(e>r&&(e=r),r>i&&(i=r))}else{for(;++u<o;)if(null!=(r=t.call(n,n[u],u))&&r>=r){e=i=r;break}for(;++u<o;)null!=(r=t.call(n,n[u],u))&&(e>r&&(e=r),r>i&&(i=r))}return[e,i]},ao.sum=function(n,t){var e,r=0,u=n.length,o=-1;if(1===arguments.length)for(;++o<u;)i(e=+n[o])&&(r+=e);else for(;++o<u;)i(e=+t.call(n,n[o],o))&&(r+=e);return r},ao.mean=function(n,t){var e,u=0,o=n.length,a=-1,l=o;if(1===arguments.length)for(;++a<o;)i(e=r(n[a]))?u+=e:--l;else for(;++a<o;)i(e=r(t.call(n,n[a],a)))?u+=e:--l;return l?u/l:void 0},ao.quantile=function(n,t){var e=(n.length-1)*t+1,r=Math.floor(e),i=+n[r-1],u=e-r;return u?i+u*(n[r]-i):i},ao.median=function(n,t){var u,o=[],a=n.length,l=-1;if(1===arguments.length)for(;++l<a;)i(u=r(n[l]))&&o.push(u);else for(;++l<a;)i(u=r(t.call(n,n[l],l)))&&o.push(u);return o.length?ao.quantile(o.sort(e),.5):void 0},ao.variance=function(n,t){var e,u,o=n.length,a=0,l=0,c=-1,f=0;if(1===arguments.length)for(;++c<o;)i(e=r(n[c]))&&(u=e-a,a+=u/++f,l+=u*(e-a));else for(;++c<o;)i(e=r(t.call(n,n[c],c)))&&(u=e-a,a+=u/++f,l+=u*(e-a));return f>1?l/(f-1):void 0},ao.deviation=function(){var n=ao.variance.apply(this,arguments);return n?Math.sqrt(n):n};var Mo=u(e);ao.bisectLeft=Mo.left,ao.bisect=ao.bisectRight=Mo.right,ao.bisector=function(n){return u(1===n.length?function(t,r){return e(n(t),r)}:n)},ao.shuffle=function(n,t,e){(u=arguments.length)<3&&(e=n.length,2>u&&(t=0));for(var r,i,u=e-t;u;)i=Math.random()*u--|0,r=n[u+t],n[u+t]=n[i+t],n[i+t]=r;return n},ao.permute=function(n,t){for(var e=t.length,r=new Array(e);e--;)r[e]=n[t[e]];return r},ao.pairs=function(n){for(var t,e=0,r=n.length-1,i=n[0],u=new Array(0>r?0:r);r>e;)u[e]=[t=i,i=n[++e]];return u},ao.transpose=function(n){if(!(i=n.length))return[];for(var t=-1,e=ao.min(n,o),r=new Array(e);++t<e;)for(var i,u=-1,a=r[t]=new Array(i);++u<i;)a[u]=n[u][t];return r},ao.zip=function(){return ao.transpose(arguments)},ao.keys=function(n){var t=[];for(var e in n)t.push(e);return t},ao.values=function(n){var t=[];for(var e in n)t.push(n[e]);return t},ao.entries=function(n){var t=[];for(var e in n)t.push({key:e,value:n[e]});return t},ao.merge=function(n){for(var t,e,r,i=n.length,u=-1,o=0;++u<i;)o+=n[u].length;for(e=new Array(o);--i>=0;)for(r=n[i],t=r.length;--t>=0;)e[--o]=r[t];return e};var xo=Math.abs;ao.range=function(n,t,e){if(arguments.length<3&&(e=1,arguments.length<2&&(t=n,n=0)),(t-n)/e===1/0)throw new Error("infinite range");var r,i=[],u=a(xo(e)),o=-1;if(n*=u,t*=u,e*=u,0>e)for(;(r=n+e*++o)>t;)i.push(r/u);else for(;(r=n+e*++o)<t;)i.push(r/u);return i},ao.map=function(n,t){var e=new c;if(n instanceof c)n.forEach(function(n,t){e.set(n,t)});else if(Array.isArray(n)){var r,i=-1,u=n.length;if(1===arguments.length)for(;++i<u;)e.set(i,n[i]);else for(;++i<u;)e.set(t.call(n,r=n[i],i),r)}else for(var o in n)e.set(o,n[o]);return e};var bo="__proto__",_o="\x00";l(c,{has:h,get:function(n){return this._[f(n)]},set:function(n,t){return this._[f(n)]=t},remove:p,keys:g,values:function(){var n=[];for(var t in this._)n.push(this._[t]);return n},entries:function(){var n=[];for(var t in this._)n.push({key:s(t),value:this._[t]});return n},size:v,empty:d,forEach:function(n){for(var t in this._)n.call(this,s(t),this._[t])}}),ao.nest=function(){function n(t,o,a){if(a>=u.length)return r?r.call(i,o):e?o.sort(e):o;for(var l,f,s,h,p=-1,g=o.length,v=u[a++],d=new c;++p<g;)(h=d.get(l=v(f=o[p])))?h.push(f):d.set(l,[f]);return t?(f=t(),s=function(e,r){f.set(e,n(t,r,a))}):(f={},s=function(e,r){f[e]=n(t,r,a)}),d.forEach(s),f}function t(n,e){if(e>=u.length)return n;var r=[],i=o[e++];return n.forEach(function(n,i){r.push({key:n,values:t(i,e)})}),i?r.sort(function(n,t){return i(n.key,t.key)}):r}var e,r,i={},u=[],o=[];return i.map=function(t,e){return n(e,t,0)},i.entries=function(e){return t(n(ao.map,e,0),0)},i.key=function(n){return u.push(n),i},i.sortKeys=function(n){return o[u.length-1]=n,i},i.sortValues=function(n){return e=n,i},i.rollup=function(n){return r=n,i},i},ao.set=function(n){var t=new y;if(n)for(var e=0,r=n.length;r>e;++e)t.add(n[e]);return t},l(y,{has:h,add:function(n){return this._[f(n+="")]=!0,n},remove:p,values:g,size:v,empty:d,forEach:function(n){for(var t in this._)n.call(this,s(t))}}),ao.behavior={},ao.rebind=function(n,t){for(var e,r=1,i=arguments.length;++r<i;)n[e=arguments[r]]=M(n,t,t[e]);return n};var wo=["webkit","ms","moz","Moz","o","O"];ao.dispatch=function(){for(var n=new _,t=-1,e=arguments.length;++t<e;)n[arguments[t]]=w(n);return n},_.prototype.on=function(n,t){var e=n.indexOf("."),r="";if(e>=0&&(r=n.slice(e+1),n=n.slice(0,e)),n)return arguments.length<2?this[n].on(r):this[n].on(r,t);if(2===arguments.length){if(null==t)for(n in this)this.hasOwnProperty(n)&&this[n].on(r,null);return this}},ao.event=null,ao.requote=function(n){return n.replace(So,"\\$&")};var So=/[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g,ko={}.__proto__?function(n,t){n.__proto__=t}:function(n,t){for(var e in t)n[e]=t[e]},No=function(n,t){return t.querySelector(n)},Eo=function(n,t){return t.querySelectorAll(n)},Ao=function(n,t){var e=n.matches||n[x(n,"matchesSelector")];return(Ao=function(n,t){return e.call(n,t)})(n,t)};"function"==typeof Sizzle&&(No=function(n,t){return Sizzle(n,t)[0]||null},Eo=Sizzle,Ao=Sizzle.matchesSelector),ao.selection=function(){return ao.select(fo.documentElement)};var Co=ao.selection.prototype=[];Co.select=function(n){var t,e,r,i,u=[];n=A(n);for(var o=-1,a=this.length;++o<a;){u.push(t=[]),t.parentNode=(r=this[o]).parentNode;for(var l=-1,c=r.length;++l<c;)(i=r[l])?(t.push(e=n.call(i,i.__data__,l,o)),e&&"__data__"in i&&(e.__data__=i.__data__)):t.push(null)}return E(u)},Co.selectAll=function(n){var t,e,r=[];n=C(n);for(var i=-1,u=this.length;++i<u;)for(var o=this[i],a=-1,l=o.length;++a<l;)(e=o[a])&&(r.push(t=co(n.call(e,e.__data__,a,i))),t.parentNode=e);return E(r)};var zo="http://www.w3.org/1999/xhtml",Lo={svg:"http://www.w3.org/2000/svg",xhtml:zo,xlink:"http://www.w3.org/1999/xlink",xml:"http://www.w3.org/XML/1998/namespace",xmlns:"http://www.w3.org/2000/xmlns/"};ao.ns={prefix:Lo,qualify:function(n){var t=n.indexOf(":"),e=n;return t>=0&&"xmlns"!==(e=n.slice(0,t))&&(n=n.slice(t+1)),Lo.hasOwnProperty(e)?{space:Lo[e],local:n}:n}},Co.attr=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node();return n=ao.ns.qualify(n),n.local?e.getAttributeNS(n.space,n.local):e.getAttribute(n)}for(t in n)this.each(z(t,n[t]));return this}return this.each(z(n,t))},Co.classed=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node(),r=(n=T(n)).length,i=-1;if(t=e.classList){for(;++i<r;)if(!t.contains(n[i]))return!1}else for(t=e.getAttribute("class");++i<r;)if(!q(n[i]).test(t))return!1;return!0}for(t in n)this.each(R(t,n[t]));return this}return this.each(R(n,t))},Co.style=function(n,e,r){var i=arguments.length;if(3>i){if("string"!=typeof n){2>i&&(e="");for(r in n)this.each(P(r,n[r],e));return this}if(2>i){var u=this.node();return t(u).getComputedStyle(u,null).getPropertyValue(n)}r=""}return this.each(P(n,e,r))},Co.property=function(n,t){if(arguments.length<2){if("string"==typeof n)return this.node()[n];for(t in n)this.each(U(t,n[t]));return this}return this.each(U(n,t))},Co.text=function(n){return arguments.length?this.each("function"==typeof n?function(){var t=n.apply(this,arguments);this.textContent=null==t?"":t}:null==n?function(){this.textContent=""}:function(){this.textContent=n}):this.node().textContent},Co.html=function(n){return arguments.length?this.each("function"==typeof n?function(){var t=n.apply(this,arguments);this.innerHTML=null==t?"":t}:null==n?function(){this.innerHTML=""}:function(){this.innerHTML=n}):this.node().innerHTML},Co.append=function(n){return n=j(n),this.select(function(){return this.appendChild(n.apply(this,arguments))})},Co.insert=function(n,t){return n=j(n),t=A(t),this.select(function(){return this.insertBefore(n.apply(this,arguments),t.apply(this,arguments)||null)})},Co.remove=function(){return this.each(F)},Co.data=function(n,t){function e(n,e){var r,i,u,o=n.length,s=e.length,h=Math.min(o,s),p=new Array(s),g=new Array(s),v=new Array(o);if(t){var d,y=new c,m=new Array(o);for(r=-1;++r<o;)(i=n[r])&&(y.has(d=t.call(i,i.__data__,r))?v[r]=i:y.set(d,i),m[r]=d);for(r=-1;++r<s;)(i=y.get(d=t.call(e,u=e[r],r)))?i!==!0&&(p[r]=i,i.__data__=u):g[r]=H(u),y.set(d,!0);for(r=-1;++r<o;)r in m&&y.get(m[r])!==!0&&(v[r]=n[r])}else{for(r=-1;++r<h;)i=n[r],u=e[r],i?(i.__data__=u,p[r]=i):g[r]=H(u);for(;s>r;++r)g[r]=H(e[r]);for(;o>r;++r)v[r]=n[r]}g.update=p,g.parentNode=p.parentNode=v.parentNode=n.parentNode,a.push(g),l.push(p),f.push(v)}var r,i,u=-1,o=this.length;if(!arguments.length){for(n=new Array(o=(r=this[0]).length);++u<o;)(i=r[u])&&(n[u]=i.__data__);return n}var a=Z([]),l=E([]),f=E([]);if("function"==typeof n)for(;++u<o;)e(r=this[u],n.call(r,r.parentNode.__data__,u));else for(;++u<o;)e(r=this[u],n);return l.enter=function(){return a},l.exit=function(){return f},l},Co.datum=function(n){return arguments.length?this.property("__data__",n):this.property("__data__")},Co.filter=function(n){var t,e,r,i=[];"function"!=typeof n&&(n=O(n));for(var u=0,o=this.length;o>u;u++){i.push(t=[]),t.parentNode=(e=this[u]).parentNode;for(var a=0,l=e.length;l>a;a++)(r=e[a])&&n.call(r,r.__data__,a,u)&&t.push(r)}return E(i)},Co.order=function(){for(var n=-1,t=this.length;++n<t;)for(var e,r=this[n],i=r.length-1,u=r[i];--i>=0;)(e=r[i])&&(u&&u!==e.nextSibling&&u.parentNode.insertBefore(e,u),u=e);return this},Co.sort=function(n){n=I.apply(this,arguments);for(var t=-1,e=this.length;++t<e;)this[t].sort(n);return this.order()},Co.each=function(n){return Y(this,function(t,e,r){n.call(t,t.__data__,e,r)})},Co.call=function(n){var t=co(arguments);return n.apply(t[0]=this,t),this},Co.empty=function(){return!this.node()},Co.node=function(){for(var n=0,t=this.length;t>n;n++)for(var e=this[n],r=0,i=e.length;i>r;r++){var u=e[r];if(u)return u}return null},Co.size=function(){var n=0;return Y(this,function(){++n}),n};var qo=[];ao.selection.enter=Z,ao.selection.enter.prototype=qo,qo.append=Co.append,qo.empty=Co.empty,qo.node=Co.node,qo.call=Co.call,qo.size=Co.size,qo.select=function(n){for(var t,e,r,i,u,o=[],a=-1,l=this.length;++a<l;){r=(i=this[a]).update,o.push(t=[]),t.parentNode=i.parentNode;for(var c=-1,f=i.length;++c<f;)(u=i[c])?(t.push(r[c]=e=n.call(i.parentNode,u.__data__,c,a)),e.__data__=u.__data__):t.push(null)}return E(o)},qo.insert=function(n,t){return arguments.length<2&&(t=V(this)),Co.insert.call(this,n,t)},ao.select=function(t){var e;return"string"==typeof t?(e=[No(t,fo)],e.parentNode=fo.documentElement):(e=[t],e.parentNode=n(t)),E([e])},ao.selectAll=function(n){var t;return"string"==typeof n?(t=co(Eo(n,fo)),t.parentNode=fo.documentElement):(t=co(n),t.parentNode=null),E([t])},Co.on=function(n,t,e){var r=arguments.length;if(3>r){if("string"!=typeof n){2>r&&(t=!1);for(e in n)this.each(X(e,n[e],t));return this}if(2>r)return(r=this.node()["__on"+n])&&r._;e=!1}return this.each(X(n,t,e))};var To=ao.map({mouseenter:"mouseover",mouseleave:"mouseout"});fo&&To.forEach(function(n){"on"+n in fo&&To.remove(n)});var Ro,Do=0;ao.mouse=function(n){return J(n,k())};var Po=this.navigator&&/WebKit/.test(this.navigator.userAgent)?-1:0;ao.touch=function(n,t,e){if(arguments.length<3&&(e=t,t=k().changedTouches),t)for(var r,i=0,u=t.length;u>i;++i)if((r=t[i]).identifier===e)return J(n,r)},ao.behavior.drag=function(){function n(){this.on("mousedown.drag",u).on("touchstart.drag",o)}function e(n,t,e,u,o){return function(){function a(){var n,e,r=t(h,v);r&&(n=r[0]-M[0],e=r[1]-M[1],g|=n|e,M=r,p({type:"drag",x:r[0]+c[0],y:r[1]+c[1],dx:n,dy:e}))}function l(){t(h,v)&&(y.on(u+d,null).on(o+d,null),m(g),p({type:"dragend"}))}var c,f=this,s=ao.event.target.correspondingElement||ao.event.target,h=f.parentNode,p=r.of(f,arguments),g=0,v=n(),d=".drag"+(null==v?"":"-"+v),y=ao.select(e(s)).on(u+d,a).on(o+d,l),m=W(s),M=t(h,v);i?(c=i.apply(f,arguments),c=[c.x-M[0],c.y-M[1]]):c=[0,0],p({type:"dragstart"})}}var r=N(n,"drag","dragstart","dragend"),i=null,u=e(b,ao.mouse,t,"mousemove","mouseup"),o=e(G,ao.touch,m,"touchmove","touchend");return n.origin=function(t){return arguments.length?(i=t,n):i},ao.rebind(n,r,"on")},ao.touches=function(n,t){return arguments.length<2&&(t=k().touches),t?co(t).map(function(t){var e=J(n,t);return e.identifier=t.identifier,e}):[]};var Uo=1e-6,jo=Uo*Uo,Fo=Math.PI,Ho=2*Fo,Oo=Ho-Uo,Io=Fo/2,Yo=Fo/180,Zo=180/Fo,Vo=Math.SQRT2,Xo=2,$o=4;ao.interpolateZoom=function(n,t){var e,r,i=n[0],u=n[1],o=n[2],a=t[0],l=t[1],c=t[2],f=a-i,s=l-u,h=f*f+s*s;if(jo>h)r=Math.log(c/o)/Vo,e=function(n){return[i+n*f,u+n*s,o*Math.exp(Vo*n*r)]};else{var p=Math.sqrt(h),g=(c*c-o*o+$o*h)/(2*o*Xo*p),v=(c*c-o*o-$o*h)/(2*c*Xo*p),d=Math.log(Math.sqrt(g*g+1)-g),y=Math.log(Math.sqrt(v*v+1)-v);r=(y-d)/Vo,e=function(n){var t=n*r,e=rn(d),a=o/(Xo*p)*(e*un(Vo*t+d)-en(d));return[i+a*f,u+a*s,o*e/rn(Vo*t+d)]}}return e.duration=1e3*r,e},ao.behavior.zoom=function(){function n(n){n.on(L,s).on(Wo+".zoom",p).on("dblclick.zoom",g).on(R,h)}function e(n){return[(n[0]-k.x)/k.k,(n[1]-k.y)/k.k]}function r(n){return[n[0]*k.k+k.x,n[1]*k.k+k.y]}function i(n){k.k=Math.max(A[0],Math.min(A[1],n))}function u(n,t){t=r(t),k.x+=n[0]-t[0],k.y+=n[1]-t[1]}function o(t,e,r,o){t.__chart__={x:k.x,y:k.y,k:k.k},i(Math.pow(2,o)),u(d=e,r),t=ao.select(t),C>0&&(t=t.transition().duration(C)),t.call(n.event)}function a(){b&&b.domain(x.range().map(function(n){return(n-k.x)/k.k}).map(x.invert)),w&&w.domain(_.range().map(function(n){return(n-k.y)/k.k}).map(_.invert))}function l(n){z++||n({type:"zoomstart"})}function c(n){a(),n({type:"zoom",scale:k.k,translate:[k.x,k.y]})}function f(n){--z||(n({type:"zoomend"}),d=null)}function s(){function n(){a=1,u(ao.mouse(i),h),c(o)}function r(){s.on(q,null).on(T,null),p(a),f(o)}var i=this,o=D.of(i,arguments),a=0,s=ao.select(t(i)).on(q,n).on(T,r),h=e(ao.mouse(i)),p=W(i);Il.call(i),l(o)}function h(){function n(){var n=ao.touches(g);return p=k.k,n.forEach(function(n){n.identifier in d&&(d[n.identifier]=e(n))}),n}function t(){var t=ao.event.target;ao.select(t).on(x,r).on(b,a),_.push(t);for(var e=ao.event.changedTouches,i=0,u=e.length;u>i;++i)d[e[i].identifier]=null;var l=n(),c=Date.now();if(1===l.length){if(500>c-M){var f=l[0];o(g,f,d[f.identifier],Math.floor(Math.log(k.k)/Math.LN2)+1),S()}M=c}else if(l.length>1){var f=l[0],s=l[1],h=f[0]-s[0],p=f[1]-s[1];y=h*h+p*p}}function r(){var n,t,e,r,o=ao.touches(g);Il.call(g);for(var a=0,l=o.length;l>a;++a,r=null)if(e=o[a],r=d[e.identifier]){if(t)break;n=e,t=r}if(r){var f=(f=e[0]-n[0])*f+(f=e[1]-n[1])*f,s=y&&Math.sqrt(f/y);n=[(n[0]+e[0])/2,(n[1]+e[1])/2],t=[(t[0]+r[0])/2,(t[1]+r[1])/2],i(s*p)}M=null,u(n,t),c(v)}function a(){if(ao.event.touches.length){for(var t=ao.event.changedTouches,e=0,r=t.length;r>e;++e)delete d[t[e].identifier];for(var i in d)return void n()}ao.selectAll(_).on(m,null),w.on(L,s).on(R,h),N(),f(v)}var p,g=this,v=D.of(g,arguments),d={},y=0,m=".zoom-"+ao.event.changedTouches[0].identifier,x="touchmove"+m,b="touchend"+m,_=[],w=ao.select(g),N=W(g);t(),l(v),w.on(L,null).on(R,t)}function p(){var n=D.of(this,arguments);m?clearTimeout(m):(Il.call(this),v=e(d=y||ao.mouse(this)),l(n)),m=setTimeout(function(){m=null,f(n)},50),S(),i(Math.pow(2,.002*Bo())*k.k),u(d,v),c(n)}function g(){var n=ao.mouse(this),t=Math.log(k.k)/Math.LN2;o(this,n,e(n),ao.event.shiftKey?Math.ceil(t)-1:Math.floor(t)+1)}var v,d,y,m,M,x,b,_,w,k={x:0,y:0,k:1},E=[960,500],A=Jo,C=250,z=0,L="mousedown.zoom",q="mousemove.zoom",T="mouseup.zoom",R="touchstart.zoom",D=N(n,"zoomstart","zoom","zoomend");return Wo||(Wo="onwheel"in fo?(Bo=function(){return-ao.event.deltaY*(ao.event.deltaMode?120:1)},"wheel"):"onmousewheel"in fo?(Bo=function(){return ao.event.wheelDelta},"mousewheel"):(Bo=function(){return-ao.event.detail},"MozMousePixelScroll")),n.event=function(n){n.each(function(){var n=D.of(this,arguments),t=k;Hl?ao.select(this).transition().each("start.zoom",function(){k=this.__chart__||{x:0,y:0,k:1},l(n)}).tween("zoom:zoom",function(){var e=E[0],r=E[1],i=d?d[0]:e/2,u=d?d[1]:r/2,o=ao.interpolateZoom([(i-k.x)/k.k,(u-k.y)/k.k,e/k.k],[(i-t.x)/t.k,(u-t.y)/t.k,e/t.k]);return function(t){var r=o(t),a=e/r[2];this.__chart__=k={x:i-r[0]*a,y:u-r[1]*a,k:a},c(n)}}).each("interrupt.zoom",function(){f(n)}).each("end.zoom",function(){f(n)}):(this.__chart__=k,l(n),c(n),f(n))})},n.translate=function(t){return arguments.length?(k={x:+t[0],y:+t[1],k:k.k},a(),n):[k.x,k.y]},n.scale=function(t){return arguments.length?(k={x:k.x,y:k.y,k:null},i(+t),a(),n):k.k},n.scaleExtent=function(t){return arguments.length?(A=null==t?Jo:[+t[0],+t[1]],n):A},n.center=function(t){return arguments.length?(y=t&&[+t[0],+t[1]],n):y},n.size=function(t){return arguments.length?(E=t&&[+t[0],+t[1]],n):E},n.duration=function(t){return arguments.length?(C=+t,n):C},n.x=function(t){return arguments.length?(b=t,x=t.copy(),k={x:0,y:0,k:1},n):b},n.y=function(t){return arguments.length?(w=t,_=t.copy(),k={x:0,y:0,k:1},n):w},ao.rebind(n,D,"on")};var Bo,Wo,Jo=[0,1/0];ao.color=an,an.prototype.toString=function(){return this.rgb()+""},ao.hsl=ln;var Go=ln.prototype=new an;Go.brighter=function(n){return n=Math.pow(.7,arguments.length?n:1),new ln(this.h,this.s,this.l/n)},Go.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),new ln(this.h,this.s,n*this.l)},Go.rgb=function(){return cn(this.h,this.s,this.l)},ao.hcl=fn;var Ko=fn.prototype=new an;Ko.brighter=function(n){return new fn(this.h,this.c,Math.min(100,this.l+Qo*(arguments.length?n:1)))},Ko.darker=function(n){return new fn(this.h,this.c,Math.max(0,this.l-Qo*(arguments.length?n:1)))},Ko.rgb=function(){return sn(this.h,this.c,this.l).rgb()},ao.lab=hn;var Qo=18,na=.95047,ta=1,ea=1.08883,ra=hn.prototype=new an;ra.brighter=function(n){return new hn(Math.min(100,this.l+Qo*(arguments.length?n:1)),this.a,this.b)},ra.darker=function(n){return new hn(Math.max(0,this.l-Qo*(arguments.length?n:1)),this.a,this.b)},ra.rgb=function(){return pn(this.l,this.a,this.b)},ao.rgb=mn;var ia=mn.prototype=new an;ia.brighter=function(n){n=Math.pow(.7,arguments.length?n:1);var t=this.r,e=this.g,r=this.b,i=30;return t||e||r?(t&&i>t&&(t=i),e&&i>e&&(e=i),r&&i>r&&(r=i),new mn(Math.min(255,t/n),Math.min(255,e/n),Math.min(255,r/n))):new mn(i,i,i)},ia.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),new mn(n*this.r,n*this.g,n*this.b)},ia.hsl=function(){return wn(this.r,this.g,this.b)},ia.toString=function(){return"#"+bn(this.r)+bn(this.g)+bn(this.b)};var ua=ao.map({aliceblue:15792383,antiquewhite:16444375,aqua:65535,aquamarine:8388564,azure:15794175,beige:16119260,bisque:16770244,black:0,blanchedalmond:16772045,blue:255,blueviolet:9055202,brown:10824234,burlywood:14596231,cadetblue:6266528,chartreuse:8388352,chocolate:13789470,coral:16744272,cornflowerblue:6591981,cornsilk:16775388,crimson:14423100,cyan:65535,darkblue:139,darkcyan:35723,darkgoldenrod:12092939,darkgray:11119017,darkgreen:25600,darkgrey:11119017,darkkhaki:12433259,darkmagenta:9109643,darkolivegreen:5597999,darkorange:16747520,darkorchid:10040012,darkred:9109504,darksalmon:15308410,darkseagreen:9419919,darkslateblue:4734347,darkslategray:3100495,darkslategrey:3100495,darkturquoise:52945,darkviolet:9699539,deeppink:16716947,deepskyblue:49151,dimgray:6908265,dimgrey:6908265,dodgerblue:2003199,firebrick:11674146,floralwhite:16775920,forestgreen:2263842,fuchsia:16711935,gainsboro:14474460,ghostwhite:16316671,gold:16766720,goldenrod:14329120,gray:8421504,green:32768,greenyellow:11403055,grey:8421504,honeydew:15794160,hotpink:16738740,indianred:13458524,indigo:4915330,ivory:16777200,khaki:15787660,lavender:15132410,lavenderblush:16773365,lawngreen:8190976,lemonchiffon:16775885,lightblue:11393254,lightcoral:15761536,lightcyan:14745599,lightgoldenrodyellow:16448210,lightgray:13882323,lightgreen:9498256,lightgrey:13882323,lightpink:16758465,lightsalmon:16752762,lightseagreen:2142890,lightskyblue:8900346,lightslategray:7833753,lightslategrey:7833753,lightsteelblue:11584734,lightyellow:16777184,lime:65280,limegreen:3329330,linen:16445670,magenta:16711935,maroon:8388608,mediumaquamarine:6737322,mediumblue:205,mediumorchid:12211667,mediumpurple:9662683,mediumseagreen:3978097,mediumslateblue:8087790,mediumspringgreen:64154,mediumturquoise:4772300,mediumvioletred:13047173,midnightblue:1644912,mintcream:16121850,mistyrose:16770273,moccasin:16770229,navajowhite:16768685,navy:128,oldlace:16643558,olive:8421376,olivedrab:7048739,orange:16753920,orangered:16729344,orchid:14315734,palegoldenrod:15657130,palegreen:10025880,paleturquoise:11529966,palevioletred:14381203,papayawhip:16773077,peachpuff:16767673,peru:13468991,pink:16761035,plum:14524637,powderblue:11591910,purple:8388736,rebeccapurple:6697881,red:16711680,rosybrown:12357519,royalblue:4286945,saddlebrown:9127187,salmon:16416882,sandybrown:16032864,seagreen:3050327,seashell:16774638,sienna:10506797,silver:12632256,skyblue:8900331,slateblue:6970061,slategray:7372944,slategrey:7372944,snow:16775930,springgreen:65407,steelblue:4620980,tan:13808780,teal:32896,thistle:14204888,tomato:16737095,turquoise:4251856,violet:15631086,wheat:16113331,white:16777215,whitesmoke:16119285,yellow:16776960,yellowgreen:10145074});ua.forEach(function(n,t){ua.set(n,Mn(t))}),ao.functor=En,ao.xhr=An(m),ao.dsv=function(n,t){function e(n,e,u){arguments.length<3&&(u=e,e=null);var o=Cn(n,t,null==e?r:i(e),u);return o.row=function(n){return arguments.length?o.response(null==(e=n)?r:i(n)):e},o}function r(n){return e.parse(n.responseText)}function i(n){return function(t){return e.parse(t.responseText,n)}}function u(t){return t.map(o).join(n)}function o(n){return a.test(n)?'"'+n.replace(/\"/g,'""')+'"':n}var a=new RegExp('["'+n+"\n]"),l=n.charCodeAt(0);return e.parse=function(n,t){var r;return e.parseRows(n,function(n,e){if(r)return r(n,e-1);var i=new Function("d","return {"+n.map(function(n,t){return JSON.stringify(n)+": d["+t+"]"}).join(",")+"}");r=t?function(n,e){return t(i(n),e)}:i})},e.parseRows=function(n,t){function e(){if(f>=c)return o;if(i)return i=!1,u;var t=f;if(34===n.charCodeAt(t)){for(var e=t;e++<c;)if(34===n.charCodeAt(e)){if(34!==n.charCodeAt(e+1))break;++e}f=e+2;var r=n.charCodeAt(e+1);return 13===r?(i=!0,10===n.charCodeAt(e+2)&&++f):10===r&&(i=!0),n.slice(t+1,e).replace(/""/g,'"')}for(;c>f;){var r=n.charCodeAt(f++),a=1;if(10===r)i=!0;else if(13===r)i=!0,10===n.charCodeAt(f)&&(++f,++a);else if(r!==l)continue;return n.slice(t,f-a)}return n.slice(t)}for(var r,i,u={},o={},a=[],c=n.length,f=0,s=0;(r=e())!==o;){for(var h=[];r!==u&&r!==o;)h.push(r),r=e();t&&null==(h=t(h,s++))||a.push(h)}return a},e.format=function(t){if(Array.isArray(t[0]))return e.formatRows(t);var r=new y,i=[];return t.forEach(function(n){for(var t in n)r.has(t)||i.push(r.add(t))}),[i.map(o).join(n)].concat(t.map(function(t){return i.map(function(n){return o(t[n])}).join(n)})).join("\n")},e.formatRows=function(n){return n.map(u).join("\n")},e},ao.csv=ao.dsv(",","text/csv"),ao.tsv=ao.dsv(" ","text/tab-separated-values");var oa,aa,la,ca,fa=this[x(this,"requestAnimationFrame")]||function(n){setTimeout(n,17)};ao.timer=function(){qn.apply(this,arguments)},ao.timer.flush=function(){Rn(),Dn()},ao.round=function(n,t){return t?Math.round(n*(t=Math.pow(10,t)))/t:Math.round(n)};var sa=["y","z","a","f","p","n","\xb5","m","","k","M","G","T","P","E","Z","Y"].map(Un);ao.formatPrefix=function(n,t){var e=0;return(n=+n)&&(0>n&&(n*=-1),t&&(n=ao.round(n,Pn(n,t))),e=1+Math.floor(1e-12+Math.log(n)/Math.LN10),e=Math.max(-24,Math.min(24,3*Math.floor((e-1)/3)))),sa[8+e/3]};var ha=/(?:([^{])?([<>=^]))?([+\- ])?([$#])?(0)?(\d+)?(,)?(\.-?\d+)?([a-z%])?/i,pa=ao.map({b:function(n){return n.toString(2)},c:function(n){return String.fromCharCode(n)},o:function(n){return n.toString(8)},x:function(n){return n.toString(16)},X:function(n){return n.toString(16).toUpperCase()},g:function(n,t){return n.toPrecision(t)},e:function(n,t){return n.toExponential(t)},f:function(n,t){return n.toFixed(t)},r:function(n,t){return(n=ao.round(n,Pn(n,t))).toFixed(Math.max(0,Math.min(20,Pn(n*(1+1e-15),t))))}}),ga=ao.time={},va=Date;Hn.prototype={getDate:function(){return this._.getUTCDate()},getDay:function(){return this._.getUTCDay()},getFullYear:function(){return this._.getUTCFullYear()},getHours:function(){return this._.getUTCHours()},getMilliseconds:function(){return this._.getUTCMilliseconds()},getMinutes:function(){return this._.getUTCMinutes()},getMonth:function(){return this._.getUTCMonth()},getSeconds:function(){return this._.getUTCSeconds()},getTime:function(){return this._.getTime()},getTimezoneOffset:function(){return 0},valueOf:function(){return this._.valueOf()},setDate:function(){da.setUTCDate.apply(this._,arguments)},setDay:function(){da.setUTCDay.apply(this._,arguments)},setFullYear:function(){da.setUTCFullYear.apply(this._,arguments)},setHours:function(){da.setUTCHours.apply(this._,arguments)},setMilliseconds:function(){da.setUTCMilliseconds.apply(this._,arguments)},setMinutes:function(){da.setUTCMinutes.apply(this._,arguments)},setMonth:function(){da.setUTCMonth.apply(this._,arguments)},setSeconds:function(){da.setUTCSeconds.apply(this._,arguments)},setTime:function(){da.setTime.apply(this._,arguments)}};var da=Date.prototype;ga.year=On(function(n){return n=ga.day(n),n.setMonth(0,1),n},function(n,t){n.setFullYear(n.getFullYear()+t)},function(n){return n.getFullYear()}),ga.years=ga.year.range,ga.years.utc=ga.year.utc.range,ga.day=On(function(n){var t=new va(2e3,0);return t.setFullYear(n.getFullYear(),n.getMonth(),n.getDate()),t},function(n,t){n.setDate(n.getDate()+t)},function(n){return n.getDate()-1}),ga.days=ga.day.range,ga.days.utc=ga.day.utc.range,ga.dayOfYear=function(n){var t=ga.year(n);return Math.floor((n-t-6e4*(n.getTimezoneOffset()-t.getTimezoneOffset()))/864e5)},["sunday","monday","tuesday","wednesday","thursday","friday","saturday"].forEach(function(n,t){t=7-t;var e=ga[n]=On(function(n){return(n=ga.day(n)).setDate(n.getDate()-(n.getDay()+t)%7),n},function(n,t){n.setDate(n.getDate()+7*Math.floor(t))},function(n){var e=ga.year(n).getDay();return Math.floor((ga.dayOfYear(n)+(e+t)%7)/7)-(e!==t)});ga[n+"s"]=e.range,ga[n+"s"].utc=e.utc.range,ga[n+"OfYear"]=function(n){var e=ga.year(n).getDay();return Math.floor((ga.dayOfYear(n)+(e+t)%7)/7)}}),ga.week=ga.sunday,ga.weeks=ga.sunday.range,ga.weeks.utc=ga.sunday.utc.range,ga.weekOfYear=ga.sundayOfYear;var ya={"-":"",_:" ",0:"0"},ma=/^\s*\d+/,Ma=/^%/;ao.locale=function(n){return{numberFormat:jn(n),timeFormat:Yn(n)}};var xa=ao.locale({decimal:".",thousands:",",grouping:[3],currency:["$",""],dateTime:"%a %b %e %X %Y",date:"%m/%d/%Y",time:"%H:%M:%S",periods:["AM","PM"],days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],
33780 shortDays:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],months:["January","February","March","April","May","June","July","August","September","October","November","December"],shortMonths:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]});ao.format=xa.numberFormat,ao.geo={},ft.prototype={s:0,t:0,add:function(n){st(n,this.t,ba),st(ba.s,this.s,this),this.s?this.t+=ba.t:this.s=ba.t},reset:function(){this.s=this.t=0},valueOf:function(){return this.s}};var ba=new ft;ao.geo.stream=function(n,t){n&&_a.hasOwnProperty(n.type)?_a[n.type](n,t):ht(n,t)};var _a={Feature:function(n,t){ht(n.geometry,t)},FeatureCollection:function(n,t){for(var e=n.features,r=-1,i=e.length;++r<i;)ht(e[r].geometry,t)}},wa={Sphere:function(n,t){t.sphere()},Point:function(n,t){n=n.coordinates,t.point(n[0],n[1],n[2])},MultiPoint:function(n,t){for(var e=n.coordinates,r=-1,i=e.length;++r<i;)n=e[r],t.point(n[0],n[1],n[2])},LineString:function(n,t){pt(n.coordinates,t,0)},MultiLineString:function(n,t){for(var e=n.coordinates,r=-1,i=e.length;++r<i;)pt(e[r],t,0)},Polygon:function(n,t){gt(n.coordinates,t)},MultiPolygon:function(n,t){for(var e=n.coordinates,r=-1,i=e.length;++r<i;)gt(e[r],t)},GeometryCollection:function(n,t){for(var e=n.geometries,r=-1,i=e.length;++r<i;)ht(e[r],t)}};ao.geo.area=function(n){return Sa=0,ao.geo.stream(n,Na),Sa};var Sa,ka=new ft,Na={sphere:function(){Sa+=4*Fo},point:b,lineStart:b,lineEnd:b,polygonStart:function(){ka.reset(),Na.lineStart=vt},polygonEnd:function(){var n=2*ka;Sa+=0>n?4*Fo+n:n,Na.lineStart=Na.lineEnd=Na.point=b}};ao.geo.bounds=function(){function n(n,t){M.push(x=[f=n,h=n]),s>t&&(s=t),t>p&&(p=t)}function t(t,e){var r=dt([t*Yo,e*Yo]);if(y){var i=mt(y,r),u=[i[1],-i[0],0],o=mt(u,i);bt(o),o=_t(o);var l=t-g,c=l>0?1:-1,v=o[0]*Zo*c,d=xo(l)>180;if(d^(v>c*g&&c*t>v)){var m=o[1]*Zo;m>p&&(p=m)}else if(v=(v+360)%360-180,d^(v>c*g&&c*t>v)){var m=-o[1]*Zo;s>m&&(s=m)}else s>e&&(s=e),e>p&&(p=e);d?g>t?a(f,t)>a(f,h)&&(h=t):a(t,h)>a(f,h)&&(f=t):h>=f?(f>t&&(f=t),t>h&&(h=t)):t>g?a(f,t)>a(f,h)&&(h=t):a(t,h)>a(f,h)&&(f=t)}else n(t,e);y=r,g=t}function e(){b.point=t}function r(){x[0]=f,x[1]=h,b.point=n,y=null}function i(n,e){if(y){var r=n-g;m+=xo(r)>180?r+(r>0?360:-360):r}else v=n,d=e;Na.point(n,e),t(n,e)}function u(){Na.lineStart()}function o(){i(v,d),Na.lineEnd(),xo(m)>Uo&&(f=-(h=180)),x[0]=f,x[1]=h,y=null}function a(n,t){return(t-=n)<0?t+360:t}function l(n,t){return n[0]-t[0]}function c(n,t){return t[0]<=t[1]?t[0]<=n&&n<=t[1]:n<t[0]||t[1]<n}var f,s,h,p,g,v,d,y,m,M,x,b={point:n,lineStart:e,lineEnd:r,polygonStart:function(){b.point=i,b.lineStart=u,b.lineEnd=o,m=0,Na.polygonStart()},polygonEnd:function(){Na.polygonEnd(),b.point=n,b.lineStart=e,b.lineEnd=r,0>ka?(f=-(h=180),s=-(p=90)):m>Uo?p=90:-Uo>m&&(s=-90),x[0]=f,x[1]=h}};return function(n){p=h=-(f=s=1/0),M=[],ao.geo.stream(n,b);var t=M.length;if(t){M.sort(l);for(var e,r=1,i=M[0],u=[i];t>r;++r)e=M[r],c(e[0],i)||c(e[1],i)?(a(i[0],e[1])>a(i[0],i[1])&&(i[1]=e[1]),a(e[0],i[1])>a(i[0],i[1])&&(i[0]=e[0])):u.push(i=e);for(var o,e,g=-(1/0),t=u.length-1,r=0,i=u[t];t>=r;i=e,++r)e=u[r],(o=a(i[1],e[0]))>g&&(g=o,f=e[0],h=i[1])}return M=x=null,f===1/0||s===1/0?[[NaN,NaN],[NaN,NaN]]:[[f,s],[h,p]]}}(),ao.geo.centroid=function(n){Ea=Aa=Ca=za=La=qa=Ta=Ra=Da=Pa=Ua=0,ao.geo.stream(n,ja);var t=Da,e=Pa,r=Ua,i=t*t+e*e+r*r;return jo>i&&(t=qa,e=Ta,r=Ra,Uo>Aa&&(t=Ca,e=za,r=La),i=t*t+e*e+r*r,jo>i)?[NaN,NaN]:[Math.atan2(e,t)*Zo,tn(r/Math.sqrt(i))*Zo]};var Ea,Aa,Ca,za,La,qa,Ta,Ra,Da,Pa,Ua,ja={sphere:b,point:St,lineStart:Nt,lineEnd:Et,polygonStart:function(){ja.lineStart=At},polygonEnd:function(){ja.lineStart=Nt}},Fa=Rt(zt,jt,Ht,[-Fo,-Fo/2]),Ha=1e9;ao.geo.clipExtent=function(){var n,t,e,r,i,u,o={stream:function(n){return i&&(i.valid=!1),i=u(n),i.valid=!0,i},extent:function(a){return arguments.length?(u=Zt(n=+a[0][0],t=+a[0][1],e=+a[1][0],r=+a[1][1]),i&&(i.valid=!1,i=null),o):[[n,t],[e,r]]}};return o.extent([[0,0],[960,500]])},(ao.geo.conicEqualArea=function(){return Vt(Xt)}).raw=Xt,ao.geo.albers=function(){return ao.geo.conicEqualArea().rotate([96,0]).center([-.6,38.7]).parallels([29.5,45.5]).scale(1070)},ao.geo.albersUsa=function(){function n(n){var u=n[0],o=n[1];return t=null,e(u,o),t||(r(u,o),t)||i(u,o),t}var t,e,r,i,u=ao.geo.albers(),o=ao.geo.conicEqualArea().rotate([154,0]).center([-2,58.5]).parallels([55,65]),a=ao.geo.conicEqualArea().rotate([157,0]).center([-3,19.9]).parallels([8,18]),l={point:function(n,e){t=[n,e]}};return n.invert=function(n){var t=u.scale(),e=u.translate(),r=(n[0]-e[0])/t,i=(n[1]-e[1])/t;return(i>=.12&&.234>i&&r>=-.425&&-.214>r?o:i>=.166&&.234>i&&r>=-.214&&-.115>r?a:u).invert(n)},n.stream=function(n){var t=u.stream(n),e=o.stream(n),r=a.stream(n);return{point:function(n,i){t.point(n,i),e.point(n,i),r.point(n,i)},sphere:function(){t.sphere(),e.sphere(),r.sphere()},lineStart:function(){t.lineStart(),e.lineStart(),r.lineStart()},lineEnd:function(){t.lineEnd(),e.lineEnd(),r.lineEnd()},polygonStart:function(){t.polygonStart(),e.polygonStart(),r.polygonStart()},polygonEnd:function(){t.polygonEnd(),e.polygonEnd(),r.polygonEnd()}}},n.precision=function(t){return arguments.length?(u.precision(t),o.precision(t),a.precision(t),n):u.precision()},n.scale=function(t){return arguments.length?(u.scale(t),o.scale(.35*t),a.scale(t),n.translate(u.translate())):u.scale()},n.translate=function(t){if(!arguments.length)return u.translate();var c=u.scale(),f=+t[0],s=+t[1];return e=u.translate(t).clipExtent([[f-.455*c,s-.238*c],[f+.455*c,s+.238*c]]).stream(l).point,r=o.translate([f-.307*c,s+.201*c]).clipExtent([[f-.425*c+Uo,s+.12*c+Uo],[f-.214*c-Uo,s+.234*c-Uo]]).stream(l).point,i=a.translate([f-.205*c,s+.212*c]).clipExtent([[f-.214*c+Uo,s+.166*c+Uo],[f-.115*c-Uo,s+.234*c-Uo]]).stream(l).point,n},n.scale(1070)};var Oa,Ia,Ya,Za,Va,Xa,$a={point:b,lineStart:b,lineEnd:b,polygonStart:function(){Ia=0,$a.lineStart=$t},polygonEnd:function(){$a.lineStart=$a.lineEnd=$a.point=b,Oa+=xo(Ia/2)}},Ba={point:Bt,lineStart:b,lineEnd:b,polygonStart:b,polygonEnd:b},Wa={point:Gt,lineStart:Kt,lineEnd:Qt,polygonStart:function(){Wa.lineStart=ne},polygonEnd:function(){Wa.point=Gt,Wa.lineStart=Kt,Wa.lineEnd=Qt}};ao.geo.path=function(){function n(n){return n&&("function"==typeof a&&u.pointRadius(+a.apply(this,arguments)),o&&o.valid||(o=i(u)),ao.geo.stream(n,o)),u.result()}function t(){return o=null,n}var e,r,i,u,o,a=4.5;return n.area=function(n){return Oa=0,ao.geo.stream(n,i($a)),Oa},n.centroid=function(n){return Ca=za=La=qa=Ta=Ra=Da=Pa=Ua=0,ao.geo.stream(n,i(Wa)),Ua?[Da/Ua,Pa/Ua]:Ra?[qa/Ra,Ta/Ra]:La?[Ca/La,za/La]:[NaN,NaN]},n.bounds=function(n){return Va=Xa=-(Ya=Za=1/0),ao.geo.stream(n,i(Ba)),[[Ya,Za],[Va,Xa]]},n.projection=function(n){return arguments.length?(i=(e=n)?n.stream||re(n):m,t()):e},n.context=function(n){return arguments.length?(u=null==(r=n)?new Wt:new te(n),"function"!=typeof a&&u.pointRadius(a),t()):r},n.pointRadius=function(t){return arguments.length?(a="function"==typeof t?t:(u.pointRadius(+t),+t),n):a},n.projection(ao.geo.albersUsa()).context(null)},ao.geo.transform=function(n){return{stream:function(t){var e=new ie(t);for(var r in n)e[r]=n[r];return e}}},ie.prototype={point:function(n,t){this.stream.point(n,t)},sphere:function(){this.stream.sphere()},lineStart:function(){this.stream.lineStart()},lineEnd:function(){this.stream.lineEnd()},polygonStart:function(){this.stream.polygonStart()},polygonEnd:function(){this.stream.polygonEnd()}},ao.geo.projection=oe,ao.geo.projectionMutator=ae,(ao.geo.equirectangular=function(){return oe(ce)}).raw=ce.invert=ce,ao.geo.rotation=function(n){function t(t){return t=n(t[0]*Yo,t[1]*Yo),t[0]*=Zo,t[1]*=Zo,t}return n=se(n[0]%360*Yo,n[1]*Yo,n.length>2?n[2]*Yo:0),t.invert=function(t){return t=n.invert(t[0]*Yo,t[1]*Yo),t[0]*=Zo,t[1]*=Zo,t},t},fe.invert=ce,ao.geo.circle=function(){function n(){var n="function"==typeof r?r.apply(this,arguments):r,t=se(-n[0]*Yo,-n[1]*Yo,0).invert,i=[];return e(null,null,1,{point:function(n,e){i.push(n=t(n,e)),n[0]*=Zo,n[1]*=Zo}}),{type:"Polygon",coordinates:[i]}}var t,e,r=[0,0],i=6;return n.origin=function(t){return arguments.length?(r=t,n):r},n.angle=function(r){return arguments.length?(e=ve((t=+r)*Yo,i*Yo),n):t},n.precision=function(r){return arguments.length?(e=ve(t*Yo,(i=+r)*Yo),n):i},n.angle(90)},ao.geo.distance=function(n,t){var e,r=(t[0]-n[0])*Yo,i=n[1]*Yo,u=t[1]*Yo,o=Math.sin(r),a=Math.cos(r),l=Math.sin(i),c=Math.cos(i),f=Math.sin(u),s=Math.cos(u);return Math.atan2(Math.sqrt((e=s*o)*e+(e=c*f-l*s*a)*e),l*f+c*s*a)},ao.geo.graticule=function(){function n(){return{type:"MultiLineString",coordinates:t()}}function t(){return ao.range(Math.ceil(u/d)*d,i,d).map(h).concat(ao.range(Math.ceil(c/y)*y,l,y).map(p)).concat(ao.range(Math.ceil(r/g)*g,e,g).filter(function(n){return xo(n%d)>Uo}).map(f)).concat(ao.range(Math.ceil(a/v)*v,o,v).filter(function(n){return xo(n%y)>Uo}).map(s))}var e,r,i,u,o,a,l,c,f,s,h,p,g=10,v=g,d=90,y=360,m=2.5;return n.lines=function(){return t().map(function(n){return{type:"LineString",coordinates:n}})},n.outline=function(){return{type:"Polygon",coordinates:[h(u).concat(p(l).slice(1),h(i).reverse().slice(1),p(c).reverse().slice(1))]}},n.extent=function(t){return arguments.length?n.majorExtent(t).minorExtent(t):n.minorExtent()},n.majorExtent=function(t){return arguments.length?(u=+t[0][0],i=+t[1][0],c=+t[0][1],l=+t[1][1],u>i&&(t=u,u=i,i=t),c>l&&(t=c,c=l,l=t),n.precision(m)):[[u,c],[i,l]]},n.minorExtent=function(t){return arguments.length?(r=+t[0][0],e=+t[1][0],a=+t[0][1],o=+t[1][1],r>e&&(t=r,r=e,e=t),a>o&&(t=a,a=o,o=t),n.precision(m)):[[r,a],[e,o]]},n.step=function(t){return arguments.length?n.majorStep(t).minorStep(t):n.minorStep()},n.majorStep=function(t){return arguments.length?(d=+t[0],y=+t[1],n):[d,y]},n.minorStep=function(t){return arguments.length?(g=+t[0],v=+t[1],n):[g,v]},n.precision=function(t){return arguments.length?(m=+t,f=ye(a,o,90),s=me(r,e,m),h=ye(c,l,90),p=me(u,i,m),n):m},n.majorExtent([[-180,-90+Uo],[180,90-Uo]]).minorExtent([[-180,-80-Uo],[180,80+Uo]])},ao.geo.greatArc=function(){function n(){return{type:"LineString",coordinates:[t||r.apply(this,arguments),e||i.apply(this,arguments)]}}var t,e,r=Me,i=xe;return n.distance=function(){return ao.geo.distance(t||r.apply(this,arguments),e||i.apply(this,arguments))},n.source=function(e){return arguments.length?(r=e,t="function"==typeof e?null:e,n):r},n.target=function(t){return arguments.length?(i=t,e="function"==typeof t?null:t,n):i},n.precision=function(){return arguments.length?n:0},n},ao.geo.interpolate=function(n,t){return be(n[0]*Yo,n[1]*Yo,t[0]*Yo,t[1]*Yo)},ao.geo.length=function(n){return Ja=0,ao.geo.stream(n,Ga),Ja};var Ja,Ga={sphere:b,point:b,lineStart:_e,lineEnd:b,polygonStart:b,polygonEnd:b},Ka=we(function(n){return Math.sqrt(2/(1+n))},function(n){return 2*Math.asin(n/2)});(ao.geo.azimuthalEqualArea=function(){return oe(Ka)}).raw=Ka;var Qa=we(function(n){var t=Math.acos(n);return t&&t/Math.sin(t)},m);(ao.geo.azimuthalEquidistant=function(){return oe(Qa)}).raw=Qa,(ao.geo.conicConformal=function(){return Vt(Se)}).raw=Se,(ao.geo.conicEquidistant=function(){return Vt(ke)}).raw=ke;var nl=we(function(n){return 1/n},Math.atan);(ao.geo.gnomonic=function(){return oe(nl)}).raw=nl,Ne.invert=function(n,t){return[n,2*Math.atan(Math.exp(t))-Io]},(ao.geo.mercator=function(){return Ee(Ne)}).raw=Ne;var tl=we(function(){return 1},Math.asin);(ao.geo.orthographic=function(){return oe(tl)}).raw=tl;var el=we(function(n){return 1/(1+n)},function(n){return 2*Math.atan(n)});(ao.geo.stereographic=function(){return oe(el)}).raw=el,Ae.invert=function(n,t){return[-t,2*Math.atan(Math.exp(n))-Io]},(ao.geo.transverseMercator=function(){var n=Ee(Ae),t=n.center,e=n.rotate;return n.center=function(n){return n?t([-n[1],n[0]]):(n=t(),[n[1],-n[0]])},n.rotate=function(n){return n?e([n[0],n[1],n.length>2?n[2]+90:90]):(n=e(),[n[0],n[1],n[2]-90])},e([0,0,90])}).raw=Ae,ao.geom={},ao.geom.hull=function(n){function t(n){if(n.length<3)return[];var t,i=En(e),u=En(r),o=n.length,a=[],l=[];for(t=0;o>t;t++)a.push([+i.call(this,n[t],t),+u.call(this,n[t],t),t]);for(a.sort(qe),t=0;o>t;t++)l.push([a[t][0],-a[t][1]]);var c=Le(a),f=Le(l),s=f[0]===c[0],h=f[f.length-1]===c[c.length-1],p=[];for(t=c.length-1;t>=0;--t)p.push(n[a[c[t]][2]]);for(t=+s;t<f.length-h;++t)p.push(n[a[f[t]][2]]);return p}var e=Ce,r=ze;return arguments.length?t(n):(t.x=function(n){return arguments.length?(e=n,t):e},t.y=function(n){return arguments.length?(r=n,t):r},t)},ao.geom.polygon=function(n){return ko(n,rl),n};var rl=ao.geom.polygon.prototype=[];rl.area=function(){for(var n,t=-1,e=this.length,r=this[e-1],i=0;++t<e;)n=r,r=this[t],i+=n[1]*r[0]-n[0]*r[1];return.5*i},rl.centroid=function(n){var t,e,r=-1,i=this.length,u=0,o=0,a=this[i-1];for(arguments.length||(n=-1/(6*this.area()));++r<i;)t=a,a=this[r],e=t[0]*a[1]-a[0]*t[1],u+=(t[0]+a[0])*e,o+=(t[1]+a[1])*e;return[u*n,o*n]},rl.clip=function(n){for(var t,e,r,i,u,o,a=De(n),l=-1,c=this.length-De(this),f=this[c-1];++l<c;){for(t=n.slice(),n.length=0,i=this[l],u=t[(r=t.length-a)-1],e=-1;++e<r;)o=t[e],Te(o,f,i)?(Te(u,f,i)||n.push(Re(u,o,f,i)),n.push(o)):Te(u,f,i)&&n.push(Re(u,o,f,i)),u=o;a&&n.push(n[0]),f=i}return n};var il,ul,ol,al,ll,cl=[],fl=[];Ye.prototype.prepare=function(){for(var n,t=this.edges,e=t.length;e--;)n=t[e].edge,n.b&&n.a||t.splice(e,1);return t.sort(Ve),t.length},tr.prototype={start:function(){return this.edge.l===this.site?this.edge.a:this.edge.b},end:function(){return this.edge.l===this.site?this.edge.b:this.edge.a}},er.prototype={insert:function(n,t){var e,r,i;if(n){if(t.P=n,t.N=n.N,n.N&&(n.N.P=t),n.N=t,n.R){for(n=n.R;n.L;)n=n.L;n.L=t}else n.R=t;e=n}else this._?(n=or(this._),t.P=null,t.N=n,n.P=n.L=t,e=n):(t.P=t.N=null,this._=t,e=null);for(t.L=t.R=null,t.U=e,t.C=!0,n=t;e&&e.C;)r=e.U,e===r.L?(i=r.R,i&&i.C?(e.C=i.C=!1,r.C=!0,n=r):(n===e.R&&(ir(this,e),n=e,e=n.U),e.C=!1,r.C=!0,ur(this,r))):(i=r.L,i&&i.C?(e.C=i.C=!1,r.C=!0,n=r):(n===e.L&&(ur(this,e),n=e,e=n.U),e.C=!1,r.C=!0,ir(this,r))),e=n.U;this._.C=!1},remove:function(n){n.N&&(n.N.P=n.P),n.P&&(n.P.N=n.N),n.N=n.P=null;var t,e,r,i=n.U,u=n.L,o=n.R;if(e=u?o?or(o):u:o,i?i.L===n?i.L=e:i.R=e:this._=e,u&&o?(r=e.C,e.C=n.C,e.L=u,u.U=e,e!==o?(i=e.U,e.U=n.U,n=e.R,i.L=n,e.R=o,o.U=e):(e.U=i,i=e,n=e.R)):(r=n.C,n=e),n&&(n.U=i),!r){if(n&&n.C)return void(n.C=!1);do{if(n===this._)break;if(n===i.L){if(t=i.R,t.C&&(t.C=!1,i.C=!0,ir(this,i),t=i.R),t.L&&t.L.C||t.R&&t.R.C){t.R&&t.R.C||(t.L.C=!1,t.C=!0,ur(this,t),t=i.R),t.C=i.C,i.C=t.R.C=!1,ir(this,i),n=this._;break}}else if(t=i.L,t.C&&(t.C=!1,i.C=!0,ur(this,i),t=i.L),t.L&&t.L.C||t.R&&t.R.C){t.L&&t.L.C||(t.R.C=!1,t.C=!0,ir(this,t),t=i.L),t.C=i.C,i.C=t.L.C=!1,ur(this,i),n=this._;break}t.C=!0,n=i,i=i.U}while(!n.C);n&&(n.C=!1)}}},ao.geom.voronoi=function(n){function t(n){var t=new Array(n.length),r=a[0][0],i=a[0][1],u=a[1][0],o=a[1][1];return ar(e(n),a).cells.forEach(function(e,a){var l=e.edges,c=e.site,f=t[a]=l.length?l.map(function(n){var t=n.start();return[t.x,t.y]}):c.x>=r&&c.x<=u&&c.y>=i&&c.y<=o?[[r,o],[u,o],[u,i],[r,i]]:[];f.point=n[a]}),t}function e(n){return n.map(function(n,t){return{x:Math.round(u(n,t)/Uo)*Uo,y:Math.round(o(n,t)/Uo)*Uo,i:t}})}var r=Ce,i=ze,u=r,o=i,a=sl;return n?t(n):(t.links=function(n){return ar(e(n)).edges.filter(function(n){return n.l&&n.r}).map(function(t){return{source:n[t.l.i],target:n[t.r.i]}})},t.triangles=function(n){var t=[];return ar(e(n)).cells.forEach(function(e,r){for(var i,u,o=e.site,a=e.edges.sort(Ve),l=-1,c=a.length,f=a[c-1].edge,s=f.l===o?f.r:f.l;++l<c;)i=f,u=s,f=a[l].edge,s=f.l===o?f.r:f.l,r<u.i&&r<s.i&&cr(o,u,s)<0&&t.push([n[r],n[u.i],n[s.i]])}),t},t.x=function(n){return arguments.length?(u=En(r=n),t):r},t.y=function(n){return arguments.length?(o=En(i=n),t):i},t.clipExtent=function(n){return arguments.length?(a=null==n?sl:n,t):a===sl?null:a},t.size=function(n){return arguments.length?t.clipExtent(n&&[[0,0],n]):a===sl?null:a&&a[1]},t)};var sl=[[-1e6,-1e6],[1e6,1e6]];ao.geom.delaunay=function(n){return ao.geom.voronoi().triangles(n)},ao.geom.quadtree=function(n,t,e,r,i){function u(n){function u(n,t,e,r,i,u,o,a){if(!isNaN(e)&&!isNaN(r))if(n.leaf){var l=n.x,f=n.y;if(null!=l)if(xo(l-e)+xo(f-r)<.01)c(n,t,e,r,i,u,o,a);else{var s=n.point;n.x=n.y=n.point=null,c(n,s,l,f,i,u,o,a),c(n,t,e,r,i,u,o,a)}else n.x=e,n.y=r,n.point=t}else c(n,t,e,r,i,u,o,a)}function c(n,t,e,r,i,o,a,l){var c=.5*(i+a),f=.5*(o+l),s=e>=c,h=r>=f,p=h<<1|s;n.leaf=!1,n=n.nodes[p]||(n.nodes[p]=hr()),s?i=c:a=c,h?o=f:l=f,u(n,t,e,r,i,o,a,l)}var f,s,h,p,g,v,d,y,m,M=En(a),x=En(l);if(null!=t)v=t,d=e,y=r,m=i;else if(y=m=-(v=d=1/0),s=[],h=[],g=n.length,o)for(p=0;g>p;++p)f=n[p],f.x<v&&(v=f.x),f.y<d&&(d=f.y),f.x>y&&(y=f.x),f.y>m&&(m=f.y),s.push(f.x),h.push(f.y);else for(p=0;g>p;++p){var b=+M(f=n[p],p),_=+x(f,p);v>b&&(v=b),d>_&&(d=_),b>y&&(y=b),_>m&&(m=_),s.push(b),h.push(_)}var w=y-v,S=m-d;w>S?m=d+w:y=v+S;var k=hr();if(k.add=function(n){u(k,n,+M(n,++p),+x(n,p),v,d,y,m)},k.visit=function(n){pr(n,k,v,d,y,m)},k.find=function(n){return gr(k,n[0],n[1],v,d,y,m)},p=-1,null==t){for(;++p<g;)u(k,n[p],s[p],h[p],v,d,y,m);--p}else n.forEach(k.add);return s=h=n=f=null,k}var o,a=Ce,l=ze;return(o=arguments.length)?(a=fr,l=sr,3===o&&(i=e,r=t,e=t=0),u(n)):(u.x=function(n){return arguments.length?(a=n,u):a},u.y=function(n){return arguments.length?(l=n,u):l},u.extent=function(n){return arguments.length?(null==n?t=e=r=i=null:(t=+n[0][0],e=+n[0][1],r=+n[1][0],i=+n[1][1]),u):null==t?null:[[t,e],[r,i]]},u.size=function(n){return arguments.length?(null==n?t=e=r=i=null:(t=e=0,r=+n[0],i=+n[1]),u):null==t?null:[r-t,i-e]},u)},ao.interpolateRgb=vr,ao.interpolateObject=dr,ao.interpolateNumber=yr,ao.interpolateString=mr;var hl=/[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?/g,pl=new RegExp(hl.source,"g");ao.interpolate=Mr,ao.interpolators=[function(n,t){var e=typeof t;return("string"===e?ua.has(t.toLowerCase())||/^(#|rgb\(|hsl\()/i.test(t)?vr:mr:t instanceof an?vr:Array.isArray(t)?xr:"object"===e&&isNaN(t)?dr:yr)(n,t)}],ao.interpolateArray=xr;var gl=function(){return m},vl=ao.map({linear:gl,poly:Er,quad:function(){return Sr},cubic:function(){return kr},sin:function(){return Ar},exp:function(){return Cr},circle:function(){return zr},elastic:Lr,back:qr,bounce:function(){return Tr}}),dl=ao.map({"in":m,out:_r,"in-out":wr,"out-in":function(n){return wr(_r(n))}});ao.ease=function(n){var t=n.indexOf("-"),e=t>=0?n.slice(0,t):n,r=t>=0?n.slice(t+1):"in";return e=vl.get(e)||gl,r=dl.get(r)||m,br(r(e.apply(null,lo.call(arguments,1))))},ao.interpolateHcl=Rr,ao.interpolateHsl=Dr,ao.interpolateLab=Pr,ao.interpolateRound=Ur,ao.transform=function(n){var t=fo.createElementNS(ao.ns.prefix.svg,"g");return(ao.transform=function(n){if(null!=n){t.setAttribute("transform",n);var e=t.transform.baseVal.consolidate()}return new jr(e?e.matrix:yl)})(n)},jr.prototype.toString=function(){return"translate("+this.translate+")rotate("+this.rotate+")skewX("+this.skew+")scale("+this.scale+")"};var yl={a:1,b:0,c:0,d:1,e:0,f:0};ao.interpolateTransform=$r,ao.layout={},ao.layout.bundle=function(){return function(n){for(var t=[],e=-1,r=n.length;++e<r;)t.push(Jr(n[e]));return t}},ao.layout.chord=function(){function n(){var n,c,s,h,p,g={},v=[],d=ao.range(u),y=[];for(e=[],r=[],n=0,h=-1;++h<u;){for(c=0,p=-1;++p<u;)c+=i[h][p];v.push(c),y.push(ao.range(u)),n+=c}for(o&&d.sort(function(n,t){return o(v[n],v[t])}),a&&y.forEach(function(n,t){n.sort(function(n,e){return a(i[t][n],i[t][e])})}),n=(Ho-f*u)/n,c=0,h=-1;++h<u;){for(s=c,p=-1;++p<u;){var m=d[h],M=y[m][p],x=i[m][M],b=c,_=c+=x*n;g[m+"-"+M]={index:m,subindex:M,startAngle:b,endAngle:_,value:x}}r[m]={index:m,startAngle:s,endAngle:c,value:v[m]},c+=f}for(h=-1;++h<u;)for(p=h-1;++p<u;){var w=g[h+"-"+p],S=g[p+"-"+h];(w.value||S.value)&&e.push(w.value<S.value?{source:S,target:w}:{source:w,target:S})}l&&t()}function t(){e.sort(function(n,t){return l((n.source.value+n.target.value)/2,(t.source.value+t.target.value)/2)})}var e,r,i,u,o,a,l,c={},f=0;return c.matrix=function(n){return arguments.length?(u=(i=n)&&i.length,e=r=null,c):i},c.padding=function(n){return arguments.length?(f=n,e=r=null,c):f},c.sortGroups=function(n){return arguments.length?(o=n,e=r=null,c):o},c.sortSubgroups=function(n){return arguments.length?(a=n,e=null,c):a},c.sortChords=function(n){return arguments.length?(l=n,e&&t(),c):l},c.chords=function(){return e||n(),e},c.groups=function(){return r||n(),r},c},ao.layout.force=function(){function n(n){return function(t,e,r,i){if(t.point!==n){var u=t.cx-n.x,o=t.cy-n.y,a=i-e,l=u*u+o*o;if(l>a*a/y){if(v>l){var c=t.charge/l;n.px-=u*c,n.py-=o*c}return!0}if(t.point&&l&&v>l){var c=t.pointCharge/l;n.px-=u*c,n.py-=o*c}}return!t.charge}}function t(n){n.px=ao.event.x,n.py=ao.event.y,l.resume()}var e,r,i,u,o,a,l={},c=ao.dispatch("start","tick","end"),f=[1,1],s=.9,h=ml,p=Ml,g=-30,v=xl,d=.1,y=.64,M=[],x=[];return l.tick=function(){if((i*=.99)<.005)return e=null,c.end({type:"end",alpha:i=0}),!0;var t,r,l,h,p,v,y,m,b,_=M.length,w=x.length;for(r=0;w>r;++r)l=x[r],h=l.source,p=l.target,m=p.x-h.x,b=p.y-h.y,(v=m*m+b*b)&&(v=i*o[r]*((v=Math.sqrt(v))-u[r])/v,m*=v,b*=v,p.x-=m*(y=h.weight+p.weight?h.weight/(h.weight+p.weight):.5),p.y-=b*y,h.x+=m*(y=1-y),h.y+=b*y);if((y=i*d)&&(m=f[0]/2,b=f[1]/2,r=-1,y))for(;++r<_;)l=M[r],l.x+=(m-l.x)*y,l.y+=(b-l.y)*y;if(g)for(ri(t=ao.geom.quadtree(M),i,a),r=-1;++r<_;)(l=M[r]).fixed||t.visit(n(l));for(r=-1;++r<_;)l=M[r],l.fixed?(l.x=l.px,l.y=l.py):(l.x-=(l.px-(l.px=l.x))*s,l.y-=(l.py-(l.py=l.y))*s);c.tick({type:"tick",alpha:i})},l.nodes=function(n){return arguments.length?(M=n,l):M},l.links=function(n){return arguments.length?(x=n,l):x},l.size=function(n){return arguments.length?(f=n,l):f},l.linkDistance=function(n){return arguments.length?(h="function"==typeof n?n:+n,l):h},l.distance=l.linkDistance,l.linkStrength=function(n){return arguments.length?(p="function"==typeof n?n:+n,l):p},l.friction=function(n){return arguments.length?(s=+n,l):s},l.charge=function(n){return arguments.length?(g="function"==typeof n?n:+n,l):g},l.chargeDistance=function(n){return arguments.length?(v=n*n,l):Math.sqrt(v)},l.gravity=function(n){return arguments.length?(d=+n,l):d},l.theta=function(n){return arguments.length?(y=n*n,l):Math.sqrt(y)},l.alpha=function(n){return arguments.length?(n=+n,i?n>0?i=n:(e.c=null,e.t=NaN,e=null,c.end({type:"end",alpha:i=0})):n>0&&(c.start({type:"start",alpha:i=n}),e=qn(l.tick)),l):i},l.start=function(){function n(n,r){if(!e){for(e=new Array(i),l=0;i>l;++l)e[l]=[];for(l=0;c>l;++l){var u=x[l];e[u.source.index].push(u.target),e[u.target.index].push(u.source)}}for(var o,a=e[t],l=-1,f=a.length;++l<f;)if(!isNaN(o=a[l][n]))return o;return Math.random()*r}var t,e,r,i=M.length,c=x.length,s=f[0],v=f[1];for(t=0;i>t;++t)(r=M[t]).index=t,r.weight=0;for(t=0;c>t;++t)r=x[t],"number"==typeof r.source&&(r.source=M[r.source]),"number"==typeof r.target&&(r.target=M[r.target]),++r.source.weight,++r.target.weight;for(t=0;i>t;++t)r=M[t],isNaN(r.x)&&(r.x=n("x",s)),isNaN(r.y)&&(r.y=n("y",v)),isNaN(r.px)&&(r.px=r.x),isNaN(r.py)&&(r.py=r.y);if(u=[],"function"==typeof h)for(t=0;c>t;++t)u[t]=+h.call(this,x[t],t);else for(t=0;c>t;++t)u[t]=h;if(o=[],"function"==typeof p)for(t=0;c>t;++t)o[t]=+p.call(this,x[t],t);else for(t=0;c>t;++t)o[t]=p;if(a=[],"function"==typeof g)for(t=0;i>t;++t)a[t]=+g.call(this,M[t],t);else for(t=0;i>t;++t)a[t]=g;return l.resume()},l.resume=function(){return l.alpha(.1)},l.stop=function(){return l.alpha(0)},l.drag=function(){return r||(r=ao.behavior.drag().origin(m).on("dragstart.force",Qr).on("drag.force",t).on("dragend.force",ni)),arguments.length?void this.on("mouseover.force",ti).on("mouseout.force",ei).call(r):r},ao.rebind(l,c,"on")};var ml=20,Ml=1,xl=1/0;ao.layout.hierarchy=function(){function n(i){var u,o=[i],a=[];for(i.depth=0;null!=(u=o.pop());)if(a.push(u),(c=e.call(n,u,u.depth))&&(l=c.length)){for(var l,c,f;--l>=0;)o.push(f=c[l]),f.parent=u,f.depth=u.depth+1;r&&(u.value=0),u.children=c}else r&&(u.value=+r.call(n,u,u.depth)||0),delete u.children;return oi(i,function(n){var e,i;t&&(e=n.children)&&e.sort(t),r&&(i=n.parent)&&(i.value+=n.value)}),a}var t=ci,e=ai,r=li;return n.sort=function(e){return arguments.length?(t=e,n):t},n.children=function(t){return arguments.length?(e=t,n):e},n.value=function(t){return arguments.length?(r=t,n):r},n.revalue=function(t){return r&&(ui(t,function(n){n.children&&(n.value=0)}),oi(t,function(t){var e;t.children||(t.value=+r.call(n,t,t.depth)||0),(e=t.parent)&&(e.value+=t.value)})),t},n},ao.layout.partition=function(){function n(t,e,r,i){var u=t.children;if(t.x=e,t.y=t.depth*i,t.dx=r,t.dy=i,u&&(o=u.length)){var o,a,l,c=-1;for(r=t.value?r/t.value:0;++c<o;)n(a=u[c],e,l=a.value*r,i),e+=l}}function t(n){var e=n.children,r=0;if(e&&(i=e.length))for(var i,u=-1;++u<i;)r=Math.max(r,t(e[u]));return 1+r}function e(e,u){var o=r.call(this,e,u);return n(o[0],0,i[0],i[1]/t(o[0])),o}var r=ao.layout.hierarchy(),i=[1,1];return e.size=function(n){return arguments.length?(i=n,e):i},ii(e,r)},ao.layout.pie=function(){function n(o){var a,l=o.length,c=o.map(function(e,r){return+t.call(n,e,r)}),f=+("function"==typeof r?r.apply(this,arguments):r),s=("function"==typeof i?i.apply(this,arguments):i)-f,h=Math.min(Math.abs(s)/l,+("function"==typeof u?u.apply(this,arguments):u)),p=h*(0>s?-1:1),g=ao.sum(c),v=g?(s-l*p)/g:0,d=ao.range(l),y=[];return null!=e&&d.sort(e===bl?function(n,t){return c[t]-c[n]}:function(n,t){return e(o[n],o[t])}),d.forEach(function(n){y[n]={data:o[n],value:a=c[n],startAngle:f,endAngle:f+=a*v+p,padAngle:h}}),y}var t=Number,e=bl,r=0,i=Ho,u=0;return n.value=function(e){return arguments.length?(t=e,n):t},n.sort=function(t){return arguments.length?(e=t,n):e},n.startAngle=function(t){return arguments.length?(r=t,n):r},n.endAngle=function(t){return arguments.length?(i=t,n):i},n.padAngle=function(t){return arguments.length?(u=t,n):u},n};var bl={};ao.layout.stack=function(){function n(a,l){if(!(h=a.length))return a;var c=a.map(function(e,r){return t.call(n,e,r)}),f=c.map(function(t){return t.map(function(t,e){return[u.call(n,t,e),o.call(n,t,e)]})}),s=e.call(n,f,l);c=ao.permute(c,s),f=ao.permute(f,s);var h,p,g,v,d=r.call(n,f,l),y=c[0].length;for(g=0;y>g;++g)for(i.call(n,c[0][g],v=d[g],f[0][g][1]),p=1;h>p;++p)i.call(n,c[p][g],v+=f[p-1][g][1],f[p][g][1]);return a}var t=m,e=gi,r=vi,i=pi,u=si,o=hi;return n.values=function(e){return arguments.length?(t=e,n):t},n.order=function(t){return arguments.length?(e="function"==typeof t?t:_l.get(t)||gi,n):e},n.offset=function(t){return arguments.length?(r="function"==typeof t?t:wl.get(t)||vi,n):r},n.x=function(t){return arguments.length?(u=t,n):u},n.y=function(t){return arguments.length?(o=t,n):o},n.out=function(t){return arguments.length?(i=t,n):i},n};var _l=ao.map({"inside-out":function(n){var t,e,r=n.length,i=n.map(di),u=n.map(yi),o=ao.range(r).sort(function(n,t){return i[n]-i[t]}),a=0,l=0,c=[],f=[];for(t=0;r>t;++t)e=o[t],l>a?(a+=u[e],c.push(e)):(l+=u[e],f.push(e));return f.reverse().concat(c)},reverse:function(n){return ao.range(n.length).reverse()},"default":gi}),wl=ao.map({silhouette:function(n){var t,e,r,i=n.length,u=n[0].length,o=[],a=0,l=[];for(e=0;u>e;++e){for(t=0,r=0;i>t;t++)r+=n[t][e][1];r>a&&(a=r),o.push(r)}for(e=0;u>e;++e)l[e]=(a-o[e])/2;return l},wiggle:function(n){var t,e,r,i,u,o,a,l,c,f=n.length,s=n[0],h=s.length,p=[];for(p[0]=l=c=0,e=1;h>e;++e){for(t=0,i=0;f>t;++t)i+=n[t][e][1];for(t=0,u=0,a=s[e][0]-s[e-1][0];f>t;++t){for(r=0,o=(n[t][e][1]-n[t][e-1][1])/(2*a);t>r;++r)o+=(n[r][e][1]-n[r][e-1][1])/a;u+=o*n[t][e][1]}p[e]=l-=i?u/i*a:0,c>l&&(c=l)}for(e=0;h>e;++e)p[e]-=c;return p},expand:function(n){var t,e,r,i=n.length,u=n[0].length,o=1/i,a=[];for(e=0;u>e;++e){for(t=0,r=0;i>t;t++)r+=n[t][e][1];if(r)for(t=0;i>t;t++)n[t][e][1]/=r;else for(t=0;i>t;t++)n[t][e][1]=o}for(e=0;u>e;++e)a[e]=0;return a},zero:vi});ao.layout.histogram=function(){function n(n,u){for(var o,a,l=[],c=n.map(e,this),f=r.call(this,c,u),s=i.call(this,f,c,u),u=-1,h=c.length,p=s.length-1,g=t?1:1/h;++u<p;)o=l[u]=[],o.dx=s[u+1]-(o.x=s[u]),o.y=0;if(p>0)for(u=-1;++u<h;)a=c[u],a>=f[0]&&a<=f[1]&&(o=l[ao.bisect(s,a,1,p)-1],o.y+=g,o.push(n[u]));return l}var t=!0,e=Number,r=bi,i=Mi;return n.value=function(t){return arguments.length?(e=t,n):e},n.range=function(t){return arguments.length?(r=En(t),n):r},n.bins=function(t){return arguments.length?(i="number"==typeof t?function(n){return xi(n,t)}:En(t),n):i},n.frequency=function(e){return arguments.length?(t=!!e,n):t},n},ao.layout.pack=function(){function n(n,u){var o=e.call(this,n,u),a=o[0],l=i[0],c=i[1],f=null==t?Math.sqrt:"function"==typeof t?t:function(){return t};if(a.x=a.y=0,oi(a,function(n){n.r=+f(n.value)}),oi(a,Ni),r){var s=r*(t?1:Math.max(2*a.r/l,2*a.r/c))/2;oi(a,function(n){n.r+=s}),oi(a,Ni),oi(a,function(n){n.r-=s})}return Ci(a,l/2,c/2,t?1:1/Math.max(2*a.r/l,2*a.r/c)),o}var t,e=ao.layout.hierarchy().sort(_i),r=0,i=[1,1];return n.size=function(t){return arguments.length?(i=t,n):i},n.radius=function(e){return arguments.length?(t=null==e||"function"==typeof e?e:+e,n):t},n.padding=function(t){return arguments.length?(r=+t,n):r},ii(n,e)},ao.layout.tree=function(){function n(n,i){var f=o.call(this,n,i),s=f[0],h=t(s);if(oi(h,e),h.parent.m=-h.z,ui(h,r),c)ui(s,u);else{var p=s,g=s,v=s;ui(s,function(n){n.x<p.x&&(p=n),n.x>g.x&&(g=n),n.depth>v.depth&&(v=n)});var d=a(p,g)/2-p.x,y=l[0]/(g.x+a(g,p)/2+d),m=l[1]/(v.depth||1);ui(s,function(n){n.x=(n.x+d)*y,n.y=n.depth*m})}return f}function t(n){for(var t,e={A:null,children:[n]},r=[e];null!=(t=r.pop());)for(var i,u=t.children,o=0,a=u.length;a>o;++o)r.push((u[o]=i={_:u[o],parent:t,children:(i=u[o].children)&&i.slice()||[],A:null,a:null,z:0,m:0,c:0,s:0,t:null,i:o}).a=i);return e.children[0]}function e(n){var t=n.children,e=n.parent.children,r=n.i?e[n.i-1]:null;if(t.length){Di(n);var u=(t[0].z+t[t.length-1].z)/2;r?(n.z=r.z+a(n._,r._),n.m=n.z-u):n.z=u}else r&&(n.z=r.z+a(n._,r._));n.parent.A=i(n,r,n.parent.A||e[0])}function r(n){n._.x=n.z+n.parent.m,n.m+=n.parent.m}function i(n,t,e){if(t){for(var r,i=n,u=n,o=t,l=i.parent.children[0],c=i.m,f=u.m,s=o.m,h=l.m;o=Ti(o),i=qi(i),o&&i;)l=qi(l),u=Ti(u),u.a=n,r=o.z+s-i.z-c+a(o._,i._),r>0&&(Ri(Pi(o,n,e),n,r),c+=r,f+=r),s+=o.m,c+=i.m,h+=l.m,f+=u.m;o&&!Ti(u)&&(u.t=o,u.m+=s-f),i&&!qi(l)&&(l.t=i,l.m+=c-h,e=n)}return e}function u(n){n.x*=l[0],n.y=n.depth*l[1]}var o=ao.layout.hierarchy().sort(null).value(null),a=Li,l=[1,1],c=null;return n.separation=function(t){return arguments.length?(a=t,n):a},n.size=function(t){return arguments.length?(c=null==(l=t)?u:null,n):c?null:l},n.nodeSize=function(t){return arguments.length?(c=null==(l=t)?null:u,n):c?l:null},ii(n,o)},ao.layout.cluster=function(){function n(n,u){var o,a=t.call(this,n,u),l=a[0],c=0;oi(l,function(n){var t=n.children;t&&t.length?(n.x=ji(t),n.y=Ui(t)):(n.x=o?c+=e(n,o):0,n.y=0,o=n)});var f=Fi(l),s=Hi(l),h=f.x-e(f,s)/2,p=s.x+e(s,f)/2;return oi(l,i?function(n){n.x=(n.x-l.x)*r[0],n.y=(l.y-n.y)*r[1]}:function(n){n.x=(n.x-h)/(p-h)*r[0],n.y=(1-(l.y?n.y/l.y:1))*r[1]}),a}var t=ao.layout.hierarchy().sort(null).value(null),e=Li,r=[1,1],i=!1;return n.separation=function(t){return arguments.length?(e=t,n):e},n.size=function(t){return arguments.length?(i=null==(r=t),n):i?null:r},n.nodeSize=function(t){return arguments.length?(i=null!=(r=t),n):i?r:null},ii(n,t)},ao.layout.treemap=function(){function n(n,t){for(var e,r,i=-1,u=n.length;++i<u;)r=(e=n[i]).value*(0>t?0:t),e.area=isNaN(r)||0>=r?0:r}function t(e){var u=e.children;if(u&&u.length){var o,a,l,c=s(e),f=[],h=u.slice(),g=1/0,v="slice"===p?c.dx:"dice"===p?c.dy:"slice-dice"===p?1&e.depth?c.dy:c.dx:Math.min(c.dx,c.dy);for(n(h,c.dx*c.dy/e.value),f.area=0;(l=h.length)>0;)f.push(o=h[l-1]),f.area+=o.area,"squarify"!==p||(a=r(f,v))<=g?(h.pop(),g=a):(f.area-=f.pop().area,i(f,v,c,!1),v=Math.min(c.dx,c.dy),f.length=f.area=0,g=1/0);f.length&&(i(f,v,c,!0),f.length=f.area=0),u.forEach(t)}}function e(t){var r=t.children;if(r&&r.length){var u,o=s(t),a=r.slice(),l=[];for(n(a,o.dx*o.dy/t.value),l.area=0;u=a.pop();)l.push(u),l.area+=u.area,null!=u.z&&(i(l,u.z?o.dx:o.dy,o,!a.length),l.length=l.area=0);r.forEach(e)}}function r(n,t){for(var e,r=n.area,i=0,u=1/0,o=-1,a=n.length;++o<a;)(e=n[o].area)&&(u>e&&(u=e),e>i&&(i=e));return r*=r,t*=t,r?Math.max(t*i*g/r,r/(t*u*g)):1/0}function i(n,t,e,r){var i,u=-1,o=n.length,a=e.x,c=e.y,f=t?l(n.area/t):0;
33781 if(t==e.dx){for((r||f>e.dy)&&(f=e.dy);++u<o;)i=n[u],i.x=a,i.y=c,i.dy=f,a+=i.dx=Math.min(e.x+e.dx-a,f?l(i.area/f):0);i.z=!0,i.dx+=e.x+e.dx-a,e.y+=f,e.dy-=f}else{for((r||f>e.dx)&&(f=e.dx);++u<o;)i=n[u],i.x=a,i.y=c,i.dx=f,c+=i.dy=Math.min(e.y+e.dy-c,f?l(i.area/f):0);i.z=!1,i.dy+=e.y+e.dy-c,e.x+=f,e.dx-=f}}function u(r){var i=o||a(r),u=i[0];return u.x=u.y=0,u.value?(u.dx=c[0],u.dy=c[1]):u.dx=u.dy=0,o&&a.revalue(u),n([u],u.dx*u.dy/u.value),(o?e:t)(u),h&&(o=i),i}var o,a=ao.layout.hierarchy(),l=Math.round,c=[1,1],f=null,s=Oi,h=!1,p="squarify",g=.5*(1+Math.sqrt(5));return u.size=function(n){return arguments.length?(c=n,u):c},u.padding=function(n){function t(t){var e=n.call(u,t,t.depth);return null==e?Oi(t):Ii(t,"number"==typeof e?[e,e,e,e]:e)}function e(t){return Ii(t,n)}if(!arguments.length)return f;var r;return s=null==(f=n)?Oi:"function"==(r=typeof n)?t:"number"===r?(n=[n,n,n,n],e):e,u},u.round=function(n){return arguments.length?(l=n?Math.round:Number,u):l!=Number},u.sticky=function(n){return arguments.length?(h=n,o=null,u):h},u.ratio=function(n){return arguments.length?(g=n,u):g},u.mode=function(n){return arguments.length?(p=n+"",u):p},ii(u,a)},ao.random={normal:function(n,t){var e=arguments.length;return 2>e&&(t=1),1>e&&(n=0),function(){var e,r,i;do e=2*Math.random()-1,r=2*Math.random()-1,i=e*e+r*r;while(!i||i>1);return n+t*e*Math.sqrt(-2*Math.log(i)/i)}},logNormal:function(){var n=ao.random.normal.apply(ao,arguments);return function(){return Math.exp(n())}},bates:function(n){var t=ao.random.irwinHall(n);return function(){return t()/n}},irwinHall:function(n){return function(){for(var t=0,e=0;n>e;e++)t+=Math.random();return t}}},ao.scale={};var Sl={floor:m,ceil:m};ao.scale.linear=function(){return Wi([0,1],[0,1],Mr,!1)};var kl={s:1,g:1,p:1,r:1,e:1};ao.scale.log=function(){return ru(ao.scale.linear().domain([0,1]),10,!0,[1,10])};var Nl=ao.format(".0e"),El={floor:function(n){return-Math.ceil(-n)},ceil:function(n){return-Math.floor(-n)}};ao.scale.pow=function(){return iu(ao.scale.linear(),1,[0,1])},ao.scale.sqrt=function(){return ao.scale.pow().exponent(.5)},ao.scale.ordinal=function(){return ou([],{t:"range",a:[[]]})},ao.scale.category10=function(){return ao.scale.ordinal().range(Al)},ao.scale.category20=function(){return ao.scale.ordinal().range(Cl)},ao.scale.category20b=function(){return ao.scale.ordinal().range(zl)},ao.scale.category20c=function(){return ao.scale.ordinal().range(Ll)};var Al=[2062260,16744206,2924588,14034728,9725885,9197131,14907330,8355711,12369186,1556175].map(xn),Cl=[2062260,11454440,16744206,16759672,2924588,10018698,14034728,16750742,9725885,12955861,9197131,12885140,14907330,16234194,8355711,13092807,12369186,14408589,1556175,10410725].map(xn),zl=[3750777,5395619,7040719,10264286,6519097,9216594,11915115,13556636,9202993,12426809,15186514,15190932,8666169,11356490,14049643,15177372,8077683,10834324,13528509,14589654].map(xn),Ll=[3244733,7057110,10406625,13032431,15095053,16616764,16625259,16634018,3253076,7652470,10607003,13101504,7695281,10394312,12369372,14342891,6513507,9868950,12434877,14277081].map(xn);ao.scale.quantile=function(){return au([],[])},ao.scale.quantize=function(){return lu(0,1,[0,1])},ao.scale.threshold=function(){return cu([.5],[0,1])},ao.scale.identity=function(){return fu([0,1])},ao.svg={},ao.svg.arc=function(){function n(){var n=Math.max(0,+e.apply(this,arguments)),c=Math.max(0,+r.apply(this,arguments)),f=o.apply(this,arguments)-Io,s=a.apply(this,arguments)-Io,h=Math.abs(s-f),p=f>s?0:1;if(n>c&&(g=c,c=n,n=g),h>=Oo)return t(c,p)+(n?t(n,1-p):"")+"Z";var g,v,d,y,m,M,x,b,_,w,S,k,N=0,E=0,A=[];if((y=(+l.apply(this,arguments)||0)/2)&&(d=u===ql?Math.sqrt(n*n+c*c):+u.apply(this,arguments),p||(E*=-1),c&&(E=tn(d/c*Math.sin(y))),n&&(N=tn(d/n*Math.sin(y)))),c){m=c*Math.cos(f+E),M=c*Math.sin(f+E),x=c*Math.cos(s-E),b=c*Math.sin(s-E);var C=Math.abs(s-f-2*E)<=Fo?0:1;if(E&&yu(m,M,x,b)===p^C){var z=(f+s)/2;m=c*Math.cos(z),M=c*Math.sin(z),x=b=null}}else m=M=0;if(n){_=n*Math.cos(s-N),w=n*Math.sin(s-N),S=n*Math.cos(f+N),k=n*Math.sin(f+N);var L=Math.abs(f-s+2*N)<=Fo?0:1;if(N&&yu(_,w,S,k)===1-p^L){var q=(f+s)/2;_=n*Math.cos(q),w=n*Math.sin(q),S=k=null}}else _=w=0;if(h>Uo&&(g=Math.min(Math.abs(c-n)/2,+i.apply(this,arguments)))>.001){v=c>n^p?0:1;var T=g,R=g;if(Fo>h){var D=null==S?[_,w]:null==x?[m,M]:Re([m,M],[S,k],[x,b],[_,w]),P=m-D[0],U=M-D[1],j=x-D[0],F=b-D[1],H=1/Math.sin(Math.acos((P*j+U*F)/(Math.sqrt(P*P+U*U)*Math.sqrt(j*j+F*F)))/2),O=Math.sqrt(D[0]*D[0]+D[1]*D[1]);R=Math.min(g,(n-O)/(H-1)),T=Math.min(g,(c-O)/(H+1))}if(null!=x){var I=mu(null==S?[_,w]:[S,k],[m,M],c,T,p),Y=mu([x,b],[_,w],c,T,p);g===T?A.push("M",I[0],"A",T,",",T," 0 0,",v," ",I[1],"A",c,",",c," 0 ",1-p^yu(I[1][0],I[1][1],Y[1][0],Y[1][1]),",",p," ",Y[1],"A",T,",",T," 0 0,",v," ",Y[0]):A.push("M",I[0],"A",T,",",T," 0 1,",v," ",Y[0])}else A.push("M",m,",",M);if(null!=S){var Z=mu([m,M],[S,k],n,-R,p),V=mu([_,w],null==x?[m,M]:[x,b],n,-R,p);g===R?A.push("L",V[0],"A",R,",",R," 0 0,",v," ",V[1],"A",n,",",n," 0 ",p^yu(V[1][0],V[1][1],Z[1][0],Z[1][1]),",",1-p," ",Z[1],"A",R,",",R," 0 0,",v," ",Z[0]):A.push("L",V[0],"A",R,",",R," 0 0,",v," ",Z[0])}else A.push("L",_,",",w)}else A.push("M",m,",",M),null!=x&&A.push("A",c,",",c," 0 ",C,",",p," ",x,",",b),A.push("L",_,",",w),null!=S&&A.push("A",n,",",n," 0 ",L,",",1-p," ",S,",",k);return A.push("Z"),A.join("")}function t(n,t){return"M0,"+n+"A"+n+","+n+" 0 1,"+t+" 0,"+-n+"A"+n+","+n+" 0 1,"+t+" 0,"+n}var e=hu,r=pu,i=su,u=ql,o=gu,a=vu,l=du;return n.innerRadius=function(t){return arguments.length?(e=En(t),n):e},n.outerRadius=function(t){return arguments.length?(r=En(t),n):r},n.cornerRadius=function(t){return arguments.length?(i=En(t),n):i},n.padRadius=function(t){return arguments.length?(u=t==ql?ql:En(t),n):u},n.startAngle=function(t){return arguments.length?(o=En(t),n):o},n.endAngle=function(t){return arguments.length?(a=En(t),n):a},n.padAngle=function(t){return arguments.length?(l=En(t),n):l},n.centroid=function(){var n=(+e.apply(this,arguments)+ +r.apply(this,arguments))/2,t=(+o.apply(this,arguments)+ +a.apply(this,arguments))/2-Io;return[Math.cos(t)*n,Math.sin(t)*n]},n};var ql="auto";ao.svg.line=function(){return Mu(m)};var Tl=ao.map({linear:xu,"linear-closed":bu,step:_u,"step-before":wu,"step-after":Su,basis:zu,"basis-open":Lu,"basis-closed":qu,bundle:Tu,cardinal:Eu,"cardinal-open":ku,"cardinal-closed":Nu,monotone:Fu});Tl.forEach(function(n,t){t.key=n,t.closed=/-closed$/.test(n)});var Rl=[0,2/3,1/3,0],Dl=[0,1/3,2/3,0],Pl=[0,1/6,2/3,1/6];ao.svg.line.radial=function(){var n=Mu(Hu);return n.radius=n.x,delete n.x,n.angle=n.y,delete n.y,n},wu.reverse=Su,Su.reverse=wu,ao.svg.area=function(){return Ou(m)},ao.svg.area.radial=function(){var n=Ou(Hu);return n.radius=n.x,delete n.x,n.innerRadius=n.x0,delete n.x0,n.outerRadius=n.x1,delete n.x1,n.angle=n.y,delete n.y,n.startAngle=n.y0,delete n.y0,n.endAngle=n.y1,delete n.y1,n},ao.svg.chord=function(){function n(n,a){var l=t(this,u,n,a),c=t(this,o,n,a);return"M"+l.p0+r(l.r,l.p1,l.a1-l.a0)+(e(l,c)?i(l.r,l.p1,l.r,l.p0):i(l.r,l.p1,c.r,c.p0)+r(c.r,c.p1,c.a1-c.a0)+i(c.r,c.p1,l.r,l.p0))+"Z"}function t(n,t,e,r){var i=t.call(n,e,r),u=a.call(n,i,r),o=l.call(n,i,r)-Io,f=c.call(n,i,r)-Io;return{r:u,a0:o,a1:f,p0:[u*Math.cos(o),u*Math.sin(o)],p1:[u*Math.cos(f),u*Math.sin(f)]}}function e(n,t){return n.a0==t.a0&&n.a1==t.a1}function r(n,t,e){return"A"+n+","+n+" 0 "+ +(e>Fo)+",1 "+t}function i(n,t,e,r){return"Q 0,0 "+r}var u=Me,o=xe,a=Iu,l=gu,c=vu;return n.radius=function(t){return arguments.length?(a=En(t),n):a},n.source=function(t){return arguments.length?(u=En(t),n):u},n.target=function(t){return arguments.length?(o=En(t),n):o},n.startAngle=function(t){return arguments.length?(l=En(t),n):l},n.endAngle=function(t){return arguments.length?(c=En(t),n):c},n},ao.svg.diagonal=function(){function n(n,i){var u=t.call(this,n,i),o=e.call(this,n,i),a=(u.y+o.y)/2,l=[u,{x:u.x,y:a},{x:o.x,y:a},o];return l=l.map(r),"M"+l[0]+"C"+l[1]+" "+l[2]+" "+l[3]}var t=Me,e=xe,r=Yu;return n.source=function(e){return arguments.length?(t=En(e),n):t},n.target=function(t){return arguments.length?(e=En(t),n):e},n.projection=function(t){return arguments.length?(r=t,n):r},n},ao.svg.diagonal.radial=function(){var n=ao.svg.diagonal(),t=Yu,e=n.projection;return n.projection=function(n){return arguments.length?e(Zu(t=n)):t},n},ao.svg.symbol=function(){function n(n,r){return(Ul.get(t.call(this,n,r))||$u)(e.call(this,n,r))}var t=Xu,e=Vu;return n.type=function(e){return arguments.length?(t=En(e),n):t},n.size=function(t){return arguments.length?(e=En(t),n):e},n};var Ul=ao.map({circle:$u,cross:function(n){var t=Math.sqrt(n/5)/2;return"M"+-3*t+","+-t+"H"+-t+"V"+-3*t+"H"+t+"V"+-t+"H"+3*t+"V"+t+"H"+t+"V"+3*t+"H"+-t+"V"+t+"H"+-3*t+"Z"},diamond:function(n){var t=Math.sqrt(n/(2*Fl)),e=t*Fl;return"M0,"+-t+"L"+e+",0 0,"+t+" "+-e+",0Z"},square:function(n){var t=Math.sqrt(n)/2;return"M"+-t+","+-t+"L"+t+","+-t+" "+t+","+t+" "+-t+","+t+"Z"},"triangle-down":function(n){var t=Math.sqrt(n/jl),e=t*jl/2;return"M0,"+e+"L"+t+","+-e+" "+-t+","+-e+"Z"},"triangle-up":function(n){var t=Math.sqrt(n/jl),e=t*jl/2;return"M0,"+-e+"L"+t+","+e+" "+-t+","+e+"Z"}});ao.svg.symbolTypes=Ul.keys();var jl=Math.sqrt(3),Fl=Math.tan(30*Yo);Co.transition=function(n){for(var t,e,r=Hl||++Zl,i=Ku(n),u=[],o=Ol||{time:Date.now(),ease:Nr,delay:0,duration:250},a=-1,l=this.length;++a<l;){u.push(t=[]);for(var c=this[a],f=-1,s=c.length;++f<s;)(e=c[f])&&Qu(e,f,i,r,o),t.push(e)}return Wu(u,i,r)},Co.interrupt=function(n){return this.each(null==n?Il:Bu(Ku(n)))};var Hl,Ol,Il=Bu(Ku()),Yl=[],Zl=0;Yl.call=Co.call,Yl.empty=Co.empty,Yl.node=Co.node,Yl.size=Co.size,ao.transition=function(n,t){return n&&n.transition?Hl?n.transition(t):n:ao.selection().transition(n)},ao.transition.prototype=Yl,Yl.select=function(n){var t,e,r,i=this.id,u=this.namespace,o=[];n=A(n);for(var a=-1,l=this.length;++a<l;){o.push(t=[]);for(var c=this[a],f=-1,s=c.length;++f<s;)(r=c[f])&&(e=n.call(r,r.__data__,f,a))?("__data__"in r&&(e.__data__=r.__data__),Qu(e,f,u,i,r[u][i]),t.push(e)):t.push(null)}return Wu(o,u,i)},Yl.selectAll=function(n){var t,e,r,i,u,o=this.id,a=this.namespace,l=[];n=C(n);for(var c=-1,f=this.length;++c<f;)for(var s=this[c],h=-1,p=s.length;++h<p;)if(r=s[h]){u=r[a][o],e=n.call(r,r.__data__,h,c),l.push(t=[]);for(var g=-1,v=e.length;++g<v;)(i=e[g])&&Qu(i,g,a,o,u),t.push(i)}return Wu(l,a,o)},Yl.filter=function(n){var t,e,r,i=[];"function"!=typeof n&&(n=O(n));for(var u=0,o=this.length;o>u;u++){i.push(t=[]);for(var e=this[u],a=0,l=e.length;l>a;a++)(r=e[a])&&n.call(r,r.__data__,a,u)&&t.push(r)}return Wu(i,this.namespace,this.id)},Yl.tween=function(n,t){var e=this.id,r=this.namespace;return arguments.length<2?this.node()[r][e].tween.get(n):Y(this,null==t?function(t){t[r][e].tween.remove(n)}:function(i){i[r][e].tween.set(n,t)})},Yl.attr=function(n,t){function e(){this.removeAttribute(a)}function r(){this.removeAttributeNS(a.space,a.local)}function i(n){return null==n?e:(n+="",function(){var t,e=this.getAttribute(a);return e!==n&&(t=o(e,n),function(n){this.setAttribute(a,t(n))})})}function u(n){return null==n?r:(n+="",function(){var t,e=this.getAttributeNS(a.space,a.local);return e!==n&&(t=o(e,n),function(n){this.setAttributeNS(a.space,a.local,t(n))})})}if(arguments.length<2){for(t in n)this.attr(t,n[t]);return this}var o="transform"==n?$r:Mr,a=ao.ns.qualify(n);return Ju(this,"attr."+n,t,a.local?u:i)},Yl.attrTween=function(n,t){function e(n,e){var r=t.call(this,n,e,this.getAttribute(i));return r&&function(n){this.setAttribute(i,r(n))}}function r(n,e){var r=t.call(this,n,e,this.getAttributeNS(i.space,i.local));return r&&function(n){this.setAttributeNS(i.space,i.local,r(n))}}var i=ao.ns.qualify(n);return this.tween("attr."+n,i.local?r:e)},Yl.style=function(n,e,r){function i(){this.style.removeProperty(n)}function u(e){return null==e?i:(e+="",function(){var i,u=t(this).getComputedStyle(this,null).getPropertyValue(n);return u!==e&&(i=Mr(u,e),function(t){this.style.setProperty(n,i(t),r)})})}var o=arguments.length;if(3>o){if("string"!=typeof n){2>o&&(e="");for(r in n)this.style(r,n[r],e);return this}r=""}return Ju(this,"style."+n,e,u)},Yl.styleTween=function(n,e,r){function i(i,u){var o=e.call(this,i,u,t(this).getComputedStyle(this,null).getPropertyValue(n));return o&&function(t){this.style.setProperty(n,o(t),r)}}return arguments.length<3&&(r=""),this.tween("style."+n,i)},Yl.text=function(n){return Ju(this,"text",n,Gu)},Yl.remove=function(){var n=this.namespace;return this.each("end.transition",function(){var t;this[n].count<2&&(t=this.parentNode)&&t.removeChild(this)})},Yl.ease=function(n){var t=this.id,e=this.namespace;return arguments.length<1?this.node()[e][t].ease:("function"!=typeof n&&(n=ao.ease.apply(ao,arguments)),Y(this,function(r){r[e][t].ease=n}))},Yl.delay=function(n){var t=this.id,e=this.namespace;return arguments.length<1?this.node()[e][t].delay:Y(this,"function"==typeof n?function(r,i,u){r[e][t].delay=+n.call(r,r.__data__,i,u)}:(n=+n,function(r){r[e][t].delay=n}))},Yl.duration=function(n){var t=this.id,e=this.namespace;return arguments.length<1?this.node()[e][t].duration:Y(this,"function"==typeof n?function(r,i,u){r[e][t].duration=Math.max(1,n.call(r,r.__data__,i,u))}:(n=Math.max(1,n),function(r){r[e][t].duration=n}))},Yl.each=function(n,t){var e=this.id,r=this.namespace;if(arguments.length<2){var i=Ol,u=Hl;try{Hl=e,Y(this,function(t,i,u){Ol=t[r][e],n.call(t,t.__data__,i,u)})}finally{Ol=i,Hl=u}}else Y(this,function(i){var u=i[r][e];(u.event||(u.event=ao.dispatch("start","end","interrupt"))).on(n,t)});return this},Yl.transition=function(){for(var n,t,e,r,i=this.id,u=++Zl,o=this.namespace,a=[],l=0,c=this.length;c>l;l++){a.push(n=[]);for(var t=this[l],f=0,s=t.length;s>f;f++)(e=t[f])&&(r=e[o][i],Qu(e,f,o,u,{time:r.time,ease:r.ease,delay:r.delay+r.duration,duration:r.duration})),n.push(e)}return Wu(a,o,u)},ao.svg.axis=function(){function n(n){n.each(function(){var n,c=ao.select(this),f=this.__chart__||e,s=this.__chart__=e.copy(),h=null==l?s.ticks?s.ticks.apply(s,a):s.domain():l,p=null==t?s.tickFormat?s.tickFormat.apply(s,a):m:t,g=c.selectAll(".tick").data(h,s),v=g.enter().insert("g",".domain").attr("class","tick").style("opacity",Uo),d=ao.transition(g.exit()).style("opacity",Uo).remove(),y=ao.transition(g.order()).style("opacity",1),M=Math.max(i,0)+o,x=Zi(s),b=c.selectAll(".domain").data([0]),_=(b.enter().append("path").attr("class","domain"),ao.transition(b));v.append("line"),v.append("text");var w,S,k,N,E=v.select("line"),A=y.select("line"),C=g.select("text").text(p),z=v.select("text"),L=y.select("text"),q="top"===r||"left"===r?-1:1;if("bottom"===r||"top"===r?(n=no,w="x",k="y",S="x2",N="y2",C.attr("dy",0>q?"0em":".71em").style("text-anchor","middle"),_.attr("d","M"+x[0]+","+q*u+"V0H"+x[1]+"V"+q*u)):(n=to,w="y",k="x",S="y2",N="x2",C.attr("dy",".32em").style("text-anchor",0>q?"end":"start"),_.attr("d","M"+q*u+","+x[0]+"H0V"+x[1]+"H"+q*u)),E.attr(N,q*i),z.attr(k,q*M),A.attr(S,0).attr(N,q*i),L.attr(w,0).attr(k,q*M),s.rangeBand){var T=s,R=T.rangeBand()/2;f=s=function(n){return T(n)+R}}else f.rangeBand?f=s:d.call(n,s,f);v.call(n,f,s),y.call(n,s,s)})}var t,e=ao.scale.linear(),r=Vl,i=6,u=6,o=3,a=[10],l=null;return n.scale=function(t){return arguments.length?(e=t,n):e},n.orient=function(t){return arguments.length?(r=t in Xl?t+"":Vl,n):r},n.ticks=function(){return arguments.length?(a=co(arguments),n):a},n.tickValues=function(t){return arguments.length?(l=t,n):l},n.tickFormat=function(e){return arguments.length?(t=e,n):t},n.tickSize=function(t){var e=arguments.length;return e?(i=+t,u=+arguments[e-1],n):i},n.innerTickSize=function(t){return arguments.length?(i=+t,n):i},n.outerTickSize=function(t){return arguments.length?(u=+t,n):u},n.tickPadding=function(t){return arguments.length?(o=+t,n):o},n.tickSubdivide=function(){return arguments.length&&n},n};var Vl="bottom",Xl={top:1,right:1,bottom:1,left:1};ao.svg.brush=function(){function n(t){t.each(function(){var t=ao.select(this).style("pointer-events","all").style("-webkit-tap-highlight-color","rgba(0,0,0,0)").on("mousedown.brush",u).on("touchstart.brush",u),o=t.selectAll(".background").data([0]);o.enter().append("rect").attr("class","background").style("visibility","hidden").style("cursor","crosshair"),t.selectAll(".extent").data([0]).enter().append("rect").attr("class","extent").style("cursor","move");var a=t.selectAll(".resize").data(v,m);a.exit().remove(),a.enter().append("g").attr("class",function(n){return"resize "+n}).style("cursor",function(n){return $l[n]}).append("rect").attr("x",function(n){return/[ew]$/.test(n)?-3:null}).attr("y",function(n){return/^[ns]/.test(n)?-3:null}).attr("width",6).attr("height",6).style("visibility","hidden"),a.style("display",n.empty()?"none":null);var l,s=ao.transition(t),h=ao.transition(o);c&&(l=Zi(c),h.attr("x",l[0]).attr("width",l[1]-l[0]),r(s)),f&&(l=Zi(f),h.attr("y",l[0]).attr("height",l[1]-l[0]),i(s)),e(s)})}function e(n){n.selectAll(".resize").attr("transform",function(n){return"translate("+s[+/e$/.test(n)]+","+h[+/^s/.test(n)]+")"})}function r(n){n.select(".extent").attr("x",s[0]),n.selectAll(".extent,.n>rect,.s>rect").attr("width",s[1]-s[0])}function i(n){n.select(".extent").attr("y",h[0]),n.selectAll(".extent,.e>rect,.w>rect").attr("height",h[1]-h[0])}function u(){function u(){32==ao.event.keyCode&&(C||(M=null,L[0]-=s[1],L[1]-=h[1],C=2),S())}function v(){32==ao.event.keyCode&&2==C&&(L[0]+=s[1],L[1]+=h[1],C=0,S())}function d(){var n=ao.mouse(b),t=!1;x&&(n[0]+=x[0],n[1]+=x[1]),C||(ao.event.altKey?(M||(M=[(s[0]+s[1])/2,(h[0]+h[1])/2]),L[0]=s[+(n[0]<M[0])],L[1]=h[+(n[1]<M[1])]):M=null),E&&y(n,c,0)&&(r(k),t=!0),A&&y(n,f,1)&&(i(k),t=!0),t&&(e(k),w({type:"brush",mode:C?"move":"resize"}))}function y(n,t,e){var r,i,u=Zi(t),l=u[0],c=u[1],f=L[e],v=e?h:s,d=v[1]-v[0];return C&&(l-=f,c-=d+f),r=(e?g:p)?Math.max(l,Math.min(c,n[e])):n[e],C?i=(r+=f)+d:(M&&(f=Math.max(l,Math.min(c,2*M[e]-r))),r>f?(i=r,r=f):i=f),v[0]!=r||v[1]!=i?(e?a=null:o=null,v[0]=r,v[1]=i,!0):void 0}function m(){d(),k.style("pointer-events","all").selectAll(".resize").style("display",n.empty()?"none":null),ao.select("body").style("cursor",null),q.on("mousemove.brush",null).on("mouseup.brush",null).on("touchmove.brush",null).on("touchend.brush",null).on("keydown.brush",null).on("keyup.brush",null),z(),w({type:"brushend"})}var M,x,b=this,_=ao.select(ao.event.target),w=l.of(b,arguments),k=ao.select(b),N=_.datum(),E=!/^(n|s)$/.test(N)&&c,A=!/^(e|w)$/.test(N)&&f,C=_.classed("extent"),z=W(b),L=ao.mouse(b),q=ao.select(t(b)).on("keydown.brush",u).on("keyup.brush",v);if(ao.event.changedTouches?q.on("touchmove.brush",d).on("touchend.brush",m):q.on("mousemove.brush",d).on("mouseup.brush",m),k.interrupt().selectAll("*").interrupt(),C)L[0]=s[0]-L[0],L[1]=h[0]-L[1];else if(N){var T=+/w$/.test(N),R=+/^n/.test(N);x=[s[1-T]-L[0],h[1-R]-L[1]],L[0]=s[T],L[1]=h[R]}else ao.event.altKey&&(M=L.slice());k.style("pointer-events","none").selectAll(".resize").style("display",null),ao.select("body").style("cursor",_.style("cursor")),w({type:"brushstart"}),d()}var o,a,l=N(n,"brushstart","brush","brushend"),c=null,f=null,s=[0,0],h=[0,0],p=!0,g=!0,v=Bl[0];return n.event=function(n){n.each(function(){var n=l.of(this,arguments),t={x:s,y:h,i:o,j:a},e=this.__chart__||t;this.__chart__=t,Hl?ao.select(this).transition().each("start.brush",function(){o=e.i,a=e.j,s=e.x,h=e.y,n({type:"brushstart"})}).tween("brush:brush",function(){var e=xr(s,t.x),r=xr(h,t.y);return o=a=null,function(i){s=t.x=e(i),h=t.y=r(i),n({type:"brush",mode:"resize"})}}).each("end.brush",function(){o=t.i,a=t.j,n({type:"brush",mode:"resize"}),n({type:"brushend"})}):(n({type:"brushstart"}),n({type:"brush",mode:"resize"}),n({type:"brushend"}))})},n.x=function(t){return arguments.length?(c=t,v=Bl[!c<<1|!f],n):c},n.y=function(t){return arguments.length?(f=t,v=Bl[!c<<1|!f],n):f},n.clamp=function(t){return arguments.length?(c&&f?(p=!!t[0],g=!!t[1]):c?p=!!t:f&&(g=!!t),n):c&&f?[p,g]:c?p:f?g:null},n.extent=function(t){var e,r,i,u,l;return arguments.length?(c&&(e=t[0],r=t[1],f&&(e=e[0],r=r[0]),o=[e,r],c.invert&&(e=c(e),r=c(r)),e>r&&(l=e,e=r,r=l),e==s[0]&&r==s[1]||(s=[e,r])),f&&(i=t[0],u=t[1],c&&(i=i[1],u=u[1]),a=[i,u],f.invert&&(i=f(i),u=f(u)),i>u&&(l=i,i=u,u=l),i==h[0]&&u==h[1]||(h=[i,u])),n):(c&&(o?(e=o[0],r=o[1]):(e=s[0],r=s[1],c.invert&&(e=c.invert(e),r=c.invert(r)),e>r&&(l=e,e=r,r=l))),f&&(a?(i=a[0],u=a[1]):(i=h[0],u=h[1],f.invert&&(i=f.invert(i),u=f.invert(u)),i>u&&(l=i,i=u,u=l))),c&&f?[[e,i],[r,u]]:c?[e,r]:f&&[i,u])},n.clear=function(){return n.empty()||(s=[0,0],h=[0,0],o=a=null),n},n.empty=function(){return!!c&&s[0]==s[1]||!!f&&h[0]==h[1]},ao.rebind(n,l,"on")};var $l={n:"ns-resize",e:"ew-resize",s:"ns-resize",w:"ew-resize",nw:"nwse-resize",ne:"nesw-resize",se:"nwse-resize",sw:"nesw-resize"},Bl=[["n","e","s","w","nw","ne","se","sw"],["e","w"],["n","s"],[]],Wl=ga.format=xa.timeFormat,Jl=Wl.utc,Gl=Jl("%Y-%m-%dT%H:%M:%S.%LZ");Wl.iso=Date.prototype.toISOString&&+new Date("2000-01-01T00:00:00.000Z")?eo:Gl,eo.parse=function(n){var t=new Date(n);return isNaN(t)?null:t},eo.toString=Gl.toString,ga.second=On(function(n){return new va(1e3*Math.floor(n/1e3))},function(n,t){n.setTime(n.getTime()+1e3*Math.floor(t))},function(n){return n.getSeconds()}),ga.seconds=ga.second.range,ga.seconds.utc=ga.second.utc.range,ga.minute=On(function(n){return new va(6e4*Math.floor(n/6e4))},function(n,t){n.setTime(n.getTime()+6e4*Math.floor(t))},function(n){return n.getMinutes()}),ga.minutes=ga.minute.range,ga.minutes.utc=ga.minute.utc.range,ga.hour=On(function(n){var t=n.getTimezoneOffset()/60;return new va(36e5*(Math.floor(n/36e5-t)+t))},function(n,t){n.setTime(n.getTime()+36e5*Math.floor(t))},function(n){return n.getHours()}),ga.hours=ga.hour.range,ga.hours.utc=ga.hour.utc.range,ga.month=On(function(n){return n=ga.day(n),n.setDate(1),n},function(n,t){n.setMonth(n.getMonth()+t)},function(n){return n.getMonth()}),ga.months=ga.month.range,ga.months.utc=ga.month.utc.range;var Kl=[1e3,5e3,15e3,3e4,6e4,3e5,9e5,18e5,36e5,108e5,216e5,432e5,864e5,1728e5,6048e5,2592e6,7776e6,31536e6],Ql=[[ga.second,1],[ga.second,5],[ga.second,15],[ga.second,30],[ga.minute,1],[ga.minute,5],[ga.minute,15],[ga.minute,30],[ga.hour,1],[ga.hour,3],[ga.hour,6],[ga.hour,12],[ga.day,1],[ga.day,2],[ga.week,1],[ga.month,1],[ga.month,3],[ga.year,1]],nc=Wl.multi([[".%L",function(n){return n.getMilliseconds()}],[":%S",function(n){return n.getSeconds()}],["%I:%M",function(n){return n.getMinutes()}],["%I %p",function(n){return n.getHours()}],["%a %d",function(n){return n.getDay()&&1!=n.getDate()}],["%b %d",function(n){return 1!=n.getDate()}],["%B",function(n){return n.getMonth()}],["%Y",zt]]),tc={range:function(n,t,e){return ao.range(Math.ceil(n/e)*e,+t,e).map(io)},floor:m,ceil:m};Ql.year=ga.year,ga.scale=function(){return ro(ao.scale.linear(),Ql,nc)};var ec=Ql.map(function(n){return[n[0].utc,n[1]]}),rc=Jl.multi([[".%L",function(n){return n.getUTCMilliseconds()}],[":%S",function(n){return n.getUTCSeconds()}],["%I:%M",function(n){return n.getUTCMinutes()}],["%I %p",function(n){return n.getUTCHours()}],["%a %d",function(n){return n.getUTCDay()&&1!=n.getUTCDate()}],["%b %d",function(n){return 1!=n.getUTCDate()}],["%B",function(n){return n.getUTCMonth()}],["%Y",zt]]);ec.year=ga.year.utc,ga.scale.utc=function(){return ro(ao.scale.linear(),ec,rc)},ao.text=An(function(n){return n.responseText}),ao.json=function(n,t){return Cn(n,"application/json",uo,t)},ao.html=function(n,t){return Cn(n,"text/html",oo,t)},ao.xml=An(function(n){return n.responseXML}),"function"==typeof define&&define.amd?(this.d3=ao,define(ao)):"object"==typeof module&&module.exports?module.exports=ao:this.d3=ao}(); $(function() {
33782 var $window = $(window)
33783 , $top_link = $('#toplink')
33784 , $body = $('body, html')
33785 , offset = $('#code').offset().top
33786 , hidePopover = function ($target) {
33787 $target.data('popover-hover', false);
33788
33789 setTimeout(function () {
33790 if (!$target.data('popover-hover')) {
33791 $target.popover('hide');
33792 }
33793 }, 300);
33794 };
33795
33796 $top_link.hide().click(function(event) {
33797 event.preventDefault();
33798 $body.animate({scrollTop:0}, 800);
33799 });
33800
33801 $window.scroll(function() {
33802 if($window.scrollTop() > offset) {
33803 $top_link.fadeIn();
33804 } else {
33805 $top_link.fadeOut();
33806 }
33807 }).scroll();
33808
33809 $('.popin')
33810 .popover({trigger: 'manual'})
33811 .on({
33812 'mouseenter.popover': function () {
33813 var $target = $(this);
33814 var $container = $target.children().first();
33815
33816 $target.data('popover-hover', true);
33817
33818 // popover already displayed
33819 if ($target.next('.popover').length) {
33820 return;
33821 }
33822
33823 // show the popover
33824 $container.popover('show');
33825
33826 // register mouse events on the popover
33827 $target.next('.popover:not(.popover-initialized)')
33828 .on({
33829 'mouseenter': function () {
33830 $target.data('popover-hover', true);
33831 },
33832 'mouseleave': function () {
33833 hidePopover($container);
33834 }
33835 })
33836 .addClass('popover-initialized');
33837 },
33838 'mouseleave.popover': function () {
33839 hidePopover($(this).children().first());
33840 }
33841 });
33842 });
33843 /*! jQuery v3.6.1 | (c) OpenJS Foundation and other contributors | jquery.org/license */
33844 !function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(C,e){"use strict";var t=[],r=Object.getPrototypeOf,s=t.slice,g=t.flat?function(e){return t.flat.call(e)}:function(e){return t.concat.apply([],e)},u=t.push,i=t.indexOf,n={},o=n.toString,y=n.hasOwnProperty,a=y.toString,l=a.call(Object),v={},m=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType&&"function"!=typeof e.item},x=function(e){return null!=e&&e===e.window},E=C.document,c={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||E).createElement("script");if(o.text=e,t)for(r in c)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.6.1",S=function(e,t){return new S.fn.init(e,t)};function p(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!m(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0<t&&t-1 in e)}S.fn=S.prototype={jquery:f,constructor:S,length:0,toArray:function(){return s.call(this)},get:function(e){return null==e?s.call(this):e<0?this[e+this.length]:this[e]},pushStack:function(e){var t=S.merge(this.constructor(),e);return t.prevObject=this,t},each:function(e){return S.each(this,e)},map:function(n){return this.pushStack(S.map(this,function(e,t){return n.call(e,t,e)}))},slice:function(){return this.pushStack(s.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},even:function(){return this.pushStack(S.grep(this,function(e,t){return(t+1)%2}))},odd:function(){return this.pushStack(S.grep(this,function(e,t){return t%2}))},eq:function(e){var t=this.length,n=+e+(e<0?t:0);return this.pushStack(0<=n&&n<t?[this[n]]:[])},end:function(){return this.prevObject||this.constructor()},push:u,sort:t.sort,splice:t.splice},S.extend=S.fn.extend=function(){var e,t,n,r,i,o,a=arguments[0]||{},s=1,u=arguments.length,l=!1;for("boolean"==typeof a&&(l=a,a=arguments[s]||{},s++),"object"==typeof a||m(a)||(a={}),s===u&&(a=this,s--);s<u;s++)if(null!=(e=arguments[s]))for(t in e)r=e[t],"__proto__"!==t&&a!==r&&(l&&r&&(S.isPlainObject(r)||(i=Array.isArray(r)))?(n=a[t],o=i&&!Array.isArray(n)?[]:i||S.isPlainObject(n)?n:{},i=!1,a[t]=S.extend(l,o,r)):void 0!==r&&(a[t]=r));return a},S.extend({expando:"jQuery"+(f+Math.random()).replace(/\D/g,""),isReady:!0,error:function(e){throw new Error(e)},noop:function(){},isPlainObject:function(e){var t,n;return!(!e||"[object Object]"!==o.call(e))&&(!(t=r(e))||"function"==typeof(n=y.call(t,"constructor")&&t.constructor)&&a.call(n)===l)},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},globalEval:function(e,t,n){b(e,{nonce:t&&t.nonce},n)},each:function(e,t){var n,r=0;if(p(e)){for(n=e.length;r<n;r++)if(!1===t.call(e[r],r,e[r]))break}else for(r in e)if(!1===t.call(e[r],r,e[r]))break;return e},makeArray:function(e,t){var n=t||[];return null!=e&&(p(Object(e))?S.merge(n,"string"==typeof e?[e]:e):u.call(n,e)),n},inArray:function(e,t,n){return null==t?-1:i.call(t,e,n)},merge:function(e,t){for(var n=+t.length,r=0,i=e.length;r<n;r++)e[i++]=t[r];return e.length=i,e},grep:function(e,t,n){for(var r=[],i=0,o=e.length,a=!n;i<o;i++)!t(e[i],i)!==a&&r.push(e[i]);return r},map:function(e,t,n){var r,i,o=0,a=[];if(p(e))for(r=e.length;o<r;o++)null!=(i=t(e[o],o,n))&&a.push(i);else for(o in e)null!=(i=t(e[o],o,n))&&a.push(i);return g(a)},guid:1,support:v}),"function"==typeof Symbol&&(S.fn[Symbol.iterator]=t[Symbol.iterator]),S.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(e,t){n["[object "+t+"]"]=t.toLowerCase()});var d=function(n){var e,d,b,o,i,h,f,g,w,u,l,T,C,a,E,y,s,c,v,S="sizzle"+1*new Date,p=n.document,k=0,r=0,m=ue(),x=ue(),A=ue(),N=ue(),j=function(e,t){return e===t&&(l=!0),0},D={}.hasOwnProperty,t=[],q=t.pop,L=t.push,H=t.push,O=t.slice,P=function(e,t){for(var n=0,r=e.length;n<r;n++)if(e[n]===t)return n;return-1},R="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",M="[\\x20\\t\\r\\n\\f]",I="(?:\\\\[\\da-fA-F]{1,6}"+M+"?|\\\\[^\\r\\n\\f]|[\\w-]|[^\0-\\x7f])+",W="\\["+M+"*("+I+")(?:"+M+"*([*^$|!~]?=)"+M+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+I+"))|)"+M+"*\\]",F=":("+I+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+W+")*)|.*)\\)|)",$=new RegExp(M+"+","g"),B=new RegExp("^"+M+"+|((?:^|[^\\\\])(?:\\\\.)*)"+M+"+$","g"),_=new RegExp("^"+M+"*,"+M+"*"),z=new RegExp("^"+M+"*([>+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp(F),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+F),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\[\\da-fA-F]{1,6}"+M+"?|\\\\([^\\r\\n\\f])","g"),ne=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(p.childNodes),p.childNodes),t[p.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&v(e,a)&&a.id===i)return n.push(a),n}else{if(u[2])return H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!N[t+" "]&&(!y||!y.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&(U.test(t)||z.test(t))){(f=ee.test(t)&&ve(e.parentNode)||e)===e&&d.scope||((s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=S)),o=(l=h(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+xe(l[o]);c=l.join(",")}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){N(t,!0)}finally{s===S&&e.removeAttribute("id")}}}return g(t.replace(B,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[S]=!0,e}function ce(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split("|"),r=n.length;while(r--)b.attrHandle[n[r]]=t}function pe(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function de(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function he(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function ge(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ye(a){return le(function(o){return o=+o,le(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function ve(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}for(e in d=se.support={},i=se.isXML=function(e){var t=e&&e.namespaceURI,n=e&&(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||"HTML")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:p;return r!=C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),p!=C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.scope=ce(function(e){return a.appendChild(e).appendChild(C.createElement("div")),"undefined"!=typeof e.querySelectorAll&&!e.querySelectorAll(":scope fieldset div").length}),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=S,!C.getElementsByName||!C.getElementsByName(S).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(te,ne);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],y=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){var t;a.appendChild(e).innerHTML="<a id='"+S+"'></a><select id='"+S+"-\r\\' msallowcapture=''><option selected=''></option></select>",e.querySelectorAll("[msallowcapture^='']").length&&y.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||y.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+S+"-]").length||y.push("~="),(t=C.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||y.push("\\["+M+"*name"+M+"*="+M+"*(?:''|\"\")"),e.querySelectorAll(":checked").length||y.push(":checked"),e.querySelectorAll("a#"+S+"+*").length||y.push(".#.+[+~]"),e.querySelectorAll("\\\f"),y.push("[\\r\\n\\f]")}),ce(function(e){e.innerHTML="<a href='' disabled='disabled'></a><select disabled='disabled'><option/></select>";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&y.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&y.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&y.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),y.push(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",F)}),y=y.length&&new RegExp(y.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),v=t||K.test(a.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},j=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e==C||e.ownerDocument==p&&v(p,e)?-1:t==C||t.ownerDocument==p&&v(p,t)?1:u?P(u,e)-P(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e==C?-1:t==C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?pe(a[r],s[r]):a[r]==p?-1:s[r]==p?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if(T(e),d.matchesSelector&&E&&!N[t+" "]&&(!s||!s.test(t))&&(!y||!y.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){N(t,!0)}return 0<se(t,C,null,[e]).length},se.contains=function(e,t){return(e.ownerDocument||e)!=C&&T(e),v(e,t)},se.attr=function(e,t){(e.ownerDocument||e)!=C&&T(e);var n=b.attrHandle[t.toLowerCase()],r=n&&D.call(b.attrHandle,t.toLowerCase())?n(e,t,!E):void 0;return void 0!==r?r:d.attributes||!E?e.getAttribute(t):(r=e.getAttributeNode(t))&&r.specified?r.value:null},se.escape=function(e){return(e+"").replace(re,ie)},se.error=function(e){throw new Error("Syntax error, unrecognized expression: "+e)},se.uniqueSort=function(e){var t,n=[],r=0,i=0;if(l=!d.detectDuplicates,u=!d.sortStable&&e.slice(0),e.sort(j),l){while(t=e[i++])t===e[i]&&(r=n.push(i));while(r--)e.splice(n[r],1)}return u=null,e},o=se.getText=function(e){var t,n="",r=0,i=e.nodeType;if(i){if(1===i||9===i||11===i){if("string"==typeof e.textContent)return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=o(e)}else if(3===i||4===i)return e.nodeValue}else while(t=e[r++])n+=o(t);return n},(b=se.selectors={cacheLength:50,createPseudo:le,match:G,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=h(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=m[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&m(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=se.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1<t.indexOf(i):"$="===r?i&&t.slice(-i.length)===i:"~="===r?-1<(" "+t.replace($," ")+" ").indexOf(i):"|="===r&&(t===i||t.slice(0,i.length+1)===i+"-"))}},CHILD:function(h,e,t,g,y){var v="nth"!==h.slice(0,3),m="last"!==h.slice(-4),x="of-type"===e;return 1===g&&0===y?function(e){return!!e.parentNode}:function(e,t,n){var r,i,o,a,s,u,l=v!==m?"nextSibling":"previousSibling",c=e.parentNode,f=x&&e.nodeName.toLowerCase(),p=!n&&!x,d=!1;if(c){if(v){while(l){a=e;while(a=a[l])if(x?a.nodeName.toLowerCase()===f:1===a.nodeType)return!1;u=l="only"===h&&!u&&"nextSibling"}return!0}if(u=[m?c.firstChild:c.lastChild],m&&p){d=(s=(r=(i=(o=(a=c)[S]||(a[S]={}))[a.uniqueID]||(o[a.uniqueID]={}))[h]||[])[0]===k&&r[1])&&r[2],a=s&&c.childNodes[s];while(a=++s&&a&&a[l]||(d=s=0)||u.pop())if(1===a.nodeType&&++d&&a===e){i[h]=[k,s,d];break}}else if(p&&(d=s=(r=(i=(o=(a=e)[S]||(a[S]={}))[a.uniqueID]||(o[a.uniqueID]={}))[h]||[])[0]===k&&r[1]),!1===d)while(a=++s&&a&&a[l]||(d=s=0)||u.pop())if((x?a.nodeName.toLowerCase()===f:1===a.nodeType)&&++d&&(p&&((i=(o=a[S]||(a[S]={}))[a.uniqueID]||(o[a.uniqueID]={}))[h]=[k,d]),a===e))break;return(d-=y)===g||d%g==0&&0<=d/g}}},PSEUDO:function(e,o){var t,a=b.pseudos[e]||b.setFilters[e.toLowerCase()]||se.error("unsupported pseudo: "+e);return a[S]?a(o):1<a.length?(t=[e,e,"",o],b.setFilters.hasOwnProperty(e.toLowerCase())?le(function(e,t){var n,r=a(e,o),i=r.length;while(i--)e[n=P(e,r[i])]=!(t[n]=r[i])}):function(e){return a(e,0,t)}):a}},pseudos:{not:le(function(e){var r=[],i=[],s=f(e.replace(B,"$1"));return s[S]?le(function(e,t,n,r){var i,o=s(e,null,r,[]),a=e.length;while(a--)(i=o[a])&&(e[a]=!(t[a]=i))}):function(e,t,n){return r[0]=e,s(r,null,n,i),r[0]=null,!i.pop()}}),has:le(function(t){return function(e){return 0<se(t,e).length}}),contains:le(function(t){return t=t.replace(te,ne),function(e){return-1<(e.textContent||o(e)).indexOf(t)}}),lang:le(function(n){return V.test(n||"")||se.error("unsupported lang: "+n),n=n.replace(te,ne).toLowerCase(),function(e){var t;do{if(t=E?e.lang:e.getAttribute("xml:lang")||e.getAttribute("lang"))return(t=t.toLowerCase())===n||0===t.indexOf(n+"-")}while((e=e.parentNode)&&1===e.nodeType);return!1}}),target:function(e){var t=n.location&&n.location.hash;return t&&t.slice(1)===e.id},root:function(e){return e===a},focus:function(e){return e===C.activeElement&&(!C.hasFocus||C.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:ge(!1),disabled:ge(!0),checked:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&!!e.checked||"option"===t&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,!0===e.selected},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeType<6)return!1;return!0},parent:function(e){return!b.pseudos.empty(e)},header:function(e){return J.test(e.nodeName)},input:function(e){return Q.test(e.nodeName)},button:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&"button"===e.type||"button"===t},text:function(e){var t;return"input"===e.nodeName.toLowerCase()&&"text"===e.type&&(null==(t=e.getAttribute("type"))||"text"===t.toLowerCase())},first:ye(function(){return[0]}),last:ye(function(e,t){return[t-1]}),eq:ye(function(e,t,n){return[n<0?n+t:n]}),even:ye(function(e,t){for(var n=0;n<t;n+=2)e.push(n);return e}),odd:ye(function(e,t){for(var n=1;n<t;n+=2)e.push(n);return e}),lt:ye(function(e,t,n){for(var r=n<0?n+t:t<n?t:n;0<=--r;)e.push(r);return e}),gt:ye(function(e,t,n){for(var r=n<0?n+t:n;++r<t;)e.push(r);return e})}}).pseudos.nth=b.pseudos.eq,{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})b.pseudos[e]=de(e);for(e in{submit:!0,reset:!0})b.pseudos[e]=he(e);function me(){}function xe(e){for(var t=0,n=e.length,r="";t<n;t++)r+=e[t].value;return r}function be(s,e,t){var u=e.dir,l=e.next,c=l||u,f=t&&"parentNode"===c,p=r++;return e.first?function(e,t,n){while(e=e[u])if(1===e.nodeType||f)return s(e,t,n);return!1}:function(e,t,n){var r,i,o,a=[k,p];if(n){while(e=e[u])if((1===e.nodeType||f)&&s(e,t,n))return!0}else while(e=e[u])if(1===e.nodeType||f)if(i=(o=e[S]||(e[S]={}))[e.uniqueID]||(o[e.uniqueID]={}),l&&l===e.nodeName.toLowerCase())e=e[u]||e;else{if((r=i[c])&&r[0]===k&&r[1]===p)return a[2]=r[2];if((i[c]=a)[2]=s(e,t,n))return!0}return!1}}function we(i){return 1<i.length?function(e,t,n){var r=i.length;while(r--)if(!i[r](e,t,n))return!1;return!0}:i[0]}function Te(e,t,n,r,i){for(var o,a=[],s=0,u=e.length,l=null!=t;s<u;s++)(o=e[s])&&(n&&!n(o,r,i)||(a.push(o),l&&t.push(s)));return a}function Ce(d,h,g,y,v,e){return y&&!y[S]&&(y=Ce(y)),v&&!v[S]&&(v=Ce(v,e)),le(function(e,t,n,r){var i,o,a,s=[],u=[],l=t.length,c=e||function(e,t,n){for(var r=0,i=t.length;r<i;r++)se(e,t[r],n);return n}(h||"*",n.nodeType?[n]:n,[]),f=!d||!e&&h?c:Te(c,s,d,n,r),p=g?v||(e?d:l||y)?[]:t:f;if(g&&g(f,p,n,r),y){i=Te(p,u),y(i,[],n,r),o=i.length;while(o--)(a=i[o])&&(p[u[o]]=!(f[u[o]]=a))}if(e){if(v||d){if(v){i=[],o=p.length;while(o--)(a=p[o])&&i.push(f[o]=a);v(null,p=[],i,r)}o=p.length;while(o--)(a=p[o])&&-1<(i=v?P(e,a):s[o])&&(e[i]=!(t[i]=a))}}else p=Te(p===t?p.splice(l,p.length):p),v?v(null,t,p,r):H.apply(t,p)})}function Ee(e){for(var i,t,n,r=e.length,o=b.relative[e[0].type],a=o||b.relative[" "],s=o?1:0,u=be(function(e){return e===i},a,!0),l=be(function(e){return-1<P(i,e)},a,!0),c=[function(e,t,n){var r=!o&&(n||t!==w)||((i=t).nodeType?u(e,t,n):l(e,t,n));return i=null,r}];s<r;s++)if(t=b.relative[e[s].type])c=[be(we(c),t)];else{if((t=b.filter[e[s].type].apply(null,e[s].matches))[S]){for(n=++s;n<r;n++)if(b.relative[e[n].type])break;return Ce(1<s&&we(c),1<s&&xe(e.slice(0,s-1).concat({value:" "===e[s-2].type?"*":""})).replace(B,"$1"),t,s<n&&Ee(e.slice(s,n)),n<r&&Ee(e=e.slice(n)),n<r&&xe(e))}c.push(t)}return we(c)}return me.prototype=b.filters=b.pseudos,b.setFilters=new me,h=se.tokenize=function(e,t){var n,r,i,o,a,s,u,l=x[e+" "];if(l)return t?0:l.slice(0);a=e,s=[],u=b.preFilter;while(a){for(o in n&&!(r=_.exec(a))||(r&&(a=a.slice(r[0].length)||a),s.push(i=[])),n=!1,(r=z.exec(a))&&(n=r.shift(),i.push({value:n,type:r[0].replace(B," ")}),a=a.slice(n.length)),b.filter)!(r=G[o].exec(a))||u[o]&&!(r=u[o](r))||(n=r.shift(),i.push({value:n,type:o,matches:r}),a=a.slice(n.length));if(!n)break}return t?a.length:a?se.error(e):x(e,s).slice(0)},f=se.compile=function(e,t){var n,y,v,m,x,r,i=[],o=[],a=A[e+" "];if(!a){t||(t=h(e)),n=t.length;while(n--)(a=Ee(t[n]))[S]?i.push(a):o.push(a);(a=A(e,(y=o,m=0<(v=i).length,x=0<y.length,r=function(e,t,n,r,i){var o,a,s,u=0,l="0",c=e&&[],f=[],p=w,d=e||x&&b.find.TAG("*",i),h=k+=null==p?1:Math.random()||.1,g=d.length;for(i&&(w=t==C||t||i);l!==g&&null!=(o=d[l]);l++){if(x&&o){a=0,t||o.ownerDocument==C||(T(o),n=!E);while(s=y[a++])if(s(o,t||C,n)){r.push(o);break}i&&(k=h)}m&&((o=!s&&o)&&u--,e&&c.push(o))}if(u+=l,m&&l!==u){a=0;while(s=v[a++])s(c,f,t,n);if(e){if(0<u)while(l--)c[l]||f[l]||(f[l]=q.call(r));f=Te(f)}H.apply(r,f),i&&!e&&0<f.length&&1<u+v.length&&se.uniqueSort(r)}return i&&(k=h,w=p),c},m?le(r):r))).selector=e}return a},g=se.select=function(e,t,n,r){var i,o,a,s,u,l="function"==typeof e&&e,c=!r&&h(e=l.selector||e);if(n=n||[],1===c.length){if(2<(o=c[0]=c[0].slice(0)).length&&"ID"===(a=o[0]).type&&9===t.nodeType&&E&&b.relative[o[1].type]){if(!(t=(b.find.ID(a.matches[0].replace(te,ne),t)||[])[0]))return n;l&&(t=t.parentNode),e=e.slice(o.shift().value.length)}i=G.needsContext.test(e)?0:o.length;while(i--){if(a=o[i],b.relative[s=a.type])break;if((u=b.find[s])&&(r=u(a.matches[0].replace(te,ne),ee.test(o[0].type)&&ve(t.parentNode)||t))){if(o.splice(i,1),!(e=r.length&&xe(o)))return H.apply(n,r),n;break}}}return(l||f(e,c))(r,t,!E,n,!t||ee.test(e)&&ve(t.parentNode)||t),n},d.sortStable=S.split("").sort(j).join("")===S,d.detectDuplicates=!!l,T(),d.sortDetached=ce(function(e){return 1&e.compareDocumentPosition(C.createElement("fieldset"))}),ce(function(e){return e.innerHTML="<a href='#'></a>","#"===e.firstChild.getAttribute("href")})||fe("type|href|height|width",function(e,t,n){if(!n)return e.getAttribute(t,"type"===t.toLowerCase()?1:2)}),d.attributes&&ce(function(e){return e.innerHTML="<input/>",e.firstChild.setAttribute("value",""),""===e.firstChild.getAttribute("value")})||fe("value",function(e,t,n){if(!n&&"input"===e.nodeName.toLowerCase())return e.defaultValue}),ce(function(e){return null==e.getAttribute("disabled")})||fe(R,function(e,t,n){var r;if(!n)return!0===e[t]?t.toLowerCase():(r=e.getAttributeNode(t))&&r.specified?r.value:null}),se}(C);S.find=d,S.expr=d.selectors,S.expr[":"]=S.expr.pseudos,S.uniqueSort=S.unique=d.uniqueSort,S.text=d.getText,S.isXMLDoc=d.isXML,S.contains=d.contains,S.escapeSelector=d.escape;var h=function(e,t,n){var r=[],i=void 0!==n;while((e=e[t])&&9!==e.nodeType)if(1===e.nodeType){if(i&&S(e).is(n))break;r.push(e)}return r},T=function(e,t){for(var n=[];e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n},k=S.expr.match.needsContext;function A(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()}var N=/^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function j(e,n,r){return m(n)?S.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?S.grep(e,function(e){return e===n!==r}):"string"!=typeof n?S.grep(e,function(e){return-1<i.call(n,e)!==r}):S.filter(n,e,r)}S.filter=function(e,t,n){var r=t[0];return n&&(e=":not("+e+")"),1===t.length&&1===r.nodeType?S.find.matchesSelector(r,e)?[r]:[]:S.find.matches(e,S.grep(t,function(e){return 1===e.nodeType}))},S.fn.extend({find:function(e){var t,n,r=this.length,i=this;if("string"!=typeof e)return this.pushStack(S(e).filter(function(){for(t=0;t<r;t++)if(S.contains(i[t],this))return!0}));for(n=this.pushStack([]),t=0;t<r;t++)S.find(e,i[t],n);return 1<r?S.uniqueSort(n):n},filter:function(e){return this.pushStack(j(this,e||[],!1))},not:function(e){return this.pushStack(j(this,e||[],!0))},is:function(e){return!!j(this,"string"==typeof e&&k.test(e)?S(e):e||[],!1).length}});var D,q=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/;(S.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||D,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:q.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof S?t[0]:t,S.merge(this,S.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),N.test(r[1])&&S.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(S):S.makeArray(e,this)}).prototype=S.fn,D=S(E);var L=/^(?:parents|prev(?:Until|All))/,H={children:!0,contents:!0,next:!0,prev:!0};function O(e,t){while((e=e[t])&&1!==e.nodeType);return e}S.fn.extend({has:function(e){var t=S(e,this),n=t.length;return this.filter(function(){for(var e=0;e<n;e++)if(S.contains(this,t[e]))return!0})},closest:function(e,t){var n,r=0,i=this.length,o=[],a="string"!=typeof e&&S(e);if(!k.test(e))for(;r<i;r++)for(n=this[r];n&&n!==t;n=n.parentNode)if(n.nodeType<11&&(a?-1<a.index(n):1===n.nodeType&&S.find.matchesSelector(n,e))){o.push(n);break}return this.pushStack(1<o.length?S.uniqueSort(o):o)},index:function(e){return e?"string"==typeof e?i.call(S(e),this[0]):i.call(this,e.jquery?e[0]:e):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,t){return this.pushStack(S.uniqueSort(S.merge(this.get(),S(e,t))))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}}),S.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return h(e,"parentNode")},parentsUntil:function(e,t,n){return h(e,"parentNode",n)},next:function(e){return O(e,"nextSibling")},prev:function(e){return O(e,"previousSibling")},nextAll:function(e){return h(e,"nextSibling")},prevAll:function(e){return h(e,"previousSibling")},nextUntil:function(e,t,n){return h(e,"nextSibling",n)},prevUntil:function(e,t,n){return h(e,"previousSibling",n)},siblings:function(e){return T((e.parentNode||{}).firstChild,e)},children:function(e){return T(e.firstChild)},contents:function(e){return null!=e.contentDocument&&r(e.contentDocument)?e.contentDocument:(A(e,"template")&&(e=e.content||e),S.merge([],e.childNodes))}},function(r,i){S.fn[r]=function(e,t){var n=S.map(this,i,e);return"Until"!==r.slice(-5)&&(t=e),t&&"string"==typeof t&&(n=S.filter(t,n)),1<this.length&&(H[r]||S.uniqueSort(n),L.test(r)&&n.reverse()),this.pushStack(n)}});var P=/[^\x20\t\r\n\f]+/g;function R(e){return e}function M(e){throw e}function I(e,t,n,r){var i;try{e&&m(i=e.promise)?i.call(e).done(t).fail(n):e&&m(i=e.then)?i.call(e,t,n):t.apply(void 0,[e].slice(r))}catch(e){n.apply(void 0,[e])}}S.Callbacks=function(r){var e,n;r="string"==typeof r?(e=r,n={},S.each(e.match(P)||[],function(e,t){n[t]=!0}),n):S.extend({},r);var i,t,o,a,s=[],u=[],l=-1,c=function(){for(a=a||r.once,o=i=!0;u.length;l=-1){t=u.shift();while(++l<s.length)!1===s[l].apply(t[0],t[1])&&r.stopOnFalse&&(l=s.length,t=!1)}r.memory||(t=!1),i=!1,a&&(s=t?[]:"")},f={add:function(){return s&&(t&&!i&&(l=s.length-1,u.push(t)),function n(e){S.each(e,function(e,t){m(t)?r.unique&&f.has(t)||s.push(t):t&&t.length&&"string"!==w(t)&&n(t)})}(arguments),t&&!i&&c()),this},remove:function(){return S.each(arguments,function(e,t){var n;while(-1<(n=S.inArray(t,s,n)))s.splice(n,1),n<=l&&l--}),this},has:function(e){return e?-1<S.inArray(e,s):0<s.length},empty:function(){return s&&(s=[]),this},disable:function(){return a=u=[],s=t="",this},disabled:function(){return!s},lock:function(){return a=u=[],t||i||(s=t=""),this},locked:function(){return!!a},fireWith:function(e,t){return a||(t=[e,(t=t||[]).slice?t.slice():t],u.push(t),i||c()),this},fire:function(){return f.fireWith(this,arguments),this},fired:function(){return!!o}};return f},S.extend({Deferred:function(e){var o=[["notify","progress",S.Callbacks("memory"),S.Callbacks("memory"),2],["resolve","done",S.Callbacks("once memory"),S.Callbacks("once memory"),0,"resolved"],["reject","fail",S.Callbacks("once memory"),S.Callbacks("once memory"),1,"rejected"]],i="pending",a={state:function(){return i},always:function(){return s.done(arguments).fail(arguments),this},"catch":function(e){return a.then(null,e)},pipe:function(){var i=arguments;return S.Deferred(function(r){S.each(o,function(e,t){var n=m(i[t[4]])&&i[t[4]];s[t[1]](function(){var e=n&&n.apply(this,arguments);e&&m(e.promise)?e.promise().progress(r.notify).done(r.resolve).fail(r.reject):r[t[0]+"With"](this,n?[e]:arguments)})}),i=null}).promise()},then:function(t,n,r){var u=0;function l(i,o,a,s){return function(){var n=this,r=arguments,e=function(){var e,t;if(!(i<u)){if((e=a.apply(n,r))===o.promise())throw new TypeError("Thenable self-resolution");t=e&&("object"==typeof e||"function"==typeof e)&&e.then,m(t)?s?t.call(e,l(u,o,R,s),l(u,o,M,s)):(u++,t.call(e,l(u,o,R,s),l(u,o,M,s),l(u,o,R,o.notifyWith))):(a!==R&&(n=void 0,r=[e]),(s||o.resolveWith)(n,r))}},t=s?e:function(){try{e()}catch(e){S.Deferred.exceptionHook&&S.Deferred.exceptionHook(e,t.stackTrace),u<=i+1&&(a!==M&&(n=void 0,r=[e]),o.rejectWith(n,r))}};i?t():(S.Deferred.getStackHook&&(t.stackTrace=S.Deferred.getStackHook()),C.setTimeout(t))}}return S.Deferred(function(e){o[0][3].add(l(0,e,m(r)?r:R,e.notifyWith)),o[1][3].add(l(0,e,m(t)?t:R)),o[2][3].add(l(0,e,m(n)?n:M))}).promise()},promise:function(e){return null!=e?S.extend(e,a):a}},s={};return S.each(o,function(e,t){var n=t[2],r=t[5];a[t[1]]=n.add,r&&n.add(function(){i=r},o[3-e][2].disable,o[3-e][3].disable,o[0][2].lock,o[0][3].lock),n.add(t[3].fire),s[t[0]]=function(){return s[t[0]+"With"](this===s?void 0:this,arguments),this},s[t[0]+"With"]=n.fireWith}),a.promise(s),e&&e.call(s,s),s},when:function(e){var n=arguments.length,t=n,r=Array(t),i=s.call(arguments),o=S.Deferred(),a=function(t){return function(e){r[t]=this,i[t]=1<arguments.length?s.call(arguments):e,--n||o.resolveWith(r,i)}};if(n<=1&&(I(e,o.done(a(t)).resolve,o.reject,!n),"pending"===o.state()||m(i[t]&&i[t].then)))return o.then();while(t--)I(i[t],a(t),o.reject);return o.promise()}});var W=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;S.Deferred.exceptionHook=function(e,t){C.console&&C.console.warn&&e&&W.test(e.name)&&C.console.warn("jQuery.Deferred exception: "+e.message,e.stack,t)},S.readyException=function(e){C.setTimeout(function(){throw e})};var F=S.Deferred();function $(){E.removeEventListener("DOMContentLoaded",$),C.removeEventListener("load",$),S.ready()}S.fn.ready=function(e){return F.then(e)["catch"](function(e){S.readyException(e)}),this},S.extend({isReady:!1,readyWait:1,ready:function(e){(!0===e?--S.readyWait:S.isReady)||(S.isReady=!0)!==e&&0<--S.readyWait||F.resolveWith(E,[S])}}),S.ready.then=F.then,"complete"===E.readyState||"loading"!==E.readyState&&!E.documentElement.doScroll?C.setTimeout(S.ready):(E.addEventListener("DOMContentLoaded",$),C.addEventListener("load",$));var B=function(e,t,n,r,i,o,a){var s=0,u=e.length,l=null==n;if("object"===w(n))for(s in i=!0,n)B(e,t,s,n[s],!0,o,a);else if(void 0!==r&&(i=!0,m(r)||(a=!0),l&&(a?(t.call(e,r),t=null):(l=t,t=function(e,t,n){return l.call(S(e),n)})),t))for(;s<u;s++)t(e[s],n,a?r:r.call(e[s],s,t(e[s],n)));return i?e:l?t.call(e):u?t(e[0],n):o},_=/^-ms-/,z=/-([a-z])/g;function U(e,t){return t.toUpperCase()}function X(e){return e.replace(_,"ms-").replace(z,U)}var V=function(e){return 1===e.nodeType||9===e.nodeType||!+e.nodeType};function G(){this.expando=S.expando+G.uid++}G.uid=1,G.prototype={cache:function(e){var t=e[this.expando];return t||(t={},V(e)&&(e.nodeType?e[this.expando]=t:Object.defineProperty(e,this.expando,{value:t,configurable:!0}))),t},set:function(e,t,n){var r,i=this.cache(e);if("string"==typeof t)i[X(t)]=n;else for(r in t)i[X(r)]=t[r];return i},get:function(e,t){return void 0===t?this.cache(e):e[this.expando]&&e[this.expando][X(t)]},access:function(e,t,n){return void 0===t||t&&"string"==typeof t&&void 0===n?this.get(e,t):(this.set(e,t,n),void 0!==n?n:t)},remove:function(e,t){var n,r=e[this.expando];if(void 0!==r){if(void 0!==t){n=(t=Array.isArray(t)?t.map(X):(t=X(t))in r?[t]:t.match(P)||[]).length;while(n--)delete r[t[n]]}(void 0===t||S.isEmptyObject(r))&&(e.nodeType?e[this.expando]=void 0:delete e[this.expando])}},hasData:function(e){var t=e[this.expando];return void 0!==t&&!S.isEmptyObject(t)}};var Y=new G,Q=new G,J=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,K=/[A-Z]/g;function Z(e,t,n){var r,i;if(void 0===n&&1===e.nodeType)if(r="data-"+t.replace(K,"-$&").toLowerCase(),"string"==typeof(n=e.getAttribute(r))){try{n="true"===(i=n)||"false"!==i&&("null"===i?null:i===+i+""?+i:J.test(i)?JSON.parse(i):i)}catch(e){}Q.set(e,t,n)}else n=void 0;return n}S.extend({hasData:function(e){return Q.hasData(e)||Y.hasData(e)},data:function(e,t,n){return Q.access(e,t,n)},removeData:function(e,t){Q.remove(e,t)},_data:function(e,t,n){return Y.access(e,t,n)},_removeData:function(e,t){Y.remove(e,t)}}),S.fn.extend({data:function(n,e){var t,r,i,o=this[0],a=o&&o.attributes;if(void 0===n){if(this.length&&(i=Q.get(o),1===o.nodeType&&!Y.get(o,"hasDataAttrs"))){t=a.length;while(t--)a[t]&&0===(r=a[t].name).indexOf("data-")&&(r=X(r.slice(5)),Z(o,r,i[r]));Y.set(o,"hasDataAttrs",!0)}return i}return"object"==typeof n?this.each(function(){Q.set(this,n)}):B(this,function(e){var t;if(o&&void 0===e)return void 0!==(t=Q.get(o,n))?t:void 0!==(t=Z(o,n))?t:void 0;this.each(function(){Q.set(this,n,e)})},null,e,1<arguments.length,null,!0)},removeData:function(e){return this.each(function(){Q.remove(this,e)})}}),S.extend({queue:function(e,t,n){var r;if(e)return t=(t||"fx")+"queue",r=Y.get(e,t),n&&(!r||Array.isArray(n)?r=Y.access(e,t,S.makeArray(n)):r.push(n)),r||[]},dequeue:function(e,t){t=t||"fx";var n=S.queue(e,t),r=n.length,i=n.shift(),o=S._queueHooks(e,t);"inprogress"===i&&(i=n.shift(),r--),i&&("fx"===t&&n.unshift("inprogress"),delete o.stop,i.call(e,function(){S.dequeue(e,t)},o)),!r&&o&&o.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return Y.get(e,n)||Y.access(e,n,{empty:S.Callbacks("once memory").add(function(){Y.remove(e,[t+"queue",n])})})}}),S.fn.extend({queue:function(t,n){var e=2;return"string"!=typeof t&&(n=t,t="fx",e--),arguments.length<e?S.queue(this[0],t):void 0===n?this:this.each(function(){var e=S.queue(this,t,n);S._queueHooks(this,t),"fx"===t&&"inprogress"!==e[0]&&S.dequeue(this,t)})},dequeue:function(e){return this.each(function(){S.dequeue(this,e)})},clearQueue:function(e){return this.queue(e||"fx",[])},promise:function(e,t){var n,r=1,i=S.Deferred(),o=this,a=this.length,s=function(){--r||i.resolveWith(o,[o])};"string"!=typeof e&&(t=e,e=void 0),e=e||"fx";while(a--)(n=Y.get(o[a],e+"queueHooks"))&&n.empty&&(r++,n.empty.add(s));return s(),i.promise(t)}});var ee=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,te=new RegExp("^(?:([+-])=|)("+ee+")([a-z%]*)$","i"),ne=["Top","Right","Bottom","Left"],re=E.documentElement,ie=function(e){return S.contains(e.ownerDocument,e)},oe={composed:!0};re.getRootNode&&(ie=function(e){return S.contains(e.ownerDocument,e)||e.getRootNode(oe)===e.ownerDocument});var ae=function(e,t){return"none"===(e=t||e).style.display||""===e.style.display&&ie(e)&&"none"===S.css(e,"display")};function se(e,t,n,r){var i,o,a=20,s=r?function(){return r.cur()}:function(){return S.css(e,t,"")},u=s(),l=n&&n[3]||(S.cssNumber[t]?"":"px"),c=e.nodeType&&(S.cssNumber[t]||"px"!==l&&+u)&&te.exec(S.css(e,t));if(c&&c[3]!==l){u/=2,l=l||c[3],c=+u||1;while(a--)S.style(e,t,c+l),(1-o)*(1-(o=s()/u||.5))<=0&&(a=0),c/=o;c*=2,S.style(e,t,c+l),n=n||[]}return n&&(c=+c||+u||0,i=n[1]?c+(n[1]+1)*n[2]:+n[2],r&&(r.unit=l,r.start=c,r.end=i)),i}var ue={};function le(e,t){for(var n,r,i,o,a,s,u,l=[],c=0,f=e.length;c<f;c++)(r=e[c]).style&&(n=r.style.display,t?("none"===n&&(l[c]=Y.get(r,"display")||null,l[c]||(r.style.display="")),""===r.style.display&&ae(r)&&(l[c]=(u=a=o=void 0,a=(i=r).ownerDocument,s=i.nodeName,(u=ue[s])||(o=a.body.appendChild(a.createElement(s)),u=S.css(o,"display"),o.parentNode.removeChild(o),"none"===u&&(u="block"),ue[s]=u)))):"none"!==n&&(l[c]="none",Y.set(r,"display",n)));for(c=0;c<f;c++)null!=l[c]&&(e[c].style.display=l[c]);return e}S.fn.extend({show:function(){return le(this,!0)},hide:function(){return le(this)},toggle:function(e){return"boolean"==typeof e?e?this.show():this.hide():this.each(function(){ae(this)?S(this).show():S(this).hide()})}});var ce,fe,pe=/^(?:checkbox|radio)$/i,de=/<([a-z][^\/\0>\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i;ce=E.createDocumentFragment().appendChild(E.createElement("div")),(fe=E.createElement("input")).setAttribute("type","radio"),fe.setAttribute("checked","checked"),fe.setAttribute("name","t"),ce.appendChild(fe),v.checkClone=ce.cloneNode(!0).cloneNode(!0).lastChild.checked,ce.innerHTML="<textarea>x</textarea>",v.noCloneChecked=!!ce.cloneNode(!0).lastChild.defaultValue,ce.innerHTML="<option></option>",v.option=!!ce.lastChild;var ge={thead:[1,"<table>","</table>"],col:[2,"<table><colgroup>","</colgroup></table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:[0,"",""]};function ye(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?S.merge([e],n):n}function ve(e,t){for(var n=0,r=e.length;n<r;n++)Y.set(e[n],"globalEval",!t||Y.get(t[n],"globalEval"))}ge.tbody=ge.tfoot=ge.colgroup=ge.caption=ge.thead,ge.th=ge.td,v.option||(ge.optgroup=ge.option=[1,"<select multiple='multiple'>","</select>"]);var me=/<|&#?\w+;/;function xe(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d<h;d++)if((o=e[d])||0===o)if("object"===w(o))S.merge(p,o.nodeType?[o]:o);else if(me.test(o)){a=a||f.appendChild(t.createElement("div")),s=(de.exec(o)||["",""])[1].toLowerCase(),u=ge[s]||ge._default,a.innerHTML=u[1]+S.htmlPrefilter(o)+u[2],c=u[0];while(c--)a=a.lastChild;S.merge(p,a.childNodes),(a=f.firstChild).textContent=""}else p.push(t.createTextNode(o));f.textContent="",d=0;while(o=p[d++])if(r&&-1<S.inArray(o,r))i&&i.push(o);else if(l=ie(o),a=ye(f.appendChild(o),"script"),l&&ve(a),n){c=0;while(o=a[c++])he.test(o.type||"")&&n.push(o)}return f}var be=/^([^.]*)(?:\.(.+)|)/;function we(){return!0}function Te(){return!1}function Ce(e,t){return e===function(){try{return E.activeElement}catch(e){}}()==("focus"===t)}function Ee(e,t,n,r,i,o){var a,s;if("object"==typeof t){for(s in"string"!=typeof n&&(r=r||n,n=void 0),t)Ee(e,s,n,r,t[s],o);return e}if(null==r&&null==i?(i=n,r=n=void 0):null==i&&("string"==typeof n?(i=r,r=void 0):(i=r,r=n,n=void 0)),!1===i)i=Te;else if(!i)return e;return 1===o&&(a=i,(i=function(e){return S().off(e),a.apply(this,arguments)}).guid=a.guid||(a.guid=S.guid++)),e.each(function(){S.event.add(this,t,i,r,n)})}function Se(e,i,o){o?(Y.set(e,i,!1),S.event.add(e,i,{namespace:!1,handler:function(e){var t,n,r=Y.get(this,i);if(1&e.isTrigger&&this[i]){if(r.length)(S.event.special[i]||{}).delegateType&&e.stopPropagation();else if(r=s.call(arguments),Y.set(this,i,r),t=o(this,i),this[i](),r!==(n=Y.get(this,i))||t?Y.set(this,i,!1):n={},r!==n)return e.stopImmediatePropagation(),e.preventDefault(),n&&n.value}else r.length&&(Y.set(this,i,{value:S.event.trigger(S.extend(r[0],S.Event.prototype),r.slice(1),this)}),e.stopImmediatePropagation())}})):void 0===Y.get(e,i)&&S.event.add(e,i,we)}S.event={global:{},add:function(t,e,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,y=Y.get(t);if(V(t)){n.handler&&(n=(o=n).handler,i=o.selector),i&&S.find.matchesSelector(re,i),n.guid||(n.guid=S.guid++),(u=y.events)||(u=y.events=Object.create(null)),(a=y.handle)||(a=y.handle=function(e){return"undefined"!=typeof S&&S.event.triggered!==e.type?S.event.dispatch.apply(t,arguments):void 0}),l=(e=(e||"").match(P)||[""]).length;while(l--)d=g=(s=be.exec(e[l])||[])[1],h=(s[2]||"").split(".").sort(),d&&(f=S.event.special[d]||{},d=(i?f.delegateType:f.bindType)||d,f=S.event.special[d]||{},c=S.extend({type:d,origType:g,data:r,handler:n,guid:n.guid,selector:i,needsContext:i&&S.expr.match.needsContext.test(i),namespace:h.join(".")},o),(p=u[d])||((p=u[d]=[]).delegateCount=0,f.setup&&!1!==f.setup.call(t,r,h,a)||t.addEventListener&&t.addEventListener(d,a)),f.add&&(f.add.call(t,c),c.handler.guid||(c.handler.guid=n.guid)),i?p.splice(p.delegateCount++,0,c):p.push(c),S.event.global[d]=!0)}},remove:function(e,t,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,y=Y.hasData(e)&&Y.get(e);if(y&&(u=y.events)){l=(t=(t||"").match(P)||[""]).length;while(l--)if(d=g=(s=be.exec(t[l])||[])[1],h=(s[2]||"").split(".").sort(),d){f=S.event.special[d]||{},p=u[d=(r?f.delegateType:f.bindType)||d]||[],s=s[2]&&new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"),a=o=p.length;while(o--)c=p[o],!i&&g!==c.origType||n&&n.guid!==c.guid||s&&!s.test(c.namespace)||r&&r!==c.selector&&("**"!==r||!c.selector)||(p.splice(o,1),c.selector&&p.delegateCount--,f.remove&&f.remove.call(e,c));a&&!p.length&&(f.teardown&&!1!==f.teardown.call(e,h,y.handle)||S.removeEvent(e,d,y.handle),delete u[d])}else for(d in u)S.event.remove(e,d+t[l],n,r,!0);S.isEmptyObject(u)&&Y.remove(e,"handle events")}},dispatch:function(e){var t,n,r,i,o,a,s=new Array(arguments.length),u=S.event.fix(e),l=(Y.get(this,"events")||Object.create(null))[u.type]||[],c=S.event.special[u.type]||{};for(s[0]=u,t=1;t<arguments.length;t++)s[t]=arguments[t];if(u.delegateTarget=this,!c.preDispatch||!1!==c.preDispatch.call(this,u)){a=S.event.handlers.call(this,u,l),t=0;while((i=a[t++])&&!u.isPropagationStopped()){u.currentTarget=i.elem,n=0;while((o=i.handlers[n++])&&!u.isImmediatePropagationStopped())u.rnamespace&&!1!==o.namespace&&!u.rnamespace.test(o.namespace)||(u.handleObj=o,u.data=o.data,void 0!==(r=((S.event.special[o.origType]||{}).handle||o.handler).apply(i.elem,s))&&!1===(u.result=r)&&(u.preventDefault(),u.stopPropagation()))}return c.postDispatch&&c.postDispatch.call(this,u),u.result}},handlers:function(e,t){var n,r,i,o,a,s=[],u=t.delegateCount,l=e.target;if(u&&l.nodeType&&!("click"===e.type&&1<=e.button))for(;l!==this;l=l.parentNode||this)if(1===l.nodeType&&("click"!==e.type||!0!==l.disabled)){for(o=[],a={},n=0;n<u;n++)void 0===a[i=(r=t[n]).selector+" "]&&(a[i]=r.needsContext?-1<S(i,this).index(l):S.find(i,this,null,[l]).length),a[i]&&o.push(r);o.length&&s.push({elem:l,handlers:o})}return l=this,u<t.length&&s.push({elem:l,handlers:t.slice(u)}),s},addProp:function(t,e){Object.defineProperty(S.Event.prototype,t,{enumerable:!0,configurable:!0,get:m(e)?function(){if(this.originalEvent)return e(this.originalEvent)}:function(){if(this.originalEvent)return this.originalEvent[t]},set:function(e){Object.defineProperty(this,t,{enumerable:!0,configurable:!0,writable:!0,value:e})}})},fix:function(e){return e[S.expando]?e:new S.Event(e)},special:{load:{noBubble:!0},click:{setup:function(e){var t=this||e;return pe.test(t.type)&&t.click&&A(t,"input")&&Se(t,"click",we),!1},trigger:function(e){var t=this||e;return pe.test(t.type)&&t.click&&A(t,"input")&&Se(t,"click"),!0},_default:function(e){var t=e.target;return pe.test(t.type)&&t.click&&A(t,"input")&&Y.get(t,"click")||A(t,"a")}},beforeunload:{postDispatch:function(e){void 0!==e.result&&e.originalEvent&&(e.originalEvent.returnValue=e.result)}}}},S.removeEvent=function(e,t,n){e.removeEventListener&&e.removeEventListener(t,n)},S.Event=function(e,t){if(!(this instanceof S.Event))return new S.Event(e,t);e&&e.type?(this.originalEvent=e,this.type=e.type,this.isDefaultPrevented=e.defaultPrevented||void 0===e.defaultPrevented&&!1===e.returnValue?we:Te,this.target=e.target&&3===e.target.nodeType?e.target.parentNode:e.target,this.currentTarget=e.currentTarget,this.relatedTarget=e.relatedTarget):this.type=e,t&&S.extend(this,t),this.timeStamp=e&&e.timeStamp||Date.now(),this[S.expando]=!0},S.Event.prototype={constructor:S.Event,isDefaultPrevented:Te,isPropagationStopped:Te,isImmediatePropagationStopped:Te,isSimulated:!1,preventDefault:function(){var e=this.originalEvent;this.isDefaultPrevented=we,e&&!this.isSimulated&&e.preventDefault()},stopPropagation:function(){var e=this.originalEvent;this.isPropagationStopped=we,e&&!this.isSimulated&&e.stopPropagation()},stopImmediatePropagation:function(){var e=this.originalEvent;this.isImmediatePropagationStopped=we,e&&!this.isSimulated&&e.stopImmediatePropagation(),this.stopPropagation()}},S.each({altKey:!0,bubbles:!0,cancelable:!0,changedTouches:!0,ctrlKey:!0,detail:!0,eventPhase:!0,metaKey:!0,pageX:!0,pageY:!0,shiftKey:!0,view:!0,"char":!0,code:!0,charCode:!0,key:!0,keyCode:!0,button:!0,buttons:!0,clientX:!0,clientY:!0,offsetX:!0,offsetY:!0,pointerId:!0,pointerType:!0,screenX:!0,screenY:!0,targetTouches:!0,toElement:!0,touches:!0,which:!0},S.event.addProp),S.each({focus:"focusin",blur:"focusout"},function(t,e){S.event.special[t]={setup:function(){return Se(this,t,Ce),!1},trigger:function(){return Se(this,t),!0},_default:function(e){return Y.get(e.target,t)},delegateType:e}}),S.each({mouseenter:"mouseover",mouseleave:"mouseout",pointerenter:"pointerover",pointerleave:"pointerout"},function(e,i){S.event.special[e]={delegateType:i,bindType:i,handle:function(e){var t,n=e.relatedTarget,r=e.handleObj;return n&&(n===this||S.contains(this,n))||(e.type=r.origType,t=r.handler.apply(this,arguments),e.type=i),t}}}),S.fn.extend({on:function(e,t,n,r){return Ee(this,e,t,n,r)},one:function(e,t,n,r){return Ee(this,e,t,n,r,1)},off:function(e,t,n){var r,i;if(e&&e.preventDefault&&e.handleObj)return r=e.handleObj,S(e.delegateTarget).off(r.namespace?r.origType+"."+r.namespace:r.origType,r.selector,r.handler),this;if("object"==typeof e){for(i in e)this.off(i,t,e[i]);return this}return!1!==t&&"function"!=typeof t||(n=t,t=void 0),!1===n&&(n=Te),this.each(function(){S.event.remove(this,e,n,t)})}});var ke=/<script|<style|<link/i,Ae=/checked\s*(?:[^=]|=\s*.checked.)/i,Ne=/^\s*<!\[CDATA\[|\]\]>\s*$/g;function je(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&S(e).children("tbody")[0]||e}function De(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function qe(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Le(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(Y.hasData(e)&&(s=Y.get(e).events))for(i in Y.remove(t,"handle events"),s)for(n=0,r=s[i].length;n<r;n++)S.event.add(t,i,s[i][n]);Q.hasData(e)&&(o=Q.access(e),a=S.extend({},o),Q.set(t,a))}}function He(n,r,i,o){r=g(r);var e,t,a,s,u,l,c=0,f=n.length,p=f-1,d=r[0],h=m(d);if(h||1<f&&"string"==typeof d&&!v.checkClone&&Ae.test(d))return n.each(function(e){var t=n.eq(e);h&&(r[0]=d.call(this,e,t.html())),He(t,r,i,o)});if(f&&(t=(e=xe(r,n[0].ownerDocument,!1,n,o)).firstChild,1===e.childNodes.length&&(e=t),t||o)){for(s=(a=S.map(ye(e,"script"),De)).length;c<f;c++)u=e,c!==p&&(u=S.clone(u,!0,!0),s&&S.merge(a,ye(u,"script"))),i.call(n[c],u,c);if(s)for(l=a[a.length-1].ownerDocument,S.map(a,qe),c=0;c<s;c++)u=a[c],he.test(u.type||"")&&!Y.access(u,"globalEval")&&S.contains(l,u)&&(u.src&&"module"!==(u.type||"").toLowerCase()?S._evalUrl&&!u.noModule&&S._evalUrl(u.src,{nonce:u.nonce||u.getAttribute("nonce")},l):b(u.textContent.replace(Ne,""),u,l))}return n}function Oe(e,t,n){for(var r,i=t?S.filter(t,e):e,o=0;null!=(r=i[o]);o++)n||1!==r.nodeType||S.cleanData(ye(r)),r.parentNode&&(n&&ie(r)&&ve(ye(r,"script")),r.parentNode.removeChild(r));return e}S.extend({htmlPrefilter:function(e){return e},clone:function(e,t,n){var r,i,o,a,s,u,l,c=e.cloneNode(!0),f=ie(e);if(!(v.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||S.isXMLDoc(e)))for(a=ye(c),r=0,i=(o=ye(e)).length;r<i;r++)s=o[r],u=a[r],void 0,"input"===(l=u.nodeName.toLowerCase())&&pe.test(s.type)?u.checked=s.checked:"input"!==l&&"textarea"!==l||(u.defaultValue=s.defaultValue);if(t)if(n)for(o=o||ye(e),a=a||ye(c),r=0,i=o.length;r<i;r++)Le(o[r],a[r]);else Le(e,c);return 0<(a=ye(c,"script")).length&&ve(a,!f&&ye(e,"script")),c},cleanData:function(e){for(var t,n,r,i=S.event.special,o=0;void 0!==(n=e[o]);o++)if(V(n)){if(t=n[Y.expando]){if(t.events)for(r in t.events)i[r]?S.event.remove(n,r):S.removeEvent(n,r,t.handle);n[Y.expando]=void 0}n[Q.expando]&&(n[Q.expando]=void 0)}}}),S.fn.extend({detach:function(e){return Oe(this,e,!0)},remove:function(e){return Oe(this,e)},text:function(e){return B(this,function(e){return void 0===e?S.text(this):this.empty().each(function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=e)})},null,e,arguments.length)},append:function(){return He(this,arguments,function(e){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||je(this,e).appendChild(e)})},prepend:function(){return He(this,arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=je(this,e);t.insertBefore(e,t.firstChild)}})},before:function(){return He(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this)})},after:function(){return He(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)})},empty:function(){for(var e,t=0;null!=(e=this[t]);t++)1===e.nodeType&&(S.cleanData(ye(e,!1)),e.textContent="");return this},clone:function(e,t){return e=null!=e&&e,t=null==t?e:t,this.map(function(){return S.clone(this,e,t)})},html:function(e){return B(this,function(e){var t=this[0]||{},n=0,r=this.length;if(void 0===e&&1===t.nodeType)return t.innerHTML;if("string"==typeof e&&!ke.test(e)&&!ge[(de.exec(e)||["",""])[1].toLowerCase()]){e=S.htmlPrefilter(e);try{for(;n<r;n++)1===(t=this[n]||{}).nodeType&&(S.cleanData(ye(t,!1)),t.innerHTML=e);t=0}catch(e){}}t&&this.empty().append(e)},null,e,arguments.length)},replaceWith:function(){var n=[];return He(this,arguments,function(e){var t=this.parentNode;S.inArray(this,n)<0&&(S.cleanData(ye(this)),t&&t.replaceChild(e,this))},n)}}),S.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(e,a){S.fn[e]=function(e){for(var t,n=[],r=S(e),i=r.length-1,o=0;o<=i;o++)t=o===i?this:this.clone(!0),S(r[o])[a](t),u.apply(n,t.get());return this.pushStack(n)}});var Pe=new RegExp("^("+ee+")(?!px)[a-z%]+$","i"),Re=/^--/,Me=function(e){var t=e.ownerDocument.defaultView;return t&&t.opener||(t=C),t.getComputedStyle(e)},Ie=function(e,t,n){var r,i,o={};for(i in t)o[i]=e.style[i],e.style[i]=t[i];for(i in r=n.call(e),t)e.style[i]=o[i];return r},We=new RegExp(ne.join("|"),"i"),Fe="[\\x20\\t\\r\\n\\f]",$e=new RegExp("^"+Fe+"+|((?:^|[^\\\\])(?:\\\\.)*)"+Fe+"+$","g");function Be(e,t,n){var r,i,o,a,s=Re.test(t),u=e.style;return(n=n||Me(e))&&(a=n.getPropertyValue(t)||n[t],s&&(a=a.replace($e,"$1")),""!==a||ie(e)||(a=S.style(e,t)),!v.pixelBoxStyles()&&Pe.test(a)&&We.test(t)&&(r=u.width,i=u.minWidth,o=u.maxWidth,u.minWidth=u.maxWidth=u.width=a,a=n.width,u.width=r,u.minWidth=i,u.maxWidth=o)),void 0!==a?a+"":a}function _e(e,t){return{get:function(){if(!e())return(this.get=t).apply(this,arguments);delete this.get}}}!function(){function e(){if(l){u.style.cssText="position:absolute;left:-11111px;width:60px;margin-top:1px;padding:0;border:0",l.style.cssText="position:relative;display:block;box-sizing:border-box;overflow:scroll;margin:auto;border:1px;padding:1px;width:60%;top:1%",re.appendChild(u).appendChild(l);var e=C.getComputedStyle(l);n="1%"!==e.top,s=12===t(e.marginLeft),l.style.right="60%",o=36===t(e.right),r=36===t(e.width),l.style.position="absolute",i=12===t(l.offsetWidth/3),re.removeChild(u),l=null}}function t(e){return Math.round(parseFloat(e))}var n,r,i,o,a,s,u=E.createElement("div"),l=E.createElement("div");l.style&&(l.style.backgroundClip="content-box",l.cloneNode(!0).style.backgroundClip="",v.clearCloneStyle="content-box"===l.style.backgroundClip,S.extend(v,{boxSizingReliable:function(){return e(),r},pixelBoxStyles:function(){return e(),o},pixelPosition:function(){return e(),n},reliableMarginLeft:function(){return e(),s},scrollboxSize:function(){return e(),i},reliableTrDimensions:function(){var e,t,n,r;return null==a&&(e=E.createElement("table"),t=E.createElement("tr"),n=E.createElement("div"),e.style.cssText="position:absolute;left:-11111px;border-collapse:separate",t.style.cssText="border:1px solid",t.style.height="1px",n.style.height="9px",n.style.display="block",re.appendChild(e).appendChild(t).appendChild(n),r=C.getComputedStyle(t),a=parseInt(r.height,10)+parseInt(r.borderTopWidth,10)+parseInt(r.borderBottomWidth,10)===t.offsetHeight,re.removeChild(e)),a}}))}();var ze=["Webkit","Moz","ms"],Ue=E.createElement("div").style,Xe={};function Ve(e){var t=S.cssProps[e]||Xe[e];return t||(e in Ue?e:Xe[e]=function(e){var t=e[0].toUpperCase()+e.slice(1),n=ze.length;while(n--)if((e=ze[n]+t)in Ue)return e}(e)||e)}var Ge=/^(none|table(?!-c[ea]).+)/,Ye={position:"absolute",visibility:"hidden",display:"block"},Qe={letterSpacing:"0",fontWeight:"400"};function Je(e,t,n){var r=te.exec(t);return r?Math.max(0,r[2]-(n||0))+(r[3]||"px"):t}function Ke(e,t,n,r,i,o){var a="width"===t?1:0,s=0,u=0;if(n===(r?"border":"content"))return 0;for(;a<4;a+=2)"margin"===n&&(u+=S.css(e,n+ne[a],!0,i)),r?("content"===n&&(u-=S.css(e,"padding"+ne[a],!0,i)),"margin"!==n&&(u-=S.css(e,"border"+ne[a]+"Width",!0,i))):(u+=S.css(e,"padding"+ne[a],!0,i),"padding"!==n?u+=S.css(e,"border"+ne[a]+"Width",!0,i):s+=S.css(e,"border"+ne[a]+"Width",!0,i));return!r&&0<=o&&(u+=Math.max(0,Math.ceil(e["offset"+t[0].toUpperCase()+t.slice(1)]-o-u-s-.5))||0),u}function Ze(e,t,n){var r=Me(e),i=(!v.boxSizingReliable()||n)&&"border-box"===S.css(e,"boxSizing",!1,r),o=i,a=Be(e,t,r),s="offset"+t[0].toUpperCase()+t.slice(1);if(Pe.test(a)){if(!n)return a;a="auto"}return(!v.boxSizingReliable()&&i||!v.reliableTrDimensions()&&A(e,"tr")||"auto"===a||!parseFloat(a)&&"inline"===S.css(e,"display",!1,r))&&e.getClientRects().length&&(i="border-box"===S.css(e,"boxSizing",!1,r),(o=s in e)&&(a=e[s])),(a=parseFloat(a)||0)+Ke(e,t,n||(i?"border":"content"),o,r,a)+"px"}function et(e,t,n,r,i){return new et.prototype.init(e,t,n,r,i)}S.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=Be(e,"opacity");return""===n?"1":n}}}},cssNumber:{animationIterationCount:!0,columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,gridArea:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnStart:!0,gridRow:!0,gridRowEnd:!0,gridRowStart:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{},style:function(e,t,n,r){if(e&&3!==e.nodeType&&8!==e.nodeType&&e.style){var i,o,a,s=X(t),u=Re.test(t),l=e.style;if(u||(t=Ve(s)),a=S.cssHooks[t]||S.cssHooks[s],void 0===n)return a&&"get"in a&&void 0!==(i=a.get(e,!1,r))?i:l[t];"string"===(o=typeof n)&&(i=te.exec(n))&&i[1]&&(n=se(e,t,i),o="number"),null!=n&&n==n&&("number"!==o||u||(n+=i&&i[3]||(S.cssNumber[s]?"":"px")),v.clearCloneStyle||""!==n||0!==t.indexOf("background")||(l[t]="inherit"),a&&"set"in a&&void 0===(n=a.set(e,n,r))||(u?l.setProperty(t,n):l[t]=n))}},css:function(e,t,n,r){var i,o,a,s=X(t);return Re.test(t)||(t=Ve(s)),(a=S.cssHooks[t]||S.cssHooks[s])&&"get"in a&&(i=a.get(e,!0,n)),void 0===i&&(i=Be(e,t,r)),"normal"===i&&t in Qe&&(i=Qe[t]),""===n||n?(o=parseFloat(i),!0===n||isFinite(o)?o||0:i):i}}),S.each(["height","width"],function(e,u){S.cssHooks[u]={get:function(e,t,n){if(t)return!Ge.test(S.css(e,"display"))||e.getClientRects().length&&e.getBoundingClientRect().width?Ze(e,u,n):Ie(e,Ye,function(){return Ze(e,u,n)})},set:function(e,t,n){var r,i=Me(e),o=!v.scrollboxSize()&&"absolute"===i.position,a=(o||n)&&"border-box"===S.css(e,"boxSizing",!1,i),s=n?Ke(e,u,n,a,i):0;return a&&o&&(s-=Math.ceil(e["offset"+u[0].toUpperCase()+u.slice(1)]-parseFloat(i[u])-Ke(e,u,"border",!1,i)-.5)),s&&(r=te.exec(t))&&"px"!==(r[3]||"px")&&(e.style[u]=t,t=S.css(e,u)),Je(0,t,s)}}}),S.cssHooks.marginLeft=_e(v.reliableMarginLeft,function(e,t){if(t)return(parseFloat(Be(e,"marginLeft"))||e.getBoundingClientRect().left-Ie(e,{marginLeft:0},function(){return e.getBoundingClientRect().left}))+"px"}),S.each({margin:"",padding:"",border:"Width"},function(i,o){S.cssHooks[i+o]={expand:function(e){for(var t=0,n={},r="string"==typeof e?e.split(" "):[e];t<4;t++)n[i+ne[t]+o]=r[t]||r[t-2]||r[0];return n}},"margin"!==i&&(S.cssHooks[i+o].set=Je)}),S.fn.extend({css:function(e,t){return B(this,function(e,t,n){var r,i,o={},a=0;if(Array.isArray(t)){for(r=Me(e),i=t.length;a<i;a++)o[t[a]]=S.css(e,t[a],!1,r);return o}return void 0!==n?S.style(e,t,n):S.css(e,t)},e,t,1<arguments.length)}}),((S.Tween=et).prototype={constructor:et,init:function(e,t,n,r,i,o){this.elem=e,this.prop=n,this.easing=i||S.easing._default,this.options=t,this.start=this.now=this.cur(),this.end=r,this.unit=o||(S.cssNumber[n]?"":"px")},cur:function(){var e=et.propHooks[this.prop];return e&&e.get?e.get(this):et.propHooks._default.get(this)},run:function(e){var t,n=et.propHooks[this.prop];return this.options.duration?this.pos=t=S.easing[this.easing](e,this.options.duration*e,0,1,this.options.duration):this.pos=t=e,this.now=(this.end-this.start)*t+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):et.propHooks._default.set(this),this}}).init.prototype=et.prototype,(et.propHooks={_default:{get:function(e){var t;return 1!==e.elem.nodeType||null!=e.elem[e.prop]&&null==e.elem.style[e.prop]?e.elem[e.prop]:(t=S.css(e.elem,e.prop,""))&&"auto"!==t?t:0},set:function(e){S.fx.step[e.prop]?S.fx.step[e.prop](e):1!==e.elem.nodeType||!S.cssHooks[e.prop]&&null==e.elem.style[Ve(e.prop)]?e.elem[e.prop]=e.now:S.style(e.elem,e.prop,e.now+e.unit)}}}).scrollTop=et.propHooks.scrollLeft={set:function(e){e.elem.nodeType&&e.elem.parentNode&&(e.elem[e.prop]=e.now)}},S.easing={linear:function(e){return e},swing:function(e){return.5-Math.cos(e*Math.PI)/2},_default:"swing"},S.fx=et.prototype.init,S.fx.step={};var tt,nt,rt,it,ot=/^(?:toggle|show|hide)$/,at=/queueHooks$/;function st(){nt&&(!1===E.hidden&&C.requestAnimationFrame?C.requestAnimationFrame(st):C.setTimeout(st,S.fx.interval),S.fx.tick())}function ut(){return C.setTimeout(function(){tt=void 0}),tt=Date.now()}function lt(e,t){var n,r=0,i={height:e};for(t=t?1:0;r<4;r+=2-t)i["margin"+(n=ne[r])]=i["padding"+n]=e;return t&&(i.opacity=i.width=e),i}function ct(e,t,n){for(var r,i=(ft.tweeners[t]||[]).concat(ft.tweeners["*"]),o=0,a=i.length;o<a;o++)if(r=i[o].call(n,t,e))return r}function ft(o,e,t){var n,a,r=0,i=ft.prefilters.length,s=S.Deferred().always(function(){delete u.elem}),u=function(){if(a)return!1;for(var e=tt||ut(),t=Math.max(0,l.startTime+l.duration-e),n=1-(t/l.duration||0),r=0,i=l.tweens.length;r<i;r++)l.tweens[r].run(n);return s.notifyWith(o,[l,n,t]),n<1&&i?t:(i||s.notifyWith(o,[l,1,0]),s.resolveWith(o,[l]),!1)},l=s.promise({elem:o,props:S.extend({},e),opts:S.extend(!0,{specialEasing:{},easing:S.easing._default},t),originalProperties:e,originalOptions:t,startTime:tt||ut(),duration:t.duration,tweens:[],createTween:function(e,t){var n=S.Tween(o,l.opts,e,t,l.opts.specialEasing[e]||l.opts.easing);return l.tweens.push(n),n},stop:function(e){var t=0,n=e?l.tweens.length:0;if(a)return this;for(a=!0;t<n;t++)l.tweens[t].run(1);return e?(s.notifyWith(o,[l,1,0]),s.resolveWith(o,[l,e])):s.rejectWith(o,[l,e]),this}}),c=l.props;for(!function(e,t){var n,r,i,o,a;for(n in e)if(i=t[r=X(n)],o=e[n],Array.isArray(o)&&(i=o[1],o=e[n]=o[0]),n!==r&&(e[r]=o,delete e[n]),(a=S.cssHooks[r])&&"expand"in a)for(n in o=a.expand(o),delete e[r],o)n in e||(e[n]=o[n],t[n]=i);else t[r]=i}(c,l.opts.specialEasing);r<i;r++)if(n=ft.prefilters[r].call(l,o,c,l.opts))return m(n.stop)&&(S._queueHooks(l.elem,l.opts.queue).stop=n.stop.bind(n)),n;return S.map(c,ct,l),m(l.opts.start)&&l.opts.start.call(o,l),l.progress(l.opts.progress).done(l.opts.done,l.opts.complete).fail(l.opts.fail).always(l.opts.always),S.fx.timer(S.extend(u,{elem:o,anim:l,queue:l.opts.queue})),l}S.Animation=S.extend(ft,{tweeners:{"*":[function(e,t){var n=this.createTween(e,t);return se(n.elem,e,te.exec(t),n),n}]},tweener:function(e,t){m(e)?(t=e,e=["*"]):e=e.match(P);for(var n,r=0,i=e.length;r<i;r++)n=e[r],ft.tweeners[n]=ft.tweeners[n]||[],ft.tweeners[n].unshift(t)},prefilters:[function(e,t,n){var r,i,o,a,s,u,l,c,f="width"in t||"height"in t,p=this,d={},h=e.style,g=e.nodeType&&ae(e),y=Y.get(e,"fxshow");for(r in n.queue||(null==(a=S._queueHooks(e,"fx")).unqueued&&(a.unqueued=0,s=a.empty.fire,a.empty.fire=function(){a.unqueued||s()}),a.unqueued++,p.always(function(){p.always(function(){a.unqueued--,S.queue(e,"fx").length||a.empty.fire()})})),t)if(i=t[r],ot.test(i)){if(delete t[r],o=o||"toggle"===i,i===(g?"hide":"show")){if("show"!==i||!y||void 0===y[r])continue;g=!0}d[r]=y&&y[r]||S.style(e,r)}if((u=!S.isEmptyObject(t))||!S.isEmptyObject(d))for(r in f&&1===e.nodeType&&(n.overflow=[h.overflow,h.overflowX,h.overflowY],null==(l=y&&y.display)&&(l=Y.get(e,"display")),"none"===(c=S.css(e,"display"))&&(l?c=l:(le([e],!0),l=e.style.display||l,c=S.css(e,"display"),le([e]))),("inline"===c||"inline-block"===c&&null!=l)&&"none"===S.css(e,"float")&&(u||(p.done(function(){h.display=l}),null==l&&(c=h.display,l="none"===c?"":c)),h.display="inline-block")),n.overflow&&(h.overflow="hidden",p.always(function(){h.overflow=n.overflow[0],h.overflowX=n.overflow[1],h.overflowY=n.overflow[2]})),u=!1,d)u||(y?"hidden"in y&&(g=y.hidden):y=Y.access(e,"fxshow",{display:l}),o&&(y.hidden=!g),g&&le([e],!0),p.done(function(){for(r in g||le([e]),Y.remove(e,"fxshow"),d)S.style(e,r,d[r])})),u=ct(g?y[r]:0,r,p),r in y||(y[r]=u.start,g&&(u.end=u.start,u.start=0))}],prefilter:function(e,t){t?ft.prefilters.unshift(e):ft.prefilters.push(e)}}),S.speed=function(e,t,n){var r=e&&"object"==typeof e?S.extend({},e):{complete:n||!n&&t||m(e)&&e,duration:e,easing:n&&t||t&&!m(t)&&t};return S.fx.off?r.duration=0:"number"!=typeof r.duration&&(r.duration in S.fx.speeds?r.duration=S.fx.speeds[r.duration]:r.duration=S.fx.speeds._default),null!=r.queue&&!0!==r.queue||(r.queue="fx"),r.old=r.complete,r.complete=function(){m(r.old)&&r.old.call(this),r.queue&&S.dequeue(this,r.queue)},r},S.fn.extend({fadeTo:function(e,t,n,r){return this.filter(ae).css("opacity",0).show().end().animate({opacity:t},e,n,r)},animate:function(t,e,n,r){var i=S.isEmptyObject(t),o=S.speed(e,n,r),a=function(){var e=ft(this,S.extend({},t),o);(i||Y.get(this,"finish"))&&e.stop(!0)};return a.finish=a,i||!1===o.queue?this.each(a):this.queue(o.queue,a)},stop:function(i,e,o){var a=function(e){var t=e.stop;delete e.stop,t(o)};return"string"!=typeof i&&(o=e,e=i,i=void 0),e&&this.queue(i||"fx",[]),this.each(function(){var e=!0,t=null!=i&&i+"queueHooks",n=S.timers,r=Y.get(this);if(t)r[t]&&r[t].stop&&a(r[t]);else for(t in r)r[t]&&r[t].stop&&at.test(t)&&a(r[t]);for(t=n.length;t--;)n[t].elem!==this||null!=i&&n[t].queue!==i||(n[t].anim.stop(o),e=!1,n.splice(t,1));!e&&o||S.dequeue(this,i)})},finish:function(a){return!1!==a&&(a=a||"fx"),this.each(function(){var e,t=Y.get(this),n=t[a+"queue"],r=t[a+"queueHooks"],i=S.timers,o=n?n.length:0;for(t.finish=!0,S.queue(this,a,[]),r&&r.stop&&r.stop.call(this,!0),e=i.length;e--;)i[e].elem===this&&i[e].queue===a&&(i[e].anim.stop(!0),i.splice(e,1));for(e=0;e<o;e++)n[e]&&n[e].finish&&n[e].finish.call(this);delete t.finish})}}),S.each(["toggle","show","hide"],function(e,r){var i=S.fn[r];S.fn[r]=function(e,t,n){return null==e||"boolean"==typeof e?i.apply(this,arguments):this.animate(lt(r,!0),e,t,n)}}),S.each({slideDown:lt("show"),slideUp:lt("hide"),slideToggle:lt("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(e,r){S.fn[e]=function(e,t,n){return this.animate(r,e,t,n)}}),S.timers=[],S.fx.tick=function(){var e,t=0,n=S.timers;for(tt=Date.now();t<n.length;t++)(e=n[t])()||n[t]!==e||n.splice(t--,1);n.length||S.fx.stop(),tt=void 0},S.fx.timer=function(e){S.timers.push(e),S.fx.start()},S.fx.interval=13,S.fx.start=function(){nt||(nt=!0,st())},S.fx.stop=function(){nt=null},S.fx.speeds={slow:600,fast:200,_default:400},S.fn.delay=function(r,e){return r=S.fx&&S.fx.speeds[r]||r,e=e||"fx",this.queue(e,function(e,t){var n=C.setTimeout(e,r);t.stop=function(){C.clearTimeout(n)}})},rt=E.createElement("input"),it=E.createElement("select").appendChild(E.createElement("option")),rt.type="checkbox",v.checkOn=""!==rt.value,v.optSelected=it.selected,(rt=E.createElement("input")).value="t",rt.type="radio",v.radioValue="t"===rt.value;var pt,dt=S.expr.attrHandle;S.fn.extend({attr:function(e,t){return B(this,S.attr,e,t,1<arguments.length)},removeAttr:function(e){return this.each(function(){S.removeAttr(this,e)})}}),S.extend({attr:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return"undefined"==typeof e.getAttribute?S.prop(e,t,n):(1===o&&S.isXMLDoc(e)||(i=S.attrHooks[t.toLowerCase()]||(S.expr.match.bool.test(t)?pt:void 0)),void 0!==n?null===n?void S.removeAttr(e,t):i&&"set"in i&&void 0!==(r=i.set(e,n,t))?r:(e.setAttribute(t,n+""),n):i&&"get"in i&&null!==(r=i.get(e,t))?r:null==(r=S.find.attr(e,t))?void 0:r)},attrHooks:{type:{set:function(e,t){if(!v.radioValue&&"radio"===t&&A(e,"input")){var n=e.value;return e.setAttribute("type",t),n&&(e.value=n),t}}}},removeAttr:function(e,t){var n,r=0,i=t&&t.match(P);if(i&&1===e.nodeType)while(n=i[r++])e.removeAttribute(n)}}),pt={set:function(e,t,n){return!1===t?S.removeAttr(e,n):e.setAttribute(n,n),n}},S.each(S.expr.match.bool.source.match(/\w+/g),function(e,t){var a=dt[t]||S.find.attr;dt[t]=function(e,t,n){var r,i,o=t.toLowerCase();return n||(i=dt[o],dt[o]=r,r=null!=a(e,t,n)?o:null,dt[o]=i),r}});var ht=/^(?:input|select|textarea|button)$/i,gt=/^(?:a|area)$/i;function yt(e){return(e.match(P)||[]).join(" ")}function vt(e){return e.getAttribute&&e.getAttribute("class")||""}function mt(e){return Array.isArray(e)?e:"string"==typeof e&&e.match(P)||[]}S.fn.extend({prop:function(e,t){return B(this,S.prop,e,t,1<arguments.length)},removeProp:function(e){return this.each(function(){delete this[S.propFix[e]||e]})}}),S.extend({prop:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return 1===o&&S.isXMLDoc(e)||(t=S.propFix[t]||t,i=S.propHooks[t]),void 0!==n?i&&"set"in i&&void 0!==(r=i.set(e,n,t))?r:e[t]=n:i&&"get"in i&&null!==(r=i.get(e,t))?r:e[t]},propHooks:{tabIndex:{get:function(e){var t=S.find.attr(e,"tabindex");return t?parseInt(t,10):ht.test(e.nodeName)||gt.test(e.nodeName)&&e.href?0:-1}}},propFix:{"for":"htmlFor","class":"className"}}),v.optSelected||(S.propHooks.selected={get:function(e){var t=e.parentNode;return t&&t.parentNode&&t.parentNode.selectedIndex,null},set:function(e){var t=e.parentNode;t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex)}}),S.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){S.propFix[this.toLowerCase()]=this}),S.fn.extend({addClass:function(t){var e,n,r,i,o,a;return m(t)?this.each(function(e){S(this).addClass(t.call(this,e,vt(this)))}):(e=mt(t)).length?this.each(function(){if(r=vt(this),n=1===this.nodeType&&" "+yt(r)+" "){for(o=0;o<e.length;o++)i=e[o],n.indexOf(" "+i+" ")<0&&(n+=i+" ");a=yt(n),r!==a&&this.setAttribute("class",a)}}):this},removeClass:function(t){var e,n,r,i,o,a;return m(t)?this.each(function(e){S(this).removeClass(t.call(this,e,vt(this)))}):arguments.length?(e=mt(t)).length?this.each(function(){if(r=vt(this),n=1===this.nodeType&&" "+yt(r)+" "){for(o=0;o<e.length;o++){i=e[o];while(-1<n.indexOf(" "+i+" "))n=n.replace(" "+i+" "," ")}a=yt(n),r!==a&&this.setAttribute("class",a)}}):this:this.attr("class","")},toggleClass:function(t,n){var e,r,i,o,a=typeof t,s="string"===a||Array.isArray(t);return m(t)?this.each(function(e){S(this).toggleClass(t.call(this,e,vt(this),n),n)}):"boolean"==typeof n&&s?n?this.addClass(t):this.removeClass(t):(e=mt(t),this.each(function(){if(s)for(o=S(this),i=0;i<e.length;i++)r=e[i],o.hasClass(r)?o.removeClass(r):o.addClass(r);else void 0!==t&&"boolean"!==a||((r=vt(this))&&Y.set(this,"__className__",r),this.setAttribute&&this.setAttribute("class",r||!1===t?"":Y.get(this,"__className__")||""))}))},hasClass:function(e){var t,n,r=0;t=" "+e+" ";while(n=this[r++])if(1===n.nodeType&&-1<(" "+yt(vt(n))+" ").indexOf(t))return!0;return!1}});var xt=/\r/g;S.fn.extend({val:function(n){var r,e,i,t=this[0];return arguments.length?(i=m(n),this.each(function(e){var t;1===this.nodeType&&(null==(t=i?n.call(this,e,S(this).val()):n)?t="":"number"==typeof t?t+="":Array.isArray(t)&&(t=S.map(t,function(e){return null==e?"":e+""})),(r=S.valHooks[this.type]||S.valHooks[this.nodeName.toLowerCase()])&&"set"in r&&void 0!==r.set(this,t,"value")||(this.value=t))})):t?(r=S.valHooks[t.type]||S.valHooks[t.nodeName.toLowerCase()])&&"get"in r&&void 0!==(e=r.get(t,"value"))?e:"string"==typeof(e=t.value)?e.replace(xt,""):null==e?"":e:void 0}}),S.extend({valHooks:{option:{get:function(e){var t=S.find.attr(e,"value");return null!=t?t:yt(S.text(e))}},select:{get:function(e){var t,n,r,i=e.options,o=e.selectedIndex,a="select-one"===e.type,s=a?null:[],u=a?o+1:i.length;for(r=o<0?u:a?o:0;r<u;r++)if(((n=i[r]).selected||r===o)&&!n.disabled&&(!n.parentNode.disabled||!A(n.parentNode,"optgroup"))){if(t=S(n).val(),a)return t;s.push(t)}return s},set:function(e,t){var n,r,i=e.options,o=S.makeArray(t),a=i.length;while(a--)((r=i[a]).selected=-1<S.inArray(S.valHooks.option.get(r),o))&&(n=!0);return n||(e.selectedIndex=-1),o}}}}),S.each(["radio","checkbox"],function(){S.valHooks[this]={set:function(e,t){if(Array.isArray(t))return e.checked=-1<S.inArray(S(e).val(),t)}},v.checkOn||(S.valHooks[this].get=function(e){return null===e.getAttribute("value")?"on":e.value})}),v.focusin="onfocusin"in C;var bt=/^(?:focusinfocus|focusoutblur)$/,wt=function(e){e.stopPropagation()};S.extend(S.event,{trigger:function(e,t,n,r){var i,o,a,s,u,l,c,f,p=[n||E],d=y.call(e,"type")?e.type:e,h=y.call(e,"namespace")?e.namespace.split("."):[];if(o=f=a=n=n||E,3!==n.nodeType&&8!==n.nodeType&&!bt.test(d+S.event.triggered)&&(-1<d.indexOf(".")&&(d=(h=d.split(".")).shift(),h.sort()),u=d.indexOf(":")<0&&"on"+d,(e=e[S.expando]?e:new S.Event(d,"object"==typeof e&&e)).isTrigger=r?2:3,e.namespace=h.join("."),e.rnamespace=e.namespace?new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,e.result=void 0,e.target||(e.target=n),t=null==t?[e]:S.makeArray(t,[e]),c=S.event.special[d]||{},r||!c.trigger||!1!==c.trigger.apply(n,t))){if(!r&&!c.noBubble&&!x(n)){for(s=c.delegateType||d,bt.test(s+d)||(o=o.parentNode);o;o=o.parentNode)p.push(o),a=o;a===(n.ownerDocument||E)&&p.push(a.defaultView||a.parentWindow||C)}i=0;while((o=p[i++])&&!e.isPropagationStopped())f=o,e.type=1<i?s:c.bindType||d,(l=(Y.get(o,"events")||Object.create(null))[e.type]&&Y.get(o,"handle"))&&l.apply(o,t),(l=u&&o[u])&&l.apply&&V(o)&&(e.result=l.apply(o,t),!1===e.result&&e.preventDefault());return e.type=d,r||e.isDefaultPrevented()||c._default&&!1!==c._default.apply(p.pop(),t)||!V(n)||u&&m(n[d])&&!x(n)&&((a=n[u])&&(n[u]=null),S.event.triggered=d,e.isPropagationStopped()&&f.addEventListener(d,wt),n[d](),e.isPropagationStopped()&&f.removeEventListener(d,wt),S.event.triggered=void 0,a&&(n[u]=a)),e.result}},simulate:function(e,t,n){var r=S.extend(new S.Event,n,{type:e,isSimulated:!0});S.event.trigger(r,null,t)}}),S.fn.extend({trigger:function(e,t){return this.each(function(){S.event.trigger(e,t,this)})},triggerHandler:function(e,t){var n=this[0];if(n)return S.event.trigger(e,t,n,!0)}}),v.focusin||S.each({focus:"focusin",blur:"focusout"},function(n,r){var i=function(e){S.event.simulate(r,e.target,S.event.fix(e))};S.event.special[r]={setup:function(){var e=this.ownerDocument||this.document||this,t=Y.access(e,r);t||e.addEventListener(n,i,!0),Y.access(e,r,(t||0)+1)},teardown:function(){var e=this.ownerDocument||this.document||this,t=Y.access(e,r)-1;t?Y.access(e,r,t):(e.removeEventListener(n,i,!0),Y.remove(e,r))}}});var Tt=C.location,Ct={guid:Date.now()},Et=/\?/;S.parseXML=function(e){var t,n;if(!e||"string"!=typeof e)return null;try{t=(new C.DOMParser).parseFromString(e,"text/xml")}catch(e){}return n=t&&t.getElementsByTagName("parsererror")[0],t&&!n||S.error("Invalid XML: "+(n?S.map(n.childNodes,function(e){return e.textContent}).join("\n"):e)),t};var St=/\[\]$/,kt=/\r?\n/g,At=/^(?:submit|button|image|reset|file)$/i,Nt=/^(?:input|select|textarea|keygen)/i;function jt(n,e,r,i){var t;if(Array.isArray(e))S.each(e,function(e,t){r||St.test(n)?i(n,t):jt(n+"["+("object"==typeof t&&null!=t?e:"")+"]",t,r,i)});else if(r||"object"!==w(e))i(n,e);else for(t in e)jt(n+"["+t+"]",e[t],r,i)}S.param=function(e,t){var n,r=[],i=function(e,t){var n=m(t)?t():t;r[r.length]=encodeURIComponent(e)+"="+encodeURIComponent(null==n?"":n)};if(null==e)return"";if(Array.isArray(e)||e.jquery&&!S.isPlainObject(e))S.each(e,function(){i(this.name,this.value)});else for(n in e)jt(n,e[n],t,i);return r.join("&")},S.fn.extend({serialize:function(){return S.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var e=S.prop(this,"elements");return e?S.makeArray(e):this}).filter(function(){var e=this.type;return this.name&&!S(this).is(":disabled")&&Nt.test(this.nodeName)&&!At.test(e)&&(this.checked||!pe.test(e))}).map(function(e,t){var n=S(this).val();return null==n?null:Array.isArray(n)?S.map(n,function(e){return{name:t.name,value:e.replace(kt,"\r\n")}}):{name:t.name,value:n.replace(kt,"\r\n")}}).get()}});var Dt=/%20/g,qt=/#.*$/,Lt=/([?&])_=[^&]*/,Ht=/^(.*?):[ \t]*([^\r\n]*)$/gm,Ot=/^(?:GET|HEAD)$/,Pt=/^\/\//,Rt={},Mt={},It="*/".concat("*"),Wt=E.createElement("a");function Ft(o){return function(e,t){"string"!=typeof e&&(t=e,e="*");var n,r=0,i=e.toLowerCase().match(P)||[];if(m(t))while(n=i[r++])"+"===n[0]?(n=n.slice(1)||"*",(o[n]=o[n]||[]).unshift(t)):(o[n]=o[n]||[]).push(t)}}function $t(t,i,o,a){var s={},u=t===Mt;function l(e){var r;return s[e]=!0,S.each(t[e]||[],function(e,t){var n=t(i,o,a);return"string"!=typeof n||u||s[n]?u?!(r=n):void 0:(i.dataTypes.unshift(n),l(n),!1)}),r}return l(i.dataTypes[0])||!s["*"]&&l("*")}function Bt(e,t){var n,r,i=S.ajaxSettings.flatOptions||{};for(n in t)void 0!==t[n]&&((i[n]?e:r||(r={}))[n]=t[n]);return r&&S.extend(!0,e,r),e}Wt.href=Tt.href,S.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:Tt.href,type:"GET",isLocal:/^(?:about|app|app-storage|.+-extension|file|res|widget):$/.test(Tt.protocol),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":It,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/\bxml\b/,html:/\bhtml/,json:/\bjson\b/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":JSON.parse,"text xml":S.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(e,t){return t?Bt(Bt(e,S.ajaxSettings),t):Bt(S.ajaxSettings,e)},ajaxPrefilter:Ft(Rt),ajaxTransport:Ft(Mt),ajax:function(e,t){"object"==typeof e&&(t=e,e=void 0),t=t||{};var c,f,p,n,d,r,h,g,i,o,y=S.ajaxSetup({},t),v=y.context||y,m=y.context&&(v.nodeType||v.jquery)?S(v):S.event,x=S.Deferred(),b=S.Callbacks("once memory"),w=y.statusCode||{},a={},s={},u="canceled",T={readyState:0,getResponseHeader:function(e){var t;if(h){if(!n){n={};while(t=Ht.exec(p))n[t[1].toLowerCase()+" "]=(n[t[1].toLowerCase()+" "]||[]).concat(t[2])}t=n[e.toLowerCase()+" "]}return null==t?null:t.join(", ")},getAllResponseHeaders:function(){return h?p:null},setRequestHeader:function(e,t){return null==h&&(e=s[e.toLowerCase()]=s[e.toLowerCase()]||e,a[e]=t),this},overrideMimeType:function(e){return null==h&&(y.mimeType=e),this},statusCode:function(e){var t;if(e)if(h)T.always(e[T.status]);else for(t in e)w[t]=[w[t],e[t]];return this},abort:function(e){var t=e||u;return c&&c.abort(t),l(0,t),this}};if(x.promise(T),y.url=((e||y.url||Tt.href)+"").replace(Pt,Tt.protocol+"//"),y.type=t.method||t.type||y.method||y.type,y.dataTypes=(y.dataType||"*").toLowerCase().match(P)||[""],null==y.crossDomain){r=E.createElement("a");try{r.href=y.url,r.href=r.href,y.crossDomain=Wt.protocol+"//"+Wt.host!=r.protocol+"//"+r.host}catch(e){y.crossDomain=!0}}if(y.data&&y.processData&&"string"!=typeof y.data&&(y.data=S.param(y.data,y.traditional)),$t(Rt,y,t,T),h)return T;for(i in(g=S.event&&y.global)&&0==S.active++&&S.event.trigger("ajaxStart"),y.type=y.type.toUpperCase(),y.hasContent=!Ot.test(y.type),f=y.url.replace(qt,""),y.hasContent?y.data&&y.processData&&0===(y.contentType||"").indexOf("application/x-www-form-urlencoded")&&(y.data=y.data.replace(Dt,"+")):(o=y.url.slice(f.length),y.data&&(y.processData||"string"==typeof y.data)&&(f+=(Et.test(f)?"&":"?")+y.data,delete y.data),!1===y.cache&&(f=f.replace(Lt,"$1"),o=(Et.test(f)?"&":"?")+"_="+Ct.guid+++o),y.url=f+o),y.ifModified&&(S.lastModified[f]&&T.setRequestHeader("If-Modified-Since",S.lastModified[f]),S.etag[f]&&T.setRequestHeader("If-None-Match",S.etag[f])),(y.data&&y.hasContent&&!1!==y.contentType||t.contentType)&&T.setRequestHeader("Content-Type",y.contentType),T.setRequestHeader("Accept",y.dataTypes[0]&&y.accepts[y.dataTypes[0]]?y.accepts[y.dataTypes[0]]+("*"!==y.dataTypes[0]?", "+It+"; q=0.01":""):y.accepts["*"]),y.headers)T.setRequestHeader(i,y.headers[i]);if(y.beforeSend&&(!1===y.beforeSend.call(v,T,y)||h))return T.abort();if(u="abort",b.add(y.complete),T.done(y.success),T.fail(y.error),c=$t(Mt,y,t,T)){if(T.readyState=1,g&&m.trigger("ajaxSend",[T,y]),h)return T;y.async&&0<y.timeout&&(d=C.setTimeout(function(){T.abort("timeout")},y.timeout));try{h=!1,c.send(a,l)}catch(e){if(h)throw e;l(-1,e)}}else l(-1,"No Transport");function l(e,t,n,r){var i,o,a,s,u,l=t;h||(h=!0,d&&C.clearTimeout(d),c=void 0,p=r||"",T.readyState=0<e?4:0,i=200<=e&&e<300||304===e,n&&(s=function(e,t,n){var r,i,o,a,s=e.contents,u=e.dataTypes;while("*"===u[0])u.shift(),void 0===r&&(r=e.mimeType||t.getResponseHeader("Content-Type"));if(r)for(i in s)if(s[i]&&s[i].test(r)){u.unshift(i);break}if(u[0]in n)o=u[0];else{for(i in n){if(!u[0]||e.converters[i+" "+u[0]]){o=i;break}a||(a=i)}o=o||a}if(o)return o!==u[0]&&u.unshift(o),n[o]}(y,T,n)),!i&&-1<S.inArray("script",y.dataTypes)&&S.inArray("json",y.dataTypes)<0&&(y.converters["text script"]=function(){}),s=function(e,t,n,r){var i,o,a,s,u,l={},c=e.dataTypes.slice();if(c[1])for(a in e.converters)l[a.toLowerCase()]=e.converters[a];o=c.shift();while(o)if(e.responseFields[o]&&(n[e.responseFields[o]]=t),!u&&r&&e.dataFilter&&(t=e.dataFilter(t,e.dataType)),u=o,o=c.shift())if("*"===o)o=u;else if("*"!==u&&u!==o){if(!(a=l[u+" "+o]||l["* "+o]))for(i in l)if((s=i.split(" "))[1]===o&&(a=l[u+" "+s[0]]||l["* "+s[0]])){!0===a?a=l[i]:!0!==l[i]&&(o=s[0],c.unshift(s[1]));break}if(!0!==a)if(a&&e["throws"])t=a(t);else try{t=a(t)}catch(e){return{state:"parsererror",error:a?e:"No conversion from "+u+" to "+o}}}return{state:"success",data:t}}(y,s,T,i),i?(y.ifModified&&((u=T.getResponseHeader("Last-Modified"))&&(S.lastModified[f]=u),(u=T.getResponseHeader("etag"))&&(S.etag[f]=u)),204===e||"HEAD"===y.type?l="nocontent":304===e?l="notmodified":(l=s.state,o=s.data,i=!(a=s.error))):(a=l,!e&&l||(l="error",e<0&&(e=0))),T.status=e,T.statusText=(t||l)+"",i?x.resolveWith(v,[o,l,T]):x.rejectWith(v,[T,l,a]),T.statusCode(w),w=void 0,g&&m.trigger(i?"ajaxSuccess":"ajaxError",[T,y,i?o:a]),b.fireWith(v,[T,l]),g&&(m.trigger("ajaxComplete",[T,y]),--S.active||S.event.trigger("ajaxStop")))}return T},getJSON:function(e,t,n){return S.get(e,t,n,"json")},getScript:function(e,t){return S.get(e,void 0,t,"script")}}),S.each(["get","post"],function(e,i){S[i]=function(e,t,n,r){return m(t)&&(r=r||n,n=t,t=void 0),S.ajax(S.extend({url:e,type:i,dataType:r,data:t,success:n},S.isPlainObject(e)&&e))}}),S.ajaxPrefilter(function(e){var t;for(t in e.headers)"content-type"===t.toLowerCase()&&(e.contentType=e.headers[t]||"")}),S._evalUrl=function(e,t,n){return S.ajax({url:e,type:"GET",dataType:"script",cache:!0,async:!1,global:!1,converters:{"text script":function(){}},dataFilter:function(e){S.globalEval(e,t,n)}})},S.fn.extend({wrapAll:function(e){var t;return this[0]&&(m(e)&&(e=e.call(this[0])),t=S(e,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){var e=this;while(e.firstElementChild)e=e.firstElementChild;return e}).append(this)),this},wrapInner:function(n){return m(n)?this.each(function(e){S(this).wrapInner(n.call(this,e))}):this.each(function(){var e=S(this),t=e.contents();t.length?t.wrapAll(n):e.append(n)})},wrap:function(t){var n=m(t);return this.each(function(e){S(this).wrapAll(n?t.call(this,e):t)})},unwrap:function(e){return this.parent(e).not("body").each(function(){S(this).replaceWith(this.childNodes)}),this}}),S.expr.pseudos.hidden=function(e){return!S.expr.pseudos.visible(e)},S.expr.pseudos.visible=function(e){return!!(e.offsetWidth||e.offsetHeight||e.getClientRects().length)},S.ajaxSettings.xhr=function(){try{return new C.XMLHttpRequest}catch(e){}};var _t={0:200,1223:204},zt=S.ajaxSettings.xhr();v.cors=!!zt&&"withCredentials"in zt,v.ajax=zt=!!zt,S.ajaxTransport(function(i){var o,a;if(v.cors||zt&&!i.crossDomain)return{send:function(e,t){var n,r=i.xhr();if(r.open(i.type,i.url,i.async,i.username,i.password),i.xhrFields)for(n in i.xhrFields)r[n]=i.xhrFields[n];for(n in i.mimeType&&r.overrideMimeType&&r.overrideMimeType(i.mimeType),i.crossDomain||e["X-Requested-With"]||(e["X-Requested-With"]="XMLHttpRequest"),e)r.setRequestHeader(n,e[n]);o=function(e){return function(){o&&(o=a=r.onload=r.onerror=r.onabort=r.ontimeout=r.onreadystatechange=null,"abort"===e?r.abort():"error"===e?"number"!=typeof r.status?t(0,"error"):t(r.status,r.statusText):t(_t[r.status]||r.status,r.statusText,"text"!==(r.responseType||"text")||"string"!=typeof r.responseText?{binary:r.response}:{text:r.responseText},r.getAllResponseHeaders()))}},r.onload=o(),a=r.onerror=r.ontimeout=o("error"),void 0!==r.onabort?r.onabort=a:r.onreadystatechange=function(){4===r.readyState&&C.setTimeout(function(){o&&a()})},o=o("abort");try{r.send(i.hasContent&&i.data||null)}catch(e){if(o)throw e}},abort:function(){o&&o()}}}),S.ajaxPrefilter(function(e){e.crossDomain&&(e.contents.script=!1)}),S.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(e){return S.globalEval(e),e}}}),S.ajaxPrefilter("script",function(e){void 0===e.cache&&(e.cache=!1),e.crossDomain&&(e.type="GET")}),S.ajaxTransport("script",function(n){var r,i;if(n.crossDomain||n.scriptAttrs)return{send:function(e,t){r=S("<script>").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var Ut,Xt=[],Vt=/(=)\?(?=&|$)|\?\?/;S.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Xt.pop()||S.expando+"_"+Ct.guid++;return this[e]=!0,e}}),S.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Vt.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Vt.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Vt,"$1"+r):!1!==e.jsonp&&(e.url+=(Et.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||S.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?S(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,Xt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),v.createHTMLDocument=((Ut=E.implementation.createHTMLDocument("").body).innerHTML="<form></form><form></form>",2===Ut.childNodes.length),S.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(v.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=N.exec(e))?[t.createElement(i[1])]:(i=xe([e],t,o),o&&o.length&&S(o).remove(),S.merge([],i.childNodes)));var r,i,o},S.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1<s&&(r=yt(e.slice(s)),e=e.slice(0,s)),m(t)?(n=t,t=void 0):t&&"object"==typeof t&&(i="POST"),0<a.length&&S.ajax({url:e,type:i||"GET",dataType:"html",data:t}).done(function(e){o=arguments,a.html(r?S("<div>").append(S.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},S.expr.pseudos.animated=function(t){return S.grep(S.timers,function(e){return t===e.elem}).length},S.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=S.css(e,"position"),c=S(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=S.css(e,"top"),u=S.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),m(t)&&(t=t.call(e,n,S.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):c.css(f)}},S.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){S.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===S.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===S.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=S(e).offset()).top+=S.css(e,"borderTopWidth",!0),i.left+=S.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-S.css(r,"marginTop",!0),left:t.left-i.left-S.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===S.css(e,"position"))e=e.offsetParent;return e||re})}}),S.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;S.fn[t]=function(e){return B(this,function(e,t,n){var r;if(x(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),S.each(["top","left"],function(e,n){S.cssHooks[n]=_e(v.pixelPosition,function(e,t){if(t)return t=Be(e,n),Pe.test(t)?S(e).position()[n]+"px":t})}),S.each({Height:"height",Width:"width"},function(a,s){S.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){S.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return B(this,function(e,t,n){var r;return x(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?S.css(e,t,i):S.style(e,t,n,i)},s,n?e:void 0,n)}})}),S.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){S.fn[t]=function(e){return this.on(t,e)}}),S.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),S.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){S.fn[n]=function(e,t){return 0<arguments.length?this.on(n,null,e,t):this.trigger(n)}});var Gt=/^[\s\uFEFF\xA0]+|([^\s\uFEFF\xA0])[\s\uFEFF\xA0]+$/g;S.proxy=function(e,t){var n,r,i;if("string"==typeof t&&(n=e[t],t=e,e=n),m(e))return r=s.call(arguments,2),(i=function(){return e.apply(t||this,r.concat(s.call(arguments)))}).guid=e.guid=e.guid||S.guid++,i},S.holdReady=function(e){e?S.readyWait++:S.ready(!0)},S.isArray=Array.isArray,S.parseJSON=JSON.parse,S.nodeName=A,S.isFunction=m,S.isWindow=x,S.camelCase=X,S.type=w,S.now=Date.now,S.isNumeric=function(e){var t=S.type(e);return("number"===t||"string"===t)&&!isNaN(e-parseFloat(e))},S.trim=function(e){return null==e?"":(e+"").replace(Gt,"$1")},"function"==typeof define&&define.amd&&define("jquery",[],function(){return S});var Yt=C.jQuery,Qt=C.$;return S.noConflict=function(e){return C.$===S&&(C.$=Qt),e&&C.jQuery===S&&(C.jQuery=Yt),S},"undefined"==typeof e&&(C.jQuery=C.$=S),S});
33845 /* nvd3 version 1.8.1 (https://github.com/novus/nvd3) 2015-06-15 */
33846 !function(){var a={};a.dev=!1,a.tooltip=a.tooltip||{},a.utils=a.utils||{},a.models=a.models||{},a.charts={},a.logs={},a.dom={},a.dispatch=d3.dispatch("render_start","render_end"),Function.prototype.bind||(Function.prototype.bind=function(a){if("function"!=typeof this)throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");var b=Array.prototype.slice.call(arguments,1),c=this,d=function(){},e=function(){return c.apply(this instanceof d&&a?this:a,b.concat(Array.prototype.slice.call(arguments)))};return d.prototype=this.prototype,e.prototype=new d,e}),a.dev&&(a.dispatch.on("render_start",function(){a.logs.startTime=+new Date}),a.dispatch.on("render_end",function(){a.logs.endTime=+new Date,a.logs.totalTime=a.logs.endTime-a.logs.startTime,a.log("total",a.logs.totalTime)})),a.log=function(){if(a.dev&&window.console&&console.log&&console.log.apply)console.log.apply(console,arguments);else if(a.dev&&window.console&&"function"==typeof console.log&&Function.prototype.bind){var b=Function.prototype.bind.call(console.log,console);b.apply(console,arguments)}return arguments[arguments.length-1]},a.deprecated=function(a,b){console&&console.warn&&console.warn("nvd3 warning: `"+a+"` has been deprecated. ",b||"")},a.render=function(b){b=b||1,a.render.active=!0,a.dispatch.render_start();var c=function(){for(var d,e,f=0;b>f&&(e=a.render.queue[f]);f++)d=e.generate(),typeof e.callback==typeof Function&&e.callback(d);a.render.queue.splice(0,f),a.render.queue.length?setTimeout(c):(a.dispatch.render_end(),a.render.active=!1)};setTimeout(c)},a.render.active=!1,a.render.queue=[],a.addGraph=function(b){typeof arguments[0]==typeof Function&&(b={generate:arguments[0],callback:arguments[1]}),a.render.queue.push(b),a.render.active||a.render()},"undefined"!=typeof module&&"undefined"!=typeof exports&&(module.exports=a),"undefined"!=typeof window&&(window.nv=a),a.dom.write=function(a){return void 0!==window.fastdom?fastdom.write(a):a()},a.dom.read=function(a){return void 0!==window.fastdom?fastdom.read(a):a()},a.interactiveGuideline=function(){"use strict";function b(l){l.each(function(l){function m(){var a=d3.mouse(this),d=a[0],e=a[1],i=!0,j=!1;if(k&&(d=d3.event.offsetX,e=d3.event.offsetY,"svg"!==d3.event.target.tagName&&(i=!1),d3.event.target.className.baseVal.match("nv-legend")&&(j=!0)),i&&(d-=f.left,e-=f.top),0>d||0>e||d>o||e>p||d3.event.relatedTarget&&void 0===d3.event.relatedTarget.ownerSVGElement||j){if(k&&d3.event.relatedTarget&&void 0===d3.event.relatedTarget.ownerSVGElement&&(void 0===d3.event.relatedTarget.className||d3.event.relatedTarget.className.match(c.nvPointerEventsClass)))return;return h.elementMouseout({mouseX:d,mouseY:e}),b.renderGuideLine(null),void c.hidden(!0)}c.hidden(!1);var l=g.invert(d);h.elementMousemove({mouseX:d,mouseY:e,pointXValue:l}),"dblclick"===d3.event.type&&h.elementDblclick({mouseX:d,mouseY:e,pointXValue:l}),"click"===d3.event.type&&h.elementClick({mouseX:d,mouseY:e,pointXValue:l})}var n=d3.select(this),o=d||960,p=e||400,q=n.selectAll("g.nv-wrap.nv-interactiveLineLayer").data([l]),r=q.enter().append("g").attr("class"," nv-wrap nv-interactiveLineLayer");r.append("g").attr("class","nv-interactiveGuideLine"),j&&(j.on("touchmove",m).on("mousemove",m,!0).on("mouseout",m,!0).on("dblclick",m).on("click",m),b.guideLine=null,b.renderGuideLine=function(c){i&&(b.guideLine&&b.guideLine.attr("x1")===c||a.dom.write(function(){var b=q.select(".nv-interactiveGuideLine").selectAll("line").data(null!=c?[a.utils.NaNtoZero(c)]:[],String);b.enter().append("line").attr("class","nv-guideline").attr("x1",function(a){return a}).attr("x2",function(a){return a}).attr("y1",p).attr("y2",0),b.exit().remove()}))})})}var c=a.models.tooltip();c.duration(0).hideDelay(0)._isInteractiveLayer(!0).hidden(!1);var d=null,e=null,f={left:0,top:0},g=d3.scale.linear(),h=d3.dispatch("elementMousemove","elementMouseout","elementClick","elementDblclick"),i=!0,j=null,k="ActiveXObject"in window;return b.dispatch=h,b.tooltip=c,b.margin=function(a){return arguments.length?(f.top="undefined"!=typeof a.top?a.top:f.top,f.left="undefined"!=typeof a.left?a.left:f.left,b):f},b.width=function(a){return arguments.length?(d=a,b):d},b.height=function(a){return arguments.length?(e=a,b):e},b.xScale=function(a){return arguments.length?(g=a,b):g},b.showGuideLine=function(a){return arguments.length?(i=a,b):i},b.svgContainer=function(a){return arguments.length?(j=a,b):j},b},a.interactiveBisect=function(a,b,c){"use strict";if(!(a instanceof Array))return null;var d;d="function"!=typeof c?function(a){return a.x}:c;var e=function(a,b){return d(a)-b},f=d3.bisector(e).left,g=d3.max([0,f(a,b)-1]),h=d(a[g]);if("undefined"==typeof h&&(h=g),h===b)return g;var i=d3.min([g+1,a.length-1]),j=d(a[i]);return"undefined"==typeof j&&(j=i),Math.abs(j-b)>=Math.abs(h-b)?g:i},a.nearestValueIndex=function(a,b,c){"use strict";var d=1/0,e=null;return a.forEach(function(a,f){var g=Math.abs(b-a);null!=a&&d>=g&&c>g&&(d=g,e=f)}),e},function(){"use strict";a.models.tooltip=function(){function b(){if(k){var a=d3.select(k);"svg"!==a.node().tagName&&(a=a.select("svg"));var b=a.node()?a.attr("viewBox"):null;if(b){b=b.split(" ");var c=parseInt(a.style("width"),10)/b[2];p.left=p.left*c,p.top=p.top*c}}}function c(){if(!n){var a;a=k?k:document.body,n=d3.select(a).append("div").attr("class","nvtooltip "+(j?j:"xy-tooltip")).attr("id",v),n.style("top",0).style("left",0),n.style("opacity",0),n.selectAll("div, table, td, tr").classed(w,!0),n.classed(w,!0),o=n.node()}}function d(){if(r&&B(e)){b();var f=p.left,g=null!==i?i:p.top;return a.dom.write(function(){c();var b=A(e);b&&(o.innerHTML=b),k&&u?a.dom.read(function(){var a=k.getElementsByTagName("svg")[0],b={left:0,top:0};if(a){var c=a.getBoundingClientRect(),d=k.getBoundingClientRect(),e=c.top;if(0>e){var i=k.getBoundingClientRect();e=Math.abs(e)>i.height?0:e}b.top=Math.abs(e-d.top),b.left=Math.abs(c.left-d.left)}f+=k.offsetLeft+b.left-2*k.scrollLeft,g+=k.offsetTop+b.top-2*k.scrollTop,h&&h>0&&(g=Math.floor(g/h)*h),C([f,g])}):C([f,g])}),d}}var e=null,f="w",g=25,h=0,i=null,j=null,k=null,l=!0,m=400,n=null,o=null,p={left:null,top:null},q={left:0,top:0},r=!0,s=100,t=!0,u=!1,v="nvtooltip-"+Math.floor(1e5*Math.random()),w="nv-pointer-events-none",x=function(a){return a},y=function(a){return a},z=function(a){return a},A=function(a){if(null===a)return"";var b=d3.select(document.createElement("table"));if(t){var c=b.selectAll("thead").data([a]).enter().append("thead");c.append("tr").append("td").attr("colspan",3).append("strong").classed("x-value",!0).html(y(a.value))}var d=b.selectAll("tbody").data([a]).enter().append("tbody"),e=d.selectAll("tr").data(function(a){return a.series}).enter().append("tr").classed("highlight",function(a){return a.highlight});e.append("td").classed("legend-color-guide",!0).append("div").style("background-color",function(a){return a.color}),e.append("td").classed("key",!0).html(function(a,b){return z(a.key,b)}),e.append("td").classed("value",!0).html(function(a,b){return x(a.value,b)}),e.selectAll("td").each(function(a){if(a.highlight){var b=d3.scale.linear().domain([0,1]).range(["#fff",a.color]),c=.6;d3.select(this).style("border-bottom-color",b(c)).style("border-top-color",b(c))}});var f=b.node().outerHTML;return void 0!==a.footer&&(f+="<div class='footer'>"+a.footer+"</div>"),f},B=function(a){if(a&&a.series){if(a.series instanceof Array)return!!a.series.length;if(a.series instanceof Object)return a.series=[a.series],!0}return!1},C=function(b){o&&a.dom.read(function(){var c,d,e=parseInt(o.offsetHeight,10),h=parseInt(o.offsetWidth,10),i=a.utils.windowSize().width,j=a.utils.windowSize().height,k=window.pageYOffset,p=window.pageXOffset;j=window.innerWidth>=document.body.scrollWidth?j:j-16,i=window.innerHeight>=document.body.scrollHeight?i:i-16;var r,t,u=function(a){var b=d;do isNaN(a.offsetTop)||(b+=a.offsetTop),a=a.offsetParent;while(a);return b},v=function(a){var b=c;do isNaN(a.offsetLeft)||(b+=a.offsetLeft),a=a.offsetParent;while(a);return b};switch(f){case"e":c=b[0]-h-g,d=b[1]-e/2,r=v(o),t=u(o),p>r&&(c=b[0]+g>p?b[0]+g:p-r+c),k>t&&(d=k-t+d),t+e>k+j&&(d=k+j-t+d-e);break;case"w":c=b[0]+g,d=b[1]-e/2,r=v(o),t=u(o),r+h>i&&(c=b[0]-h-g),k>t&&(d=k+5),t+e>k+j&&(d=k+j-t+d-e);break;case"n":c=b[0]-h/2-5,d=b[1]+g,r=v(o),t=u(o),p>r&&(c=p+5),r+h>i&&(c=c-h/2+5),t+e>k+j&&(d=k+j-t+d-e);break;case"s":c=b[0]-h/2,d=b[1]-e-g,r=v(o),t=u(o),p>r&&(c=p+5),r+h>i&&(c=c-h/2+5),k>t&&(d=k);break;case"none":c=b[0],d=b[1]-g,r=v(o),t=u(o)}c-=q.left,d-=q.top;var w=o.getBoundingClientRect(),k=window.pageYOffset||document.documentElement.scrollTop,p=window.pageXOffset||document.documentElement.scrollLeft,x="translate("+(w.left+p)+"px, "+(w.top+k)+"px)",y="translate("+c+"px, "+d+"px)",z=d3.interpolateString(x,y),A=n.style("opacity")<.1;l?n.transition().delay(m).duration(0).style("opacity",0):n.interrupt().transition().duration(A?0:s).styleTween("transform",function(){return z},"important").style("-webkit-transform",y).style("opacity",1)})};return d.nvPointerEventsClass=w,d.options=a.utils.optionsFunc.bind(d),d._options=Object.create({},{duration:{get:function(){return s},set:function(a){s=a}},gravity:{get:function(){return f},set:function(a){f=a}},distance:{get:function(){return g},set:function(a){g=a}},snapDistance:{get:function(){return h},set:function(a){h=a}},classes:{get:function(){return j},set:function(a){j=a}},chartContainer:{get:function(){return k},set:function(a){k=a}},fixedTop:{get:function(){return i},set:function(a){i=a}},enabled:{get:function(){return r},set:function(a){r=a}},hideDelay:{get:function(){return m},set:function(a){m=a}},contentGenerator:{get:function(){return A},set:function(a){A=a}},valueFormatter:{get:function(){return x},set:function(a){x=a}},headerFormatter:{get:function(){return y},set:function(a){y=a}},keyFormatter:{get:function(){return z},set:function(a){z=a}},headerEnabled:{get:function(){return t},set:function(a){t=a}},_isInteractiveLayer:{get:function(){return u},set:function(a){u=!!a}},position:{get:function(){return p},set:function(a){p.left=void 0!==a.left?a.left:p.left,p.top=void 0!==a.top?a.top:p.top}},offset:{get:function(){return q},set:function(a){q.left=void 0!==a.left?a.left:q.left,q.top=void 0!==a.top?a.top:q.top}},hidden:{get:function(){return l},set:function(a){l!=a&&(l=!!a,d())}},data:{get:function(){return e},set:function(a){a.point&&(a.value=a.point.x,a.series=a.series||{},a.series.value=a.point.y,a.series.color=a.point.color||a.series.color),e=a}},tooltipElem:{get:function(){return o},set:function(){}},id:{get:function(){return v},set:function(){}}}),a.utils.initOptions(d),d}}(),a.utils.windowSize=function(){var a={width:640,height:480};return window.innerWidth&&window.innerHeight?(a.width=window.innerWidth,a.height=window.innerHeight,a):"CSS1Compat"==document.compatMode&&document.documentElement&&document.documentElement.offsetWidth?(a.width=document.documentElement.offsetWidth,a.height=document.documentElement.offsetHeight,a):document.body&&document.body.offsetWidth?(a.width=document.body.offsetWidth,a.height=document.body.offsetHeight,a):a},a.utils.windowResize=function(b){return window.addEventListener?window.addEventListener("resize",b):a.log("ERROR: Failed to bind to window.resize with: ",b),{callback:b,clear:function(){window.removeEventListener("resize",b)}}},a.utils.getColor=function(b){if(void 0===b)return a.utils.defaultColor();if(Array.isArray(b)){var c=d3.scale.ordinal().range(b);return function(a,b){var d=void 0===b?a:b;return a.color||c(d)}}return b},a.utils.defaultColor=function(){return a.utils.getColor(d3.scale.category20().range())},a.utils.customTheme=function(a,b,c){b=b||function(a){return a.key},c=c||d3.scale.category20().range();var d=c.length;return function(e){var f=b(e);return"function"==typeof a[f]?a[f]():void 0!==a[f]?a[f]:(d||(d=c.length),d-=1,c[d])}},a.utils.pjax=function(b,c){var d=function(d){d3.html(d,function(d){var e=d3.select(c).node();e.parentNode.replaceChild(d3.select(d).select(c).node(),e),a.utils.pjax(b,c)})};d3.selectAll(b).on("click",function(){history.pushState(this.href,this.textContent,this.href),d(this.href),d3.event.preventDefault()}),d3.select(window).on("popstate",function(){d3.event.state&&d(d3.event.state)})},a.utils.calcApproxTextWidth=function(a){if("function"==typeof a.style&&"function"==typeof a.text){var b=parseInt(a.style("font-size").replace("px",""),10),c=a.text().length;return c*b*.5}return 0},a.utils.NaNtoZero=function(a){return"number"!=typeof a||isNaN(a)||null===a||1/0===a||a===-1/0?0:a},d3.selection.prototype.watchTransition=function(a){var b=[this].concat([].slice.call(arguments,1));return a.transition.apply(a,b)},a.utils.renderWatch=function(b,c){if(!(this instanceof a.utils.renderWatch))return new a.utils.renderWatch(b,c);var d=void 0!==c?c:250,e=[],f=this;this.models=function(a){return a=[].slice.call(arguments,0),a.forEach(function(a){a.__rendered=!1,function(a){a.dispatch.on("renderEnd",function(){a.__rendered=!0,f.renderEnd("model")})}(a),e.indexOf(a)<0&&e.push(a)}),this},this.reset=function(a){void 0!==a&&(d=a),e=[]},this.transition=function(a,b,c){if(b=arguments.length>1?[].slice.call(arguments,1):[],c=b.length>1?b.pop():void 0!==d?d:250,a.__rendered=!1,e.indexOf(a)<0&&e.push(a),0===c)return a.__rendered=!0,a.delay=function(){return this},a.duration=function(){return this},a;a.__rendered=0===a.length?!0:a.every(function(a){return!a.length})?!0:!1;var g=0;return a.transition().duration(c).each(function(){++g}).each("end",function(){0===--g&&(a.__rendered=!0,f.renderEnd.apply(this,b))})},this.renderEnd=function(){e.every(function(a){return a.__rendered})&&(e.forEach(function(a){a.__rendered=!1}),b.renderEnd.apply(this,arguments))}},a.utils.deepExtend=function(b){var c=arguments.length>1?[].slice.call(arguments,1):[];c.forEach(function(c){for(var d in c){var e=b[d]instanceof Array,f="object"==typeof b[d],g="object"==typeof c[d];f&&!e&&g?a.utils.deepExtend(b[d],c[d]):b[d]=c[d]}})},a.utils.state=function(){if(!(this instanceof a.utils.state))return new a.utils.state;var b={},c=function(){},d=function(){return{}},e=null,f=null;this.dispatch=d3.dispatch("change","set"),this.dispatch.on("set",function(a){c(a,!0)}),this.getter=function(a){return d=a,this},this.setter=function(a,b){return b||(b=function(){}),c=function(c,d){a(c),d&&b()},this},this.init=function(b){e=e||{},a.utils.deepExtend(e,b)};var g=function(){var a=d();if(JSON.stringify(a)===JSON.stringify(b))return!1;for(var c in a)void 0===b[c]&&(b[c]={}),b[c]=a[c],f=!0;return!0};this.update=function(){e&&(c(e,!1),e=null),g.call(this)&&this.dispatch.change(b)}},a.utils.optionsFunc=function(a){return a&&d3.map(a).forEach(function(a,b){"function"==typeof this[a]&&this[a](b)}.bind(this)),this},a.utils.calcTicksX=function(b,c){var d=1,e=0;for(e;e<c.length;e+=1){var f=c[e]&&c[e].values?c[e].values.length:0;d=f>d?f:d}return a.log("Requested number of ticks: ",b),a.log("Calculated max values to be: ",d),b=b>d?b=d-1:b,b=1>b?1:b,b=Math.floor(b),a.log("Calculating tick count as: ",b),b},a.utils.calcTicksY=function(b,c){return a.utils.calcTicksX(b,c)},a.utils.initOption=function(a,b){a._calls&&a._calls[b]?a[b]=a._calls[b]:(a[b]=function(c){return arguments.length?(a._overrides[b]=!0,a._options[b]=c,a):a._options[b]},a["_"+b]=function(c){return arguments.length?(a._overrides[b]||(a._options[b]=c),a):a._options[b]})},a.utils.initOptions=function(b){b._overrides=b._overrides||{};var c=Object.getOwnPropertyNames(b._options||{}),d=Object.getOwnPropertyNames(b._calls||{});c=c.concat(d);for(var e in c)a.utils.initOption(b,c[e])},a.utils.inheritOptionsD3=function(a,b,c){a._d3options=c.concat(a._d3options||[]),c.unshift(b),c.unshift(a),d3.rebind.apply(this,c)},a.utils.arrayUnique=function(a){return a.sort().filter(function(b,c){return!c||b!=a[c-1]})},a.utils.symbolMap=d3.map(),a.utils.symbol=function(){function b(b,e){var f=c.call(this,b,e),g=d.call(this,b,e);return-1!==d3.svg.symbolTypes.indexOf(f)?d3.svg.symbol().type(f).size(g)():a.utils.symbolMap.get(f)(g)}var c,d=64;return b.type=function(a){return arguments.length?(c=d3.functor(a),b):c},b.size=function(a){return arguments.length?(d=d3.functor(a),b):d},b},a.utils.inheritOptions=function(b,c){var d=Object.getOwnPropertyNames(c._options||{}),e=Object.getOwnPropertyNames(c._calls||{}),f=c._inherited||[],g=c._d3options||[],h=d.concat(e).concat(f).concat(g);h.unshift(c),h.unshift(b),d3.rebind.apply(this,h),b._inherited=a.utils.arrayUnique(d.concat(e).concat(f).concat(d).concat(b._inherited||[])),b._d3options=a.utils.arrayUnique(g.concat(b._d3options||[]))},a.utils.initSVG=function(a){a.classed({"nvd3-svg":!0})},a.utils.sanitizeHeight=function(a,b){return a||parseInt(b.style("height"),10)||400},a.utils.sanitizeWidth=function(a,b){return a||parseInt(b.style("width"),10)||960},a.utils.availableHeight=function(b,c,d){return a.utils.sanitizeHeight(b,c)-d.top-d.bottom},a.utils.availableWidth=function(b,c,d){return a.utils.sanitizeWidth(b,c)-d.left-d.right},a.utils.noData=function(b,c){var d=b.options(),e=d.margin(),f=d.noData(),g=null==f?["No Data Available."]:[f],h=a.utils.availableHeight(d.height(),c,e),i=a.utils.availableWidth(d.width(),c,e),j=e.left+i/2,k=e.top+h/2;c.selectAll("g").remove();var l=c.selectAll(".nv-noData").data(g);l.enter().append("text").attr("class","nvd3 nv-noData").attr("dy","-.7em").style("text-anchor","middle"),l.attr("x",j).attr("y",k).text(function(a){return a})},a.models.axis=function(){"use strict";function b(g){return s.reset(),g.each(function(b){var g=d3.select(this);a.utils.initSVG(g);var p=g.selectAll("g.nv-wrap.nv-axis").data([b]),q=p.enter().append("g").attr("class","nvd3 nv-wrap nv-axis"),t=(q.append("g"),p.select("g"));null!==n?c.ticks(n):("top"==c.orient()||"bottom"==c.orient())&&c.ticks(Math.abs(d.range()[1]-d.range()[0])/100),t.watchTransition(s,"axis").call(c),r=r||c.scale();var u=c.tickFormat();null==u&&(u=r.tickFormat());var v=t.selectAll("text.nv-axislabel").data([h||null]);v.exit().remove();var w,x,y;switch(c.orient()){case"top":v.enter().append("text").attr("class","nv-axislabel"),y=d.range().length<2?0:2===d.range().length?d.range()[1]:d.range()[d.range().length-1]+(d.range()[1]-d.range()[0]),v.attr("text-anchor","middle").attr("y",0).attr("x",y/2),i&&(x=p.selectAll("g.nv-axisMaxMin").data(d.domain()),x.enter().append("g").attr("class",function(a,b){return["nv-axisMaxMin","nv-axisMaxMin-x",0==b?"nv-axisMin-x":"nv-axisMax-x"].join(" ")}).append("text"),x.exit().remove(),x.attr("transform",function(b){return"translate("+a.utils.NaNtoZero(d(b))+",0)"}).select("text").attr("dy","-0.5em").attr("y",-c.tickPadding()).attr("text-anchor","middle").text(function(a){var b=u(a);return(""+b).match("NaN")?"":b}),x.watchTransition(s,"min-max top").attr("transform",function(b,c){return"translate("+a.utils.NaNtoZero(d.range()[c])+",0)"}));break;case"bottom":w=o+36;var z=30,A=0,B=t.selectAll("g").select("text"),C="";if(j%360){B.each(function(){var a=this.getBoundingClientRect(),b=a.width;A=a.height,b>z&&(z=b)}),C="rotate("+j+" 0,"+(A/2+c.tickPadding())+")";var D=Math.abs(Math.sin(j*Math.PI/180));w=(D?D*z:z)+30,B.attr("transform",C).style("text-anchor",j%360>0?"start":"end")}v.enter().append("text").attr("class","nv-axislabel"),y=d.range().length<2?0:2===d.range().length?d.range()[1]:d.range()[d.range().length-1]+(d.range()[1]-d.range()[0]),v.attr("text-anchor","middle").attr("y",w).attr("x",y/2),i&&(x=p.selectAll("g.nv-axisMaxMin").data([d.domain()[0],d.domain()[d.domain().length-1]]),x.enter().append("g").attr("class",function(a,b){return["nv-axisMaxMin","nv-axisMaxMin-x",0==b?"nv-axisMin-x":"nv-axisMax-x"].join(" ")}).append("text"),x.exit().remove(),x.attr("transform",function(b){return"translate("+a.utils.NaNtoZero(d(b)+(m?d.rangeBand()/2:0))+",0)"}).select("text").attr("dy",".71em").attr("y",c.tickPadding()).attr("transform",C).style("text-anchor",j?j%360>0?"start":"end":"middle").text(function(a){var b=u(a);return(""+b).match("NaN")?"":b}),x.watchTransition(s,"min-max bottom").attr("transform",function(b){return"translate("+a.utils.NaNtoZero(d(b)+(m?d.rangeBand()/2:0))+",0)"})),l&&B.attr("transform",function(a,b){return"translate(0,"+(b%2==0?"0":"12")+")"});break;case"right":v.enter().append("text").attr("class","nv-axislabel"),v.style("text-anchor",k?"middle":"begin").attr("transform",k?"rotate(90)":"").attr("y",k?-Math.max(e.right,f)+12:-10).attr("x",k?d3.max(d.range())/2:c.tickPadding()),i&&(x=p.selectAll("g.nv-axisMaxMin").data(d.domain()),x.enter().append("g").attr("class",function(a,b){return["nv-axisMaxMin","nv-axisMaxMin-y",0==b?"nv-axisMin-y":"nv-axisMax-y"].join(" ")}).append("text").style("opacity",0),x.exit().remove(),x.attr("transform",function(b){return"translate(0,"+a.utils.NaNtoZero(d(b))+")"}).select("text").attr("dy",".32em").attr("y",0).attr("x",c.tickPadding()).style("text-anchor","start").text(function(a){var b=u(a);return(""+b).match("NaN")?"":b}),x.watchTransition(s,"min-max right").attr("transform",function(b,c){return"translate(0,"+a.utils.NaNtoZero(d.range()[c])+")"}).select("text").style("opacity",1));break;case"left":v.enter().append("text").attr("class","nv-axislabel"),v.style("text-anchor",k?"middle":"end").attr("transform",k?"rotate(-90)":"").attr("y",k?-Math.max(e.left,f)+25-(o||0):-10).attr("x",k?-d3.max(d.range())/2:-c.tickPadding()),i&&(x=p.selectAll("g.nv-axisMaxMin").data(d.domain()),x.enter().append("g").attr("class",function(a,b){return["nv-axisMaxMin","nv-axisMaxMin-y",0==b?"nv-axisMin-y":"nv-axisMax-y"].join(" ")}).append("text").style("opacity",0),x.exit().remove(),x.attr("transform",function(b){return"translate(0,"+a.utils.NaNtoZero(r(b))+")"}).select("text").attr("dy",".32em").attr("y",0).attr("x",-c.tickPadding()).attr("text-anchor","end").text(function(a){var b=u(a);return(""+b).match("NaN")?"":b}),x.watchTransition(s,"min-max right").attr("transform",function(b,c){return"translate(0,"+a.utils.NaNtoZero(d.range()[c])+")"}).select("text").style("opacity",1))}if(v.text(function(a){return a}),!i||"left"!==c.orient()&&"right"!==c.orient()||(t.selectAll("g").each(function(a){d3.select(this).select("text").attr("opacity",1),(d(a)<d.range()[1]+10||d(a)>d.range()[0]-10)&&((a>1e-10||-1e-10>a)&&d3.select(this).attr("opacity",0),d3.select(this).select("text").attr("opacity",0))}),d.domain()[0]==d.domain()[1]&&0==d.domain()[0]&&p.selectAll("g.nv-axisMaxMin").style("opacity",function(a,b){return b?0:1})),i&&("top"===c.orient()||"bottom"===c.orient())){var E=[];p.selectAll("g.nv-axisMaxMin").each(function(a,b){try{E.push(b?d(a)-this.getBoundingClientRect().width-4:d(a)+this.getBoundingClientRect().width+4)}catch(c){E.push(b?d(a)-4:d(a)+4)}}),t.selectAll("g").each(function(a){(d(a)<E[0]||d(a)>E[1])&&(a>1e-10||-1e-10>a?d3.select(this).remove():d3.select(this).select("text").remove())})}t.selectAll(".tick").filter(function(a){return!parseFloat(Math.round(1e5*a)/1e6)&&void 0!==a}).classed("zero",!0),r=d.copy()}),s.renderEnd("axis immediate"),b}var c=d3.svg.axis(),d=d3.scale.linear(),e={top:0,right:0,bottom:0,left:0},f=75,g=60,h=null,i=!0,j=0,k=!0,l=!1,m=!1,n=null,o=0,p=250,q=d3.dispatch("renderEnd");c.scale(d).orient("bottom").tickFormat(function(a){return a});var r,s=a.utils.renderWatch(q,p);return b.axis=c,b.dispatch=q,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{axisLabelDistance:{get:function(){return o},set:function(a){o=a}},staggerLabels:{get:function(){return l},set:function(a){l=a}},rotateLabels:{get:function(){return j},set:function(a){j=a}},rotateYLabel:{get:function(){return k},set:function(a){k=a}},showMaxMin:{get:function(){return i},set:function(a){i=a}},axisLabel:{get:function(){return h},set:function(a){h=a}},height:{get:function(){return g},set:function(a){g=a}},ticks:{get:function(){return n},set:function(a){n=a}},width:{get:function(){return f},set:function(a){f=a}},margin:{get:function(){return e},set:function(a){e.top=void 0!==a.top?a.top:e.top,e.right=void 0!==a.right?a.right:e.right,e.bottom=void 0!==a.bottom?a.bottom:e.bottom,e.left=void 0!==a.left?a.left:e.left}},duration:{get:function(){return p},set:function(a){p=a,s.reset(p)}},scale:{get:function(){return d},set:function(e){d=e,c.scale(d),m="function"==typeof d.rangeBands,a.utils.inheritOptionsD3(b,d,["domain","range","rangeBand","rangeBands"])}}}),a.utils.initOptions(b),a.utils.inheritOptionsD3(b,c,["orient","tickValues","tickSubdivide","tickSize","tickPadding","tickFormat"]),a.utils.inheritOptionsD3(b,d,["domain","range","rangeBand","rangeBands"]),b},a.models.boxPlot=function(){"use strict";function b(l){return v.reset(),l.each(function(b){var l=j-i.left-i.right,p=k-i.top-i.bottom;r=d3.select(this),a.utils.initSVG(r),m.domain(c||b.map(function(a,b){return o(a,b)})).rangeBands(e||[0,l],.1);var w=[];if(!d){var x=d3.min(b.map(function(a){var b=[];return b.push(a.values.Q1),a.values.hasOwnProperty("whisker_low")&&null!==a.values.whisker_low&&b.push(a.values.whisker_low),a.values.hasOwnProperty("outliers")&&null!==a.values.outliers&&(b=b.concat(a.values.outliers)),d3.min(b)})),y=d3.max(b.map(function(a){var b=[];return b.push(a.values.Q3),a.values.hasOwnProperty("whisker_high")&&null!==a.values.whisker_high&&b.push(a.values.whisker_high),a.values.hasOwnProperty("outliers")&&null!==a.values.outliers&&(b=b.concat(a.values.outliers)),d3.max(b)}));w=[x,y]}n.domain(d||w),n.range(f||[p,0]),g=g||m,h=h||n.copy().range([n(0),n(0)]);{var z=r.selectAll("g.nv-wrap").data([b]);z.enter().append("g").attr("class","nvd3 nv-wrap")}z.attr("transform","translate("+i.left+","+i.top+")");var A=z.selectAll(".nv-boxplot").data(function(a){return a}),B=A.enter().append("g").style("stroke-opacity",1e-6).style("fill-opacity",1e-6);A.attr("class","nv-boxplot").attr("transform",function(a,b){return"translate("+(m(o(a,b))+.05*m.rangeBand())+", 0)"}).classed("hover",function(a){return a.hover}),A.watchTransition(v,"nv-boxplot: boxplots").style("stroke-opacity",1).style("fill-opacity",.75).delay(function(a,c){return c*t/b.length}).attr("transform",function(a,b){return"translate("+(m(o(a,b))+.05*m.rangeBand())+", 0)"}),A.exit().remove(),B.each(function(a,b){var c=d3.select(this);["low","high"].forEach(function(d){a.values.hasOwnProperty("whisker_"+d)&&null!==a.values["whisker_"+d]&&(c.append("line").style("stroke",a.color?a.color:q(a,b)).attr("class","nv-boxplot-whisker nv-boxplot-"+d),c.append("line").style("stroke",a.color?a.color:q(a,b)).attr("class","nv-boxplot-tick nv-boxplot-"+d))})});var C=A.selectAll(".nv-boxplot-outlier").data(function(a){return a.values.hasOwnProperty("outliers")&&null!==a.values.outliers?a.values.outliers:[]});C.enter().append("circle").style("fill",function(a,b,c){return q(a,c)}).style("stroke",function(a,b,c){return q(a,c)}).on("mouseover",function(a,b,c){d3.select(this).classed("hover",!0),s.elementMouseover({series:{key:a,color:q(a,c)},e:d3.event})}).on("mouseout",function(a,b,c){d3.select(this).classed("hover",!1),s.elementMouseout({series:{key:a,color:q(a,c)},e:d3.event})}).on("mousemove",function(){s.elementMousemove({e:d3.event})}),C.attr("class","nv-boxplot-outlier"),C.watchTransition(v,"nv-boxplot: nv-boxplot-outlier").attr("cx",.45*m.rangeBand()).attr("cy",function(a){return n(a)}).attr("r","3"),C.exit().remove();var D=function(){return null===u?.9*m.rangeBand():Math.min(75,.9*m.rangeBand())},E=function(){return.45*m.rangeBand()-D()/2},F=function(){return.45*m.rangeBand()+D()/2};["low","high"].forEach(function(a){var b="low"===a?"Q1":"Q3";A.select("line.nv-boxplot-whisker.nv-boxplot-"+a).watchTransition(v,"nv-boxplot: boxplots").attr("x1",.45*m.rangeBand()).attr("y1",function(b){return n(b.values["whisker_"+a])}).attr("x2",.45*m.rangeBand()).attr("y2",function(a){return n(a.values[b])}),A.select("line.nv-boxplot-tick.nv-boxplot-"+a).watchTransition(v,"nv-boxplot: boxplots").attr("x1",E).attr("y1",function(b){return n(b.values["whisker_"+a])}).attr("x2",F).attr("y2",function(b){return n(b.values["whisker_"+a])})}),["low","high"].forEach(function(a){B.selectAll(".nv-boxplot-"+a).on("mouseover",function(b,c,d){d3.select(this).classed("hover",!0),s.elementMouseover({series:{key:b.values["whisker_"+a],color:q(b,d)},e:d3.event})}).on("mouseout",function(b,c,d){d3.select(this).classed("hover",!1),s.elementMouseout({series:{key:b.values["whisker_"+a],color:q(b,d)},e:d3.event})}).on("mousemove",function(){s.elementMousemove({e:d3.event})})}),B.append("rect").attr("class","nv-boxplot-box").on("mouseover",function(a,b){d3.select(this).classed("hover",!0),s.elementMouseover({key:a.label,value:a.label,series:[{key:"Q3",value:a.values.Q3,color:a.color||q(a,b)},{key:"Q2",value:a.values.Q2,color:a.color||q(a,b)},{key:"Q1",value:a.values.Q1,color:a.color||q(a,b)}],data:a,index:b,e:d3.event})}).on("mouseout",function(a,b){d3.select(this).classed("hover",!1),s.elementMouseout({key:a.label,value:a.label,series:[{key:"Q3",value:a.values.Q3,color:a.color||q(a,b)},{key:"Q2",value:a.values.Q2,color:a.color||q(a,b)},{key:"Q1",value:a.values.Q1,color:a.color||q(a,b)}],data:a,index:b,e:d3.event})}).on("mousemove",function(){s.elementMousemove({e:d3.event})}),A.select("rect.nv-boxplot-box").watchTransition(v,"nv-boxplot: boxes").attr("y",function(a){return n(a.values.Q3)}).attr("width",D).attr("x",E).attr("height",function(a){return Math.abs(n(a.values.Q3)-n(a.values.Q1))||1}).style("fill",function(a,b){return a.color||q(a,b)}).style("stroke",function(a,b){return a.color||q(a,b)}),B.append("line").attr("class","nv-boxplot-median"),A.select("line.nv-boxplot-median").watchTransition(v,"nv-boxplot: boxplots line").attr("x1",E).attr("y1",function(a){return n(a.values.Q2)}).attr("x2",F).attr("y2",function(a){return n(a.values.Q2)}),g=m.copy(),h=n.copy()}),v.renderEnd("nv-boxplot immediate"),b}var c,d,e,f,g,h,i={top:0,right:0,bottom:0,left:0},j=960,k=500,l=Math.floor(1e4*Math.random()),m=d3.scale.ordinal(),n=d3.scale.linear(),o=function(a){return a.x},p=function(a){return a.y},q=a.utils.defaultColor(),r=null,s=d3.dispatch("elementMouseover","elementMouseout","elementMousemove","renderEnd"),t=250,u=null,v=a.utils.renderWatch(s,t);return b.dispatch=s,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return j},set:function(a){j=a}},height:{get:function(){return k},set:function(a){k=a}},maxBoxWidth:{get:function(){return u},set:function(a){u=a}},x:{get:function(){return o},set:function(a){o=a}},y:{get:function(){return p},set:function(a){p=a}},xScale:{get:function(){return m},set:function(a){m=a}},yScale:{get:function(){return n},set:function(a){n=a}},xDomain:{get:function(){return c},set:function(a){c=a}},yDomain:{get:function(){return d},set:function(a){d=a}},xRange:{get:function(){return e},set:function(a){e=a}},yRange:{get:function(){return f},set:function(a){f=a}},id:{get:function(){return l},set:function(a){l=a}},margin:{get:function(){return i},set:function(a){i.top=void 0!==a.top?a.top:i.top,i.right=void 0!==a.right?a.right:i.right,i.bottom=void 0!==a.bottom?a.bottom:i.bottom,i.left=void 0!==a.left?a.left:i.left}},color:{get:function(){return q},set:function(b){q=a.utils.getColor(b)}},duration:{get:function(){return t},set:function(a){t=a,v.reset(t)}}}),a.utils.initOptions(b),b},a.models.boxPlotChart=function(){"use strict";function b(k){return t.reset(),t.models(e),l&&t.models(f),m&&t.models(g),k.each(function(k){var p=d3.select(this);a.utils.initSVG(p);var t=(i||parseInt(p.style("width"))||960)-h.left-h.right,u=(j||parseInt(p.style("height"))||400)-h.top-h.bottom;if(b.update=function(){r.beforeUpdate(),p.transition().duration(s).call(b)},b.container=this,!(k&&k.length&&k.filter(function(a){return a.values.hasOwnProperty("Q1")&&a.values.hasOwnProperty("Q2")&&a.values.hasOwnProperty("Q3")}).length)){var v=p.selectAll(".nv-noData").data([q]);return v.enter().append("text").attr("class","nvd3 nv-noData").attr("dy","-.7em").style("text-anchor","middle"),v.attr("x",h.left+t/2).attr("y",h.top+u/2).text(function(a){return a}),b}p.selectAll(".nv-noData").remove(),c=e.xScale(),d=e.yScale().clamp(!0);var w=p.selectAll("g.nv-wrap.nv-boxPlotWithAxes").data([k]),x=w.enter().append("g").attr("class","nvd3 nv-wrap nv-boxPlotWithAxes").append("g"),y=x.append("defs"),z=w.select("g");
33847 x.append("g").attr("class","nv-x nv-axis"),x.append("g").attr("class","nv-y nv-axis").append("g").attr("class","nv-zeroLine").append("line"),x.append("g").attr("class","nv-barsWrap"),z.attr("transform","translate("+h.left+","+h.top+")"),n&&z.select(".nv-y.nv-axis").attr("transform","translate("+t+",0)"),e.width(t).height(u);var A=z.select(".nv-barsWrap").datum(k.filter(function(a){return!a.disabled}));if(A.transition().call(e),y.append("clipPath").attr("id","nv-x-label-clip-"+e.id()).append("rect"),z.select("#nv-x-label-clip-"+e.id()+" rect").attr("width",c.rangeBand()*(o?2:1)).attr("height",16).attr("x",-c.rangeBand()/(o?1:2)),l){f.scale(c).ticks(a.utils.calcTicksX(t/100,k)).tickSize(-u,0),z.select(".nv-x.nv-axis").attr("transform","translate(0,"+d.range()[0]+")"),z.select(".nv-x.nv-axis").call(f);var B=z.select(".nv-x.nv-axis").selectAll("g");o&&B.selectAll("text").attr("transform",function(a,b,c){return"translate(0,"+(c%2==0?"5":"17")+")"})}m&&(g.scale(d).ticks(Math.floor(u/36)).tickSize(-t,0),z.select(".nv-y.nv-axis").call(g)),z.select(".nv-zeroLine line").attr("x1",0).attr("x2",t).attr("y1",d(0)).attr("y2",d(0))}),t.renderEnd("nv-boxplot chart immediate"),b}var c,d,e=a.models.boxPlot(),f=a.models.axis(),g=a.models.axis(),h={top:15,right:10,bottom:50,left:60},i=null,j=null,k=a.utils.getColor(),l=!0,m=!0,n=!1,o=!1,p=a.models.tooltip(),q="No Data Available.",r=d3.dispatch("tooltipShow","tooltipHide","beforeUpdate","renderEnd"),s=250;f.orient("bottom").showMaxMin(!1).tickFormat(function(a){return a}),g.orient(n?"right":"left").tickFormat(d3.format(",.1f")),p.duration(0);var t=a.utils.renderWatch(r,s);return e.dispatch.on("elementMouseover.tooltip",function(a){p.data(a).hidden(!1)}),e.dispatch.on("elementMouseout.tooltip",function(a){p.data(a).hidden(!0)}),e.dispatch.on("elementMousemove.tooltip",function(){p.position({top:d3.event.pageY,left:d3.event.pageX})()}),b.dispatch=r,b.boxplot=e,b.xAxis=f,b.yAxis=g,b.tooltip=p,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return i},set:function(a){i=a}},height:{get:function(){return j},set:function(a){j=a}},staggerLabels:{get:function(){return o},set:function(a){o=a}},showXAxis:{get:function(){return l},set:function(a){l=a}},showYAxis:{get:function(){return m},set:function(a){m=a}},tooltips:{get:function(){return tooltips},set:function(a){tooltips=a}},tooltipContent:{get:function(){return p},set:function(a){p=a}},noData:{get:function(){return q},set:function(a){q=a}},margin:{get:function(){return h},set:function(a){h.top=void 0!==a.top?a.top:h.top,h.right=void 0!==a.right?a.right:h.right,h.bottom=void 0!==a.bottom?a.bottom:h.bottom,h.left=void 0!==a.left?a.left:h.left}},duration:{get:function(){return s},set:function(a){s=a,t.reset(s),e.duration(s),f.duration(s),g.duration(s)}},color:{get:function(){return k},set:function(b){k=a.utils.getColor(b),e.color(k)}},rightAlignYAxis:{get:function(){return n},set:function(a){n=a,g.orient(a?"right":"left")}}}),a.utils.inheritOptions(b,e),a.utils.initOptions(b),b},a.models.bullet=function(){"use strict";function b(d){return d.each(function(b,d){var p=m-c.left-c.right,s=n-c.top-c.bottom;o=d3.select(this),a.utils.initSVG(o);{var t=f.call(this,b,d).slice().sort(d3.descending),u=g.call(this,b,d).slice().sort(d3.descending),v=h.call(this,b,d).slice().sort(d3.descending),w=i.call(this,b,d).slice(),x=j.call(this,b,d).slice(),y=k.call(this,b,d).slice(),z=d3.scale.linear().domain(d3.extent(d3.merge([l,t]))).range(e?[p,0]:[0,p]);this.__chart__||d3.scale.linear().domain([0,1/0]).range(z.range())}this.__chart__=z;var A=d3.min(t),B=d3.max(t),C=t[1],D=o.selectAll("g.nv-wrap.nv-bullet").data([b]),E=D.enter().append("g").attr("class","nvd3 nv-wrap nv-bullet"),F=E.append("g"),G=D.select("g");F.append("rect").attr("class","nv-range nv-rangeMax"),F.append("rect").attr("class","nv-range nv-rangeAvg"),F.append("rect").attr("class","nv-range nv-rangeMin"),F.append("rect").attr("class","nv-measure"),D.attr("transform","translate("+c.left+","+c.top+")");var H=function(a){return Math.abs(z(a)-z(0))},I=function(a){return z(0>a?a:0)};G.select("rect.nv-rangeMax").attr("height",s).attr("width",H(B>0?B:A)).attr("x",I(B>0?B:A)).datum(B>0?B:A),G.select("rect.nv-rangeAvg").attr("height",s).attr("width",H(C)).attr("x",I(C)).datum(C),G.select("rect.nv-rangeMin").attr("height",s).attr("width",H(B)).attr("x",I(B)).attr("width",H(B>0?A:B)).attr("x",I(B>0?A:B)).datum(B>0?A:B),G.select("rect.nv-measure").style("fill",q).attr("height",s/3).attr("y",s/3).attr("width",0>v?z(0)-z(v[0]):z(v[0])-z(0)).attr("x",I(v)).on("mouseover",function(){r.elementMouseover({value:v[0],label:y[0]||"Current",color:d3.select(this).style("fill")})}).on("mousemove",function(){r.elementMousemove({value:v[0],label:y[0]||"Current",color:d3.select(this).style("fill")})}).on("mouseout",function(){r.elementMouseout({value:v[0],label:y[0]||"Current",color:d3.select(this).style("fill")})});var J=s/6,K=u.map(function(a,b){return{value:a,label:x[b]}});F.selectAll("path.nv-markerTriangle").data(K).enter().append("path").attr("class","nv-markerTriangle").attr("transform",function(a){return"translate("+z(a.value)+","+s/2+")"}).attr("d","M0,"+J+"L"+J+","+-J+" "+-J+","+-J+"Z").on("mouseover",function(a){r.elementMouseover({value:a.value,label:a.label||"Previous",color:d3.select(this).style("fill"),pos:[z(a.value),s/2]})}).on("mousemove",function(a){r.elementMousemove({value:a.value,label:a.label||"Previous",color:d3.select(this).style("fill")})}).on("mouseout",function(a){r.elementMouseout({value:a.value,label:a.label||"Previous",color:d3.select(this).style("fill")})}),D.selectAll(".nv-range").on("mouseover",function(a,b){var c=w[b]||(b?1==b?"Mean":"Minimum":"Maximum");r.elementMouseover({value:a,label:c,color:d3.select(this).style("fill")})}).on("mousemove",function(){r.elementMousemove({value:v[0],label:y[0]||"Previous",color:d3.select(this).style("fill")})}).on("mouseout",function(a,b){var c=w[b]||(b?1==b?"Mean":"Minimum":"Maximum");r.elementMouseout({value:a,label:c,color:d3.select(this).style("fill")})})}),b}var c={top:0,right:0,bottom:0,left:0},d="left",e=!1,f=function(a){return a.ranges},g=function(a){return a.markers?a.markers:[0]},h=function(a){return a.measures},i=function(a){return a.rangeLabels?a.rangeLabels:[]},j=function(a){return a.markerLabels?a.markerLabels:[]},k=function(a){return a.measureLabels?a.measureLabels:[]},l=[0],m=380,n=30,o=null,p=null,q=a.utils.getColor(["#1f77b4"]),r=d3.dispatch("elementMouseover","elementMouseout","elementMousemove");return b.dispatch=r,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{ranges:{get:function(){return f},set:function(a){f=a}},markers:{get:function(){return g},set:function(a){g=a}},measures:{get:function(){return h},set:function(a){h=a}},forceX:{get:function(){return l},set:function(a){l=a}},width:{get:function(){return m},set:function(a){m=a}},height:{get:function(){return n},set:function(a){n=a}},tickFormat:{get:function(){return p},set:function(a){p=a}},margin:{get:function(){return c},set:function(a){c.top=void 0!==a.top?a.top:c.top,c.right=void 0!==a.right?a.right:c.right,c.bottom=void 0!==a.bottom?a.bottom:c.bottom,c.left=void 0!==a.left?a.left:c.left}},orient:{get:function(){return d},set:function(a){d=a,e="right"==d||"bottom"==d}},color:{get:function(){return q},set:function(b){q=a.utils.getColor(b)}}}),a.utils.initOptions(b),b},a.models.bulletChart=function(){"use strict";function b(d){return d.each(function(e,o){var p=d3.select(this);a.utils.initSVG(p);var q=a.utils.availableWidth(k,p,g),r=l-g.top-g.bottom;if(b.update=function(){b(d)},b.container=this,!e||!h.call(this,e,o))return a.utils.noData(b,p),b;p.selectAll(".nv-noData").remove();var s=h.call(this,e,o).slice().sort(d3.descending),t=i.call(this,e,o).slice().sort(d3.descending),u=j.call(this,e,o).slice().sort(d3.descending),v=p.selectAll("g.nv-wrap.nv-bulletChart").data([e]),w=v.enter().append("g").attr("class","nvd3 nv-wrap nv-bulletChart"),x=w.append("g"),y=v.select("g");x.append("g").attr("class","nv-bulletWrap"),x.append("g").attr("class","nv-titles"),v.attr("transform","translate("+g.left+","+g.top+")");var z=d3.scale.linear().domain([0,Math.max(s[0],t[0],u[0])]).range(f?[q,0]:[0,q]),A=this.__chart__||d3.scale.linear().domain([0,1/0]).range(z.range());this.__chart__=z;var B=x.select(".nv-titles").append("g").attr("text-anchor","end").attr("transform","translate(-6,"+(l-g.top-g.bottom)/2+")");B.append("text").attr("class","nv-title").text(function(a){return a.title}),B.append("text").attr("class","nv-subtitle").attr("dy","1em").text(function(a){return a.subtitle}),c.width(q).height(r);var C=y.select(".nv-bulletWrap");d3.transition(C).call(c);var D=m||z.tickFormat(q/100),E=y.selectAll("g.nv-tick").data(z.ticks(n?n:q/50),function(a){return this.textContent||D(a)}),F=E.enter().append("g").attr("class","nv-tick").attr("transform",function(a){return"translate("+A(a)+",0)"}).style("opacity",1e-6);F.append("line").attr("y1",r).attr("y2",7*r/6),F.append("text").attr("text-anchor","middle").attr("dy","1em").attr("y",7*r/6).text(D);var G=d3.transition(E).attr("transform",function(a){return"translate("+z(a)+",0)"}).style("opacity",1);G.select("line").attr("y1",r).attr("y2",7*r/6),G.select("text").attr("y",7*r/6),d3.transition(E.exit()).attr("transform",function(a){return"translate("+z(a)+",0)"}).style("opacity",1e-6).remove()}),d3.timer.flush(),b}var c=a.models.bullet(),d=a.models.tooltip(),e="left",f=!1,g={top:5,right:40,bottom:20,left:120},h=function(a){return a.ranges},i=function(a){return a.markers?a.markers:[0]},j=function(a){return a.measures},k=null,l=55,m=null,n=null,o=null,p=d3.dispatch("tooltipShow","tooltipHide");return d.duration(0).headerEnabled(!1),c.dispatch.on("elementMouseover.tooltip",function(a){a.series={key:a.label,value:a.value,color:a.color},d.data(a).hidden(!1)}),c.dispatch.on("elementMouseout.tooltip",function(){d.hidden(!0)}),c.dispatch.on("elementMousemove.tooltip",function(){d.position({top:d3.event.pageY,left:d3.event.pageX})()}),b.bullet=c,b.dispatch=p,b.tooltip=d,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{ranges:{get:function(){return h},set:function(a){h=a}},markers:{get:function(){return i},set:function(a){i=a}},measures:{get:function(){return j},set:function(a){j=a}},width:{get:function(){return k},set:function(a){k=a}},height:{get:function(){return l},set:function(a){l=a}},tickFormat:{get:function(){return m},set:function(a){m=a}},ticks:{get:function(){return n},set:function(a){n=a}},noData:{get:function(){return o},set:function(a){o=a}},tooltips:{get:function(){return d.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),d.enabled(!!b)}},tooltipContent:{get:function(){return d.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),d.contentGenerator(b)}},margin:{get:function(){return g},set:function(a){g.top=void 0!==a.top?a.top:g.top,g.right=void 0!==a.right?a.right:g.right,g.bottom=void 0!==a.bottom?a.bottom:g.bottom,g.left=void 0!==a.left?a.left:g.left}},orient:{get:function(){return e},set:function(a){e=a,f="right"==e||"bottom"==e}}}),a.utils.inheritOptions(b,c),a.utils.initOptions(b),b},a.models.candlestickBar=function(){"use strict";function b(x){return x.each(function(b){c=d3.select(this);var x=a.utils.availableWidth(i,c,h),y=a.utils.availableHeight(j,c,h);a.utils.initSVG(c);var A=x/b[0].values.length*.45;l.domain(d||d3.extent(b[0].values.map(n).concat(t))),l.range(v?f||[.5*x/b[0].values.length,x*(b[0].values.length-.5)/b[0].values.length]:f||[5+A/2,x-A/2-5]),m.domain(e||[d3.min(b[0].values.map(s).concat(u)),d3.max(b[0].values.map(r).concat(u))]).range(g||[y,0]),l.domain()[0]===l.domain()[1]&&l.domain(l.domain()[0]?[l.domain()[0]-.01*l.domain()[0],l.domain()[1]+.01*l.domain()[1]]:[-1,1]),m.domain()[0]===m.domain()[1]&&m.domain(m.domain()[0]?[m.domain()[0]+.01*m.domain()[0],m.domain()[1]-.01*m.domain()[1]]:[-1,1]);var B=d3.select(this).selectAll("g.nv-wrap.nv-candlestickBar").data([b[0].values]),C=B.enter().append("g").attr("class","nvd3 nv-wrap nv-candlestickBar"),D=C.append("defs"),E=C.append("g"),F=B.select("g");E.append("g").attr("class","nv-ticks"),B.attr("transform","translate("+h.left+","+h.top+")"),c.on("click",function(a,b){z.chartClick({data:a,index:b,pos:d3.event,id:k})}),D.append("clipPath").attr("id","nv-chart-clip-path-"+k).append("rect"),B.select("#nv-chart-clip-path-"+k+" rect").attr("width",x).attr("height",y),F.attr("clip-path",w?"url(#nv-chart-clip-path-"+k+")":"");var G=B.select(".nv-ticks").selectAll(".nv-tick").data(function(a){return a});G.exit().remove();{var H=G.enter().append("g").attr("class",function(a,b,c){return(p(a,b)>q(a,b)?"nv-tick negative":"nv-tick positive")+" nv-tick-"+c+"-"+b});H.append("line").attr("class","nv-candlestick-lines").attr("transform",function(a,b){return"translate("+l(n(a,b))+",0)"}).attr("x1",0).attr("y1",function(a,b){return m(r(a,b))}).attr("x2",0).attr("y2",function(a,b){return m(s(a,b))}),H.append("rect").attr("class","nv-candlestick-rects nv-bars").attr("transform",function(a,b){return"translate("+(l(n(a,b))-A/2)+","+(m(o(a,b))-(p(a,b)>q(a,b)?m(q(a,b))-m(p(a,b)):0))+")"}).attr("x",0).attr("y",0).attr("width",A).attr("height",function(a,b){var c=p(a,b),d=q(a,b);return c>d?m(d)-m(c):m(c)-m(d)})}c.selectAll(".nv-candlestick-lines").transition().attr("transform",function(a,b){return"translate("+l(n(a,b))+",0)"}).attr("x1",0).attr("y1",function(a,b){return m(r(a,b))}).attr("x2",0).attr("y2",function(a,b){return m(s(a,b))}),c.selectAll(".nv-candlestick-rects").transition().attr("transform",function(a,b){return"translate("+(l(n(a,b))-A/2)+","+(m(o(a,b))-(p(a,b)>q(a,b)?m(q(a,b))-m(p(a,b)):0))+")"}).attr("x",0).attr("y",0).attr("width",A).attr("height",function(a,b){var c=p(a,b),d=q(a,b);return c>d?m(d)-m(c):m(c)-m(d)})}),b}var c,d,e,f,g,h={top:0,right:0,bottom:0,left:0},i=null,j=null,k=Math.floor(1e4*Math.random()),l=d3.scale.linear(),m=d3.scale.linear(),n=function(a){return a.x},o=function(a){return a.y},p=function(a){return a.open},q=function(a){return a.close},r=function(a){return a.high},s=function(a){return a.low},t=[],u=[],v=!1,w=!0,x=a.utils.defaultColor(),y=!1,z=d3.dispatch("tooltipShow","tooltipHide","stateChange","changeState","renderEnd","chartClick","elementClick","elementDblClick","elementMouseover","elementMouseout","elementMousemove");return b.highlightPoint=function(a,d){b.clearHighlights(),c.select(".nv-candlestickBar .nv-tick-0-"+a).classed("hover",d)},b.clearHighlights=function(){c.select(".nv-candlestickBar .nv-tick.hover").classed("hover",!1)},b.dispatch=z,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return i},set:function(a){i=a}},height:{get:function(){return j},set:function(a){j=a}},xScale:{get:function(){return l},set:function(a){l=a}},yScale:{get:function(){return m},set:function(a){m=a}},xDomain:{get:function(){return d},set:function(a){d=a}},yDomain:{get:function(){return e},set:function(a){e=a}},xRange:{get:function(){return f},set:function(a){f=a}},yRange:{get:function(){return g},set:function(a){g=a}},forceX:{get:function(){return t},set:function(a){t=a}},forceY:{get:function(){return u},set:function(a){u=a}},padData:{get:function(){return v},set:function(a){v=a}},clipEdge:{get:function(){return w},set:function(a){w=a}},id:{get:function(){return k},set:function(a){k=a}},interactive:{get:function(){return y},set:function(a){y=a}},x:{get:function(){return n},set:function(a){n=a}},y:{get:function(){return o},set:function(a){o=a}},open:{get:function(){return p()},set:function(a){p=a}},close:{get:function(){return q()},set:function(a){q=a}},high:{get:function(){return r},set:function(a){r=a}},low:{get:function(){return s},set:function(a){s=a}},margin:{get:function(){return h},set:function(a){h.top=void 0!=a.top?a.top:h.top,h.right=void 0!=a.right?a.right:h.right,h.bottom=void 0!=a.bottom?a.bottom:h.bottom,h.left=void 0!=a.left?a.left:h.left}},color:{get:function(){return x},set:function(b){x=a.utils.getColor(b)}}}),a.utils.initOptions(b),b},a.models.cumulativeLineChart=function(){"use strict";function b(l){return H.reset(),H.models(f),r&&H.models(g),s&&H.models(h),l.each(function(l){function A(){d3.select(b.container).style("cursor","ew-resize")}function E(){G.x=d3.event.x,G.i=Math.round(F.invert(G.x)),K()}function H(){d3.select(b.container).style("cursor","auto"),y.index=G.i,C.stateChange(y)}function K(){bb.data([G]);var a=b.duration();b.duration(0),b.update(),b.duration(a)}var L=d3.select(this);a.utils.initSVG(L),L.classed("nv-chart-"+x,!0);var M=this,N=a.utils.availableWidth(o,L,m),O=a.utils.availableHeight(p,L,m);if(b.update=function(){0===D?L.call(b):L.transition().duration(D).call(b)},b.container=this,y.setter(J(l),b.update).getter(I(l)).update(),y.disabled=l.map(function(a){return!!a.disabled}),!z){var P;z={};for(P in y)z[P]=y[P]instanceof Array?y[P].slice(0):y[P]}var Q=d3.behavior.drag().on("dragstart",A).on("drag",E).on("dragend",H);if(!(l&&l.length&&l.filter(function(a){return a.values.length}).length))return a.utils.noData(b,L),b;if(L.selectAll(".nv-noData").remove(),d=f.xScale(),e=f.yScale(),w)f.yDomain(null);else{var R=l.filter(function(a){return!a.disabled}).map(function(a){var b=d3.extent(a.values,f.y());return b[0]<-.95&&(b[0]=-.95),[(b[0]-b[1])/(1+b[1]),(b[1]-b[0])/(1+b[0])]}),S=[d3.min(R,function(a){return a[0]}),d3.max(R,function(a){return a[1]})];f.yDomain(S)}F.domain([0,l[0].values.length-1]).range([0,N]).clamp(!0);var l=c(G.i,l),T=v?"none":"all",U=L.selectAll("g.nv-wrap.nv-cumulativeLine").data([l]),V=U.enter().append("g").attr("class","nvd3 nv-wrap nv-cumulativeLine").append("g"),W=U.select("g");if(V.append("g").attr("class","nv-interactive"),V.append("g").attr("class","nv-x nv-axis").style("pointer-events","none"),V.append("g").attr("class","nv-y nv-axis"),V.append("g").attr("class","nv-background"),V.append("g").attr("class","nv-linesWrap").style("pointer-events",T),V.append("g").attr("class","nv-avgLinesWrap").style("pointer-events","none"),V.append("g").attr("class","nv-legendWrap"),V.append("g").attr("class","nv-controlsWrap"),q&&(i.width(N),W.select(".nv-legendWrap").datum(l).call(i),m.top!=i.height()&&(m.top=i.height(),O=a.utils.availableHeight(p,L,m)),W.select(".nv-legendWrap").attr("transform","translate(0,"+-m.top+")")),u){var X=[{key:"Re-scale y-axis",disabled:!w}];j.width(140).color(["#444","#444","#444"]).rightAlign(!1).margin({top:5,right:0,bottom:5,left:20}),W.select(".nv-controlsWrap").datum(X).attr("transform","translate(0,"+-m.top+")").call(j)}U.attr("transform","translate("+m.left+","+m.top+")"),t&&W.select(".nv-y.nv-axis").attr("transform","translate("+N+",0)");var Y=l.filter(function(a){return a.tempDisabled});U.select(".tempDisabled").remove(),Y.length&&U.append("text").attr("class","tempDisabled").attr("x",N/2).attr("y","-.71em").style("text-anchor","end").text(Y.map(function(a){return a.key}).join(", ")+" values cannot be calculated for this time period."),v&&(k.width(N).height(O).margin({left:m.left,top:m.top}).svgContainer(L).xScale(d),U.select(".nv-interactive").call(k)),V.select(".nv-background").append("rect"),W.select(".nv-background rect").attr("width",N).attr("height",O),f.y(function(a){return a.display.y}).width(N).height(O).color(l.map(function(a,b){return a.color||n(a,b)}).filter(function(a,b){return!l[b].disabled&&!l[b].tempDisabled}));var Z=W.select(".nv-linesWrap").datum(l.filter(function(a){return!a.disabled&&!a.tempDisabled}));Z.call(f),l.forEach(function(a,b){a.seriesIndex=b});var $=l.filter(function(a){return!a.disabled&&!!B(a)}),_=W.select(".nv-avgLinesWrap").selectAll("line").data($,function(a){return a.key}),ab=function(a){var b=e(B(a));return 0>b?0:b>O?O:b};_.enter().append("line").style("stroke-width",2).style("stroke-dasharray","10,10").style("stroke",function(a){return f.color()(a,a.seriesIndex)}).attr("x1",0).attr("x2",N).attr("y1",ab).attr("y2",ab),_.style("stroke-opacity",function(a){var b=e(B(a));return 0>b||b>O?0:1}).attr("x1",0).attr("x2",N).attr("y1",ab).attr("y2",ab),_.exit().remove();var bb=Z.selectAll(".nv-indexLine").data([G]);bb.enter().append("rect").attr("class","nv-indexLine").attr("width",3).attr("x",-2).attr("fill","red").attr("fill-opacity",.5).style("pointer-events","all").call(Q),bb.attr("transform",function(a){return"translate("+F(a.i)+",0)"}).attr("height",O),r&&(g.scale(d)._ticks(a.utils.calcTicksX(N/70,l)).tickSize(-O,0),W.select(".nv-x.nv-axis").attr("transform","translate(0,"+e.range()[0]+")"),W.select(".nv-x.nv-axis").call(g)),s&&(h.scale(e)._ticks(a.utils.calcTicksY(O/36,l)).tickSize(-N,0),W.select(".nv-y.nv-axis").call(h)),W.select(".nv-background rect").on("click",function(){G.x=d3.mouse(this)[0],G.i=Math.round(F.invert(G.x)),y.index=G.i,C.stateChange(y),K()}),f.dispatch.on("elementClick",function(a){G.i=a.pointIndex,G.x=F(G.i),y.index=G.i,C.stateChange(y),K()}),j.dispatch.on("legendClick",function(a){a.disabled=!a.disabled,w=!a.disabled,y.rescaleY=w,C.stateChange(y),b.update()}),i.dispatch.on("stateChange",function(a){for(var c in a)y[c]=a[c];C.stateChange(y),b.update()}),k.dispatch.on("elementMousemove",function(c){f.clearHighlights();var d,e,i,j=[];if(l.filter(function(a,b){return a.seriesIndex=b,!a.disabled}).forEach(function(g,h){e=a.interactiveBisect(g.values,c.pointXValue,b.x()),f.highlightPoint(h,e,!0);var k=g.values[e];"undefined"!=typeof k&&("undefined"==typeof d&&(d=k),"undefined"==typeof i&&(i=b.xScale()(b.x()(k,e))),j.push({key:g.key,value:b.y()(k,e),color:n(g,g.seriesIndex)}))}),j.length>2){var o=b.yScale().invert(c.mouseY),p=Math.abs(b.yScale().domain()[0]-b.yScale().domain()[1]),q=.03*p,r=a.nearestValueIndex(j.map(function(a){return a.value}),o,q);null!==r&&(j[r].highlight=!0)}var s=g.tickFormat()(b.x()(d,e),e);k.tooltip.position({left:i+m.left,top:c.mouseY+m.top}).chartContainer(M.parentNode).valueFormatter(function(a){return h.tickFormat()(a)}).data({value:s,series:j})(),k.renderGuideLine(i)}),k.dispatch.on("elementMouseout",function(){f.clearHighlights()}),C.on("changeState",function(a){"undefined"!=typeof a.disabled&&(l.forEach(function(b,c){b.disabled=a.disabled[c]}),y.disabled=a.disabled),"undefined"!=typeof a.index&&(G.i=a.index,G.x=F(G.i),y.index=a.index,bb.data([G])),"undefined"!=typeof a.rescaleY&&(w=a.rescaleY),b.update()})}),H.renderEnd("cumulativeLineChart immediate"),b}function c(a,b){return K||(K=f.y()),b.map(function(b){if(!b.values)return b;var c=b.values[a];if(null==c)return b;var d=K(c,a);return-.95>d&&!E?(b.tempDisabled=!0,b):(b.tempDisabled=!1,b.values=b.values.map(function(a,b){return a.display={y:(K(a,b)-d)/(1+d)},a}),b)})}var d,e,f=a.models.line(),g=a.models.axis(),h=a.models.axis(),i=a.models.legend(),j=a.models.legend(),k=a.interactiveGuideline(),l=a.models.tooltip(),m={top:30,right:30,bottom:50,left:60},n=a.utils.defaultColor(),o=null,p=null,q=!0,r=!0,s=!0,t=!1,u=!0,v=!1,w=!0,x=f.id(),y=a.utils.state(),z=null,A=null,B=function(a){return a.average},C=d3.dispatch("stateChange","changeState","renderEnd"),D=250,E=!1;y.index=0,y.rescaleY=w,g.orient("bottom").tickPadding(7),h.orient(t?"right":"left"),l.valueFormatter(function(a,b){return h.tickFormat()(a,b)}).headerFormatter(function(a,b){return g.tickFormat()(a,b)}),j.updateState(!1);var F=d3.scale.linear(),G={i:0,x:0},H=a.utils.renderWatch(C,D),I=function(a){return function(){return{active:a.map(function(a){return!a.disabled}),index:G.i,rescaleY:w}}},J=function(a){return function(b){void 0!==b.index&&(G.i=b.index),void 0!==b.rescaleY&&(w=b.rescaleY),void 0!==b.active&&a.forEach(function(a,c){a.disabled=!b.active[c]})}};f.dispatch.on("elementMouseover.tooltip",function(a){var c={x:b.x()(a.point),y:b.y()(a.point),color:a.point.color};a.point=c,l.data(a).position(a.pos).hidden(!1)}),f.dispatch.on("elementMouseout.tooltip",function(){l.hidden(!0)});var K=null;return b.dispatch=C,b.lines=f,b.legend=i,b.controls=j,b.xAxis=g,b.yAxis=h,b.interactiveLayer=k,b.state=y,b.tooltip=l,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return o},set:function(a){o=a}},height:{get:function(){return p},set:function(a){p=a}},rescaleY:{get:function(){return w},set:function(a){w=a}},showControls:{get:function(){return u},set:function(a){u=a}},showLegend:{get:function(){return q},set:function(a){q=a}},average:{get:function(){return B},set:function(a){B=a}},defaultState:{get:function(){return z},set:function(a){z=a}},noData:{get:function(){return A},set:function(a){A=a}},showXAxis:{get:function(){return r},set:function(a){r=a}},showYAxis:{get:function(){return s},set:function(a){s=a}},noErrorCheck:{get:function(){return E},set:function(a){E=a}},tooltips:{get:function(){return l.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),l.enabled(!!b)}},tooltipContent:{get:function(){return l.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),l.contentGenerator(b)}},margin:{get:function(){return m},set:function(a){m.top=void 0!==a.top?a.top:m.top,m.right=void 0!==a.right?a.right:m.right,m.bottom=void 0!==a.bottom?a.bottom:m.bottom,m.left=void 0!==a.left?a.left:m.left}},color:{get:function(){return n},set:function(b){n=a.utils.getColor(b),i.color(n)}},useInteractiveGuideline:{get:function(){return v},set:function(a){v=a,a===!0&&(b.interactive(!1),b.useVoronoi(!1))}},rightAlignYAxis:{get:function(){return t},set:function(a){t=a,h.orient(a?"right":"left")}},duration:{get:function(){return D},set:function(a){D=a,f.duration(D),g.duration(D),h.duration(D),H.reset(D)}}}),a.utils.inheritOptions(b,f),a.utils.initOptions(b),b},a.models.discreteBar=function(){"use strict";function b(m){return y.reset(),m.each(function(b){var m=k-j.left-j.right,x=l-j.top-j.bottom;c=d3.select(this),a.utils.initSVG(c),b.forEach(function(a,b){a.values.forEach(function(a){a.series=b})});var z=d&&e?[]:b.map(function(a){return a.values.map(function(a,b){return{x:p(a,b),y:q(a,b),y0:a.y0}})});n.domain(d||d3.merge(z).map(function(a){return a.x})).rangeBands(f||[0,m],.1),o.domain(e||d3.extent(d3.merge(z).map(function(a){return a.y}).concat(r))),o.range(t?g||[x-(o.domain()[0]<0?12:0),o.domain()[1]>0?12:0]:g||[x,0]),h=h||n,i=i||o.copy().range([o(0),o(0)]);{var A=c.selectAll("g.nv-wrap.nv-discretebar").data([b]),B=A.enter().append("g").attr("class","nvd3 nv-wrap nv-discretebar"),C=B.append("g");A.select("g")}C.append("g").attr("class","nv-groups"),A.attr("transform","translate("+j.left+","+j.top+")");var D=A.select(".nv-groups").selectAll(".nv-group").data(function(a){return a},function(a){return a.key});D.enter().append("g").style("stroke-opacity",1e-6).style("fill-opacity",1e-6),D.exit().watchTransition(y,"discreteBar: exit groups").style("stroke-opacity",1e-6).style("fill-opacity",1e-6).remove(),D.attr("class",function(a,b){return"nv-group nv-series-"+b}).classed("hover",function(a){return a.hover}),D.watchTransition(y,"discreteBar: groups").style("stroke-opacity",1).style("fill-opacity",.75);var E=D.selectAll("g.nv-bar").data(function(a){return a.values});E.exit().remove();var F=E.enter().append("g").attr("transform",function(a,b){return"translate("+(n(p(a,b))+.05*n.rangeBand())+", "+o(0)+")"}).on("mouseover",function(a,b){d3.select(this).classed("hover",!0),v.elementMouseover({data:a,index:b,color:d3.select(this).style("fill")})}).on("mouseout",function(a,b){d3.select(this).classed("hover",!1),v.elementMouseout({data:a,index:b,color:d3.select(this).style("fill")})}).on("mousemove",function(a,b){v.elementMousemove({data:a,index:b,color:d3.select(this).style("fill")})}).on("click",function(a,b){v.elementClick({data:a,index:b,color:d3.select(this).style("fill")}),d3.event.stopPropagation()}).on("dblclick",function(a,b){v.elementDblClick({data:a,index:b,color:d3.select(this).style("fill")}),d3.event.stopPropagation()});F.append("rect").attr("height",0).attr("width",.9*n.rangeBand()/b.length),t?(F.append("text").attr("text-anchor","middle"),E.select("text").text(function(a,b){return u(q(a,b))}).watchTransition(y,"discreteBar: bars text").attr("x",.9*n.rangeBand()/2).attr("y",function(a,b){return q(a,b)<0?o(q(a,b))-o(0)+12:-4})):E.selectAll("text").remove(),E.attr("class",function(a,b){return q(a,b)<0?"nv-bar negative":"nv-bar positive"}).style("fill",function(a,b){return a.color||s(a,b)}).style("stroke",function(a,b){return a.color||s(a,b)}).select("rect").attr("class",w).watchTransition(y,"discreteBar: bars rect").attr("width",.9*n.rangeBand()/b.length),E.watchTransition(y,"discreteBar: bars").attr("transform",function(a,b){var c=n(p(a,b))+.05*n.rangeBand(),d=q(a,b)<0?o(0):o(0)-o(q(a,b))<1?o(0)-1:o(q(a,b));return"translate("+c+", "+d+")"}).select("rect").attr("height",function(a,b){return Math.max(Math.abs(o(q(a,b))-o(e&&e[0]||0))||1)}),h=n.copy(),i=o.copy()}),y.renderEnd("discreteBar immediate"),b}var c,d,e,f,g,h,i,j={top:0,right:0,bottom:0,left:0},k=960,l=500,m=Math.floor(1e4*Math.random()),n=d3.scale.ordinal(),o=d3.scale.linear(),p=function(a){return a.x},q=function(a){return a.y},r=[0],s=a.utils.defaultColor(),t=!1,u=d3.format(",.2f"),v=d3.dispatch("chartClick","elementClick","elementDblClick","elementMouseover","elementMouseout","elementMousemove","renderEnd"),w="discreteBar",x=250,y=a.utils.renderWatch(v,x);return b.dispatch=v,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return k},set:function(a){k=a}},height:{get:function(){return l},set:function(a){l=a}},forceY:{get:function(){return r},set:function(a){r=a}},showValues:{get:function(){return t},set:function(a){t=a}},x:{get:function(){return p},set:function(a){p=a}},y:{get:function(){return q},set:function(a){q=a}},xScale:{get:function(){return n},set:function(a){n=a}},yScale:{get:function(){return o},set:function(a){o=a}},xDomain:{get:function(){return d},set:function(a){d=a}},yDomain:{get:function(){return e},set:function(a){e=a}},xRange:{get:function(){return f},set:function(a){f=a}},yRange:{get:function(){return g},set:function(a){g=a}},valueFormat:{get:function(){return u},set:function(a){u=a}},id:{get:function(){return m},set:function(a){m=a}},rectClass:{get:function(){return w},set:function(a){w=a}},margin:{get:function(){return j},set:function(a){j.top=void 0!==a.top?a.top:j.top,j.right=void 0!==a.right?a.right:j.right,j.bottom=void 0!==a.bottom?a.bottom:j.bottom,j.left=void 0!==a.left?a.left:j.left}},color:{get:function(){return s},set:function(b){s=a.utils.getColor(b)}},duration:{get:function(){return x},set:function(a){x=a,y.reset(x)}}}),a.utils.initOptions(b),b},a.models.discreteBarChart=function(){"use strict";function b(h){return t.reset(),t.models(e),m&&t.models(f),n&&t.models(g),h.each(function(h){var l=d3.select(this);a.utils.initSVG(l);var q=a.utils.availableWidth(j,l,i),t=a.utils.availableHeight(k,l,i);if(b.update=function(){r.beforeUpdate(),l.transition().duration(s).call(b)},b.container=this,!(h&&h.length&&h.filter(function(a){return a.values.length}).length))return a.utils.noData(b,l),b;l.selectAll(".nv-noData").remove(),c=e.xScale(),d=e.yScale().clamp(!0);var u=l.selectAll("g.nv-wrap.nv-discreteBarWithAxes").data([h]),v=u.enter().append("g").attr("class","nvd3 nv-wrap nv-discreteBarWithAxes").append("g"),w=v.append("defs"),x=u.select("g");v.append("g").attr("class","nv-x nv-axis"),v.append("g").attr("class","nv-y nv-axis").append("g").attr("class","nv-zeroLine").append("line"),v.append("g").attr("class","nv-barsWrap"),x.attr("transform","translate("+i.left+","+i.top+")"),o&&x.select(".nv-y.nv-axis").attr("transform","translate("+q+",0)"),e.width(q).height(t);var y=x.select(".nv-barsWrap").datum(h.filter(function(a){return!a.disabled}));if(y.transition().call(e),w.append("clipPath").attr("id","nv-x-label-clip-"+e.id()).append("rect"),x.select("#nv-x-label-clip-"+e.id()+" rect").attr("width",c.rangeBand()*(p?2:1)).attr("height",16).attr("x",-c.rangeBand()/(p?1:2)),m){f.scale(c)._ticks(a.utils.calcTicksX(q/100,h)).tickSize(-t,0),x.select(".nv-x.nv-axis").attr("transform","translate(0,"+(d.range()[0]+(e.showValues()&&d.domain()[0]<0?16:0))+")"),x.select(".nv-x.nv-axis").call(f);
33848 var z=x.select(".nv-x.nv-axis").selectAll("g");p&&z.selectAll("text").attr("transform",function(a,b,c){return"translate(0,"+(c%2==0?"5":"17")+")"})}n&&(g.scale(d)._ticks(a.utils.calcTicksY(t/36,h)).tickSize(-q,0),x.select(".nv-y.nv-axis").call(g)),x.select(".nv-zeroLine line").attr("x1",0).attr("x2",q).attr("y1",d(0)).attr("y2",d(0))}),t.renderEnd("discreteBar chart immediate"),b}var c,d,e=a.models.discreteBar(),f=a.models.axis(),g=a.models.axis(),h=a.models.tooltip(),i={top:15,right:10,bottom:50,left:60},j=null,k=null,l=a.utils.getColor(),m=!0,n=!0,o=!1,p=!1,q=null,r=d3.dispatch("beforeUpdate","renderEnd"),s=250;f.orient("bottom").showMaxMin(!1).tickFormat(function(a){return a}),g.orient(o?"right":"left").tickFormat(d3.format(",.1f")),h.duration(0).headerEnabled(!1).valueFormatter(function(a,b){return g.tickFormat()(a,b)}).keyFormatter(function(a,b){return f.tickFormat()(a,b)});var t=a.utils.renderWatch(r,s);return e.dispatch.on("elementMouseover.tooltip",function(a){a.series={key:b.x()(a.data),value:b.y()(a.data),color:a.color},h.data(a).hidden(!1)}),e.dispatch.on("elementMouseout.tooltip",function(){h.hidden(!0)}),e.dispatch.on("elementMousemove.tooltip",function(){h.position({top:d3.event.pageY,left:d3.event.pageX})()}),b.dispatch=r,b.discretebar=e,b.xAxis=f,b.yAxis=g,b.tooltip=h,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return j},set:function(a){j=a}},height:{get:function(){return k},set:function(a){k=a}},staggerLabels:{get:function(){return p},set:function(a){p=a}},showXAxis:{get:function(){return m},set:function(a){m=a}},showYAxis:{get:function(){return n},set:function(a){n=a}},noData:{get:function(){return q},set:function(a){q=a}},tooltips:{get:function(){return h.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),h.enabled(!!b)}},tooltipContent:{get:function(){return h.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),h.contentGenerator(b)}},margin:{get:function(){return i},set:function(a){i.top=void 0!==a.top?a.top:i.top,i.right=void 0!==a.right?a.right:i.right,i.bottom=void 0!==a.bottom?a.bottom:i.bottom,i.left=void 0!==a.left?a.left:i.left}},duration:{get:function(){return s},set:function(a){s=a,t.reset(s),e.duration(s),f.duration(s),g.duration(s)}},color:{get:function(){return l},set:function(b){l=a.utils.getColor(b),e.color(l)}},rightAlignYAxis:{get:function(){return o},set:function(a){o=a,g.orient(a?"right":"left")}}}),a.utils.inheritOptions(b,e),a.utils.initOptions(b),b},a.models.distribution=function(){"use strict";function b(k){return m.reset(),k.each(function(b){var k=(e-("x"===g?d.left+d.right:d.top+d.bottom),"x"==g?"y":"x"),l=d3.select(this);a.utils.initSVG(l),c=c||j;var n=l.selectAll("g.nv-distribution").data([b]),o=n.enter().append("g").attr("class","nvd3 nv-distribution"),p=(o.append("g"),n.select("g"));n.attr("transform","translate("+d.left+","+d.top+")");var q=p.selectAll("g.nv-dist").data(function(a){return a},function(a){return a.key});q.enter().append("g"),q.attr("class",function(a,b){return"nv-dist nv-series-"+b}).style("stroke",function(a,b){return i(a,b)});var r=q.selectAll("line.nv-dist"+g).data(function(a){return a.values});r.enter().append("line").attr(g+"1",function(a,b){return c(h(a,b))}).attr(g+"2",function(a,b){return c(h(a,b))}),m.transition(q.exit().selectAll("line.nv-dist"+g),"dist exit").attr(g+"1",function(a,b){return j(h(a,b))}).attr(g+"2",function(a,b){return j(h(a,b))}).style("stroke-opacity",0).remove(),r.attr("class",function(a,b){return"nv-dist"+g+" nv-dist"+g+"-"+b}).attr(k+"1",0).attr(k+"2",f),m.transition(r,"dist").attr(g+"1",function(a,b){return j(h(a,b))}).attr(g+"2",function(a,b){return j(h(a,b))}),c=j.copy()}),m.renderEnd("distribution immediate"),b}var c,d={top:0,right:0,bottom:0,left:0},e=400,f=8,g="x",h=function(a){return a[g]},i=a.utils.defaultColor(),j=d3.scale.linear(),k=250,l=d3.dispatch("renderEnd"),m=a.utils.renderWatch(l,k);return b.options=a.utils.optionsFunc.bind(b),b.dispatch=l,b.margin=function(a){return arguments.length?(d.top="undefined"!=typeof a.top?a.top:d.top,d.right="undefined"!=typeof a.right?a.right:d.right,d.bottom="undefined"!=typeof a.bottom?a.bottom:d.bottom,d.left="undefined"!=typeof a.left?a.left:d.left,b):d},b.width=function(a){return arguments.length?(e=a,b):e},b.axis=function(a){return arguments.length?(g=a,b):g},b.size=function(a){return arguments.length?(f=a,b):f},b.getData=function(a){return arguments.length?(h=d3.functor(a),b):h},b.scale=function(a){return arguments.length?(j=a,b):j},b.color=function(c){return arguments.length?(i=a.utils.getColor(c),b):i},b.duration=function(a){return arguments.length?(k=a,m.reset(k),b):k},b},a.models.furiousLegend=function(){"use strict";function b(p){function q(a,b){return"furious"!=o?"#000":m?a.disengaged?g(a,b):"#fff":m?void 0:a.disabled?g(a,b):"#fff"}function r(a,b){return m&&"furious"==o?a.disengaged?"#fff":g(a,b):a.disabled?"#fff":g(a,b)}return p.each(function(b){var p=d-c.left-c.right,s=d3.select(this);a.utils.initSVG(s);var t=s.selectAll("g.nv-legend").data([b]),u=(t.enter().append("g").attr("class","nvd3 nv-legend").append("g"),t.select("g"));t.attr("transform","translate("+c.left+","+c.top+")");var v,w=u.selectAll(".nv-series").data(function(a){return"furious"!=o?a:a.filter(function(a){return m?!0:!a.disengaged})}),x=w.enter().append("g").attr("class","nv-series");if("classic"==o)x.append("circle").style("stroke-width",2).attr("class","nv-legend-symbol").attr("r",5),v=w.select("circle");else if("furious"==o){x.append("rect").style("stroke-width",2).attr("class","nv-legend-symbol").attr("rx",3).attr("ry",3),v=w.select("rect"),x.append("g").attr("class","nv-check-box").property("innerHTML",'<path d="M0.5,5 L22.5,5 L22.5,26.5 L0.5,26.5 L0.5,5 Z" class="nv-box"></path><path d="M5.5,12.8618467 L11.9185089,19.2803556 L31,0.198864511" class="nv-check"></path>').attr("transform","translate(-10,-8)scale(0.5)");var y=w.select(".nv-check-box");y.each(function(a,b){d3.select(this).selectAll("path").attr("stroke",q(a,b))})}x.append("text").attr("text-anchor","start").attr("class","nv-legend-text").attr("dy",".32em").attr("dx","8");var z=w.select("text.nv-legend-text");w.on("mouseover",function(a,b){n.legendMouseover(a,b)}).on("mouseout",function(a,b){n.legendMouseout(a,b)}).on("click",function(a,b){n.legendClick(a,b);var c=w.data();if(k){if("classic"==o)l?(c.forEach(function(a){a.disabled=!0}),a.disabled=!1):(a.disabled=!a.disabled,c.every(function(a){return a.disabled})&&c.forEach(function(a){a.disabled=!1}));else if("furious"==o)if(m)a.disengaged=!a.disengaged,a.userDisabled=void 0==a.userDisabled?!!a.disabled:a.userDisabled,a.disabled=a.disengaged||a.userDisabled;else if(!m){a.disabled=!a.disabled,a.userDisabled=a.disabled;var d=c.filter(function(a){return!a.disengaged});d.every(function(a){return a.userDisabled})&&c.forEach(function(a){a.disabled=a.userDisabled=!1})}n.stateChange({disabled:c.map(function(a){return!!a.disabled}),disengaged:c.map(function(a){return!!a.disengaged})})}}).on("dblclick",function(a,b){if(("furious"!=o||!m)&&(n.legendDblclick(a,b),k)){var c=w.data();c.forEach(function(a){a.disabled=!0,"furious"==o&&(a.userDisabled=a.disabled)}),a.disabled=!1,"furious"==o&&(a.userDisabled=a.disabled),n.stateChange({disabled:c.map(function(a){return!!a.disabled})})}}),w.classed("nv-disabled",function(a){return a.userDisabled}),w.exit().remove(),z.attr("fill",q).text(f);var A;switch(o){case"furious":A=23;break;case"classic":A=20}if(h){var B=[];w.each(function(){var b,c=d3.select(this).select("text");try{if(b=c.node().getComputedTextLength(),0>=b)throw Error()}catch(d){b=a.utils.calcApproxTextWidth(c)}B.push(b+i)});for(var C=0,D=0,E=[];p>D&&C<B.length;)E[C]=B[C],D+=B[C++];for(0===C&&(C=1);D>p&&C>1;){E=[],C--;for(var F=0;F<B.length;F++)B[F]>(E[F%C]||0)&&(E[F%C]=B[F]);D=E.reduce(function(a,b){return a+b})}for(var G=[],H=0,I=0;C>H;H++)G[H]=I,I+=E[H];w.attr("transform",function(a,b){return"translate("+G[b%C]+","+(5+Math.floor(b/C)*A)+")"}),j?u.attr("transform","translate("+(d-c.right-D)+","+c.top+")"):u.attr("transform","translate(0,"+c.top+")"),e=c.top+c.bottom+Math.ceil(B.length/C)*A}else{var J,K=5,L=5,M=0;w.attr("transform",function(){var a=d3.select(this).select("text").node().getComputedTextLength()+i;return J=L,d<c.left+c.right+J+a&&(L=J=5,K+=A),L+=a,L>M&&(M=L),"translate("+J+","+K+")"}),u.attr("transform","translate("+(d-c.right-M)+","+c.top+")"),e=c.top+c.bottom+K+15}"furious"==o&&v.attr("width",function(a,b){return z[0][b].getComputedTextLength()+27}).attr("height",18).attr("y",-9).attr("x",-15),v.style("fill",r).style("stroke",function(a,b){return a.color||g(a,b)})}),b}var c={top:5,right:0,bottom:5,left:0},d=400,e=20,f=function(a){return a.key},g=a.utils.getColor(),h=!0,i=28,j=!0,k=!0,l=!1,m=!1,n=d3.dispatch("legendClick","legendDblclick","legendMouseover","legendMouseout","stateChange"),o="classic";return b.dispatch=n,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return d},set:function(a){d=a}},height:{get:function(){return e},set:function(a){e=a}},key:{get:function(){return f},set:function(a){f=a}},align:{get:function(){return h},set:function(a){h=a}},rightAlign:{get:function(){return j},set:function(a){j=a}},padding:{get:function(){return i},set:function(a){i=a}},updateState:{get:function(){return k},set:function(a){k=a}},radioButtonMode:{get:function(){return l},set:function(a){l=a}},expanded:{get:function(){return m},set:function(a){m=a}},vers:{get:function(){return o},set:function(a){o=a}},margin:{get:function(){return c},set:function(a){c.top=void 0!==a.top?a.top:c.top,c.right=void 0!==a.right?a.right:c.right,c.bottom=void 0!==a.bottom?a.bottom:c.bottom,c.left=void 0!==a.left?a.left:c.left}},color:{get:function(){return g},set:function(b){g=a.utils.getColor(b)}}}),a.utils.initOptions(b),b},a.models.historicalBar=function(){"use strict";function b(x){return x.each(function(b){w.reset(),k=d3.select(this);var x=a.utils.availableWidth(h,k,g),y=a.utils.availableHeight(i,k,g);a.utils.initSVG(k),l.domain(c||d3.extent(b[0].values.map(n).concat(p))),l.range(r?e||[.5*x/b[0].values.length,x*(b[0].values.length-.5)/b[0].values.length]:e||[0,x]),m.domain(d||d3.extent(b[0].values.map(o).concat(q))).range(f||[y,0]),l.domain()[0]===l.domain()[1]&&l.domain(l.domain()[0]?[l.domain()[0]-.01*l.domain()[0],l.domain()[1]+.01*l.domain()[1]]:[-1,1]),m.domain()[0]===m.domain()[1]&&m.domain(m.domain()[0]?[m.domain()[0]+.01*m.domain()[0],m.domain()[1]-.01*m.domain()[1]]:[-1,1]);var z=k.selectAll("g.nv-wrap.nv-historicalBar-"+j).data([b[0].values]),A=z.enter().append("g").attr("class","nvd3 nv-wrap nv-historicalBar-"+j),B=A.append("defs"),C=A.append("g"),D=z.select("g");C.append("g").attr("class","nv-bars"),z.attr("transform","translate("+g.left+","+g.top+")"),k.on("click",function(a,b){u.chartClick({data:a,index:b,pos:d3.event,id:j})}),B.append("clipPath").attr("id","nv-chart-clip-path-"+j).append("rect"),z.select("#nv-chart-clip-path-"+j+" rect").attr("width",x).attr("height",y),D.attr("clip-path",s?"url(#nv-chart-clip-path-"+j+")":"");var E=z.select(".nv-bars").selectAll(".nv-bar").data(function(a){return a},function(a,b){return n(a,b)});E.exit().remove(),E.enter().append("rect").attr("x",0).attr("y",function(b,c){return a.utils.NaNtoZero(m(Math.max(0,o(b,c))))}).attr("height",function(b,c){return a.utils.NaNtoZero(Math.abs(m(o(b,c))-m(0)))}).attr("transform",function(a,c){return"translate("+(l(n(a,c))-x/b[0].values.length*.45)+",0)"}).on("mouseover",function(a,b){v&&(d3.select(this).classed("hover",!0),u.elementMouseover({data:a,index:b,color:d3.select(this).style("fill")}))}).on("mouseout",function(a,b){v&&(d3.select(this).classed("hover",!1),u.elementMouseout({data:a,index:b,color:d3.select(this).style("fill")}))}).on("mousemove",function(a,b){v&&u.elementMousemove({data:a,index:b,color:d3.select(this).style("fill")})}).on("click",function(a,b){v&&(u.elementClick({data:a,index:b,color:d3.select(this).style("fill")}),d3.event.stopPropagation())}).on("dblclick",function(a,b){v&&(u.elementDblClick({data:a,index:b,color:d3.select(this).style("fill")}),d3.event.stopPropagation())}),E.attr("fill",function(a,b){return t(a,b)}).attr("class",function(a,b,c){return(o(a,b)<0?"nv-bar negative":"nv-bar positive")+" nv-bar-"+c+"-"+b}).watchTransition(w,"bars").attr("transform",function(a,c){return"translate("+(l(n(a,c))-x/b[0].values.length*.45)+",0)"}).attr("width",x/b[0].values.length*.9),E.watchTransition(w,"bars").attr("y",function(b,c){var d=o(b,c)<0?m(0):m(0)-m(o(b,c))<1?m(0)-1:m(o(b,c));return a.utils.NaNtoZero(d)}).attr("height",function(b,c){return a.utils.NaNtoZero(Math.max(Math.abs(m(o(b,c))-m(0)),1))})}),w.renderEnd("historicalBar immediate"),b}var c,d,e,f,g={top:0,right:0,bottom:0,left:0},h=null,i=null,j=Math.floor(1e4*Math.random()),k=null,l=d3.scale.linear(),m=d3.scale.linear(),n=function(a){return a.x},o=function(a){return a.y},p=[],q=[0],r=!1,s=!0,t=a.utils.defaultColor(),u=d3.dispatch("chartClick","elementClick","elementDblClick","elementMouseover","elementMouseout","elementMousemove","renderEnd"),v=!0,w=a.utils.renderWatch(u,0);return b.highlightPoint=function(a,b){k.select(".nv-bars .nv-bar-0-"+a).classed("hover",b)},b.clearHighlights=function(){k.select(".nv-bars .nv-bar.hover").classed("hover",!1)},b.dispatch=u,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return h},set:function(a){h=a}},height:{get:function(){return i},set:function(a){i=a}},forceX:{get:function(){return p},set:function(a){p=a}},forceY:{get:function(){return q},set:function(a){q=a}},padData:{get:function(){return r},set:function(a){r=a}},x:{get:function(){return n},set:function(a){n=a}},y:{get:function(){return o},set:function(a){o=a}},xScale:{get:function(){return l},set:function(a){l=a}},yScale:{get:function(){return m},set:function(a){m=a}},xDomain:{get:function(){return c},set:function(a){c=a}},yDomain:{get:function(){return d},set:function(a){d=a}},xRange:{get:function(){return e},set:function(a){e=a}},yRange:{get:function(){return f},set:function(a){f=a}},clipEdge:{get:function(){return s},set:function(a){s=a}},id:{get:function(){return j},set:function(a){j=a}},interactive:{get:function(){return v},set:function(a){v=a}},margin:{get:function(){return g},set:function(a){g.top=void 0!==a.top?a.top:g.top,g.right=void 0!==a.right?a.right:g.right,g.bottom=void 0!==a.bottom?a.bottom:g.bottom,g.left=void 0!==a.left?a.left:g.left}},color:{get:function(){return t},set:function(b){t=a.utils.getColor(b)}}}),a.utils.initOptions(b),b},a.models.historicalBarChart=function(b){"use strict";function c(b){return b.each(function(k){z.reset(),z.models(f),q&&z.models(g),r&&z.models(h);var w=d3.select(this),A=this;a.utils.initSVG(w);var B=a.utils.availableWidth(n,w,l),C=a.utils.availableHeight(o,w,l);if(c.update=function(){w.transition().duration(y).call(c)},c.container=this,u.disabled=k.map(function(a){return!!a.disabled}),!v){var D;v={};for(D in u)v[D]=u[D]instanceof Array?u[D].slice(0):u[D]}if(!(k&&k.length&&k.filter(function(a){return a.values.length}).length))return a.utils.noData(c,w),c;w.selectAll(".nv-noData").remove(),d=f.xScale(),e=f.yScale();var E=w.selectAll("g.nv-wrap.nv-historicalBarChart").data([k]),F=E.enter().append("g").attr("class","nvd3 nv-wrap nv-historicalBarChart").append("g"),G=E.select("g");F.append("g").attr("class","nv-x nv-axis"),F.append("g").attr("class","nv-y nv-axis"),F.append("g").attr("class","nv-barsWrap"),F.append("g").attr("class","nv-legendWrap"),F.append("g").attr("class","nv-interactive"),p&&(i.width(B),G.select(".nv-legendWrap").datum(k).call(i),l.top!=i.height()&&(l.top=i.height(),C=a.utils.availableHeight(o,w,l)),E.select(".nv-legendWrap").attr("transform","translate(0,"+-l.top+")")),E.attr("transform","translate("+l.left+","+l.top+")"),s&&G.select(".nv-y.nv-axis").attr("transform","translate("+B+",0)"),t&&(j.width(B).height(C).margin({left:l.left,top:l.top}).svgContainer(w).xScale(d),E.select(".nv-interactive").call(j)),f.width(B).height(C).color(k.map(function(a,b){return a.color||m(a,b)}).filter(function(a,b){return!k[b].disabled}));var H=G.select(".nv-barsWrap").datum(k.filter(function(a){return!a.disabled}));H.transition().call(f),q&&(g.scale(d)._ticks(a.utils.calcTicksX(B/100,k)).tickSize(-C,0),G.select(".nv-x.nv-axis").attr("transform","translate(0,"+e.range()[0]+")"),G.select(".nv-x.nv-axis").transition().call(g)),r&&(h.scale(e)._ticks(a.utils.calcTicksY(C/36,k)).tickSize(-B,0),G.select(".nv-y.nv-axis").transition().call(h)),j.dispatch.on("elementMousemove",function(b){f.clearHighlights();var d,e,i,n=[];k.filter(function(a,b){return a.seriesIndex=b,!a.disabled}).forEach(function(g){e=a.interactiveBisect(g.values,b.pointXValue,c.x()),f.highlightPoint(e,!0);var h=g.values[e];void 0!==h&&(void 0===d&&(d=h),void 0===i&&(i=c.xScale()(c.x()(h,e))),n.push({key:g.key,value:c.y()(h,e),color:m(g,g.seriesIndex),data:g.values[e]}))});var o=g.tickFormat()(c.x()(d,e));j.tooltip.position({left:i+l.left,top:b.mouseY+l.top}).chartContainer(A.parentNode).valueFormatter(function(a){return h.tickFormat()(a)}).data({value:o,index:e,series:n})(),j.renderGuideLine(i)}),j.dispatch.on("elementMouseout",function(){x.tooltipHide(),f.clearHighlights()}),i.dispatch.on("legendClick",function(a){a.disabled=!a.disabled,k.filter(function(a){return!a.disabled}).length||k.map(function(a){return a.disabled=!1,E.selectAll(".nv-series").classed("disabled",!1),a}),u.disabled=k.map(function(a){return!!a.disabled}),x.stateChange(u),b.transition().call(c)}),i.dispatch.on("legendDblclick",function(a){k.forEach(function(a){a.disabled=!0}),a.disabled=!1,u.disabled=k.map(function(a){return!!a.disabled}),x.stateChange(u),c.update()}),x.on("changeState",function(a){"undefined"!=typeof a.disabled&&(k.forEach(function(b,c){b.disabled=a.disabled[c]}),u.disabled=a.disabled),c.update()})}),z.renderEnd("historicalBarChart immediate"),c}var d,e,f=b||a.models.historicalBar(),g=a.models.axis(),h=a.models.axis(),i=a.models.legend(),j=a.interactiveGuideline(),k=a.models.tooltip(),l={top:30,right:90,bottom:50,left:90},m=a.utils.defaultColor(),n=null,o=null,p=!1,q=!0,r=!0,s=!1,t=!1,u={},v=null,w=null,x=d3.dispatch("tooltipHide","stateChange","changeState","renderEnd"),y=250;g.orient("bottom").tickPadding(7),h.orient(s?"right":"left"),k.duration(0).headerEnabled(!1).valueFormatter(function(a,b){return h.tickFormat()(a,b)}).headerFormatter(function(a,b){return g.tickFormat()(a,b)});var z=a.utils.renderWatch(x,0);return f.dispatch.on("elementMouseover.tooltip",function(a){a.series={key:c.x()(a.data),value:c.y()(a.data),color:a.color},k.data(a).hidden(!1)}),f.dispatch.on("elementMouseout.tooltip",function(){k.hidden(!0)}),f.dispatch.on("elementMousemove.tooltip",function(){k.position({top:d3.event.pageY,left:d3.event.pageX})()}),c.dispatch=x,c.bars=f,c.legend=i,c.xAxis=g,c.yAxis=h,c.interactiveLayer=j,c.tooltip=k,c.options=a.utils.optionsFunc.bind(c),c._options=Object.create({},{width:{get:function(){return n},set:function(a){n=a}},height:{get:function(){return o},set:function(a){o=a}},showLegend:{get:function(){return p},set:function(a){p=a}},showXAxis:{get:function(){return q},set:function(a){q=a}},showYAxis:{get:function(){return r},set:function(a){r=a}},defaultState:{get:function(){return v},set:function(a){v=a}},noData:{get:function(){return w},set:function(a){w=a}},tooltips:{get:function(){return k.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),k.enabled(!!b)}},tooltipContent:{get:function(){return k.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),k.contentGenerator(b)}},margin:{get:function(){return l},set:function(a){l.top=void 0!==a.top?a.top:l.top,l.right=void 0!==a.right?a.right:l.right,l.bottom=void 0!==a.bottom?a.bottom:l.bottom,l.left=void 0!==a.left?a.left:l.left}},color:{get:function(){return m},set:function(b){m=a.utils.getColor(b),i.color(m),f.color(m)}},duration:{get:function(){return y},set:function(a){y=a,z.reset(y),h.duration(y),g.duration(y)}},rightAlignYAxis:{get:function(){return s},set:function(a){s=a,h.orient(a?"right":"left")}},useInteractiveGuideline:{get:function(){return t},set:function(a){t=a,a===!0&&c.interactive(!1)}}}),a.utils.inheritOptions(c,f),a.utils.initOptions(c),c},a.models.ohlcBarChart=function(){var b=a.models.historicalBarChart(a.models.ohlcBar());return b.useInteractiveGuideline(!0),b.interactiveLayer.tooltip.contentGenerator(function(a){var c=a.series[0].data,d=c.open<c.close?"2ca02c":"d62728";return'<h3 style="color: #'+d+'">'+a.value+"</h3><table><tr><td>open:</td><td>"+b.yAxis.tickFormat()(c.open)+"</td></tr><tr><td>close:</td><td>"+b.yAxis.tickFormat()(c.close)+"</td></tr><tr><td>high</td><td>"+b.yAxis.tickFormat()(c.high)+"</td></tr><tr><td>low:</td><td>"+b.yAxis.tickFormat()(c.low)+"</td></tr></table>"}),b},a.models.candlestickBarChart=function(){var b=a.models.historicalBarChart(a.models.candlestickBar());return b.useInteractiveGuideline(!0),b.interactiveLayer.tooltip.contentGenerator(function(a){var c=a.series[0].data,d=c.open<c.close?"2ca02c":"d62728";return'<h3 style="color: #'+d+'">'+a.value+"</h3><table><tr><td>open:</td><td>"+b.yAxis.tickFormat()(c.open)+"</td></tr><tr><td>close:</td><td>"+b.yAxis.tickFormat()(c.close)+"</td></tr><tr><td>high</td><td>"+b.yAxis.tickFormat()(c.high)+"</td></tr><tr><td>low:</td><td>"+b.yAxis.tickFormat()(c.low)+"</td></tr></table>"}),b},a.models.legend=function(){"use strict";function b(p){function q(a,b){return"furious"!=o?"#000":m?a.disengaged?"#000":"#fff":m?void 0:(a.color||(a.color=g(a,b)),a.disabled?a.color:"#fff")}function r(a,b){return m&&"furious"==o&&a.disengaged?"#eee":a.color||g(a,b)}function s(a){return m&&"furious"==o?1:a.disabled?0:1}return p.each(function(b){var g=d-c.left-c.right,p=d3.select(this);a.utils.initSVG(p);var t=p.selectAll("g.nv-legend").data([b]),u=t.enter().append("g").attr("class","nvd3 nv-legend").append("g"),v=t.select("g");t.attr("transform","translate("+c.left+","+c.top+")");var w,x,y=v.selectAll(".nv-series").data(function(a){return"furious"!=o?a:a.filter(function(a){return m?!0:!a.disengaged})}),z=y.enter().append("g").attr("class","nv-series");switch(o){case"furious":x=23;break;case"classic":x=20}if("classic"==o)z.append("circle").style("stroke-width",2).attr("class","nv-legend-symbol").attr("r",5),w=y.select("circle");else if("furious"==o){z.append("rect").style("stroke-width",2).attr("class","nv-legend-symbol").attr("rx",3).attr("ry",3),w=y.select(".nv-legend-symbol"),z.append("g").attr("class","nv-check-box").property("innerHTML",'<path d="M0.5,5 L22.5,5 L22.5,26.5 L0.5,26.5 L0.5,5 Z" class="nv-box"></path><path d="M5.5,12.8618467 L11.9185089,19.2803556 L31,0.198864511" class="nv-check"></path>').attr("transform","translate(-10,-8)scale(0.5)");var A=y.select(".nv-check-box");A.each(function(a,b){d3.select(this).selectAll("path").attr("stroke",q(a,b))})}z.append("text").attr("text-anchor","start").attr("class","nv-legend-text").attr("dy",".32em").attr("dx","8");var B=y.select("text.nv-legend-text");y.on("mouseover",function(a,b){n.legendMouseover(a,b)}).on("mouseout",function(a,b){n.legendMouseout(a,b)}).on("click",function(a,b){n.legendClick(a,b);var c=y.data();if(k){if("classic"==o)l?(c.forEach(function(a){a.disabled=!0}),a.disabled=!1):(a.disabled=!a.disabled,c.every(function(a){return a.disabled})&&c.forEach(function(a){a.disabled=!1}));else if("furious"==o)if(m)a.disengaged=!a.disengaged,a.userDisabled=void 0==a.userDisabled?!!a.disabled:a.userDisabled,a.disabled=a.disengaged||a.userDisabled;else if(!m){a.disabled=!a.disabled,a.userDisabled=a.disabled;var d=c.filter(function(a){return!a.disengaged});d.every(function(a){return a.userDisabled})&&c.forEach(function(a){a.disabled=a.userDisabled=!1})}n.stateChange({disabled:c.map(function(a){return!!a.disabled}),disengaged:c.map(function(a){return!!a.disengaged})})}}).on("dblclick",function(a,b){if(("furious"!=o||!m)&&(n.legendDblclick(a,b),k)){var c=y.data();c.forEach(function(a){a.disabled=!0,"furious"==o&&(a.userDisabled=a.disabled)}),a.disabled=!1,"furious"==o&&(a.userDisabled=a.disabled),n.stateChange({disabled:c.map(function(a){return!!a.disabled})})}}),y.classed("nv-disabled",function(a){return a.userDisabled}),y.exit().remove(),B.attr("fill",q).text(f);var C=0;if(h){var D=[];y.each(function(){var b,c=d3.select(this).select("text");try{if(b=c.node().getComputedTextLength(),0>=b)throw Error()}catch(d){b=a.utils.calcApproxTextWidth(c)}D.push(b+i)});var E=0,F=[];for(C=0;g>C&&E<D.length;)F[E]=D[E],C+=D[E++];for(0===E&&(E=1);C>g&&E>1;){F=[],E--;for(var G=0;G<D.length;G++)D[G]>(F[G%E]||0)&&(F[G%E]=D[G]);C=F.reduce(function(a,b){return a+b})}for(var H=[],I=0,J=0;E>I;I++)H[I]=J,J+=F[I];y.attr("transform",function(a,b){return"translate("+H[b%E]+","+(5+Math.floor(b/E)*x)+")"}),j?v.attr("transform","translate("+(d-c.right-C)+","+c.top+")"):v.attr("transform","translate(0,"+c.top+")"),e=c.top+c.bottom+Math.ceil(D.length/E)*x}else{var K,L=5,M=5,N=0;y.attr("transform",function(){var a=d3.select(this).select("text").node().getComputedTextLength()+i;return K=M,d<c.left+c.right+K+a&&(M=K=5,L+=x),M+=a,M>N&&(N=M),K+N>C&&(C=K+N),"translate("+K+","+L+")"}),v.attr("transform","translate("+(d-c.right-N)+","+c.top+")"),e=c.top+c.bottom+L+15}if("furious"==o){w.attr("width",function(a,b){return B[0][b].getComputedTextLength()+27}).attr("height",18).attr("y",-9).attr("x",-15),u.insert("rect",":first-child").attr("class","nv-legend-bg").attr("fill","#eee").attr("opacity",0);var O=v.select(".nv-legend-bg");O.transition().duration(300).attr("x",-x).attr("width",C+x-12).attr("height",e+10).attr("y",-c.top-10).attr("opacity",m?1:0)}w.style("fill",r).style("fill-opacity",s).style("stroke",r)}),b}var c={top:5,right:0,bottom:5,left:0},d=400,e=20,f=function(a){return a.key},g=a.utils.getColor(),h=!0,i=32,j=!0,k=!0,l=!1,m=!1,n=d3.dispatch("legendClick","legendDblclick","legendMouseover","legendMouseout","stateChange"),o="classic";return b.dispatch=n,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return d},set:function(a){d=a}},height:{get:function(){return e},set:function(a){e=a}},key:{get:function(){return f},set:function(a){f=a}},align:{get:function(){return h},set:function(a){h=a}},rightAlign:{get:function(){return j},set:function(a){j=a}},padding:{get:function(){return i},set:function(a){i=a}},updateState:{get:function(){return k},set:function(a){k=a}},radioButtonMode:{get:function(){return l},set:function(a){l=a}},expanded:{get:function(){return m},set:function(a){m=a}},vers:{get:function(){return o},set:function(a){o=a}},margin:{get:function(){return c},set:function(a){c.top=void 0!==a.top?a.top:c.top,c.right=void 0!==a.right?a.right:c.right,c.bottom=void 0!==a.bottom?a.bottom:c.bottom,c.left=void 0!==a.left?a.left:c.left}},color:{get:function(){return g},set:function(b){g=a.utils.getColor(b)}}}),a.utils.initOptions(b),b},a.models.line=function(){"use strict";function b(r){return v.reset(),v.models(e),r.each(function(b){i=d3.select(this);var r=a.utils.availableWidth(g,i,f),s=a.utils.availableHeight(h,i,f);a.utils.initSVG(i),c=e.xScale(),d=e.yScale(),t=t||c,u=u||d;var w=i.selectAll("g.nv-wrap.nv-line").data([b]),x=w.enter().append("g").attr("class","nvd3 nv-wrap nv-line"),y=x.append("defs"),z=x.append("g"),A=w.select("g");z.append("g").attr("class","nv-groups"),z.append("g").attr("class","nv-scatterWrap"),w.attr("transform","translate("+f.left+","+f.top+")"),e.width(r).height(s);var B=w.select(".nv-scatterWrap");B.call(e),y.append("clipPath").attr("id","nv-edge-clip-"+e.id()).append("rect"),w.select("#nv-edge-clip-"+e.id()+" rect").attr("width",r).attr("height",s>0?s:0),A.attr("clip-path",p?"url(#nv-edge-clip-"+e.id()+")":""),B.attr("clip-path",p?"url(#nv-edge-clip-"+e.id()+")":"");var C=w.select(".nv-groups").selectAll(".nv-group").data(function(a){return a},function(a){return a.key});C.enter().append("g").style("stroke-opacity",1e-6).style("stroke-width",function(a){return a.strokeWidth||j}).style("fill-opacity",1e-6),C.exit().remove(),C.attr("class",function(a,b){return(a.classed||"")+" nv-group nv-series-"+b}).classed("hover",function(a){return a.hover}).style("fill",function(a,b){return k(a,b)}).style("stroke",function(a,b){return k(a,b)}),C.watchTransition(v,"line: groups").style("stroke-opacity",1).style("fill-opacity",function(a){return a.fillOpacity||.5});var D=C.selectAll("path.nv-area").data(function(a){return o(a)?[a]:[]});D.enter().append("path").attr("class","nv-area").attr("d",function(b){return d3.svg.area().interpolate(q).defined(n).x(function(b,c){return a.utils.NaNtoZero(t(l(b,c)))}).y0(function(b,c){return a.utils.NaNtoZero(u(m(b,c)))}).y1(function(){return u(d.domain()[0]<=0?d.domain()[1]>=0?0:d.domain()[1]:d.domain()[0])}).apply(this,[b.values])}),C.exit().selectAll("path.nv-area").remove(),D.watchTransition(v,"line: areaPaths").attr("d",function(b){return d3.svg.area().interpolate(q).defined(n).x(function(b,d){return a.utils.NaNtoZero(c(l(b,d)))}).y0(function(b,c){return a.utils.NaNtoZero(d(m(b,c)))}).y1(function(){return d(d.domain()[0]<=0?d.domain()[1]>=0?0:d.domain()[1]:d.domain()[0])}).apply(this,[b.values])});var E=C.selectAll("path.nv-line").data(function(a){return[a.values]});E.enter().append("path").attr("class","nv-line").attr("d",d3.svg.line().interpolate(q).defined(n).x(function(b,c){return a.utils.NaNtoZero(t(l(b,c)))}).y(function(b,c){return a.utils.NaNtoZero(u(m(b,c)))})),E.watchTransition(v,"line: linePaths").attr("d",d3.svg.line().interpolate(q).defined(n).x(function(b,d){return a.utils.NaNtoZero(c(l(b,d)))}).y(function(b,c){return a.utils.NaNtoZero(d(m(b,c)))})),t=c.copy(),u=d.copy()}),v.renderEnd("line immediate"),b}var c,d,e=a.models.scatter(),f={top:0,right:0,bottom:0,left:0},g=960,h=500,i=null,j=1.5,k=a.utils.defaultColor(),l=function(a){return a.x},m=function(a){return a.y},n=function(a,b){return!isNaN(m(a,b))&&null!==m(a,b)},o=function(a){return a.area},p=!1,q="linear",r=250,s=d3.dispatch("elementClick","elementMouseover","elementMouseout","renderEnd");e.pointSize(16).pointDomain([16,256]);var t,u,v=a.utils.renderWatch(s,r);return b.dispatch=s,b.scatter=e,e.dispatch.on("elementClick",function(){s.elementClick.apply(this,arguments)}),e.dispatch.on("elementMouseover",function(){s.elementMouseover.apply(this,arguments)}),e.dispatch.on("elementMouseout",function(){s.elementMouseout.apply(this,arguments)}),b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return g},set:function(a){g=a}},height:{get:function(){return h},set:function(a){h=a}},defined:{get:function(){return n},set:function(a){n=a}},interpolate:{get:function(){return q},set:function(a){q=a}},clipEdge:{get:function(){return p},set:function(a){p=a}},margin:{get:function(){return f},set:function(a){f.top=void 0!==a.top?a.top:f.top,f.right=void 0!==a.right?a.right:f.right,f.bottom=void 0!==a.bottom?a.bottom:f.bottom,f.left=void 0!==a.left?a.left:f.left}},duration:{get:function(){return r},set:function(a){r=a,v.reset(r),e.duration(r)}},isArea:{get:function(){return o},set:function(a){o=d3.functor(a)}},x:{get:function(){return l},set:function(a){l=a,e.x(a)}},y:{get:function(){return m},set:function(a){m=a,e.y(a)}},color:{get:function(){return k},set:function(b){k=a.utils.getColor(b),e.color(k)}}}),a.utils.inheritOptions(b,e),a.utils.initOptions(b),b},a.models.lineChart=function(){"use strict";function b(j){return y.reset(),y.models(e),p&&y.models(f),q&&y.models(g),j.each(function(j){var v=d3.select(this),y=this;a.utils.initSVG(v);var B=a.utils.availableWidth(m,v,k),C=a.utils.availableHeight(n,v,k);if(b.update=function(){0===x?v.call(b):v.transition().duration(x).call(b)},b.container=this,t.setter(A(j),b.update).getter(z(j)).update(),t.disabled=j.map(function(a){return!!a.disabled}),!u){var D;u={};for(D in t)u[D]=t[D]instanceof Array?t[D].slice(0):t[D]
33849 }if(!(j&&j.length&&j.filter(function(a){return a.values.length}).length))return a.utils.noData(b,v),b;v.selectAll(".nv-noData").remove(),c=e.xScale(),d=e.yScale();var E=v.selectAll("g.nv-wrap.nv-lineChart").data([j]),F=E.enter().append("g").attr("class","nvd3 nv-wrap nv-lineChart").append("g"),G=E.select("g");F.append("rect").style("opacity",0),F.append("g").attr("class","nv-x nv-axis"),F.append("g").attr("class","nv-y nv-axis"),F.append("g").attr("class","nv-linesWrap"),F.append("g").attr("class","nv-legendWrap"),F.append("g").attr("class","nv-interactive"),G.select("rect").attr("width",B).attr("height",C>0?C:0),o&&(h.width(B),G.select(".nv-legendWrap").datum(j).call(h),k.top!=h.height()&&(k.top=h.height(),C=a.utils.availableHeight(n,v,k)),E.select(".nv-legendWrap").attr("transform","translate(0,"+-k.top+")")),E.attr("transform","translate("+k.left+","+k.top+")"),r&&G.select(".nv-y.nv-axis").attr("transform","translate("+B+",0)"),s&&(i.width(B).height(C).margin({left:k.left,top:k.top}).svgContainer(v).xScale(c),E.select(".nv-interactive").call(i)),e.width(B).height(C).color(j.map(function(a,b){return a.color||l(a,b)}).filter(function(a,b){return!j[b].disabled}));var H=G.select(".nv-linesWrap").datum(j.filter(function(a){return!a.disabled}));H.call(e),p&&(f.scale(c)._ticks(a.utils.calcTicksX(B/100,j)).tickSize(-C,0),G.select(".nv-x.nv-axis").attr("transform","translate(0,"+d.range()[0]+")"),G.select(".nv-x.nv-axis").call(f)),q&&(g.scale(d)._ticks(a.utils.calcTicksY(C/36,j)).tickSize(-B,0),G.select(".nv-y.nv-axis").call(g)),h.dispatch.on("stateChange",function(a){for(var c in a)t[c]=a[c];w.stateChange(t),b.update()}),i.dispatch.on("elementMousemove",function(c){e.clearHighlights();var d,h,m,n=[];if(j.filter(function(a,b){return a.seriesIndex=b,!a.disabled}).forEach(function(f,g){h=a.interactiveBisect(f.values,c.pointXValue,b.x());var i=f.values[h],j=b.y()(i,h);null!=j&&e.highlightPoint(g,h,!0),void 0!==i&&(void 0===d&&(d=i),void 0===m&&(m=b.xScale()(b.x()(i,h))),n.push({key:f.key,value:j,color:l(f,f.seriesIndex)}))}),n.length>2){var o=b.yScale().invert(c.mouseY),p=Math.abs(b.yScale().domain()[0]-b.yScale().domain()[1]),q=.03*p,r=a.nearestValueIndex(n.map(function(a){return a.value}),o,q);null!==r&&(n[r].highlight=!0)}var s=f.tickFormat()(b.x()(d,h));i.tooltip.position({left:c.mouseX+k.left,top:c.mouseY+k.top}).chartContainer(y.parentNode).valueFormatter(function(a){return null==a?"N/A":g.tickFormat()(a)}).data({value:s,index:h,series:n})(),i.renderGuideLine(m)}),i.dispatch.on("elementClick",function(c){var d,f=[];j.filter(function(a,b){return a.seriesIndex=b,!a.disabled}).forEach(function(e){var g=a.interactiveBisect(e.values,c.pointXValue,b.x()),h=e.values[g];if("undefined"!=typeof h){"undefined"==typeof d&&(d=b.xScale()(b.x()(h,g)));var i=b.yScale()(b.y()(h,g));f.push({point:h,pointIndex:g,pos:[d,i],seriesIndex:e.seriesIndex,series:e})}}),e.dispatch.elementClick(f)}),i.dispatch.on("elementMouseout",function(){e.clearHighlights()}),w.on("changeState",function(a){"undefined"!=typeof a.disabled&&j.length===a.disabled.length&&(j.forEach(function(b,c){b.disabled=a.disabled[c]}),t.disabled=a.disabled),b.update()})}),y.renderEnd("lineChart immediate"),b}var c,d,e=a.models.line(),f=a.models.axis(),g=a.models.axis(),h=a.models.legend(),i=a.interactiveGuideline(),j=a.models.tooltip(),k={top:30,right:20,bottom:50,left:60},l=a.utils.defaultColor(),m=null,n=null,o=!0,p=!0,q=!0,r=!1,s=!1,t=a.utils.state(),u=null,v=null,w=d3.dispatch("tooltipShow","tooltipHide","stateChange","changeState","renderEnd"),x=250;f.orient("bottom").tickPadding(7),g.orient(r?"right":"left"),j.valueFormatter(function(a,b){return g.tickFormat()(a,b)}).headerFormatter(function(a,b){return f.tickFormat()(a,b)});var y=a.utils.renderWatch(w,x),z=function(a){return function(){return{active:a.map(function(a){return!a.disabled})}}},A=function(a){return function(b){void 0!==b.active&&a.forEach(function(a,c){a.disabled=!b.active[c]})}};return e.dispatch.on("elementMouseover.tooltip",function(a){j.data(a).position(a.pos).hidden(!1)}),e.dispatch.on("elementMouseout.tooltip",function(){j.hidden(!0)}),b.dispatch=w,b.lines=e,b.legend=h,b.xAxis=f,b.yAxis=g,b.interactiveLayer=i,b.tooltip=j,b.dispatch=w,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return m},set:function(a){m=a}},height:{get:function(){return n},set:function(a){n=a}},showLegend:{get:function(){return o},set:function(a){o=a}},showXAxis:{get:function(){return p},set:function(a){p=a}},showYAxis:{get:function(){return q},set:function(a){q=a}},defaultState:{get:function(){return u},set:function(a){u=a}},noData:{get:function(){return v},set:function(a){v=a}},tooltips:{get:function(){return j.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),j.enabled(!!b)}},tooltipContent:{get:function(){return j.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),j.contentGenerator(b)}},margin:{get:function(){return k},set:function(a){k.top=void 0!==a.top?a.top:k.top,k.right=void 0!==a.right?a.right:k.right,k.bottom=void 0!==a.bottom?a.bottom:k.bottom,k.left=void 0!==a.left?a.left:k.left}},duration:{get:function(){return x},set:function(a){x=a,y.reset(x),e.duration(x),f.duration(x),g.duration(x)}},color:{get:function(){return l},set:function(b){l=a.utils.getColor(b),h.color(l),e.color(l)}},rightAlignYAxis:{get:function(){return r},set:function(a){r=a,g.orient(r?"right":"left")}},useInteractiveGuideline:{get:function(){return s},set:function(a){s=a,s&&(e.interactive(!1),e.useVoronoi(!1))}}}),a.utils.inheritOptions(b,e),a.utils.initOptions(b),b},a.models.linePlusBarChart=function(){"use strict";function b(v){return v.each(function(v){function J(a){var b=+("e"==a),c=b?1:-1,d=X/3;return"M"+.5*c+","+d+"A6,6 0 0 "+b+" "+6.5*c+","+(d+6)+"V"+(2*d-6)+"A6,6 0 0 "+b+" "+.5*c+","+2*d+"ZM"+2.5*c+","+(d+8)+"V"+(2*d-8)+"M"+4.5*c+","+(d+8)+"V"+(2*d-8)}function S(){u.empty()||u.extent(I),kb.data([u.empty()?e.domain():I]).each(function(a){var b=e(a[0])-e.range()[0],c=e.range()[1]-e(a[1]);d3.select(this).select(".left").attr("width",0>b?0:b),d3.select(this).select(".right").attr("x",e(a[1])).attr("width",0>c?0:c)})}function T(){I=u.empty()?null:u.extent(),c=u.empty()?e.domain():u.extent(),K.brush({extent:c,brush:u}),S(),l.width(V).height(W).color(v.map(function(a,b){return a.color||C(a,b)}).filter(function(a,b){return!v[b].disabled&&v[b].bar})),j.width(V).height(W).color(v.map(function(a,b){return a.color||C(a,b)}).filter(function(a,b){return!v[b].disabled&&!v[b].bar}));var b=db.select(".nv-focus .nv-barsWrap").datum(Z.length?Z.map(function(a){return{key:a.key,values:a.values.filter(function(a,b){return l.x()(a,b)>=c[0]&&l.x()(a,b)<=c[1]})}}):[{values:[]}]),h=db.select(".nv-focus .nv-linesWrap").datum($[0].disabled?[{values:[]}]:$.map(function(a){return{area:a.area,fillOpacity:a.fillOpacity,key:a.key,values:a.values.filter(function(a,b){return j.x()(a,b)>=c[0]&&j.x()(a,b)<=c[1]})}}));d=Z.length?l.xScale():j.xScale(),n.scale(d)._ticks(a.utils.calcTicksX(V/100,v)).tickSize(-W,0),n.domain([Math.ceil(c[0]),Math.floor(c[1])]),db.select(".nv-x.nv-axis").transition().duration(L).call(n),b.transition().duration(L).call(l),h.transition().duration(L).call(j),db.select(".nv-focus .nv-x.nv-axis").attr("transform","translate(0,"+f.range()[0]+")"),p.scale(f)._ticks(a.utils.calcTicksY(W/36,v)).tickSize(-V,0),q.scale(g)._ticks(a.utils.calcTicksY(W/36,v)).tickSize(Z.length?0:-V,0),db.select(".nv-focus .nv-y1.nv-axis").style("opacity",Z.length?1:0),db.select(".nv-focus .nv-y2.nv-axis").style("opacity",$.length&&!$[0].disabled?1:0).attr("transform","translate("+d.range()[1]+",0)"),db.select(".nv-focus .nv-y1.nv-axis").transition().duration(L).call(p),db.select(".nv-focus .nv-y2.nv-axis").transition().duration(L).call(q)}var U=d3.select(this);a.utils.initSVG(U);var V=a.utils.availableWidth(y,U,w),W=a.utils.availableHeight(z,U,w)-(E?H:0),X=H-x.top-x.bottom;if(b.update=function(){U.transition().duration(L).call(b)},b.container=this,M.setter(R(v),b.update).getter(Q(v)).update(),M.disabled=v.map(function(a){return!!a.disabled}),!N){var Y;N={};for(Y in M)N[Y]=M[Y]instanceof Array?M[Y].slice(0):M[Y]}if(!(v&&v.length&&v.filter(function(a){return a.values.length}).length))return a.utils.noData(b,U),b;U.selectAll(".nv-noData").remove();var Z=v.filter(function(a){return!a.disabled&&a.bar}),$=v.filter(function(a){return!a.bar});d=l.xScale(),e=o.scale(),f=l.yScale(),g=j.yScale(),h=m.yScale(),i=k.yScale();var _=v.filter(function(a){return!a.disabled&&a.bar}).map(function(a){return a.values.map(function(a,b){return{x:A(a,b),y:B(a,b)}})}),ab=v.filter(function(a){return!a.disabled&&!a.bar}).map(function(a){return a.values.map(function(a,b){return{x:A(a,b),y:B(a,b)}})});d.range([0,V]),e.domain(d3.extent(d3.merge(_.concat(ab)),function(a){return a.x})).range([0,V]);var bb=U.selectAll("g.nv-wrap.nv-linePlusBar").data([v]),cb=bb.enter().append("g").attr("class","nvd3 nv-wrap nv-linePlusBar").append("g"),db=bb.select("g");cb.append("g").attr("class","nv-legendWrap");var eb=cb.append("g").attr("class","nv-focus");eb.append("g").attr("class","nv-x nv-axis"),eb.append("g").attr("class","nv-y1 nv-axis"),eb.append("g").attr("class","nv-y2 nv-axis"),eb.append("g").attr("class","nv-barsWrap"),eb.append("g").attr("class","nv-linesWrap");var fb=cb.append("g").attr("class","nv-context");if(fb.append("g").attr("class","nv-x nv-axis"),fb.append("g").attr("class","nv-y1 nv-axis"),fb.append("g").attr("class","nv-y2 nv-axis"),fb.append("g").attr("class","nv-barsWrap"),fb.append("g").attr("class","nv-linesWrap"),fb.append("g").attr("class","nv-brushBackground"),fb.append("g").attr("class","nv-x nv-brush"),D){var gb=t.align()?V/2:V,hb=t.align()?gb:0;t.width(gb),db.select(".nv-legendWrap").datum(v.map(function(a){return a.originalKey=void 0===a.originalKey?a.key:a.originalKey,a.key=a.originalKey+(a.bar?O:P),a})).call(t),w.top!=t.height()&&(w.top=t.height(),W=a.utils.availableHeight(z,U,w)-H),db.select(".nv-legendWrap").attr("transform","translate("+hb+","+-w.top+")")}bb.attr("transform","translate("+w.left+","+w.top+")"),db.select(".nv-context").style("display",E?"initial":"none"),m.width(V).height(X).color(v.map(function(a,b){return a.color||C(a,b)}).filter(function(a,b){return!v[b].disabled&&v[b].bar})),k.width(V).height(X).color(v.map(function(a,b){return a.color||C(a,b)}).filter(function(a,b){return!v[b].disabled&&!v[b].bar}));var ib=db.select(".nv-context .nv-barsWrap").datum(Z.length?Z:[{values:[]}]),jb=db.select(".nv-context .nv-linesWrap").datum($[0].disabled?[{values:[]}]:$);db.select(".nv-context").attr("transform","translate(0,"+(W+w.bottom+x.top)+")"),ib.transition().call(m),jb.transition().call(k),G&&(o._ticks(a.utils.calcTicksX(V/100,v)).tickSize(-X,0),db.select(".nv-context .nv-x.nv-axis").attr("transform","translate(0,"+h.range()[0]+")"),db.select(".nv-context .nv-x.nv-axis").transition().call(o)),F&&(r.scale(h)._ticks(X/36).tickSize(-V,0),s.scale(i)._ticks(X/36).tickSize(Z.length?0:-V,0),db.select(".nv-context .nv-y3.nv-axis").style("opacity",Z.length?1:0).attr("transform","translate(0,"+e.range()[0]+")"),db.select(".nv-context .nv-y2.nv-axis").style("opacity",$.length?1:0).attr("transform","translate("+e.range()[1]+",0)"),db.select(".nv-context .nv-y1.nv-axis").transition().call(r),db.select(".nv-context .nv-y2.nv-axis").transition().call(s)),u.x(e).on("brush",T),I&&u.extent(I);var kb=db.select(".nv-brushBackground").selectAll("g").data([I||u.extent()]),lb=kb.enter().append("g");lb.append("rect").attr("class","left").attr("x",0).attr("y",0).attr("height",X),lb.append("rect").attr("class","right").attr("x",0).attr("y",0).attr("height",X);var mb=db.select(".nv-x.nv-brush").call(u);mb.selectAll("rect").attr("height",X),mb.selectAll(".resize").append("path").attr("d",J),t.dispatch.on("stateChange",function(a){for(var c in a)M[c]=a[c];K.stateChange(M),b.update()}),K.on("changeState",function(a){"undefined"!=typeof a.disabled&&(v.forEach(function(b,c){b.disabled=a.disabled[c]}),M.disabled=a.disabled),b.update()}),T()}),b}var c,d,e,f,g,h,i,j=a.models.line(),k=a.models.line(),l=a.models.historicalBar(),m=a.models.historicalBar(),n=a.models.axis(),o=a.models.axis(),p=a.models.axis(),q=a.models.axis(),r=a.models.axis(),s=a.models.axis(),t=a.models.legend(),u=d3.svg.brush(),v=a.models.tooltip(),w={top:30,right:30,bottom:30,left:60},x={top:0,right:30,bottom:20,left:60},y=null,z=null,A=function(a){return a.x},B=function(a){return a.y},C=a.utils.defaultColor(),D=!0,E=!0,F=!1,G=!0,H=50,I=null,J=null,K=d3.dispatch("brush","stateChange","changeState"),L=0,M=a.utils.state(),N=null,O=" (left axis)",P=" (right axis)";j.clipEdge(!0),k.interactive(!1),n.orient("bottom").tickPadding(5),p.orient("left"),q.orient("right"),o.orient("bottom").tickPadding(5),r.orient("left"),s.orient("right"),v.headerEnabled(!0).headerFormatter(function(a,b){return n.tickFormat()(a,b)});var Q=function(a){return function(){return{active:a.map(function(a){return!a.disabled})}}},R=function(a){return function(b){void 0!==b.active&&a.forEach(function(a,c){a.disabled=!b.active[c]})}};return j.dispatch.on("elementMouseover.tooltip",function(a){v.duration(100).valueFormatter(function(a,b){return q.tickFormat()(a,b)}).data(a).position(a.pos).hidden(!1)}),j.dispatch.on("elementMouseout.tooltip",function(){v.hidden(!0)}),l.dispatch.on("elementMouseover.tooltip",function(a){a.value=b.x()(a.data),a.series={value:b.y()(a.data),color:a.color},v.duration(0).valueFormatter(function(a,b){return p.tickFormat()(a,b)}).data(a).hidden(!1)}),l.dispatch.on("elementMouseout.tooltip",function(){v.hidden(!0)}),l.dispatch.on("elementMousemove.tooltip",function(){v.position({top:d3.event.pageY,left:d3.event.pageX})()}),b.dispatch=K,b.legend=t,b.lines=j,b.lines2=k,b.bars=l,b.bars2=m,b.xAxis=n,b.x2Axis=o,b.y1Axis=p,b.y2Axis=q,b.y3Axis=r,b.y4Axis=s,b.tooltip=v,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return y},set:function(a){y=a}},height:{get:function(){return z},set:function(a){z=a}},showLegend:{get:function(){return D},set:function(a){D=a}},brushExtent:{get:function(){return I},set:function(a){I=a}},noData:{get:function(){return J},set:function(a){J=a}},focusEnable:{get:function(){return E},set:function(a){E=a}},focusHeight:{get:function(){return H},set:function(a){H=a}},focusShowAxisX:{get:function(){return G},set:function(a){G=a}},focusShowAxisY:{get:function(){return F},set:function(a){F=a}},legendLeftAxisHint:{get:function(){return O},set:function(a){O=a}},legendRightAxisHint:{get:function(){return P},set:function(a){P=a}},tooltips:{get:function(){return v.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),v.enabled(!!b)}},tooltipContent:{get:function(){return v.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),v.contentGenerator(b)}},margin:{get:function(){return w},set:function(a){w.top=void 0!==a.top?a.top:w.top,w.right=void 0!==a.right?a.right:w.right,w.bottom=void 0!==a.bottom?a.bottom:w.bottom,w.left=void 0!==a.left?a.left:w.left}},duration:{get:function(){return L},set:function(a){L=a}},color:{get:function(){return C},set:function(b){C=a.utils.getColor(b),t.color(C)}},x:{get:function(){return A},set:function(a){A=a,j.x(a),k.x(a),l.x(a),m.x(a)}},y:{get:function(){return B},set:function(a){B=a,j.y(a),k.y(a),l.y(a),m.y(a)}}}),a.utils.inheritOptions(b,j),a.utils.initOptions(b),b},a.models.lineWithFocusChart=function(){"use strict";function b(o){return o.each(function(o){function z(a){var b=+("e"==a),c=b?1:-1,d=M/3;return"M"+.5*c+","+d+"A6,6 0 0 "+b+" "+6.5*c+","+(d+6)+"V"+(2*d-6)+"A6,6 0 0 "+b+" "+.5*c+","+2*d+"ZM"+2.5*c+","+(d+8)+"V"+(2*d-8)+"M"+4.5*c+","+(d+8)+"V"+(2*d-8)}function G(){n.empty()||n.extent(y),U.data([n.empty()?e.domain():y]).each(function(a){var b=e(a[0])-c.range()[0],d=K-e(a[1]);d3.select(this).select(".left").attr("width",0>b?0:b),d3.select(this).select(".right").attr("x",e(a[1])).attr("width",0>d?0:d)})}function H(){y=n.empty()?null:n.extent();var a=n.empty()?e.domain():n.extent();if(!(Math.abs(a[0]-a[1])<=1)){A.brush({extent:a,brush:n}),G();var b=Q.select(".nv-focus .nv-linesWrap").datum(o.filter(function(a){return!a.disabled}).map(function(b){return{key:b.key,area:b.area,values:b.values.filter(function(b,c){return g.x()(b,c)>=a[0]&&g.x()(b,c)<=a[1]})}}));b.transition().duration(B).call(g),Q.select(".nv-focus .nv-x.nv-axis").transition().duration(B).call(i),Q.select(".nv-focus .nv-y.nv-axis").transition().duration(B).call(j)}}var I=d3.select(this),J=this;a.utils.initSVG(I);var K=a.utils.availableWidth(t,I,q),L=a.utils.availableHeight(u,I,q)-v,M=v-r.top-r.bottom;if(b.update=function(){I.transition().duration(B).call(b)},b.container=this,C.setter(F(o),b.update).getter(E(o)).update(),C.disabled=o.map(function(a){return!!a.disabled}),!D){var N;D={};for(N in C)D[N]=C[N]instanceof Array?C[N].slice(0):C[N]}if(!(o&&o.length&&o.filter(function(a){return a.values.length}).length))return a.utils.noData(b,I),b;I.selectAll(".nv-noData").remove(),c=g.xScale(),d=g.yScale(),e=h.xScale(),f=h.yScale();var O=I.selectAll("g.nv-wrap.nv-lineWithFocusChart").data([o]),P=O.enter().append("g").attr("class","nvd3 nv-wrap nv-lineWithFocusChart").append("g"),Q=O.select("g");P.append("g").attr("class","nv-legendWrap");var R=P.append("g").attr("class","nv-focus");R.append("g").attr("class","nv-x nv-axis"),R.append("g").attr("class","nv-y nv-axis"),R.append("g").attr("class","nv-linesWrap"),R.append("g").attr("class","nv-interactive");var S=P.append("g").attr("class","nv-context");S.append("g").attr("class","nv-x nv-axis"),S.append("g").attr("class","nv-y nv-axis"),S.append("g").attr("class","nv-linesWrap"),S.append("g").attr("class","nv-brushBackground"),S.append("g").attr("class","nv-x nv-brush"),x&&(m.width(K),Q.select(".nv-legendWrap").datum(o).call(m),q.top!=m.height()&&(q.top=m.height(),L=a.utils.availableHeight(u,I,q)-v),Q.select(".nv-legendWrap").attr("transform","translate(0,"+-q.top+")")),O.attr("transform","translate("+q.left+","+q.top+")"),w&&(p.width(K).height(L).margin({left:q.left,top:q.top}).svgContainer(I).xScale(c),O.select(".nv-interactive").call(p)),g.width(K).height(L).color(o.map(function(a,b){return a.color||s(a,b)}).filter(function(a,b){return!o[b].disabled})),h.defined(g.defined()).width(K).height(M).color(o.map(function(a,b){return a.color||s(a,b)}).filter(function(a,b){return!o[b].disabled})),Q.select(".nv-context").attr("transform","translate(0,"+(L+q.bottom+r.top)+")");var T=Q.select(".nv-context .nv-linesWrap").datum(o.filter(function(a){return!a.disabled}));d3.transition(T).call(h),i.scale(c)._ticks(a.utils.calcTicksX(K/100,o)).tickSize(-L,0),j.scale(d)._ticks(a.utils.calcTicksY(L/36,o)).tickSize(-K,0),Q.select(".nv-focus .nv-x.nv-axis").attr("transform","translate(0,"+L+")"),n.x(e).on("brush",function(){H()}),y&&n.extent(y);var U=Q.select(".nv-brushBackground").selectAll("g").data([y||n.extent()]),V=U.enter().append("g");V.append("rect").attr("class","left").attr("x",0).attr("y",0).attr("height",M),V.append("rect").attr("class","right").attr("x",0).attr("y",0).attr("height",M);var W=Q.select(".nv-x.nv-brush").call(n);W.selectAll("rect").attr("height",M),W.selectAll(".resize").append("path").attr("d",z),H(),k.scale(e)._ticks(a.utils.calcTicksX(K/100,o)).tickSize(-M,0),Q.select(".nv-context .nv-x.nv-axis").attr("transform","translate(0,"+f.range()[0]+")"),d3.transition(Q.select(".nv-context .nv-x.nv-axis")).call(k),l.scale(f)._ticks(a.utils.calcTicksY(M/36,o)).tickSize(-K,0),d3.transition(Q.select(".nv-context .nv-y.nv-axis")).call(l),Q.select(".nv-context .nv-x.nv-axis").attr("transform","translate(0,"+f.range()[0]+")"),m.dispatch.on("stateChange",function(a){for(var c in a)C[c]=a[c];A.stateChange(C),b.update()}),p.dispatch.on("elementMousemove",function(c){g.clearHighlights();var d,f,h,k=[];if(o.filter(function(a,b){return a.seriesIndex=b,!a.disabled}).forEach(function(i,j){var l=n.empty()?e.domain():n.extent(),m=i.values.filter(function(a,b){return g.x()(a,b)>=l[0]&&g.x()(a,b)<=l[1]});f=a.interactiveBisect(m,c.pointXValue,g.x());var o=m[f],p=b.y()(o,f);null!=p&&g.highlightPoint(j,f,!0),void 0!==o&&(void 0===d&&(d=o),void 0===h&&(h=b.xScale()(b.x()(o,f))),k.push({key:i.key,value:b.y()(o,f),color:s(i,i.seriesIndex)}))}),k.length>2){var l=b.yScale().invert(c.mouseY),m=Math.abs(b.yScale().domain()[0]-b.yScale().domain()[1]),r=.03*m,t=a.nearestValueIndex(k.map(function(a){return a.value}),l,r);null!==t&&(k[t].highlight=!0)}var u=i.tickFormat()(b.x()(d,f));p.tooltip.position({left:c.mouseX+q.left,top:c.mouseY+q.top}).chartContainer(J.parentNode).valueFormatter(function(a){return null==a?"N/A":j.tickFormat()(a)}).data({value:u,index:f,series:k})(),p.renderGuideLine(h)}),p.dispatch.on("elementMouseout",function(){g.clearHighlights()}),A.on("changeState",function(a){"undefined"!=typeof a.disabled&&o.forEach(function(b,c){b.disabled=a.disabled[c]}),b.update()})}),b}var c,d,e,f,g=a.models.line(),h=a.models.line(),i=a.models.axis(),j=a.models.axis(),k=a.models.axis(),l=a.models.axis(),m=a.models.legend(),n=d3.svg.brush(),o=a.models.tooltip(),p=a.interactiveGuideline(),q={top:30,right:30,bottom:30,left:60},r={top:0,right:30,bottom:20,left:60},s=a.utils.defaultColor(),t=null,u=null,v=50,w=!1,x=!0,y=null,z=null,A=d3.dispatch("brush","stateChange","changeState"),B=250,C=a.utils.state(),D=null;g.clipEdge(!0).duration(0),h.interactive(!1),i.orient("bottom").tickPadding(5),j.orient("left"),k.orient("bottom").tickPadding(5),l.orient("left"),o.valueFormatter(function(a,b){return j.tickFormat()(a,b)}).headerFormatter(function(a,b){return i.tickFormat()(a,b)});var E=function(a){return function(){return{active:a.map(function(a){return!a.disabled})}}},F=function(a){return function(b){void 0!==b.active&&a.forEach(function(a,c){a.disabled=!b.active[c]})}};return g.dispatch.on("elementMouseover.tooltip",function(a){o.data(a).position(a.pos).hidden(!1)}),g.dispatch.on("elementMouseout.tooltip",function(){o.hidden(!0)}),b.dispatch=A,b.legend=m,b.lines=g,b.lines2=h,b.xAxis=i,b.yAxis=j,b.x2Axis=k,b.y2Axis=l,b.interactiveLayer=p,b.tooltip=o,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return t},set:function(a){t=a}},height:{get:function(){return u},set:function(a){u=a}},focusHeight:{get:function(){return v},set:function(a){v=a}},showLegend:{get:function(){return x},set:function(a){x=a}},brushExtent:{get:function(){return y},set:function(a){y=a}},defaultState:{get:function(){return D},set:function(a){D=a}},noData:{get:function(){return z},set:function(a){z=a}},tooltips:{get:function(){return o.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),o.enabled(!!b)}},tooltipContent:{get:function(){return o.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),o.contentGenerator(b)}},margin:{get:function(){return q},set:function(a){q.top=void 0!==a.top?a.top:q.top,q.right=void 0!==a.right?a.right:q.right,q.bottom=void 0!==a.bottom?a.bottom:q.bottom,q.left=void 0!==a.left?a.left:q.left}},color:{get:function(){return s},set:function(b){s=a.utils.getColor(b),m.color(s)}},interpolate:{get:function(){return g.interpolate()},set:function(a){g.interpolate(a),h.interpolate(a)}},xTickFormat:{get:function(){return i.tickFormat()},set:function(a){i.tickFormat(a),k.tickFormat(a)}},yTickFormat:{get:function(){return j.tickFormat()},set:function(a){j.tickFormat(a),l.tickFormat(a)}},duration:{get:function(){return B},set:function(a){B=a,j.duration(B),l.duration(B),i.duration(B),k.duration(B)}},x:{get:function(){return g.x()},set:function(a){g.x(a),h.x(a)}},y:{get:function(){return g.y()},set:function(a){g.y(a),h.y(a)}},useInteractiveGuideline:{get:function(){return w},set:function(a){w=a,w&&(g.interactive(!1),g.useVoronoi(!1))}}}),a.utils.inheritOptions(b,g),a.utils.initOptions(b),b},a.models.multiBar=function(){"use strict";function b(E){return C.reset(),E.each(function(b){var E=k-j.left-j.right,F=l-j.top-j.bottom;p=d3.select(this),a.utils.initSVG(p);var G=0;if(x&&b.length&&(x=[{values:b[0].values.map(function(a){return{x:a.x,y:0,series:a.series,size:.01}})}]),u){var H=d3.layout.stack().offset(v).values(function(a){return a.values}).y(r)(!b.length&&x?x:b);H.forEach(function(a,c){a.nonStackable?(b[c].nonStackableSeries=G++,H[c]=b[c]):c>0&&H[c-1].nonStackable&&H[c].values.map(function(a,b){a.y0-=H[c-1].values[b].y,a.y1=a.y0+a.y})}),b=H}b.forEach(function(a,b){a.values.forEach(function(c){c.series=b,c.key=a.key})}),u&&b[0].values.map(function(a,c){var d=0,e=0;b.map(function(a,f){if(!b[f].nonStackable){var g=a.values[c];g.size=Math.abs(g.y),g.y<0?(g.y1=e,e-=g.size):(g.y1=g.size+d,d+=g.size)}})});var I=d&&e?[]:b.map(function(a,b){return a.values.map(function(a,c){return{x:q(a,c),y:r(a,c),y0:a.y0,y1:a.y1,idx:b}})});m.domain(d||d3.merge(I).map(function(a){return a.x})).rangeBands(f||[0,E],A),n.domain(e||d3.extent(d3.merge(I).map(function(a){var c=a.y;return u&&!b[a.idx].nonStackable&&(c=a.y>0?a.y1:a.y1+a.y),c}).concat(s))).range(g||[F,0]),m.domain()[0]===m.domain()[1]&&m.domain(m.domain()[0]?[m.domain()[0]-.01*m.domain()[0],m.domain()[1]+.01*m.domain()[1]]:[-1,1]),n.domain()[0]===n.domain()[1]&&n.domain(n.domain()[0]?[n.domain()[0]+.01*n.domain()[0],n.domain()[1]-.01*n.domain()[1]]:[-1,1]),h=h||m,i=i||n;var J=p.selectAll("g.nv-wrap.nv-multibar").data([b]),K=J.enter().append("g").attr("class","nvd3 nv-wrap nv-multibar"),L=K.append("defs"),M=K.append("g"),N=J.select("g");M.append("g").attr("class","nv-groups"),J.attr("transform","translate("+j.left+","+j.top+")"),L.append("clipPath").attr("id","nv-edge-clip-"+o).append("rect"),J.select("#nv-edge-clip-"+o+" rect").attr("width",E).attr("height",F),N.attr("clip-path",t?"url(#nv-edge-clip-"+o+")":"");var O=J.select(".nv-groups").selectAll(".nv-group").data(function(a){return a},function(a,b){return b});O.enter().append("g").style("stroke-opacity",1e-6).style("fill-opacity",1e-6);var P=C.transition(O.exit().selectAll("rect.nv-bar"),"multibarExit",Math.min(100,z)).attr("y",function(a){var c=i(0)||0;return u&&b[a.series]&&!b[a.series].nonStackable&&(c=i(a.y0)),c}).attr("height",0).remove();P.delay&&P.delay(function(a,b){var c=b*(z/(D+1))-b;return c}),O.attr("class",function(a,b){return"nv-group nv-series-"+b}).classed("hover",function(a){return a.hover}).style("fill",function(a,b){return w(a,b)}).style("stroke",function(a,b){return w(a,b)}),O.style("stroke-opacity",1).style("fill-opacity",.75);var Q=O.selectAll("rect.nv-bar").data(function(a){return x&&!b.length?x.values:a.values});Q.exit().remove();Q.enter().append("rect").attr("class",function(a,b){return r(a,b)<0?"nv-bar negative":"nv-bar positive"}).attr("x",function(a,c,d){return u&&!b[d].nonStackable?0:d*m.rangeBand()/b.length}).attr("y",function(a,c,d){return i(u&&!b[d].nonStackable?a.y0:0)||0}).attr("height",0).attr("width",function(a,c,d){return m.rangeBand()/(u&&!b[d].nonStackable?1:b.length)}).attr("transform",function(a,b){return"translate("+m(q(a,b))+",0)"});Q.style("fill",function(a,b,c){return w(a,c,b)}).style("stroke",function(a,b,c){return w(a,c,b)}).on("mouseover",function(a,b){d3.select(this).classed("hover",!0),B.elementMouseover({data:a,index:b,color:d3.select(this).style("fill")})}).on("mouseout",function(a,b){d3.select(this).classed("hover",!1),B.elementMouseout({data:a,index:b,color:d3.select(this).style("fill")})}).on("mousemove",function(a,b){B.elementMousemove({data:a,index:b,color:d3.select(this).style("fill")})}).on("click",function(a,b){B.elementClick({data:a,index:b,color:d3.select(this).style("fill")}),d3.event.stopPropagation()}).on("dblclick",function(a,b){B.elementDblClick({data:a,index:b,color:d3.select(this).style("fill")}),d3.event.stopPropagation()}),Q.attr("class",function(a,b){return r(a,b)<0?"nv-bar negative":"nv-bar positive"}).attr("transform",function(a,b){return"translate("+m(q(a,b))+",0)"}),y&&(c||(c=b.map(function(){return!0})),Q.style("fill",function(a,b,d){return d3.rgb(y(a,b)).darker(c.map(function(a,b){return b}).filter(function(a,b){return!c[b]})[d]).toString()}).style("stroke",function(a,b,d){return d3.rgb(y(a,b)).darker(c.map(function(a,b){return b}).filter(function(a,b){return!c[b]})[d]).toString()}));var R=Q.watchTransition(C,"multibar",Math.min(250,z)).delay(function(a,c){return c*z/b[0].values.length});u?R.attr("y",function(a,c,d){var e=0;return e=b[d].nonStackable?r(a,c)<0?n(0):n(0)-n(r(a,c))<-1?n(0)-1:n(r(a,c))||0:n(a.y1)}).attr("height",function(a,c,d){return b[d].nonStackable?Math.max(Math.abs(n(r(a,c))-n(0)),1)||0:Math.max(Math.abs(n(a.y+a.y0)-n(a.y0)),1)}).attr("x",function(a,c,d){var e=0;return b[d].nonStackable&&(e=a.series*m.rangeBand()/b.length,b.length!==G&&(e=b[d].nonStackableSeries*m.rangeBand()/(2*G))),e}).attr("width",function(a,c,d){if(b[d].nonStackable){var e=m.rangeBand()/G;return b.length!==G&&(e=m.rangeBand()/(2*G)),e}return m.rangeBand()}):R.attr("x",function(a){return a.series*m.rangeBand()/b.length}).attr("width",m.rangeBand()/b.length).attr("y",function(a,b){return r(a,b)<0?n(0):n(0)-n(r(a,b))<1?n(0)-1:n(r(a,b))||0}).attr("height",function(a,b){return Math.max(Math.abs(n(r(a,b))-n(0)),1)||0}),h=m.copy(),i=n.copy(),b[0]&&b[0].values&&(D=b[0].values.length)}),C.renderEnd("multibar immediate"),b}var c,d,e,f,g,h,i,j={top:0,right:0,bottom:0,left:0},k=960,l=500,m=d3.scale.ordinal(),n=d3.scale.linear(),o=Math.floor(1e4*Math.random()),p=null,q=function(a){return a.x},r=function(a){return a.y},s=[0],t=!0,u=!1,v="zero",w=a.utils.defaultColor(),x=!1,y=null,z=500,A=.1,B=d3.dispatch("chartClick","elementClick","elementDblClick","elementMouseover","elementMouseout","elementMousemove","renderEnd"),C=a.utils.renderWatch(B,z),D=0;return b.dispatch=B,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return k},set:function(a){k=a}},height:{get:function(){return l},set:function(a){l=a}},x:{get:function(){return q},set:function(a){q=a}},y:{get:function(){return r},set:function(a){r=a}},xScale:{get:function(){return m},set:function(a){m=a}},yScale:{get:function(){return n},set:function(a){n=a}},xDomain:{get:function(){return d},set:function(a){d=a}},yDomain:{get:function(){return e},set:function(a){e=a}},xRange:{get:function(){return f},set:function(a){f=a}},yRange:{get:function(){return g},set:function(a){g=a}},forceY:{get:function(){return s},set:function(a){s=a}},stacked:{get:function(){return u},set:function(a){u=a}},stackOffset:{get:function(){return v},set:function(a){v=a}},clipEdge:{get:function(){return t},set:function(a){t=a}},disabled:{get:function(){return c},set:function(a){c=a}},id:{get:function(){return o},set:function(a){o=a}},hideable:{get:function(){return x},set:function(a){x=a}},groupSpacing:{get:function(){return A},set:function(a){A=a}},margin:{get:function(){return j},set:function(a){j.top=void 0!==a.top?a.top:j.top,j.right=void 0!==a.right?a.right:j.right,j.bottom=void 0!==a.bottom?a.bottom:j.bottom,j.left=void 0!==a.left?a.left:j.left}},duration:{get:function(){return z},set:function(a){z=a,C.reset(z)}},color:{get:function(){return w},set:function(b){w=a.utils.getColor(b)}},barColor:{get:function(){return y},set:function(b){y=b?a.utils.getColor(b):null}}}),a.utils.initOptions(b),b},a.models.multiBarChart=function(){"use strict";function b(j){return D.reset(),D.models(e),r&&D.models(f),s&&D.models(g),j.each(function(j){var z=d3.select(this);a.utils.initSVG(z);var D=a.utils.availableWidth(l,z,k),H=a.utils.availableHeight(m,z,k);if(b.update=function(){0===C?z.call(b):z.transition().duration(C).call(b)},b.container=this,x.setter(G(j),b.update).getter(F(j)).update(),x.disabled=j.map(function(a){return!!a.disabled}),!y){var I;y={};for(I in x)y[I]=x[I]instanceof Array?x[I].slice(0):x[I]}if(!(j&&j.length&&j.filter(function(a){return a.values.length}).length))return a.utils.noData(b,z),b;z.selectAll(".nv-noData").remove(),c=e.xScale(),d=e.yScale();
33850 var J=z.selectAll("g.nv-wrap.nv-multiBarWithLegend").data([j]),K=J.enter().append("g").attr("class","nvd3 nv-wrap nv-multiBarWithLegend").append("g"),L=J.select("g");if(K.append("g").attr("class","nv-x nv-axis"),K.append("g").attr("class","nv-y nv-axis"),K.append("g").attr("class","nv-barsWrap"),K.append("g").attr("class","nv-legendWrap"),K.append("g").attr("class","nv-controlsWrap"),q&&(h.width(D-B()),L.select(".nv-legendWrap").datum(j).call(h),k.top!=h.height()&&(k.top=h.height(),H=a.utils.availableHeight(m,z,k)),L.select(".nv-legendWrap").attr("transform","translate("+B()+","+-k.top+")")),o){var M=[{key:p.grouped||"Grouped",disabled:e.stacked()},{key:p.stacked||"Stacked",disabled:!e.stacked()}];i.width(B()).color(["#444","#444","#444"]),L.select(".nv-controlsWrap").datum(M).attr("transform","translate(0,"+-k.top+")").call(i)}J.attr("transform","translate("+k.left+","+k.top+")"),t&&L.select(".nv-y.nv-axis").attr("transform","translate("+D+",0)"),e.disabled(j.map(function(a){return a.disabled})).width(D).height(H).color(j.map(function(a,b){return a.color||n(a,b)}).filter(function(a,b){return!j[b].disabled}));var N=L.select(".nv-barsWrap").datum(j.filter(function(a){return!a.disabled}));if(N.call(e),r){f.scale(c)._ticks(a.utils.calcTicksX(D/100,j)).tickSize(-H,0),L.select(".nv-x.nv-axis").attr("transform","translate(0,"+d.range()[0]+")"),L.select(".nv-x.nv-axis").call(f);var O=L.select(".nv-x.nv-axis > g").selectAll("g");if(O.selectAll("line, text").style("opacity",1),v){var P=function(a,b){return"translate("+a+","+b+")"},Q=5,R=17;O.selectAll("text").attr("transform",function(a,b,c){return P(0,c%2==0?Q:R)});var S=d3.selectAll(".nv-x.nv-axis .nv-wrap g g text")[0].length;L.selectAll(".nv-x.nv-axis .nv-axisMaxMin text").attr("transform",function(a,b){return P(0,0===b||S%2!==0?R:Q)})}u&&O.filter(function(a,b){return b%Math.ceil(j[0].values.length/(D/100))!==0}).selectAll("text, line").style("opacity",0),w&&O.selectAll(".tick text").attr("transform","rotate("+w+" 0,0)").style("text-anchor",w>0?"start":"end"),L.select(".nv-x.nv-axis").selectAll("g.nv-axisMaxMin text").style("opacity",1)}s&&(g.scale(d)._ticks(a.utils.calcTicksY(H/36,j)).tickSize(-D,0),L.select(".nv-y.nv-axis").call(g)),h.dispatch.on("stateChange",function(a){for(var c in a)x[c]=a[c];A.stateChange(x),b.update()}),i.dispatch.on("legendClick",function(a){if(a.disabled){switch(M=M.map(function(a){return a.disabled=!0,a}),a.disabled=!1,a.key){case"Grouped":case p.grouped:e.stacked(!1);break;case"Stacked":case p.stacked:e.stacked(!0)}x.stacked=e.stacked(),A.stateChange(x),b.update()}}),A.on("changeState",function(a){"undefined"!=typeof a.disabled&&(j.forEach(function(b,c){b.disabled=a.disabled[c]}),x.disabled=a.disabled),"undefined"!=typeof a.stacked&&(e.stacked(a.stacked),x.stacked=a.stacked,E=a.stacked),b.update()})}),D.renderEnd("multibarchart immediate"),b}var c,d,e=a.models.multiBar(),f=a.models.axis(),g=a.models.axis(),h=a.models.legend(),i=a.models.legend(),j=a.models.tooltip(),k={top:30,right:20,bottom:50,left:60},l=null,m=null,n=a.utils.defaultColor(),o=!0,p={},q=!0,r=!0,s=!0,t=!1,u=!0,v=!1,w=0,x=a.utils.state(),y=null,z=null,A=d3.dispatch("stateChange","changeState","renderEnd"),B=function(){return o?180:0},C=250;x.stacked=!1,e.stacked(!1),f.orient("bottom").tickPadding(7).showMaxMin(!1).tickFormat(function(a){return a}),g.orient(t?"right":"left").tickFormat(d3.format(",.1f")),j.duration(0).valueFormatter(function(a,b){return g.tickFormat()(a,b)}).headerFormatter(function(a,b){return f.tickFormat()(a,b)}),i.updateState(!1);var D=a.utils.renderWatch(A),E=!1,F=function(a){return function(){return{active:a.map(function(a){return!a.disabled}),stacked:E}}},G=function(a){return function(b){void 0!==b.stacked&&(E=b.stacked),void 0!==b.active&&a.forEach(function(a,c){a.disabled=!b.active[c]})}};return e.dispatch.on("elementMouseover.tooltip",function(a){a.value=b.x()(a.data),a.series={key:a.data.key,value:b.y()(a.data),color:a.color},j.data(a).hidden(!1)}),e.dispatch.on("elementMouseout.tooltip",function(){j.hidden(!0)}),e.dispatch.on("elementMousemove.tooltip",function(){j.position({top:d3.event.pageY,left:d3.event.pageX})()}),b.dispatch=A,b.multibar=e,b.legend=h,b.controls=i,b.xAxis=f,b.yAxis=g,b.state=x,b.tooltip=j,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return l},set:function(a){l=a}},height:{get:function(){return m},set:function(a){m=a}},showLegend:{get:function(){return q},set:function(a){q=a}},showControls:{get:function(){return o},set:function(a){o=a}},controlLabels:{get:function(){return p},set:function(a){p=a}},showXAxis:{get:function(){return r},set:function(a){r=a}},showYAxis:{get:function(){return s},set:function(a){s=a}},defaultState:{get:function(){return y},set:function(a){y=a}},noData:{get:function(){return z},set:function(a){z=a}},reduceXTicks:{get:function(){return u},set:function(a){u=a}},rotateLabels:{get:function(){return w},set:function(a){w=a}},staggerLabels:{get:function(){return v},set:function(a){v=a}},tooltips:{get:function(){return j.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),j.enabled(!!b)}},tooltipContent:{get:function(){return j.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),j.contentGenerator(b)}},margin:{get:function(){return k},set:function(a){k.top=void 0!==a.top?a.top:k.top,k.right=void 0!==a.right?a.right:k.right,k.bottom=void 0!==a.bottom?a.bottom:k.bottom,k.left=void 0!==a.left?a.left:k.left}},duration:{get:function(){return C},set:function(a){C=a,e.duration(C),f.duration(C),g.duration(C),D.reset(C)}},color:{get:function(){return n},set:function(b){n=a.utils.getColor(b),h.color(n)}},rightAlignYAxis:{get:function(){return t},set:function(a){t=a,g.orient(t?"right":"left")}},barColor:{get:function(){return e.barColor},set:function(a){e.barColor(a),h.color(function(a,b){return d3.rgb("#ccc").darker(1.5*b).toString()})}}}),a.utils.inheritOptions(b,e),a.utils.initOptions(b),b},a.models.multiBarHorizontal=function(){"use strict";function b(m){return E.reset(),m.each(function(b){var m=k-j.left-j.right,C=l-j.top-j.bottom;n=d3.select(this),a.utils.initSVG(n),w&&(b=d3.layout.stack().offset("zero").values(function(a){return a.values}).y(r)(b)),b.forEach(function(a,b){a.values.forEach(function(c){c.series=b,c.key=a.key})}),w&&b[0].values.map(function(a,c){var d=0,e=0;b.map(function(a){var b=a.values[c];b.size=Math.abs(b.y),b.y<0?(b.y1=e-b.size,e-=b.size):(b.y1=d,d+=b.size)})});var F=d&&e?[]:b.map(function(a){return a.values.map(function(a,b){return{x:q(a,b),y:r(a,b),y0:a.y0,y1:a.y1}})});o.domain(d||d3.merge(F).map(function(a){return a.x})).rangeBands(f||[0,C],A),p.domain(e||d3.extent(d3.merge(F).map(function(a){return w?a.y>0?a.y1+a.y:a.y1:a.y}).concat(t))),p.range(x&&!w?g||[p.domain()[0]<0?z:0,m-(p.domain()[1]>0?z:0)]:g||[0,m]),h=h||o,i=i||d3.scale.linear().domain(p.domain()).range([p(0),p(0)]);{var G=d3.select(this).selectAll("g.nv-wrap.nv-multibarHorizontal").data([b]),H=G.enter().append("g").attr("class","nvd3 nv-wrap nv-multibarHorizontal"),I=(H.append("defs"),H.append("g"));G.select("g")}I.append("g").attr("class","nv-groups"),G.attr("transform","translate("+j.left+","+j.top+")");var J=G.select(".nv-groups").selectAll(".nv-group").data(function(a){return a},function(a,b){return b});J.enter().append("g").style("stroke-opacity",1e-6).style("fill-opacity",1e-6),J.exit().watchTransition(E,"multibarhorizontal: exit groups").style("stroke-opacity",1e-6).style("fill-opacity",1e-6).remove(),J.attr("class",function(a,b){return"nv-group nv-series-"+b}).classed("hover",function(a){return a.hover}).style("fill",function(a,b){return u(a,b)}).style("stroke",function(a,b){return u(a,b)}),J.watchTransition(E,"multibarhorizontal: groups").style("stroke-opacity",1).style("fill-opacity",.75);var K=J.selectAll("g.nv-bar").data(function(a){return a.values});K.exit().remove();var L=K.enter().append("g").attr("transform",function(a,c,d){return"translate("+i(w?a.y0:0)+","+(w?0:d*o.rangeBand()/b.length+o(q(a,c)))+")"});L.append("rect").attr("width",0).attr("height",o.rangeBand()/(w?1:b.length)),K.on("mouseover",function(a,b){d3.select(this).classed("hover",!0),D.elementMouseover({data:a,index:b,color:d3.select(this).style("fill")})}).on("mouseout",function(a,b){d3.select(this).classed("hover",!1),D.elementMouseout({data:a,index:b,color:d3.select(this).style("fill")})}).on("mouseout",function(a,b){D.elementMouseout({data:a,index:b,color:d3.select(this).style("fill")})}).on("mousemove",function(a,b){D.elementMousemove({data:a,index:b,color:d3.select(this).style("fill")})}).on("click",function(a,b){D.elementClick({data:a,index:b,color:d3.select(this).style("fill")}),d3.event.stopPropagation()}).on("dblclick",function(a,b){D.elementDblClick({data:a,index:b,color:d3.select(this).style("fill")}),d3.event.stopPropagation()}),s(b[0],0)&&(L.append("polyline"),K.select("polyline").attr("fill","none").attr("points",function(a,c){var d=s(a,c),e=.8*o.rangeBand()/(2*(w?1:b.length));d=d.length?d:[-Math.abs(d),Math.abs(d)],d=d.map(function(a){return p(a)-p(0)});var f=[[d[0],-e],[d[0],e],[d[0],0],[d[1],0],[d[1],-e],[d[1],e]];return f.map(function(a){return a.join(",")}).join(" ")}).attr("transform",function(a,c){var d=o.rangeBand()/(2*(w?1:b.length));return"translate("+(r(a,c)<0?0:p(r(a,c))-p(0))+", "+d+")"})),L.append("text"),x&&!w?(K.select("text").attr("text-anchor",function(a,b){return r(a,b)<0?"end":"start"}).attr("y",o.rangeBand()/(2*b.length)).attr("dy",".32em").text(function(a,b){var c=B(r(a,b)),d=s(a,b);return void 0===d?c:d.length?c+"+"+B(Math.abs(d[1]))+"-"+B(Math.abs(d[0])):c+"±"+B(Math.abs(d))}),K.watchTransition(E,"multibarhorizontal: bars").select("text").attr("x",function(a,b){return r(a,b)<0?-4:p(r(a,b))-p(0)+4})):K.selectAll("text").text(""),y&&!w?(L.append("text").classed("nv-bar-label",!0),K.select("text.nv-bar-label").attr("text-anchor",function(a,b){return r(a,b)<0?"start":"end"}).attr("y",o.rangeBand()/(2*b.length)).attr("dy",".32em").text(function(a,b){return q(a,b)}),K.watchTransition(E,"multibarhorizontal: bars").select("text.nv-bar-label").attr("x",function(a,b){return r(a,b)<0?p(0)-p(r(a,b))+4:-4})):K.selectAll("text.nv-bar-label").text(""),K.attr("class",function(a,b){return r(a,b)<0?"nv-bar negative":"nv-bar positive"}),v&&(c||(c=b.map(function(){return!0})),K.style("fill",function(a,b,d){return d3.rgb(v(a,b)).darker(c.map(function(a,b){return b}).filter(function(a,b){return!c[b]})[d]).toString()}).style("stroke",function(a,b,d){return d3.rgb(v(a,b)).darker(c.map(function(a,b){return b}).filter(function(a,b){return!c[b]})[d]).toString()})),w?K.watchTransition(E,"multibarhorizontal: bars").attr("transform",function(a,b){return"translate("+p(a.y1)+","+o(q(a,b))+")"}).select("rect").attr("width",function(a,b){return Math.abs(p(r(a,b)+a.y0)-p(a.y0))}).attr("height",o.rangeBand()):K.watchTransition(E,"multibarhorizontal: bars").attr("transform",function(a,c){return"translate("+p(r(a,c)<0?r(a,c):0)+","+(a.series*o.rangeBand()/b.length+o(q(a,c)))+")"}).select("rect").attr("height",o.rangeBand()/b.length).attr("width",function(a,b){return Math.max(Math.abs(p(r(a,b))-p(0)),1)}),h=o.copy(),i=p.copy()}),E.renderEnd("multibarHorizontal immediate"),b}var c,d,e,f,g,h,i,j={top:0,right:0,bottom:0,left:0},k=960,l=500,m=Math.floor(1e4*Math.random()),n=null,o=d3.scale.ordinal(),p=d3.scale.linear(),q=function(a){return a.x},r=function(a){return a.y},s=function(a){return a.yErr},t=[0],u=a.utils.defaultColor(),v=null,w=!1,x=!1,y=!1,z=60,A=.1,B=d3.format(",.2f"),C=250,D=d3.dispatch("chartClick","elementClick","elementDblClick","elementMouseover","elementMouseout","elementMousemove","renderEnd"),E=a.utils.renderWatch(D,C);return b.dispatch=D,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return k},set:function(a){k=a}},height:{get:function(){return l},set:function(a){l=a}},x:{get:function(){return q},set:function(a){q=a}},y:{get:function(){return r},set:function(a){r=a}},yErr:{get:function(){return s},set:function(a){s=a}},xScale:{get:function(){return o},set:function(a){o=a}},yScale:{get:function(){return p},set:function(a){p=a}},xDomain:{get:function(){return d},set:function(a){d=a}},yDomain:{get:function(){return e},set:function(a){e=a}},xRange:{get:function(){return f},set:function(a){f=a}},yRange:{get:function(){return g},set:function(a){g=a}},forceY:{get:function(){return t},set:function(a){t=a}},stacked:{get:function(){return w},set:function(a){w=a}},showValues:{get:function(){return x},set:function(a){x=a}},disabled:{get:function(){return c},set:function(a){c=a}},id:{get:function(){return m},set:function(a){m=a}},valueFormat:{get:function(){return B},set:function(a){B=a}},valuePadding:{get:function(){return z},set:function(a){z=a}},groupSpacing:{get:function(){return A},set:function(a){A=a}},margin:{get:function(){return j},set:function(a){j.top=void 0!==a.top?a.top:j.top,j.right=void 0!==a.right?a.right:j.right,j.bottom=void 0!==a.bottom?a.bottom:j.bottom,j.left=void 0!==a.left?a.left:j.left}},duration:{get:function(){return C},set:function(a){C=a,E.reset(C)}},color:{get:function(){return u},set:function(b){u=a.utils.getColor(b)}},barColor:{get:function(){return v},set:function(b){v=b?a.utils.getColor(b):null}}}),a.utils.initOptions(b),b},a.models.multiBarHorizontalChart=function(){"use strict";function b(j){return C.reset(),C.models(e),r&&C.models(f),s&&C.models(g),j.each(function(j){var w=d3.select(this);a.utils.initSVG(w);var C=a.utils.availableWidth(l,w,k),D=a.utils.availableHeight(m,w,k);if(b.update=function(){w.transition().duration(z).call(b)},b.container=this,t=e.stacked(),u.setter(B(j),b.update).getter(A(j)).update(),u.disabled=j.map(function(a){return!!a.disabled}),!v){var E;v={};for(E in u)v[E]=u[E]instanceof Array?u[E].slice(0):u[E]}if(!(j&&j.length&&j.filter(function(a){return a.values.length}).length))return a.utils.noData(b,w),b;w.selectAll(".nv-noData").remove(),c=e.xScale(),d=e.yScale();var F=w.selectAll("g.nv-wrap.nv-multiBarHorizontalChart").data([j]),G=F.enter().append("g").attr("class","nvd3 nv-wrap nv-multiBarHorizontalChart").append("g"),H=F.select("g");if(G.append("g").attr("class","nv-x nv-axis"),G.append("g").attr("class","nv-y nv-axis").append("g").attr("class","nv-zeroLine").append("line"),G.append("g").attr("class","nv-barsWrap"),G.append("g").attr("class","nv-legendWrap"),G.append("g").attr("class","nv-controlsWrap"),q&&(h.width(C-y()),H.select(".nv-legendWrap").datum(j).call(h),k.top!=h.height()&&(k.top=h.height(),D=a.utils.availableHeight(m,w,k)),H.select(".nv-legendWrap").attr("transform","translate("+y()+","+-k.top+")")),o){var I=[{key:p.grouped||"Grouped",disabled:e.stacked()},{key:p.stacked||"Stacked",disabled:!e.stacked()}];i.width(y()).color(["#444","#444","#444"]),H.select(".nv-controlsWrap").datum(I).attr("transform","translate(0,"+-k.top+")").call(i)}F.attr("transform","translate("+k.left+","+k.top+")"),e.disabled(j.map(function(a){return a.disabled})).width(C).height(D).color(j.map(function(a,b){return a.color||n(a,b)}).filter(function(a,b){return!j[b].disabled}));var J=H.select(".nv-barsWrap").datum(j.filter(function(a){return!a.disabled}));if(J.transition().call(e),r){f.scale(c)._ticks(a.utils.calcTicksY(D/24,j)).tickSize(-C,0),H.select(".nv-x.nv-axis").call(f);var K=H.select(".nv-x.nv-axis").selectAll("g");K.selectAll("line, text")}s&&(g.scale(d)._ticks(a.utils.calcTicksX(C/100,j)).tickSize(-D,0),H.select(".nv-y.nv-axis").attr("transform","translate(0,"+D+")"),H.select(".nv-y.nv-axis").call(g)),H.select(".nv-zeroLine line").attr("x1",d(0)).attr("x2",d(0)).attr("y1",0).attr("y2",-D),h.dispatch.on("stateChange",function(a){for(var c in a)u[c]=a[c];x.stateChange(u),b.update()}),i.dispatch.on("legendClick",function(a){if(a.disabled){switch(I=I.map(function(a){return a.disabled=!0,a}),a.disabled=!1,a.key){case"Grouped":e.stacked(!1);break;case"Stacked":e.stacked(!0)}u.stacked=e.stacked(),x.stateChange(u),t=e.stacked(),b.update()}}),x.on("changeState",function(a){"undefined"!=typeof a.disabled&&(j.forEach(function(b,c){b.disabled=a.disabled[c]}),u.disabled=a.disabled),"undefined"!=typeof a.stacked&&(e.stacked(a.stacked),u.stacked=a.stacked,t=a.stacked),b.update()})}),C.renderEnd("multibar horizontal chart immediate"),b}var c,d,e=a.models.multiBarHorizontal(),f=a.models.axis(),g=a.models.axis(),h=a.models.legend().height(30),i=a.models.legend().height(30),j=a.models.tooltip(),k={top:30,right:20,bottom:50,left:60},l=null,m=null,n=a.utils.defaultColor(),o=!0,p={},q=!0,r=!0,s=!0,t=!1,u=a.utils.state(),v=null,w=null,x=d3.dispatch("stateChange","changeState","renderEnd"),y=function(){return o?180:0},z=250;u.stacked=!1,e.stacked(t),f.orient("left").tickPadding(5).showMaxMin(!1).tickFormat(function(a){return a}),g.orient("bottom").tickFormat(d3.format(",.1f")),j.duration(0).valueFormatter(function(a,b){return g.tickFormat()(a,b)}).headerFormatter(function(a,b){return f.tickFormat()(a,b)}),i.updateState(!1);var A=function(a){return function(){return{active:a.map(function(a){return!a.disabled}),stacked:t}}},B=function(a){return function(b){void 0!==b.stacked&&(t=b.stacked),void 0!==b.active&&a.forEach(function(a,c){a.disabled=!b.active[c]})}},C=a.utils.renderWatch(x,z);return e.dispatch.on("elementMouseover.tooltip",function(a){a.value=b.x()(a.data),a.series={key:a.data.key,value:b.y()(a.data),color:a.color},j.data(a).hidden(!1)}),e.dispatch.on("elementMouseout.tooltip",function(){j.hidden(!0)}),e.dispatch.on("elementMousemove.tooltip",function(){j.position({top:d3.event.pageY,left:d3.event.pageX})()}),b.dispatch=x,b.multibar=e,b.legend=h,b.controls=i,b.xAxis=f,b.yAxis=g,b.state=u,b.tooltip=j,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return l},set:function(a){l=a}},height:{get:function(){return m},set:function(a){m=a}},showLegend:{get:function(){return q},set:function(a){q=a}},showControls:{get:function(){return o},set:function(a){o=a}},controlLabels:{get:function(){return p},set:function(a){p=a}},showXAxis:{get:function(){return r},set:function(a){r=a}},showYAxis:{get:function(){return s},set:function(a){s=a}},defaultState:{get:function(){return v},set:function(a){v=a}},noData:{get:function(){return w},set:function(a){w=a}},tooltips:{get:function(){return j.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),j.enabled(!!b)}},tooltipContent:{get:function(){return j.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),j.contentGenerator(b)}},margin:{get:function(){return k},set:function(a){k.top=void 0!==a.top?a.top:k.top,k.right=void 0!==a.right?a.right:k.right,k.bottom=void 0!==a.bottom?a.bottom:k.bottom,k.left=void 0!==a.left?a.left:k.left}},duration:{get:function(){return z},set:function(a){z=a,C.reset(z),e.duration(z),f.duration(z),g.duration(z)}},color:{get:function(){return n},set:function(b){n=a.utils.getColor(b),h.color(n)}},barColor:{get:function(){return e.barColor},set:function(a){e.barColor(a),h.color(function(a,b){return d3.rgb("#ccc").darker(1.5*b).toString()})}}}),a.utils.inheritOptions(b,e),a.utils.initOptions(b),b},a.models.multiChart=function(){"use strict";function b(j){return j.each(function(j){function k(a){var b=2===j[a.seriesIndex].yAxis?z:y;a.value=a.point.x,a.series={value:a.point.y,color:a.point.color},B.duration(100).valueFormatter(function(a,c){return b.tickFormat()(a,c)}).data(a).position(a.pos).hidden(!1)}function l(a){var b=2===j[a.seriesIndex].yAxis?z:y;a.point.x=v.x()(a.point),a.point.y=v.y()(a.point),B.duration(100).valueFormatter(function(a,c){return b.tickFormat()(a,c)}).data(a).position(a.pos).hidden(!1)}function n(a){var b=2===j[a.data.series].yAxis?z:y;a.value=t.x()(a.data),a.series={value:t.y()(a.data),color:a.color},B.duration(0).valueFormatter(function(a,c){return b.tickFormat()(a,c)}).data(a).hidden(!1)}var C=d3.select(this);a.utils.initSVG(C),b.update=function(){C.transition().call(b)},b.container=this;var D=a.utils.availableWidth(g,C,e),E=a.utils.availableHeight(h,C,e),F=j.filter(function(a){return"line"==a.type&&1==a.yAxis}),G=j.filter(function(a){return"line"==a.type&&2==a.yAxis}),H=j.filter(function(a){return"bar"==a.type&&1==a.yAxis}),I=j.filter(function(a){return"bar"==a.type&&2==a.yAxis}),J=j.filter(function(a){return"area"==a.type&&1==a.yAxis}),K=j.filter(function(a){return"area"==a.type&&2==a.yAxis});if(!(j&&j.length&&j.filter(function(a){return a.values.length}).length))return a.utils.noData(b,C),b;C.selectAll(".nv-noData").remove();var L=j.filter(function(a){return!a.disabled&&1==a.yAxis}).map(function(a){return a.values.map(function(a){return{x:a.x,y:a.y}})}),M=j.filter(function(a){return!a.disabled&&2==a.yAxis}).map(function(a){return a.values.map(function(a){return{x:a.x,y:a.y}})});o.domain(d3.extent(d3.merge(L.concat(M)),function(a){return a.x})).range([0,D]);var N=C.selectAll("g.wrap.multiChart").data([j]),O=N.enter().append("g").attr("class","wrap nvd3 multiChart").append("g");O.append("g").attr("class","nv-x nv-axis"),O.append("g").attr("class","nv-y1 nv-axis"),O.append("g").attr("class","nv-y2 nv-axis"),O.append("g").attr("class","lines1Wrap"),O.append("g").attr("class","lines2Wrap"),O.append("g").attr("class","bars1Wrap"),O.append("g").attr("class","bars2Wrap"),O.append("g").attr("class","stack1Wrap"),O.append("g").attr("class","stack2Wrap"),O.append("g").attr("class","legendWrap");var P=N.select("g"),Q=j.map(function(a,b){return j[b].color||f(a,b)});if(i){var R=A.align()?D/2:D,S=A.align()?R:0;A.width(R),A.color(Q),P.select(".legendWrap").datum(j.map(function(a){return a.originalKey=void 0===a.originalKey?a.key:a.originalKey,a.key=a.originalKey+(1==a.yAxis?"":" (right axis)"),a})).call(A),e.top!=A.height()&&(e.top=A.height(),E=a.utils.availableHeight(h,C,e)),P.select(".legendWrap").attr("transform","translate("+S+","+-e.top+")")}r.width(D).height(E).interpolate(m).color(Q.filter(function(a,b){return!j[b].disabled&&1==j[b].yAxis&&"line"==j[b].type})),s.width(D).height(E).interpolate(m).color(Q.filter(function(a,b){return!j[b].disabled&&2==j[b].yAxis&&"line"==j[b].type})),t.width(D).height(E).color(Q.filter(function(a,b){return!j[b].disabled&&1==j[b].yAxis&&"bar"==j[b].type})),u.width(D).height(E).color(Q.filter(function(a,b){return!j[b].disabled&&2==j[b].yAxis&&"bar"==j[b].type})),v.width(D).height(E).color(Q.filter(function(a,b){return!j[b].disabled&&1==j[b].yAxis&&"area"==j[b].type})),w.width(D).height(E).color(Q.filter(function(a,b){return!j[b].disabled&&2==j[b].yAxis&&"area"==j[b].type})),P.attr("transform","translate("+e.left+","+e.top+")");var T=P.select(".lines1Wrap").datum(F.filter(function(a){return!a.disabled})),U=P.select(".bars1Wrap").datum(H.filter(function(a){return!a.disabled})),V=P.select(".stack1Wrap").datum(J.filter(function(a){return!a.disabled})),W=P.select(".lines2Wrap").datum(G.filter(function(a){return!a.disabled})),X=P.select(".bars2Wrap").datum(I.filter(function(a){return!a.disabled})),Y=P.select(".stack2Wrap").datum(K.filter(function(a){return!a.disabled})),Z=J.length?J.map(function(a){return a.values}).reduce(function(a,b){return a.map(function(a,c){return{x:a.x,y:a.y+b[c].y}})}).concat([{x:0,y:0}]):[],$=K.length?K.map(function(a){return a.values}).reduce(function(a,b){return a.map(function(a,c){return{x:a.x,y:a.y+b[c].y}})}).concat([{x:0,y:0}]):[];p.domain(c||d3.extent(d3.merge(L).concat(Z),function(a){return a.y})).range([0,E]),q.domain(d||d3.extent(d3.merge(M).concat($),function(a){return a.y})).range([0,E]),r.yDomain(p.domain()),t.yDomain(p.domain()),v.yDomain(p.domain()),s.yDomain(q.domain()),u.yDomain(q.domain()),w.yDomain(q.domain()),J.length&&d3.transition(V).call(v),K.length&&d3.transition(Y).call(w),H.length&&d3.transition(U).call(t),I.length&&d3.transition(X).call(u),F.length&&d3.transition(T).call(r),G.length&&d3.transition(W).call(s),x._ticks(a.utils.calcTicksX(D/100,j)).tickSize(-E,0),P.select(".nv-x.nv-axis").attr("transform","translate(0,"+E+")"),d3.transition(P.select(".nv-x.nv-axis")).call(x),y._ticks(a.utils.calcTicksY(E/36,j)).tickSize(-D,0),d3.transition(P.select(".nv-y1.nv-axis")).call(y),z._ticks(a.utils.calcTicksY(E/36,j)).tickSize(-D,0),d3.transition(P.select(".nv-y2.nv-axis")).call(z),P.select(".nv-y1.nv-axis").classed("nv-disabled",L.length?!1:!0).attr("transform","translate("+o.range()[0]+",0)"),P.select(".nv-y2.nv-axis").classed("nv-disabled",M.length?!1:!0).attr("transform","translate("+o.range()[1]+",0)"),A.dispatch.on("stateChange",function(){b.update()}),r.dispatch.on("elementMouseover.tooltip",k),s.dispatch.on("elementMouseover.tooltip",k),r.dispatch.on("elementMouseout.tooltip",function(){B.hidden(!0)}),s.dispatch.on("elementMouseout.tooltip",function(){B.hidden(!0)}),v.dispatch.on("elementMouseover.tooltip",l),w.dispatch.on("elementMouseover.tooltip",l),v.dispatch.on("elementMouseout.tooltip",function(){B.hidden(!0)}),w.dispatch.on("elementMouseout.tooltip",function(){B.hidden(!0)}),t.dispatch.on("elementMouseover.tooltip",n),u.dispatch.on("elementMouseover.tooltip",n),t.dispatch.on("elementMouseout.tooltip",function(){B.hidden(!0)}),u.dispatch.on("elementMouseout.tooltip",function(){B.hidden(!0)}),t.dispatch.on("elementMousemove.tooltip",function(){B.position({top:d3.event.pageY,left:d3.event.pageX})()}),u.dispatch.on("elementMousemove.tooltip",function(){B.position({top:d3.event.pageY,left:d3.event.pageX})()})}),b}var c,d,e={top:30,right:20,bottom:50,left:60},f=a.utils.defaultColor(),g=null,h=null,i=!0,j=null,k=function(a){return a.x},l=function(a){return a.y},m="monotone",n=!0,o=d3.scale.linear(),p=d3.scale.linear(),q=d3.scale.linear(),r=a.models.line().yScale(p),s=a.models.line().yScale(q),t=a.models.multiBar().stacked(!1).yScale(p),u=a.models.multiBar().stacked(!1).yScale(q),v=a.models.stackedArea().yScale(p),w=a.models.stackedArea().yScale(q),x=a.models.axis().scale(o).orient("bottom").tickPadding(5),y=a.models.axis().scale(p).orient("left"),z=a.models.axis().scale(q).orient("right"),A=a.models.legend().height(30),B=a.models.tooltip(),C=d3.dispatch();return b.dispatch=C,b.lines1=r,b.lines2=s,b.bars1=t,b.bars2=u,b.stack1=v,b.stack2=w,b.xAxis=x,b.yAxis1=y,b.yAxis2=z,b.tooltip=B,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return g},set:function(a){g=a}},height:{get:function(){return h},set:function(a){h=a}},showLegend:{get:function(){return i},set:function(a){i=a}},yDomain1:{get:function(){return c},set:function(a){c=a}},yDomain2:{get:function(){return d},set:function(a){d=a}},noData:{get:function(){return j},set:function(a){j=a}},interpolate:{get:function(){return m},set:function(a){m=a}},tooltips:{get:function(){return B.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),B.enabled(!!b)}},tooltipContent:{get:function(){return B.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),B.contentGenerator(b)}},margin:{get:function(){return e},set:function(a){e.top=void 0!==a.top?a.top:e.top,e.right=void 0!==a.right?a.right:e.right,e.bottom=void 0!==a.bottom?a.bottom:e.bottom,e.left=void 0!==a.left?a.left:e.left}},color:{get:function(){return f},set:function(b){f=a.utils.getColor(b)}},x:{get:function(){return k},set:function(a){k=a,r.x(a),s.x(a),t.x(a),u.x(a),v.x(a),w.x(a)}},y:{get:function(){return l},set:function(a){l=a,r.y(a),s.y(a),v.y(a),w.y(a),t.y(a),u.y(a)}},useVoronoi:{get:function(){return n},set:function(a){n=a,r.useVoronoi(a),s.useVoronoi(a),v.useVoronoi(a),w.useVoronoi(a)}}}),a.utils.initOptions(b),b},a.models.ohlcBar=function(){"use strict";function b(y){return y.each(function(b){k=d3.select(this);var y=a.utils.availableWidth(h,k,g),A=a.utils.availableHeight(i,k,g);a.utils.initSVG(k);var B=y/b[0].values.length*.9;l.domain(c||d3.extent(b[0].values.map(n).concat(t))),l.range(v?e||[.5*y/b[0].values.length,y*(b[0].values.length-.5)/b[0].values.length]:e||[5+B/2,y-B/2-5]),m.domain(d||[d3.min(b[0].values.map(s).concat(u)),d3.max(b[0].values.map(r).concat(u))]).range(f||[A,0]),l.domain()[0]===l.domain()[1]&&l.domain(l.domain()[0]?[l.domain()[0]-.01*l.domain()[0],l.domain()[1]+.01*l.domain()[1]]:[-1,1]),m.domain()[0]===m.domain()[1]&&m.domain(m.domain()[0]?[m.domain()[0]+.01*m.domain()[0],m.domain()[1]-.01*m.domain()[1]]:[-1,1]);var C=d3.select(this).selectAll("g.nv-wrap.nv-ohlcBar").data([b[0].values]),D=C.enter().append("g").attr("class","nvd3 nv-wrap nv-ohlcBar"),E=D.append("defs"),F=D.append("g"),G=C.select("g");F.append("g").attr("class","nv-ticks"),C.attr("transform","translate("+g.left+","+g.top+")"),k.on("click",function(a,b){z.chartClick({data:a,index:b,pos:d3.event,id:j})}),E.append("clipPath").attr("id","nv-chart-clip-path-"+j).append("rect"),C.select("#nv-chart-clip-path-"+j+" rect").attr("width",y).attr("height",A),G.attr("clip-path",w?"url(#nv-chart-clip-path-"+j+")":"");var H=C.select(".nv-ticks").selectAll(".nv-tick").data(function(a){return a});H.exit().remove(),H.enter().append("path").attr("class",function(a,b,c){return(p(a,b)>q(a,b)?"nv-tick negative":"nv-tick positive")+" nv-tick-"+c+"-"+b}).attr("d",function(a,b){return"m0,0l0,"+(m(p(a,b))-m(r(a,b)))+"l"+-B/2+",0l"+B/2+",0l0,"+(m(s(a,b))-m(p(a,b)))+"l0,"+(m(q(a,b))-m(s(a,b)))+"l"+B/2+",0l"+-B/2+",0z"}).attr("transform",function(a,b){return"translate("+l(n(a,b))+","+m(r(a,b))+")"}).attr("fill",function(){return x[0]}).attr("stroke",function(){return x[0]}).attr("x",0).attr("y",function(a,b){return m(Math.max(0,o(a,b)))}).attr("height",function(a,b){return Math.abs(m(o(a,b))-m(0))}),H.attr("class",function(a,b,c){return(p(a,b)>q(a,b)?"nv-tick negative":"nv-tick positive")+" nv-tick-"+c+"-"+b}),d3.transition(H).attr("transform",function(a,b){return"translate("+l(n(a,b))+","+m(r(a,b))+")"}).attr("d",function(a,c){var d=y/b[0].values.length*.9;return"m0,0l0,"+(m(p(a,c))-m(r(a,c)))+"l"+-d/2+",0l"+d/2+",0l0,"+(m(s(a,c))-m(p(a,c)))+"l0,"+(m(q(a,c))-m(s(a,c)))+"l"+d/2+",0l"+-d/2+",0z"})}),b}var c,d,e,f,g={top:0,right:0,bottom:0,left:0},h=null,i=null,j=Math.floor(1e4*Math.random()),k=null,l=d3.scale.linear(),m=d3.scale.linear(),n=function(a){return a.x},o=function(a){return a.y},p=function(a){return a.open},q=function(a){return a.close},r=function(a){return a.high},s=function(a){return a.low},t=[],u=[],v=!1,w=!0,x=a.utils.defaultColor(),y=!1,z=d3.dispatch("tooltipShow","tooltipHide","stateChange","changeState","renderEnd","chartClick","elementClick","elementDblClick","elementMouseover","elementMouseout","elementMousemove");return b.highlightPoint=function(a,c){b.clearHighlights(),k.select(".nv-ohlcBar .nv-tick-0-"+a).classed("hover",c)},b.clearHighlights=function(){k.select(".nv-ohlcBar .nv-tick.hover").classed("hover",!1)},b.dispatch=z,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return h},set:function(a){h=a}},height:{get:function(){return i},set:function(a){i=a}},xScale:{get:function(){return l},set:function(a){l=a}},yScale:{get:function(){return m},set:function(a){m=a}},xDomain:{get:function(){return c},set:function(a){c=a}},yDomain:{get:function(){return d},set:function(a){d=a}},xRange:{get:function(){return e},set:function(a){e=a}},yRange:{get:function(){return f},set:function(a){f=a}},forceX:{get:function(){return t},set:function(a){t=a}},forceY:{get:function(){return u},set:function(a){u=a}},padData:{get:function(){return v},set:function(a){v=a}},clipEdge:{get:function(){return w},set:function(a){w=a}},id:{get:function(){return j},set:function(a){j=a}},interactive:{get:function(){return y},set:function(a){y=a}},x:{get:function(){return n},set:function(a){n=a}},y:{get:function(){return o},set:function(a){o=a}},open:{get:function(){return p()},set:function(a){p=a}},close:{get:function(){return q()},set:function(a){q=a}},high:{get:function(){return r},set:function(a){r=a}},low:{get:function(){return s},set:function(a){s=a}},margin:{get:function(){return g},set:function(a){g.top=void 0!=a.top?a.top:g.top,g.right=void 0!=a.right?a.right:g.right,g.bottom=void 0!=a.bottom?a.bottom:g.bottom,g.left=void 0!=a.left?a.left:g.left
33851 }},color:{get:function(){return x},set:function(b){x=a.utils.getColor(b)}}}),a.utils.initOptions(b),b},a.models.parallelCoordinates=function(){"use strict";function b(p){return p.each(function(b){function p(a){return F(h.map(function(b){if(isNaN(a[b])||isNaN(parseFloat(a[b]))){var c=g[b].domain(),d=g[b].range(),e=c[0]-(c[1]-c[0])/9;if(J.indexOf(b)<0){var h=d3.scale.linear().domain([e,c[1]]).range([x-12,d[1]]);g[b].brush.y(h),J.push(b)}return[f(b),g[b](e)]}return J.length>0?(D.style("display","inline"),E.style("display","inline")):(D.style("display","none"),E.style("display","none")),[f(b),g[b](a[b])]}))}function q(){var a=h.filter(function(a){return!g[a].brush.empty()}),b=a.map(function(a){return g[a].brush.extent()});k=[],a.forEach(function(a,c){k[c]={dimension:a,extent:b[c]}}),l=[],M.style("display",function(c){var d=a.every(function(a,d){return isNaN(c[a])&&b[d][0]==g[a].brush.y().domain()[0]?!0:b[d][0]<=c[a]&&c[a]<=b[d][1]});return d&&l.push(c),d?null:"none"}),o.brush({filters:k,active:l})}function r(a){m[a]=this.parentNode.__origin__=f(a),L.attr("visibility","hidden")}function s(a){m[a]=Math.min(w,Math.max(0,this.parentNode.__origin__+=d3.event.x)),M.attr("d",p),h.sort(function(a,b){return u(a)-u(b)}),f.domain(h),N.attr("transform",function(a){return"translate("+u(a)+")"})}function t(a){delete this.parentNode.__origin__,delete m[a],d3.select(this.parentNode).attr("transform","translate("+f(a)+")"),M.attr("d",p),L.attr("d",p).attr("visibility",null)}function u(a){var b=m[a];return null==b?f(a):b}var v=d3.select(this),w=a.utils.availableWidth(d,v,c),x=a.utils.availableHeight(e,v,c);a.utils.initSVG(v),l=b,f.rangePoints([0,w],1).domain(h);var y={};h.forEach(function(a){var c=d3.extent(b,function(b){return+b[a]});return y[a]=!1,void 0===c[0]&&(y[a]=!0,c[0]=0,c[1]=0),c[0]===c[1]&&(c[0]=c[0]-1,c[1]=c[1]+1),g[a]=d3.scale.linear().domain(c).range([.9*(x-12),0]),g[a].brush=d3.svg.brush().y(g[a]).on("brush",q),"name"!=a});var z=v.selectAll("g.nv-wrap.nv-parallelCoordinates").data([b]),A=z.enter().append("g").attr("class","nvd3 nv-wrap nv-parallelCoordinates"),B=A.append("g"),C=z.select("g");B.append("g").attr("class","nv-parallelCoordinates background"),B.append("g").attr("class","nv-parallelCoordinates foreground"),B.append("g").attr("class","nv-parallelCoordinates missingValuesline"),z.attr("transform","translate("+c.left+","+c.top+")");var D,E,F=d3.svg.line().interpolate("cardinal").tension(n),G=d3.svg.axis().orient("left"),H=d3.behavior.drag().on("dragstart",r).on("drag",s).on("dragend",t),I=f.range()[1]-f.range()[0],J=[],K=[0+I/2,x-12,w-I/2,x-12];D=z.select(".missingValuesline").selectAll("line").data([K]),D.enter().append("line"),D.exit().remove(),D.attr("x1",function(a){return a[0]}).attr("y1",function(a){return a[1]}).attr("x2",function(a){return a[2]}).attr("y2",function(a){return a[3]}),E=z.select(".missingValuesline").selectAll("text").data(["undefined values"]),E.append("text").data(["undefined values"]),E.enter().append("text"),E.exit().remove(),E.attr("y",x).attr("x",w-92-I/2).text(function(a){return a});var L=z.select(".background").selectAll("path").data(b);L.enter().append("path"),L.exit().remove(),L.attr("d",p);var M=z.select(".foreground").selectAll("path").data(b);M.enter().append("path"),M.exit().remove(),M.attr("d",p).attr("stroke",j),M.on("mouseover",function(a,b){d3.select(this).classed("hover",!0),o.elementMouseover({label:a.name,data:a.data,index:b,pos:[d3.mouse(this.parentNode)[0],d3.mouse(this.parentNode)[1]]})}),M.on("mouseout",function(a,b){d3.select(this).classed("hover",!1),o.elementMouseout({label:a.name,data:a.data,index:b})});var N=C.selectAll(".dimension").data(h),O=N.enter().append("g").attr("class","nv-parallelCoordinates dimension");O.append("g").attr("class","nv-parallelCoordinates nv-axis"),O.append("g").attr("class","nv-parallelCoordinates-brush"),O.append("text").attr("class","nv-parallelCoordinates nv-label"),N.attr("transform",function(a){return"translate("+f(a)+",0)"}),N.exit().remove(),N.select(".nv-label").style("cursor","move").attr("dy","-1em").attr("text-anchor","middle").text(String).on("mouseover",function(a){o.elementMouseover({dim:a,pos:[d3.mouse(this.parentNode.parentNode)[0],d3.mouse(this.parentNode.parentNode)[1]]})}).on("mouseout",function(a){o.elementMouseout({dim:a})}).call(H),N.select(".nv-axis").each(function(a,b){d3.select(this).call(G.scale(g[a]).tickFormat(d3.format(i[b])))}),N.select(".nv-parallelCoordinates-brush").each(function(a){d3.select(this).call(g[a].brush)}).selectAll("rect").attr("x",-8).attr("width",16)}),b}var c={top:30,right:0,bottom:10,left:0},d=null,e=null,f=d3.scale.ordinal(),g={},h=[],i=[],j=a.utils.defaultColor(),k=[],l=[],m=[],n=1,o=d3.dispatch("brush","elementMouseover","elementMouseout");return b.dispatch=o,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return d},set:function(a){d=a}},height:{get:function(){return e},set:function(a){e=a}},dimensionNames:{get:function(){return h},set:function(a){h=a}},dimensionFormats:{get:function(){return i},set:function(a){i=a}},lineTension:{get:function(){return n},set:function(a){n=a}},dimensions:{get:function(){return h},set:function(b){a.deprecated("dimensions","use dimensionNames instead"),h=b}},margin:{get:function(){return c},set:function(a){c.top=void 0!==a.top?a.top:c.top,c.right=void 0!==a.right?a.right:c.right,c.bottom=void 0!==a.bottom?a.bottom:c.bottom,c.left=void 0!==a.left?a.left:c.left}},color:{get:function(){return j},set:function(b){j=a.utils.getColor(b)}}}),a.utils.initOptions(b),b},a.models.pie=function(){"use strict";function b(E){return D.reset(),E.each(function(b){function E(a,b){a.endAngle=isNaN(a.endAngle)?0:a.endAngle,a.startAngle=isNaN(a.startAngle)?0:a.startAngle,p||(a.innerRadius=0);var c=d3.interpolate(this._current,a);return this._current=c(0),function(a){return B[b](c(a))}}var F=d-c.left-c.right,G=e-c.top-c.bottom,H=Math.min(F,G)/2,I=[],J=[];if(i=d3.select(this),0===z.length)for(var K=H-H/5,L=y*H,M=0;M<b[0].length;M++)I.push(K),J.push(L);else I=z.map(function(a){return(a.outer-a.outer/5)*H}),J=z.map(function(a){return(a.inner-a.inner/5)*H}),y=d3.min(z.map(function(a){return a.inner-a.inner/5}));a.utils.initSVG(i);var N=i.selectAll(".nv-wrap.nv-pie").data(b),O=N.enter().append("g").attr("class","nvd3 nv-wrap nv-pie nv-chart-"+h),P=O.append("g"),Q=N.select("g"),R=P.append("g").attr("class","nv-pie");P.append("g").attr("class","nv-pieLabels"),N.attr("transform","translate("+c.left+","+c.top+")"),Q.select(".nv-pie").attr("transform","translate("+F/2+","+G/2+")"),Q.select(".nv-pieLabels").attr("transform","translate("+F/2+","+G/2+")"),i.on("click",function(a,b){A.chartClick({data:a,index:b,pos:d3.event,id:h})}),B=[],C=[];for(var M=0;M<b[0].length;M++){var S=d3.svg.arc().outerRadius(I[M]),T=d3.svg.arc().outerRadius(I[M]+5);u!==!1&&(S.startAngle(u),T.startAngle(u)),w!==!1&&(S.endAngle(w),T.endAngle(w)),p&&(S.innerRadius(J[M]),T.innerRadius(J[M])),S.cornerRadius&&x&&(S.cornerRadius(x),T.cornerRadius(x)),B.push(S),C.push(T)}var U=d3.layout.pie().sort(null).value(function(a){return a.disabled?0:g(a)});U.padAngle&&v&&U.padAngle(v),p&&q&&(R.append("text").attr("class","nv-pie-title"),N.select(".nv-pie-title").style("text-anchor","middle").text(function(){return q}).style("font-size",Math.min(F,G)*y*2/(q.length+2)+"px").attr("dy","0.35em").attr("transform",function(){return"translate(0, "+s+")"}));var V=N.select(".nv-pie").selectAll(".nv-slice").data(U),W=N.select(".nv-pieLabels").selectAll(".nv-label").data(U);V.exit().remove(),W.exit().remove();var X=V.enter().append("g");X.attr("class","nv-slice"),X.on("mouseover",function(a,b){d3.select(this).classed("hover",!0),r&&d3.select(this).select("path").transition().duration(70).attr("d",C[b]),A.elementMouseover({data:a.data,index:b,color:d3.select(this).style("fill")})}),X.on("mouseout",function(a,b){d3.select(this).classed("hover",!1),r&&d3.select(this).select("path").transition().duration(50).attr("d",B[b]),A.elementMouseout({data:a.data,index:b})}),X.on("mousemove",function(a,b){A.elementMousemove({data:a.data,index:b})}),X.on("click",function(a,b){A.elementClick({data:a.data,index:b,color:d3.select(this).style("fill")})}),X.on("dblclick",function(a,b){A.elementDblClick({data:a.data,index:b,color:d3.select(this).style("fill")})}),V.attr("fill",function(a,b){return j(a.data,b)}),V.attr("stroke",function(a,b){return j(a.data,b)});X.append("path").each(function(a){this._current=a});if(V.select("path").transition().attr("d",function(a,b){return B[b](a)}).attrTween("d",E),l){for(var Y=[],M=0;M<b[0].length;M++)Y.push(B[M]),m?p&&(Y[M]=d3.svg.arc().outerRadius(B[M].outerRadius()),u!==!1&&Y[M].startAngle(u),w!==!1&&Y[M].endAngle(w)):p||Y[M].innerRadius(0);W.enter().append("g").classed("nv-label",!0).each(function(a){var b=d3.select(this);b.attr("transform",function(a,b){if(t){a.outerRadius=I[b]+10,a.innerRadius=I[b]+15;var c=(a.startAngle+a.endAngle)/2*(180/Math.PI);return(a.startAngle+a.endAngle)/2<Math.PI?c-=90:c+=90,"translate("+Y[b].centroid(a)+") rotate("+c+")"}return a.outerRadius=H+10,a.innerRadius=H+15,"translate("+Y[b].centroid(a)+")"}),b.append("rect").style("stroke","#fff").style("fill","#fff").attr("rx",3).attr("ry",3),b.append("text").style("text-anchor",t?(a.startAngle+a.endAngle)/2<Math.PI?"start":"end":"middle").style("fill","#000")});var Z={},$=14,_=140,ab=function(a){return Math.floor(a[0]/_)*_+","+Math.floor(a[1]/$)*$};W.watchTransition(D,"pie labels").attr("transform",function(a,b){if(t){a.outerRadius=I[b]+10,a.innerRadius=I[b]+15;var c=(a.startAngle+a.endAngle)/2*(180/Math.PI);return(a.startAngle+a.endAngle)/2<Math.PI?c-=90:c+=90,"translate("+Y[b].centroid(a)+") rotate("+c+")"}a.outerRadius=H+10,a.innerRadius=H+15;var d=Y[b].centroid(a);if(a.value){var e=ab(d);Z[e]&&(d[1]-=$),Z[ab(d)]=!0}return"translate("+d+")"}),W.select(".nv-label text").style("text-anchor",function(a){return t?(a.startAngle+a.endAngle)/2<Math.PI?"start":"end":"middle"}).text(function(a,b){var c=(a.endAngle-a.startAngle)/(2*Math.PI),d="";if(!a.value||o>c)return"";if("function"==typeof n)d=n(a,b,{key:f(a.data),value:g(a.data),percent:k(c)});else switch(n){case"key":d=f(a.data);break;case"value":d=k(g(a.data));break;case"percent":d=d3.format("%")(c)}return d})}}),D.renderEnd("pie immediate"),b}var c={top:0,right:0,bottom:0,left:0},d=500,e=500,f=function(a){return a.x},g=function(a){return a.y},h=Math.floor(1e4*Math.random()),i=null,j=a.utils.defaultColor(),k=d3.format(",.2f"),l=!0,m=!1,n="key",o=.02,p=!1,q=!1,r=!0,s=0,t=!1,u=!1,v=!1,w=!1,x=0,y=.5,z=[],A=d3.dispatch("chartClick","elementClick","elementDblClick","elementMouseover","elementMouseout","elementMousemove","renderEnd"),B=[],C=[],D=a.utils.renderWatch(A);return b.dispatch=A,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{arcsRadius:{get:function(){return z},set:function(a){z=a}},width:{get:function(){return d},set:function(a){d=a}},height:{get:function(){return e},set:function(a){e=a}},showLabels:{get:function(){return l},set:function(a){l=a}},title:{get:function(){return q},set:function(a){q=a}},titleOffset:{get:function(){return s},set:function(a){s=a}},labelThreshold:{get:function(){return o},set:function(a){o=a}},valueFormat:{get:function(){return k},set:function(a){k=a}},x:{get:function(){return f},set:function(a){f=a}},id:{get:function(){return h},set:function(a){h=a}},endAngle:{get:function(){return w},set:function(a){w=a}},startAngle:{get:function(){return u},set:function(a){u=a}},padAngle:{get:function(){return v},set:function(a){v=a}},cornerRadius:{get:function(){return x},set:function(a){x=a}},donutRatio:{get:function(){return y},set:function(a){y=a}},labelsOutside:{get:function(){return m},set:function(a){m=a}},labelSunbeamLayout:{get:function(){return t},set:function(a){t=a}},donut:{get:function(){return p},set:function(a){p=a}},growOnHover:{get:function(){return r},set:function(a){r=a}},pieLabelsOutside:{get:function(){return m},set:function(b){m=b,a.deprecated("pieLabelsOutside","use labelsOutside instead")}},donutLabelsOutside:{get:function(){return m},set:function(b){m=b,a.deprecated("donutLabelsOutside","use labelsOutside instead")}},labelFormat:{get:function(){return k},set:function(b){k=b,a.deprecated("labelFormat","use valueFormat instead")}},margin:{get:function(){return c},set:function(a){c.top="undefined"!=typeof a.top?a.top:c.top,c.right="undefined"!=typeof a.right?a.right:c.right,c.bottom="undefined"!=typeof a.bottom?a.bottom:c.bottom,c.left="undefined"!=typeof a.left?a.left:c.left}},y:{get:function(){return g},set:function(a){g=d3.functor(a)}},color:{get:function(){return j},set:function(b){j=a.utils.getColor(b)}},labelType:{get:function(){return n},set:function(a){n=a||"key"}}}),a.utils.initOptions(b),b},a.models.pieChart=function(){"use strict";function b(e){return q.reset(),q.models(c),e.each(function(e){var k=d3.select(this);a.utils.initSVG(k);var n=a.utils.availableWidth(g,k,f),o=a.utils.availableHeight(h,k,f);if(b.update=function(){k.transition().call(b)},b.container=this,l.setter(s(e),b.update).getter(r(e)).update(),l.disabled=e.map(function(a){return!!a.disabled}),!m){var q;m={};for(q in l)m[q]=l[q]instanceof Array?l[q].slice(0):l[q]}if(!e||!e.length)return a.utils.noData(b,k),b;k.selectAll(".nv-noData").remove();var t=k.selectAll("g.nv-wrap.nv-pieChart").data([e]),u=t.enter().append("g").attr("class","nvd3 nv-wrap nv-pieChart").append("g"),v=t.select("g");if(u.append("g").attr("class","nv-pieWrap"),u.append("g").attr("class","nv-legendWrap"),i)if("top"===j)d.width(n).key(c.x()),t.select(".nv-legendWrap").datum(e).call(d),f.top!=d.height()&&(f.top=d.height(),o=a.utils.availableHeight(h,k,f)),t.select(".nv-legendWrap").attr("transform","translate(0,"+-f.top+")");else if("right"===j){var w=a.models.legend().width();w>n/2&&(w=n/2),d.height(o).key(c.x()),d.width(w),n-=d.width(),t.select(".nv-legendWrap").datum(e).call(d).attr("transform","translate("+n+",0)")}t.attr("transform","translate("+f.left+","+f.top+")"),c.width(n).height(o);var x=v.select(".nv-pieWrap").datum([e]);d3.transition(x).call(c),d.dispatch.on("stateChange",function(a){for(var c in a)l[c]=a[c];p.stateChange(l),b.update()}),p.on("changeState",function(a){"undefined"!=typeof a.disabled&&(e.forEach(function(b,c){b.disabled=a.disabled[c]}),l.disabled=a.disabled),b.update()})}),q.renderEnd("pieChart immediate"),b}var c=a.models.pie(),d=a.models.legend(),e=a.models.tooltip(),f={top:30,right:20,bottom:20,left:20},g=null,h=null,i=!0,j="top",k=a.utils.defaultColor(),l=a.utils.state(),m=null,n=null,o=250,p=d3.dispatch("tooltipShow","tooltipHide","stateChange","changeState","renderEnd");e.headerEnabled(!1).duration(0).valueFormatter(function(a,b){return c.valueFormat()(a,b)});var q=a.utils.renderWatch(p),r=function(a){return function(){return{active:a.map(function(a){return!a.disabled})}}},s=function(a){return function(b){void 0!==b.active&&a.forEach(function(a,c){a.disabled=!b.active[c]})}};return c.dispatch.on("elementMouseover.tooltip",function(a){a.series={key:b.x()(a.data),value:b.y()(a.data),color:a.color},e.data(a).hidden(!1)}),c.dispatch.on("elementMouseout.tooltip",function(){e.hidden(!0)}),c.dispatch.on("elementMousemove.tooltip",function(){e.position({top:d3.event.pageY,left:d3.event.pageX})()}),b.legend=d,b.dispatch=p,b.pie=c,b.tooltip=e,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{noData:{get:function(){return n},set:function(a){n=a}},showLegend:{get:function(){return i},set:function(a){i=a}},legendPosition:{get:function(){return j},set:function(a){j=a}},defaultState:{get:function(){return m},set:function(a){m=a}},tooltips:{get:function(){return e.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),e.enabled(!!b)}},tooltipContent:{get:function(){return e.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),e.contentGenerator(b)}},color:{get:function(){return k},set:function(a){k=a,d.color(k),c.color(k)}},duration:{get:function(){return o},set:function(a){o=a,q.reset(o)}},margin:{get:function(){return f},set:function(a){f.top=void 0!==a.top?a.top:f.top,f.right=void 0!==a.right?a.right:f.right,f.bottom=void 0!==a.bottom?a.bottom:f.bottom,f.left=void 0!==a.left?a.left:f.left}}}),a.utils.inheritOptions(b,c),a.utils.initOptions(b),b},a.models.scatter=function(){"use strict";function b(N){return P.reset(),N.each(function(b){function N(){if(O=!1,!w)return!1;if(M===!0){var a=d3.merge(b.map(function(a,b){return a.values.map(function(a,c){var d=p(a,c),e=q(a,c);return[m(d)+1e-4*Math.random(),n(e)+1e-4*Math.random(),b,c,a]}).filter(function(a,b){return x(a[4],b)})}));if(0==a.length)return!1;a.length<3&&(a.push([m.range()[0]-20,n.range()[0]-20,null,null]),a.push([m.range()[1]+20,n.range()[1]+20,null,null]),a.push([m.range()[0]-20,n.range()[0]+20,null,null]),a.push([m.range()[1]+20,n.range()[1]-20,null,null]));var c=d3.geom.polygon([[-10,-10],[-10,i+10],[h+10,i+10],[h+10,-10]]),d=d3.geom.voronoi(a).map(function(b,d){return{data:c.clip(b),series:a[d][2],point:a[d][3]}});U.select(".nv-point-paths").selectAll("path").remove();var e=U.select(".nv-point-paths").selectAll("path").data(d),f=e.enter().append("svg:path").attr("d",function(a){return a&&a.data&&0!==a.data.length?"M"+a.data.join(",")+"Z":"M 0 0"}).attr("id",function(a,b){return"nv-path-"+b}).attr("clip-path",function(a,b){return"url(#nv-clip-"+b+")"});C&&f.style("fill",d3.rgb(230,230,230)).style("fill-opacity",.4).style("stroke-opacity",1).style("stroke",d3.rgb(200,200,200)),B&&(U.select(".nv-point-clips").selectAll("clipPath").remove(),U.select(".nv-point-clips").selectAll("clipPath").data(a).enter().append("svg:clipPath").attr("id",function(a,b){return"nv-clip-"+b}).append("svg:circle").attr("cx",function(a){return a[0]}).attr("cy",function(a){return a[1]}).attr("r",D));var k=function(a,c){if(O)return 0;var d=b[a.series];if(void 0!==d){var e=d.values[a.point];e.color=j(d,a.series),e.x=p(e),e.y=q(e);var f=l.node().getBoundingClientRect(),h=window.pageYOffset||document.documentElement.scrollTop,i=window.pageXOffset||document.documentElement.scrollLeft,k={left:m(p(e,a.point))+f.left+i+g.left+10,top:n(q(e,a.point))+f.top+h+g.top+10};c({point:e,series:d,pos:k,seriesIndex:a.series,pointIndex:a.point})}};e.on("click",function(a){k(a,L.elementClick)}).on("dblclick",function(a){k(a,L.elementDblClick)}).on("mouseover",function(a){k(a,L.elementMouseover)}).on("mouseout",function(a){k(a,L.elementMouseout)})}else U.select(".nv-groups").selectAll(".nv-group").selectAll(".nv-point").on("click",function(a,c){if(O||!b[a.series])return 0;var d=b[a.series],e=d.values[c];L.elementClick({point:e,series:d,pos:[m(p(e,c))+g.left,n(q(e,c))+g.top],seriesIndex:a.series,pointIndex:c})}).on("dblclick",function(a,c){if(O||!b[a.series])return 0;var d=b[a.series],e=d.values[c];L.elementDblClick({point:e,series:d,pos:[m(p(e,c))+g.left,n(q(e,c))+g.top],seriesIndex:a.series,pointIndex:c})}).on("mouseover",function(a,c){if(O||!b[a.series])return 0;var d=b[a.series],e=d.values[c];L.elementMouseover({point:e,series:d,pos:[m(p(e,c))+g.left,n(q(e,c))+g.top],seriesIndex:a.series,pointIndex:c,color:j(a,c)})}).on("mouseout",function(a,c){if(O||!b[a.series])return 0;var d=b[a.series],e=d.values[c];L.elementMouseout({point:e,series:d,seriesIndex:a.series,pointIndex:c,color:j(a,c)})})}l=d3.select(this);var R=a.utils.availableWidth(h,l,g),S=a.utils.availableHeight(i,l,g);a.utils.initSVG(l),b.forEach(function(a,b){a.values.forEach(function(a){a.series=b})});var T=E&&F&&I?[]:d3.merge(b.map(function(a){return a.values.map(function(a,b){return{x:p(a,b),y:q(a,b),size:r(a,b)}})}));m.domain(E||d3.extent(T.map(function(a){return a.x}).concat(t))),m.range(y&&b[0]?G||[(R*z+R)/(2*b[0].values.length),R-R*(1+z)/(2*b[0].values.length)]:G||[0,R]),n.domain(F||d3.extent(T.map(function(a){return a.y}).concat(u))).range(H||[S,0]),o.domain(I||d3.extent(T.map(function(a){return a.size}).concat(v))).range(J||Q),K=m.domain()[0]===m.domain()[1]||n.domain()[0]===n.domain()[1],m.domain()[0]===m.domain()[1]&&m.domain(m.domain()[0]?[m.domain()[0]-.01*m.domain()[0],m.domain()[1]+.01*m.domain()[1]]:[-1,1]),n.domain()[0]===n.domain()[1]&&n.domain(n.domain()[0]?[n.domain()[0]-.01*n.domain()[0],n.domain()[1]+.01*n.domain()[1]]:[-1,1]),isNaN(m.domain()[0])&&m.domain([-1,1]),isNaN(n.domain()[0])&&n.domain([-1,1]),c=c||m,d=d||n,e=e||o;var U=l.selectAll("g.nv-wrap.nv-scatter").data([b]),V=U.enter().append("g").attr("class","nvd3 nv-wrap nv-scatter nv-chart-"+k),W=V.append("defs"),X=V.append("g"),Y=U.select("g");U.classed("nv-single-point",K),X.append("g").attr("class","nv-groups"),X.append("g").attr("class","nv-point-paths"),V.append("g").attr("class","nv-point-clips"),U.attr("transform","translate("+g.left+","+g.top+")"),W.append("clipPath").attr("id","nv-edge-clip-"+k).append("rect"),U.select("#nv-edge-clip-"+k+" rect").attr("width",R).attr("height",S>0?S:0),Y.attr("clip-path",A?"url(#nv-edge-clip-"+k+")":""),O=!0;var Z=U.select(".nv-groups").selectAll(".nv-group").data(function(a){return a},function(a){return a.key});Z.enter().append("g").style("stroke-opacity",1e-6).style("fill-opacity",1e-6),Z.exit().remove(),Z.attr("class",function(a,b){return"nv-group nv-series-"+b}).classed("hover",function(a){return a.hover}),Z.watchTransition(P,"scatter: groups").style("fill",function(a,b){return j(a,b)}).style("stroke",function(a,b){return j(a,b)}).style("stroke-opacity",1).style("fill-opacity",.5);var $=Z.selectAll("path.nv-point").data(function(a){return a.values.map(function(a,b){return[a,b]}).filter(function(a,b){return x(a[0],b)})});$.enter().append("path").style("fill",function(a){return a.color}).style("stroke",function(a){return a.color}).attr("transform",function(a){return"translate("+c(p(a[0],a[1]))+","+d(q(a[0],a[1]))+")"}).attr("d",a.utils.symbol().type(function(a){return s(a[0])}).size(function(a){return o(r(a[0],a[1]))})),$.exit().remove(),Z.exit().selectAll("path.nv-point").watchTransition(P,"scatter exit").attr("transform",function(a){return"translate("+m(p(a[0],a[1]))+","+n(q(a[0],a[1]))+")"}).remove(),$.each(function(a){d3.select(this).classed("nv-point",!0).classed("nv-point-"+a[1],!0).classed("nv-noninteractive",!w).classed("hover",!1)}),$.watchTransition(P,"scatter points").attr("transform",function(a){return"translate("+m(p(a[0],a[1]))+","+n(q(a[0],a[1]))+")"}).attr("d",a.utils.symbol().type(function(a){return s(a[0])}).size(function(a){return o(r(a[0],a[1]))})),clearTimeout(f),f=setTimeout(N,300),c=m.copy(),d=n.copy(),e=o.copy()}),P.renderEnd("scatter immediate"),b}var c,d,e,f,g={top:0,right:0,bottom:0,left:0},h=null,i=null,j=a.utils.defaultColor(),k=Math.floor(1e5*Math.random()),l=null,m=d3.scale.linear(),n=d3.scale.linear(),o=d3.scale.linear(),p=function(a){return a.x},q=function(a){return a.y},r=function(a){return a.size||1},s=function(a){return a.shape||"circle"},t=[],u=[],v=[],w=!0,x=function(a){return!a.notActive},y=!1,z=.1,A=!1,B=!0,C=!1,D=function(){return 25},E=null,F=null,G=null,H=null,I=null,J=null,K=!1,L=d3.dispatch("elementClick","elementDblClick","elementMouseover","elementMouseout","renderEnd"),M=!0,N=250,O=!1,P=a.utils.renderWatch(L,N),Q=[16,256];return b.dispatch=L,b.options=a.utils.optionsFunc.bind(b),b._calls=new function(){this.clearHighlights=function(){return a.dom.write(function(){l.selectAll(".nv-point.hover").classed("hover",!1)}),null},this.highlightPoint=function(b,c,d){a.dom.write(function(){l.select(" .nv-series-"+b+" .nv-point-"+c).classed("hover",d)})}},L.on("elementMouseover.point",function(a){w&&b._calls.highlightPoint(a.seriesIndex,a.pointIndex,!0)}),L.on("elementMouseout.point",function(a){w&&b._calls.highlightPoint(a.seriesIndex,a.pointIndex,!1)}),b._options=Object.create({},{width:{get:function(){return h},set:function(a){h=a}},height:{get:function(){return i},set:function(a){i=a}},xScale:{get:function(){return m},set:function(a){m=a}},yScale:{get:function(){return n},set:function(a){n=a}},pointScale:{get:function(){return o},set:function(a){o=a}},xDomain:{get:function(){return E},set:function(a){E=a}},yDomain:{get:function(){return F},set:function(a){F=a}},pointDomain:{get:function(){return I},set:function(a){I=a}},xRange:{get:function(){return G},set:function(a){G=a}},yRange:{get:function(){return H},set:function(a){H=a}},pointRange:{get:function(){return J},set:function(a){J=a}},forceX:{get:function(){return t},set:function(a){t=a}},forceY:{get:function(){return u},set:function(a){u=a}},forcePoint:{get:function(){return v},set:function(a){v=a}},interactive:{get:function(){return w},set:function(a){w=a}},pointActive:{get:function(){return x},set:function(a){x=a}},padDataOuter:{get:function(){return z},set:function(a){z=a}},padData:{get:function(){return y},set:function(a){y=a}},clipEdge:{get:function(){return A},set:function(a){A=a}},clipVoronoi:{get:function(){return B},set:function(a){B=a}},clipRadius:{get:function(){return D},set:function(a){D=a}},showVoronoi:{get:function(){return C},set:function(a){C=a}},id:{get:function(){return k},set:function(a){k=a}},x:{get:function(){return p},set:function(a){p=d3.functor(a)}},y:{get:function(){return q},set:function(a){q=d3.functor(a)}},pointSize:{get:function(){return r},set:function(a){r=d3.functor(a)}},pointShape:{get:function(){return s},set:function(a){s=d3.functor(a)}},margin:{get:function(){return g},set:function(a){g.top=void 0!==a.top?a.top:g.top,g.right=void 0!==a.right?a.right:g.right,g.bottom=void 0!==a.bottom?a.bottom:g.bottom,g.left=void 0!==a.left?a.left:g.left}},duration:{get:function(){return N},set:function(a){N=a,P.reset(N)}},color:{get:function(){return j},set:function(b){j=a.utils.getColor(b)}},useVoronoi:{get:function(){return M},set:function(a){M=a,M===!1&&(B=!1)}}}),a.utils.initOptions(b),b},a.models.scatterChart=function(){"use strict";function b(z){return D.reset(),D.models(c),t&&D.models(d),u&&D.models(e),q&&D.models(g),r&&D.models(h),z.each(function(z){m=d3.select(this),a.utils.initSVG(m);var G=a.utils.availableWidth(k,m,j),H=a.utils.availableHeight(l,m,j);if(b.update=function(){0===A?m.call(b):m.transition().duration(A).call(b)},b.container=this,w.setter(F(z),b.update).getter(E(z)).update(),w.disabled=z.map(function(a){return!!a.disabled}),!x){var I;x={};for(I in w)x[I]=w[I]instanceof Array?w[I].slice(0):w[I]}if(!(z&&z.length&&z.filter(function(a){return a.values.length}).length))return a.utils.noData(b,m),D.renderEnd("scatter immediate"),b;m.selectAll(".nv-noData").remove(),o=c.xScale(),p=c.yScale();var J=m.selectAll("g.nv-wrap.nv-scatterChart").data([z]),K=J.enter().append("g").attr("class","nvd3 nv-wrap nv-scatterChart nv-chart-"+c.id()),L=K.append("g"),M=J.select("g");if(L.append("rect").attr("class","nvd3 nv-background").style("pointer-events","none"),L.append("g").attr("class","nv-x nv-axis"),L.append("g").attr("class","nv-y nv-axis"),L.append("g").attr("class","nv-scatterWrap"),L.append("g").attr("class","nv-regressionLinesWrap"),L.append("g").attr("class","nv-distWrap"),L.append("g").attr("class","nv-legendWrap"),v&&M.select(".nv-y.nv-axis").attr("transform","translate("+G+",0)"),s){var N=G;f.width(N),J.select(".nv-legendWrap").datum(z).call(f),j.top!=f.height()&&(j.top=f.height(),H=a.utils.availableHeight(l,m,j)),J.select(".nv-legendWrap").attr("transform","translate(0,"+-j.top+")")}J.attr("transform","translate("+j.left+","+j.top+")"),c.width(G).height(H).color(z.map(function(a,b){return a.color=a.color||n(a,b),a.color}).filter(function(a,b){return!z[b].disabled})),J.select(".nv-scatterWrap").datum(z.filter(function(a){return!a.disabled})).call(c),J.select(".nv-regressionLinesWrap").attr("clip-path","url(#nv-edge-clip-"+c.id()+")");var O=J.select(".nv-regressionLinesWrap").selectAll(".nv-regLines").data(function(a){return a});O.enter().append("g").attr("class","nv-regLines");var P=O.selectAll(".nv-regLine").data(function(a){return[a]});P.enter().append("line").attr("class","nv-regLine").style("stroke-opacity",0),P.filter(function(a){return a.intercept&&a.slope}).watchTransition(D,"scatterPlusLineChart: regline").attr("x1",o.range()[0]).attr("x2",o.range()[1]).attr("y1",function(a){return p(o.domain()[0]*a.slope+a.intercept)}).attr("y2",function(a){return p(o.domain()[1]*a.slope+a.intercept)}).style("stroke",function(a,b,c){return n(a,c)}).style("stroke-opacity",function(a){return a.disabled||"undefined"==typeof a.slope||"undefined"==typeof a.intercept?0:1}),t&&(d.scale(o)._ticks(a.utils.calcTicksX(G/100,z)).tickSize(-H,0),M.select(".nv-x.nv-axis").attr("transform","translate(0,"+p.range()[0]+")").call(d)),u&&(e.scale(p)._ticks(a.utils.calcTicksY(H/36,z)).tickSize(-G,0),M.select(".nv-y.nv-axis").call(e)),q&&(g.getData(c.x()).scale(o).width(G).color(z.map(function(a,b){return a.color||n(a,b)}).filter(function(a,b){return!z[b].disabled})),L.select(".nv-distWrap").append("g").attr("class","nv-distributionX"),M.select(".nv-distributionX").attr("transform","translate(0,"+p.range()[0]+")").datum(z.filter(function(a){return!a.disabled})).call(g)),r&&(h.getData(c.y()).scale(p).width(H).color(z.map(function(a,b){return a.color||n(a,b)}).filter(function(a,b){return!z[b].disabled})),L.select(".nv-distWrap").append("g").attr("class","nv-distributionY"),M.select(".nv-distributionY").attr("transform","translate("+(v?G:-h.size())+",0)").datum(z.filter(function(a){return!a.disabled})).call(h)),f.dispatch.on("stateChange",function(a){for(var c in a)w[c]=a[c];y.stateChange(w),b.update()}),y.on("changeState",function(a){"undefined"!=typeof a.disabled&&(z.forEach(function(b,c){b.disabled=a.disabled[c]}),w.disabled=a.disabled),b.update()}),c.dispatch.on("elementMouseout.tooltip",function(a){i.hidden(!0),m.select(".nv-chart-"+c.id()+" .nv-series-"+a.seriesIndex+" .nv-distx-"+a.pointIndex).attr("y1",0),m.select(".nv-chart-"+c.id()+" .nv-series-"+a.seriesIndex+" .nv-disty-"+a.pointIndex).attr("x2",h.size())}),c.dispatch.on("elementMouseover.tooltip",function(a){m.select(".nv-series-"+a.seriesIndex+" .nv-distx-"+a.pointIndex).attr("y1",a.pos.top-H-j.top),m.select(".nv-series-"+a.seriesIndex+" .nv-disty-"+a.pointIndex).attr("x2",a.pos.left+g.size()-j.left),i.position(a.pos).data(a).hidden(!1)}),B=o.copy(),C=p.copy()}),D.renderEnd("scatter with line immediate"),b}var c=a.models.scatter(),d=a.models.axis(),e=a.models.axis(),f=a.models.legend(),g=a.models.distribution(),h=a.models.distribution(),i=a.models.tooltip(),j={top:30,right:20,bottom:50,left:75},k=null,l=null,m=null,n=a.utils.defaultColor(),o=c.xScale(),p=c.yScale(),q=!1,r=!1,s=!0,t=!0,u=!0,v=!1,w=a.utils.state(),x=null,y=d3.dispatch("stateChange","changeState","renderEnd"),z=null,A=250;c.xScale(o).yScale(p),d.orient("bottom").tickPadding(10),e.orient(v?"right":"left").tickPadding(10),g.axis("x"),h.axis("y"),i.headerFormatter(function(a,b){return d.tickFormat()(a,b)}).valueFormatter(function(a,b){return e.tickFormat()(a,b)});var B,C,D=a.utils.renderWatch(y,A),E=function(a){return function(){return{active:a.map(function(a){return!a.disabled})}}},F=function(a){return function(b){void 0!==b.active&&a.forEach(function(a,c){a.disabled=!b.active[c]})}};return b.dispatch=y,b.scatter=c,b.legend=f,b.xAxis=d,b.yAxis=e,b.distX=g,b.distY=h,b.tooltip=i,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return k},set:function(a){k=a}},height:{get:function(){return l},set:function(a){l=a}},container:{get:function(){return m},set:function(a){m=a}},showDistX:{get:function(){return q},set:function(a){q=a}},showDistY:{get:function(){return r},set:function(a){r=a}},showLegend:{get:function(){return s},set:function(a){s=a}},showXAxis:{get:function(){return t},set:function(a){t=a}},showYAxis:{get:function(){return u},set:function(a){u=a}},defaultState:{get:function(){return x},set:function(a){x=a}},noData:{get:function(){return z},set:function(a){z=a}},duration:{get:function(){return A},set:function(a){A=a}},tooltips:{get:function(){return i.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),i.enabled(!!b)
33852 }},tooltipContent:{get:function(){return i.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),i.contentGenerator(b)}},tooltipXContent:{get:function(){return i.contentGenerator()},set:function(){a.deprecated("tooltipContent","This option is removed, put values into main tooltip.")}},tooltipYContent:{get:function(){return i.contentGenerator()},set:function(){a.deprecated("tooltipContent","This option is removed, put values into main tooltip.")}},margin:{get:function(){return j},set:function(a){j.top=void 0!==a.top?a.top:j.top,j.right=void 0!==a.right?a.right:j.right,j.bottom=void 0!==a.bottom?a.bottom:j.bottom,j.left=void 0!==a.left?a.left:j.left}},rightAlignYAxis:{get:function(){return v},set:function(a){v=a,e.orient(a?"right":"left")}},color:{get:function(){return n},set:function(b){n=a.utils.getColor(b),f.color(n),g.color(n),h.color(n)}}}),a.utils.inheritOptions(b,c),a.utils.initOptions(b),b},a.models.sparkline=function(){"use strict";function b(k){return k.each(function(b){var k=h-g.left-g.right,q=i-g.top-g.bottom;j=d3.select(this),a.utils.initSVG(j),l.domain(c||d3.extent(b,n)).range(e||[0,k]),m.domain(d||d3.extent(b,o)).range(f||[q,0]);{var r=j.selectAll("g.nv-wrap.nv-sparkline").data([b]),s=r.enter().append("g").attr("class","nvd3 nv-wrap nv-sparkline");s.append("g"),r.select("g")}r.attr("transform","translate("+g.left+","+g.top+")");var t=r.selectAll("path").data(function(a){return[a]});t.enter().append("path"),t.exit().remove(),t.style("stroke",function(a,b){return a.color||p(a,b)}).attr("d",d3.svg.line().x(function(a,b){return l(n(a,b))}).y(function(a,b){return m(o(a,b))}));var u=r.selectAll("circle.nv-point").data(function(a){function b(b){if(-1!=b){var c=a[b];return c.pointIndex=b,c}return null}var c=a.map(function(a,b){return o(a,b)}),d=b(c.lastIndexOf(m.domain()[1])),e=b(c.indexOf(m.domain()[0])),f=b(c.length-1);return[e,d,f].filter(function(a){return null!=a})});u.enter().append("circle"),u.exit().remove(),u.attr("cx",function(a){return l(n(a,a.pointIndex))}).attr("cy",function(a){return m(o(a,a.pointIndex))}).attr("r",2).attr("class",function(a){return n(a,a.pointIndex)==l.domain()[1]?"nv-point nv-currentValue":o(a,a.pointIndex)==m.domain()[0]?"nv-point nv-minValue":"nv-point nv-maxValue"})}),b}var c,d,e,f,g={top:2,right:0,bottom:2,left:0},h=400,i=32,j=null,k=!0,l=d3.scale.linear(),m=d3.scale.linear(),n=function(a){return a.x},o=function(a){return a.y},p=a.utils.getColor(["#000"]);return b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return h},set:function(a){h=a}},height:{get:function(){return i},set:function(a){i=a}},xDomain:{get:function(){return c},set:function(a){c=a}},yDomain:{get:function(){return d},set:function(a){d=a}},xRange:{get:function(){return e},set:function(a){e=a}},yRange:{get:function(){return f},set:function(a){f=a}},xScale:{get:function(){return l},set:function(a){l=a}},yScale:{get:function(){return m},set:function(a){m=a}},animate:{get:function(){return k},set:function(a){k=a}},x:{get:function(){return n},set:function(a){n=d3.functor(a)}},y:{get:function(){return o},set:function(a){o=d3.functor(a)}},margin:{get:function(){return g},set:function(a){g.top=void 0!==a.top?a.top:g.top,g.right=void 0!==a.right?a.right:g.right,g.bottom=void 0!==a.bottom?a.bottom:g.bottom,g.left=void 0!==a.left?a.left:g.left}},color:{get:function(){return p},set:function(b){p=a.utils.getColor(b)}}}),a.utils.initOptions(b),b},a.models.sparklinePlus=function(){"use strict";function b(p){return p.each(function(p){function q(){if(!j){var a=z.selectAll(".nv-hoverValue").data(i),b=a.enter().append("g").attr("class","nv-hoverValue").style("stroke-opacity",0).style("fill-opacity",0);a.exit().transition().duration(250).style("stroke-opacity",0).style("fill-opacity",0).remove(),a.attr("transform",function(a){return"translate("+c(e.x()(p[a],a))+",0)"}).transition().duration(250).style("stroke-opacity",1).style("fill-opacity",1),i.length&&(b.append("line").attr("x1",0).attr("y1",-f.top).attr("x2",0).attr("y2",u),b.append("text").attr("class","nv-xValue").attr("x",-6).attr("y",-f.top).attr("text-anchor","end").attr("dy",".9em"),z.select(".nv-hoverValue .nv-xValue").text(k(e.x()(p[i[0]],i[0]))),b.append("text").attr("class","nv-yValue").attr("x",6).attr("y",-f.top).attr("text-anchor","start").attr("dy",".9em"),z.select(".nv-hoverValue .nv-yValue").text(l(e.y()(p[i[0]],i[0]))))}}function r(){function a(a,b){for(var c=Math.abs(e.x()(a[0],0)-b),d=0,f=0;f<a.length;f++)Math.abs(e.x()(a[f],f)-b)<c&&(c=Math.abs(e.x()(a[f],f)-b),d=f);return d}if(!j){var b=d3.mouse(this)[0]-f.left;i=[a(p,Math.round(c.invert(b)))],q()}}var s=d3.select(this);a.utils.initSVG(s);var t=a.utils.availableWidth(g,s,f),u=a.utils.availableHeight(h,s,f);if(b.update=function(){s.call(b)},b.container=this,!p||!p.length)return a.utils.noData(b,s),b;s.selectAll(".nv-noData").remove();var v=e.y()(p[p.length-1],p.length-1);c=e.xScale(),d=e.yScale();var w=s.selectAll("g.nv-wrap.nv-sparklineplus").data([p]),x=w.enter().append("g").attr("class","nvd3 nv-wrap nv-sparklineplus"),y=x.append("g"),z=w.select("g");y.append("g").attr("class","nv-sparklineWrap"),y.append("g").attr("class","nv-valueWrap"),y.append("g").attr("class","nv-hoverArea"),w.attr("transform","translate("+f.left+","+f.top+")");var A=z.select(".nv-sparklineWrap");if(e.width(t).height(u),A.call(e),m){var B=z.select(".nv-valueWrap"),C=B.selectAll(".nv-currentValue").data([v]);C.enter().append("text").attr("class","nv-currentValue").attr("dx",o?-8:8).attr("dy",".9em").style("text-anchor",o?"end":"start"),C.attr("x",t+(o?f.right:0)).attr("y",n?function(a){return d(a)}:0).style("fill",e.color()(p[p.length-1],p.length-1)).text(l(v))}y.select(".nv-hoverArea").append("rect").on("mousemove",r).on("click",function(){j=!j}).on("mouseout",function(){i=[],q()}),z.select(".nv-hoverArea rect").attr("transform",function(){return"translate("+-f.left+","+-f.top+")"}).attr("width",t+f.left+f.right).attr("height",u+f.top)}),b}var c,d,e=a.models.sparkline(),f={top:15,right:100,bottom:10,left:50},g=null,h=null,i=[],j=!1,k=d3.format(",r"),l=d3.format(",.2f"),m=!0,n=!0,o=!1,p=null;return b.sparkline=e,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return g},set:function(a){g=a}},height:{get:function(){return h},set:function(a){h=a}},xTickFormat:{get:function(){return k},set:function(a){k=a}},yTickFormat:{get:function(){return l},set:function(a){l=a}},showLastValue:{get:function(){return m},set:function(a){m=a}},alignValue:{get:function(){return n},set:function(a){n=a}},rightAlignValue:{get:function(){return o},set:function(a){o=a}},noData:{get:function(){return p},set:function(a){p=a}},margin:{get:function(){return f},set:function(a){f.top=void 0!==a.top?a.top:f.top,f.right=void 0!==a.right?a.right:f.right,f.bottom=void 0!==a.bottom?a.bottom:f.bottom,f.left=void 0!==a.left?a.left:f.left}}}),a.utils.inheritOptions(b,e),a.utils.initOptions(b),b},a.models.stackedArea=function(){"use strict";function b(m){return u.reset(),u.models(r),m.each(function(m){var s=f-e.left-e.right,v=g-e.top-e.bottom;j=d3.select(this),a.utils.initSVG(j),c=r.xScale(),d=r.yScale();var w=m;m.forEach(function(a,b){a.seriesIndex=b,a.values=a.values.map(function(a,c){return a.index=c,a.seriesIndex=b,a})});var x=m.filter(function(a){return!a.disabled});m=d3.layout.stack().order(o).offset(n).values(function(a){return a.values}).x(k).y(l).out(function(a,b,c){a.display={y:c,y0:b}})(x);var y=j.selectAll("g.nv-wrap.nv-stackedarea").data([m]),z=y.enter().append("g").attr("class","nvd3 nv-wrap nv-stackedarea"),A=z.append("defs"),B=z.append("g"),C=y.select("g");B.append("g").attr("class","nv-areaWrap"),B.append("g").attr("class","nv-scatterWrap"),y.attr("transform","translate("+e.left+","+e.top+")"),0==r.forceY().length&&r.forceY().push(0),r.width(s).height(v).x(k).y(function(a){return a.display.y+a.display.y0}).forceY([0]).color(m.map(function(a){return a.color||h(a,a.seriesIndex)}));var D=C.select(".nv-scatterWrap").datum(m);D.call(r),A.append("clipPath").attr("id","nv-edge-clip-"+i).append("rect"),y.select("#nv-edge-clip-"+i+" rect").attr("width",s).attr("height",v),C.attr("clip-path",q?"url(#nv-edge-clip-"+i+")":"");var E=d3.svg.area().x(function(a,b){return c(k(a,b))}).y0(function(a){return d(a.display.y0)}).y1(function(a){return d(a.display.y+a.display.y0)}).interpolate(p),F=d3.svg.area().x(function(a,b){return c(k(a,b))}).y0(function(a){return d(a.display.y0)}).y1(function(a){return d(a.display.y0)}),G=C.select(".nv-areaWrap").selectAll("path.nv-area").data(function(a){return a});G.enter().append("path").attr("class",function(a,b){return"nv-area nv-area-"+b}).attr("d",function(a){return F(a.values,a.seriesIndex)}).on("mouseover",function(a){d3.select(this).classed("hover",!0),t.areaMouseover({point:a,series:a.key,pos:[d3.event.pageX,d3.event.pageY],seriesIndex:a.seriesIndex})}).on("mouseout",function(a){d3.select(this).classed("hover",!1),t.areaMouseout({point:a,series:a.key,pos:[d3.event.pageX,d3.event.pageY],seriesIndex:a.seriesIndex})}).on("click",function(a){d3.select(this).classed("hover",!1),t.areaClick({point:a,series:a.key,pos:[d3.event.pageX,d3.event.pageY],seriesIndex:a.seriesIndex})}),G.exit().remove(),G.style("fill",function(a){return a.color||h(a,a.seriesIndex)}).style("stroke",function(a){return a.color||h(a,a.seriesIndex)}),G.watchTransition(u,"stackedArea path").attr("d",function(a,b){return E(a.values,b)}),r.dispatch.on("elementMouseover.area",function(a){C.select(".nv-chart-"+i+" .nv-area-"+a.seriesIndex).classed("hover",!0)}),r.dispatch.on("elementMouseout.area",function(a){C.select(".nv-chart-"+i+" .nv-area-"+a.seriesIndex).classed("hover",!1)}),b.d3_stackedOffset_stackPercent=function(a){var b,c,d,e=a.length,f=a[0].length,g=[];for(c=0;f>c;++c){for(b=0,d=0;b<w.length;b++)d+=l(w[b].values[c]);if(d)for(b=0;e>b;b++)a[b][c][1]/=d;else for(b=0;e>b;b++)a[b][c][1]=0}for(c=0;f>c;++c)g[c]=0;return g}}),u.renderEnd("stackedArea immediate"),b}var c,d,e={top:0,right:0,bottom:0,left:0},f=960,g=500,h=a.utils.defaultColor(),i=Math.floor(1e5*Math.random()),j=null,k=function(a){return a.x},l=function(a){return a.y},m="stack",n="zero",o="default",p="linear",q=!1,r=a.models.scatter(),s=250,t=d3.dispatch("areaClick","areaMouseover","areaMouseout","renderEnd","elementClick","elementMouseover","elementMouseout");r.pointSize(2.2).pointDomain([2.2,2.2]);var u=a.utils.renderWatch(t,s);return b.dispatch=t,b.scatter=r,r.dispatch.on("elementClick",function(){t.elementClick.apply(this,arguments)}),r.dispatch.on("elementMouseover",function(){t.elementMouseover.apply(this,arguments)}),r.dispatch.on("elementMouseout",function(){t.elementMouseout.apply(this,arguments)}),b.interpolate=function(a){return arguments.length?(p=a,b):p},b.duration=function(a){return arguments.length?(s=a,u.reset(s),r.duration(s),b):s},b.dispatch=t,b.scatter=r,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return f},set:function(a){f=a}},height:{get:function(){return g},set:function(a){g=a}},clipEdge:{get:function(){return q},set:function(a){q=a}},offset:{get:function(){return n},set:function(a){n=a}},order:{get:function(){return o},set:function(a){o=a}},interpolate:{get:function(){return p},set:function(a){p=a}},x:{get:function(){return k},set:function(a){k=d3.functor(a)}},y:{get:function(){return l},set:function(a){l=d3.functor(a)}},margin:{get:function(){return e},set:function(a){e.top=void 0!==a.top?a.top:e.top,e.right=void 0!==a.right?a.right:e.right,e.bottom=void 0!==a.bottom?a.bottom:e.bottom,e.left=void 0!==a.left?a.left:e.left}},color:{get:function(){return h},set:function(b){h=a.utils.getColor(b)}},style:{get:function(){return m},set:function(a){switch(m=a){case"stack":b.offset("zero"),b.order("default");break;case"stream":b.offset("wiggle"),b.order("inside-out");break;case"stream-center":b.offset("silhouette"),b.order("inside-out");break;case"expand":b.offset("expand"),b.order("default");break;case"stack_percent":b.offset(b.d3_stackedOffset_stackPercent),b.order("default")}}},duration:{get:function(){return s},set:function(a){s=a,u.reset(s),r.duration(s)}}}),a.utils.inheritOptions(b,r),a.utils.initOptions(b),b},a.models.stackedAreaChart=function(){"use strict";function b(k){return F.reset(),F.models(e),r&&F.models(f),s&&F.models(g),k.each(function(k){var x=d3.select(this),F=this;a.utils.initSVG(x);var K=a.utils.availableWidth(m,x,l),L=a.utils.availableHeight(n,x,l);if(b.update=function(){x.transition().duration(C).call(b)},b.container=this,v.setter(I(k),b.update).getter(H(k)).update(),v.disabled=k.map(function(a){return!!a.disabled}),!w){var M;w={};for(M in v)w[M]=v[M]instanceof Array?v[M].slice(0):v[M]}if(!(k&&k.length&&k.filter(function(a){return a.values.length}).length))return a.utils.noData(b,x),b;x.selectAll(".nv-noData").remove(),c=e.xScale(),d=e.yScale();var N=x.selectAll("g.nv-wrap.nv-stackedAreaChart").data([k]),O=N.enter().append("g").attr("class","nvd3 nv-wrap nv-stackedAreaChart").append("g"),P=N.select("g");if(O.append("rect").style("opacity",0),O.append("g").attr("class","nv-x nv-axis"),O.append("g").attr("class","nv-y nv-axis"),O.append("g").attr("class","nv-stackedWrap"),O.append("g").attr("class","nv-legendWrap"),O.append("g").attr("class","nv-controlsWrap"),O.append("g").attr("class","nv-interactive"),P.select("rect").attr("width",K).attr("height",L),q){var Q=p?K-z:K;h.width(Q),P.select(".nv-legendWrap").datum(k).call(h),l.top!=h.height()&&(l.top=h.height(),L=a.utils.availableHeight(n,x,l)),P.select(".nv-legendWrap").attr("transform","translate("+(K-Q)+","+-l.top+")")}if(p){var R=[{key:B.stacked||"Stacked",metaKey:"Stacked",disabled:"stack"!=e.style(),style:"stack"},{key:B.stream||"Stream",metaKey:"Stream",disabled:"stream"!=e.style(),style:"stream"},{key:B.expanded||"Expanded",metaKey:"Expanded",disabled:"expand"!=e.style(),style:"expand"},{key:B.stack_percent||"Stack %",metaKey:"Stack_Percent",disabled:"stack_percent"!=e.style(),style:"stack_percent"}];z=A.length/3*260,R=R.filter(function(a){return-1!==A.indexOf(a.metaKey)}),i.width(z).color(["#444","#444","#444"]),P.select(".nv-controlsWrap").datum(R).call(i),l.top!=Math.max(i.height(),h.height())&&(l.top=Math.max(i.height(),h.height()),L=a.utils.availableHeight(n,x,l)),P.select(".nv-controlsWrap").attr("transform","translate(0,"+-l.top+")")}N.attr("transform","translate("+l.left+","+l.top+")"),t&&P.select(".nv-y.nv-axis").attr("transform","translate("+K+",0)"),u&&(j.width(K).height(L).margin({left:l.left,top:l.top}).svgContainer(x).xScale(c),N.select(".nv-interactive").call(j)),e.width(K).height(L);var S=P.select(".nv-stackedWrap").datum(k);if(S.transition().call(e),r&&(f.scale(c)._ticks(a.utils.calcTicksX(K/100,k)).tickSize(-L,0),P.select(".nv-x.nv-axis").attr("transform","translate(0,"+L+")"),P.select(".nv-x.nv-axis").transition().duration(0).call(f)),s){var T;if(T="wiggle"===e.offset()?0:a.utils.calcTicksY(L/36,k),g.scale(d)._ticks(T).tickSize(-K,0),"expand"===e.style()||"stack_percent"===e.style()){var U=g.tickFormat();D&&U===J||(D=U),g.tickFormat(J)}else D&&(g.tickFormat(D),D=null);P.select(".nv-y.nv-axis").transition().duration(0).call(g)}e.dispatch.on("areaClick.toggle",function(a){k.forEach(1===k.filter(function(a){return!a.disabled}).length?function(a){a.disabled=!1}:function(b,c){b.disabled=c!=a.seriesIndex}),v.disabled=k.map(function(a){return!!a.disabled}),y.stateChange(v),b.update()}),h.dispatch.on("stateChange",function(a){for(var c in a)v[c]=a[c];y.stateChange(v),b.update()}),i.dispatch.on("legendClick",function(a){a.disabled&&(R=R.map(function(a){return a.disabled=!0,a}),a.disabled=!1,e.style(a.style),v.style=e.style(),y.stateChange(v),b.update())}),j.dispatch.on("elementMousemove",function(c){e.clearHighlights();var d,g,h,i=[];if(k.filter(function(a,b){return a.seriesIndex=b,!a.disabled}).forEach(function(f,j){g=a.interactiveBisect(f.values,c.pointXValue,b.x());var k=f.values[g],l=b.y()(k,g);if(null!=l&&e.highlightPoint(j,g,!0),"undefined"!=typeof k){"undefined"==typeof d&&(d=k),"undefined"==typeof h&&(h=b.xScale()(b.x()(k,g)));var m="expand"==e.style()?k.display.y:b.y()(k,g);i.push({key:f.key,value:m,color:o(f,f.seriesIndex),stackedValue:k.display})}}),i.reverse(),i.length>2){var m=b.yScale().invert(c.mouseY),n=null;i.forEach(function(a,b){m=Math.abs(m);var c=Math.abs(a.stackedValue.y0),d=Math.abs(a.stackedValue.y);return m>=c&&d+c>=m?void(n=b):void 0}),null!=n&&(i[n].highlight=!0)}var p=f.tickFormat()(b.x()(d,g)),q=j.tooltip.valueFormatter();"expand"===e.style()||"stack_percent"===e.style()?(E||(E=q),q=d3.format(".1%")):E&&(q=E,E=null),j.tooltip.position({left:h+l.left,top:c.mouseY+l.top}).chartContainer(F.parentNode).valueFormatter(q).data({value:p,series:i})(),j.renderGuideLine(h)}),j.dispatch.on("elementMouseout",function(){e.clearHighlights()}),y.on("changeState",function(a){"undefined"!=typeof a.disabled&&k.length===a.disabled.length&&(k.forEach(function(b,c){b.disabled=a.disabled[c]}),v.disabled=a.disabled),"undefined"!=typeof a.style&&(e.style(a.style),G=a.style),b.update()})}),F.renderEnd("stacked Area chart immediate"),b}var c,d,e=a.models.stackedArea(),f=a.models.axis(),g=a.models.axis(),h=a.models.legend(),i=a.models.legend(),j=a.interactiveGuideline(),k=a.models.tooltip(),l={top:30,right:25,bottom:50,left:60},m=null,n=null,o=a.utils.defaultColor(),p=!0,q=!0,r=!0,s=!0,t=!1,u=!1,v=a.utils.state(),w=null,x=null,y=d3.dispatch("stateChange","changeState","renderEnd"),z=250,A=["Stacked","Stream","Expanded"],B={},C=250;v.style=e.style(),f.orient("bottom").tickPadding(7),g.orient(t?"right":"left"),k.headerFormatter(function(a,b){return f.tickFormat()(a,b)}).valueFormatter(function(a,b){return g.tickFormat()(a,b)}),j.tooltip.headerFormatter(function(a,b){return f.tickFormat()(a,b)}).valueFormatter(function(a,b){return g.tickFormat()(a,b)});var D=null,E=null;i.updateState(!1);var F=a.utils.renderWatch(y),G=e.style(),H=function(a){return function(){return{active:a.map(function(a){return!a.disabled}),style:e.style()}}},I=function(a){return function(b){void 0!==b.style&&(G=b.style),void 0!==b.active&&a.forEach(function(a,c){a.disabled=!b.active[c]})}},J=d3.format("%");return e.dispatch.on("elementMouseover.tooltip",function(a){a.point.x=e.x()(a.point),a.point.y=e.y()(a.point),k.data(a).position(a.pos).hidden(!1)}),e.dispatch.on("elementMouseout.tooltip",function(){k.hidden(!0)}),b.dispatch=y,b.stacked=e,b.legend=h,b.controls=i,b.xAxis=f,b.yAxis=g,b.interactiveLayer=j,b.tooltip=k,b.dispatch=y,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return m},set:function(a){m=a}},height:{get:function(){return n},set:function(a){n=a}},showLegend:{get:function(){return q},set:function(a){q=a}},showXAxis:{get:function(){return r},set:function(a){r=a}},showYAxis:{get:function(){return s},set:function(a){s=a}},defaultState:{get:function(){return w},set:function(a){w=a}},noData:{get:function(){return x},set:function(a){x=a}},showControls:{get:function(){return p},set:function(a){p=a}},controlLabels:{get:function(){return B},set:function(a){B=a}},controlOptions:{get:function(){return A},set:function(a){A=a}},tooltips:{get:function(){return k.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),k.enabled(!!b)}},tooltipContent:{get:function(){return k.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),k.contentGenerator(b)}},margin:{get:function(){return l},set:function(a){l.top=void 0!==a.top?a.top:l.top,l.right=void 0!==a.right?a.right:l.right,l.bottom=void 0!==a.bottom?a.bottom:l.bottom,l.left=void 0!==a.left?a.left:l.left}},duration:{get:function(){return C},set:function(a){C=a,F.reset(C),e.duration(C),f.duration(C),g.duration(C)}},color:{get:function(){return o},set:function(b){o=a.utils.getColor(b),h.color(o),e.color(o)}},rightAlignYAxis:{get:function(){return t},set:function(a){t=a,g.orient(t?"right":"left")}},useInteractiveGuideline:{get:function(){return u},set:function(a){u=!!a,b.interactive(!a),b.useVoronoi(!a),e.scatter.interactive(!a)}}}),a.utils.inheritOptions(b,e),a.utils.initOptions(b),b},a.models.sunburst=function(){"use strict";function b(u){return t.reset(),u.each(function(b){function t(a){a.x0=a.x,a.dx0=a.dx}function u(a){var b=d3.interpolate(p.domain(),[a.x,a.x+a.dx]),c=d3.interpolate(q.domain(),[a.y,1]),d=d3.interpolate(q.range(),[a.y?20:0,y]);return function(a,e){return e?function(){return s(a)}:function(e){return p.domain(b(e)),q.domain(c(e)).range(d(e)),s(a)}}}l=d3.select(this);var v,w=a.utils.availableWidth(g,l,f),x=a.utils.availableHeight(h,l,f),y=Math.min(w,x)/2;a.utils.initSVG(l);var z=l.selectAll(".nv-wrap.nv-sunburst").data(b),A=z.enter().append("g").attr("class","nvd3 nv-wrap nv-sunburst nv-chart-"+k),B=A.selectAll("nv-sunburst");z.attr("transform","translate("+w/2+","+x/2+")"),l.on("click",function(a,b){o.chartClick({data:a,index:b,pos:d3.event,id:k})}),q.range([0,y]),c=c||b,e=b[0],r.value(j[i]||j.count),v=B.data(r.nodes).enter().append("path").attr("d",s).style("fill",function(a){return m((a.children?a:a.parent).name)}).style("stroke","#FFF").on("click",function(a){d!==c&&c!==a&&(d=c),c=a,v.transition().duration(n).attrTween("d",u(a))}).each(t).on("dblclick",function(a){d.parent==a&&v.transition().duration(n).attrTween("d",u(e))}).each(t).on("mouseover",function(a){d3.select(this).classed("hover",!0).style("opacity",.8),o.elementMouseover({data:a,color:d3.select(this).style("fill")})}).on("mouseout",function(a){d3.select(this).classed("hover",!1).style("opacity",1),o.elementMouseout({data:a})}).on("mousemove",function(a){o.elementMousemove({data:a})})}),t.renderEnd("sunburst immediate"),b}var c,d,e,f={top:0,right:0,bottom:0,left:0},g=null,h=null,i="count",j={count:function(){return 1},size:function(a){return a.size}},k=Math.floor(1e4*Math.random()),l=null,m=a.utils.defaultColor(),n=500,o=d3.dispatch("chartClick","elementClick","elementDblClick","elementMousemove","elementMouseover","elementMouseout","renderEnd"),p=d3.scale.linear().range([0,2*Math.PI]),q=d3.scale.sqrt(),r=d3.layout.partition().sort(null).value(function(){return 1}),s=d3.svg.arc().startAngle(function(a){return Math.max(0,Math.min(2*Math.PI,p(a.x)))}).endAngle(function(a){return Math.max(0,Math.min(2*Math.PI,p(a.x+a.dx)))}).innerRadius(function(a){return Math.max(0,q(a.y))}).outerRadius(function(a){return Math.max(0,q(a.y+a.dy))}),t=a.utils.renderWatch(o);return b.dispatch=o,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return g},set:function(a){g=a}},height:{get:function(){return h},set:function(a){h=a}},mode:{get:function(){return i},set:function(a){i=a}},id:{get:function(){return k},set:function(a){k=a}},duration:{get:function(){return n},set:function(a){n=a}},margin:{get:function(){return f},set:function(a){f.top=void 0!=a.top?a.top:f.top,f.right=void 0!=a.right?a.right:f.right,f.bottom=void 0!=a.bottom?a.bottom:f.bottom,f.left=void 0!=a.left?a.left:f.left}},color:{get:function(){return m},set:function(b){m=a.utils.getColor(b)}}}),a.utils.initOptions(b),b},a.models.sunburstChart=function(){"use strict";function b(d){return m.reset(),m.models(c),d.each(function(d){var h=d3.select(this);a.utils.initSVG(h);var i=a.utils.availableWidth(f,h,e),j=a.utils.availableHeight(g,h,e);if(b.update=function(){0===k?h.call(b):h.transition().duration(k).call(b)},b.container=this,!d||!d.length)return a.utils.noData(b,h),b;h.selectAll(".nv-noData").remove();var l=h.selectAll("g.nv-wrap.nv-sunburstChart").data(d),m=l.enter().append("g").attr("class","nvd3 nv-wrap nv-sunburstChart").append("g"),n=l.select("g");m.append("g").attr("class","nv-sunburstWrap"),l.attr("transform","translate("+e.left+","+e.top+")"),c.width(i).height(j);var o=n.select(".nv-sunburstWrap").datum(d);d3.transition(o).call(c)}),m.renderEnd("sunburstChart immediate"),b}var c=a.models.sunburst(),d=a.models.tooltip(),e={top:30,right:20,bottom:20,left:20},f=null,g=null,h=a.utils.defaultColor(),i=(Math.round(1e5*Math.random()),null),j=null,k=250,l=d3.dispatch("tooltipShow","tooltipHide","stateChange","changeState","renderEnd"),m=a.utils.renderWatch(l);return d.headerEnabled(!1).duration(0).valueFormatter(function(a){return a}),c.dispatch.on("elementMouseover.tooltip",function(a){a.series={key:a.data.name,value:a.data.size,color:a.color},d.data(a).hidden(!1)}),c.dispatch.on("elementMouseout.tooltip",function(){d.hidden(!0)}),c.dispatch.on("elementMousemove.tooltip",function(){d.position({top:d3.event.pageY,left:d3.event.pageX})()}),b.dispatch=l,b.sunburst=c,b.tooltip=d,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{noData:{get:function(){return j},set:function(a){j=a}},defaultState:{get:function(){return i},set:function(a){i=a}},color:{get:function(){return h},set:function(a){h=a,c.color(h)}},duration:{get:function(){return k},set:function(a){k=a,m.reset(k),c.duration(k)}},margin:{get:function(){return e},set:function(a){e.top=void 0!==a.top?a.top:e.top,e.right=void 0!==a.right?a.right:e.right,e.bottom=void 0!==a.bottom?a.bottom:e.bottom,e.left=void 0!==a.left?a.left:e.left}}}),a.utils.inheritOptions(b,c),a.utils.initOptions(b),b},a.version="1.8.1"}();/*
33853 Copyright (C) Federico Zivolo 2020
33854 Distributed under the MIT License (license terms are at http://opensource.org/licenses/MIT).
33855 */(function(e,t){'object'==typeof exports&&'undefined'!=typeof module?module.exports=t():'function'==typeof define&&define.amd?define(t):e.Popper=t()})(this,function(){'use strict';function e(e){return e&&'[object Function]'==={}.toString.call(e)}function t(e,t){if(1!==e.nodeType)return[];var o=e.ownerDocument.defaultView,n=o.getComputedStyle(e,null);return t?n[t]:n}function o(e){return'HTML'===e.nodeName?e:e.parentNode||e.host}function n(e){if(!e)return document.body;switch(e.nodeName){case'HTML':case'BODY':return e.ownerDocument.body;case'#document':return e.body;}var i=t(e),r=i.overflow,p=i.overflowX,s=i.overflowY;return /(auto|scroll|overlay)/.test(r+s+p)?e:n(o(e))}function i(e){return e&&e.referenceNode?e.referenceNode:e}function r(e){return 11===e?re:10===e?pe:re||pe}function p(e){if(!e)return document.documentElement;for(var o=r(10)?document.body:null,n=e.offsetParent||null;n===o&&e.nextElementSibling;)n=(e=e.nextElementSibling).offsetParent;var i=n&&n.nodeName;return i&&'BODY'!==i&&'HTML'!==i?-1!==['TH','TD','TABLE'].indexOf(n.nodeName)&&'static'===t(n,'position')?p(n):n:e?e.ownerDocument.documentElement:document.documentElement}function s(e){var t=e.nodeName;return'BODY'!==t&&('HTML'===t||p(e.firstElementChild)===e)}function d(e){return null===e.parentNode?e:d(e.parentNode)}function a(e,t){if(!e||!e.nodeType||!t||!t.nodeType)return document.documentElement;var o=e.compareDocumentPosition(t)&Node.DOCUMENT_POSITION_FOLLOWING,n=o?e:t,i=o?t:e,r=document.createRange();r.setStart(n,0),r.setEnd(i,0);var l=r.commonAncestorContainer;if(e!==l&&t!==l||n.contains(i))return s(l)?l:p(l);var f=d(e);return f.host?a(f.host,t):a(e,d(t).host)}function l(e){var t=1<arguments.length&&void 0!==arguments[1]?arguments[1]:'top',o='top'===t?'scrollTop':'scrollLeft',n=e.nodeName;if('BODY'===n||'HTML'===n){var i=e.ownerDocument.documentElement,r=e.ownerDocument.scrollingElement||i;return r[o]}return e[o]}function f(e,t){var o=2<arguments.length&&void 0!==arguments[2]&&arguments[2],n=l(t,'top'),i=l(t,'left'),r=o?-1:1;return e.top+=n*r,e.bottom+=n*r,e.left+=i*r,e.right+=i*r,e}function m(e,t){var o='x'===t?'Left':'Top',n='Left'==o?'Right':'Bottom';return parseFloat(e['border'+o+'Width'])+parseFloat(e['border'+n+'Width'])}function h(e,t,o,n){return ee(t['offset'+e],t['scroll'+e],o['client'+e],o['offset'+e],o['scroll'+e],r(10)?parseInt(o['offset'+e])+parseInt(n['margin'+('Height'===e?'Top':'Left')])+parseInt(n['margin'+('Height'===e?'Bottom':'Right')]):0)}function c(e){var t=e.body,o=e.documentElement,n=r(10)&&getComputedStyle(o);return{height:h('Height',t,o,n),width:h('Width',t,o,n)}}function g(e){return le({},e,{right:e.left+e.width,bottom:e.top+e.height})}function u(e){var o={};try{if(r(10)){o=e.getBoundingClientRect();var n=l(e,'top'),i=l(e,'left');o.top+=n,o.left+=i,o.bottom+=n,o.right+=i}else o=e.getBoundingClientRect()}catch(t){}var p={left:o.left,top:o.top,width:o.right-o.left,height:o.bottom-o.top},s='HTML'===e.nodeName?c(e.ownerDocument):{},d=s.width||e.clientWidth||p.width,a=s.height||e.clientHeight||p.height,f=e.offsetWidth-d,h=e.offsetHeight-a;if(f||h){var u=t(e);f-=m(u,'x'),h-=m(u,'y'),p.width-=f,p.height-=h}return g(p)}function b(e,o){var i=2<arguments.length&&void 0!==arguments[2]&&arguments[2],p=r(10),s='HTML'===o.nodeName,d=u(e),a=u(o),l=n(e),m=t(o),h=parseFloat(m.borderTopWidth),c=parseFloat(m.borderLeftWidth);i&&s&&(a.top=ee(a.top,0),a.left=ee(a.left,0));var b=g({top:d.top-a.top-h,left:d.left-a.left-c,width:d.width,height:d.height});if(b.marginTop=0,b.marginLeft=0,!p&&s){var w=parseFloat(m.marginTop),y=parseFloat(m.marginLeft);b.top-=h-w,b.bottom-=h-w,b.left-=c-y,b.right-=c-y,b.marginTop=w,b.marginLeft=y}return(p&&!i?o.contains(l):o===l&&'BODY'!==l.nodeName)&&(b=f(b,o)),b}function w(e){var t=1<arguments.length&&void 0!==arguments[1]&&arguments[1],o=e.ownerDocument.documentElement,n=b(e,o),i=ee(o.clientWidth,window.innerWidth||0),r=ee(o.clientHeight,window.innerHeight||0),p=t?0:l(o),s=t?0:l(o,'left'),d={top:p-n.top+n.marginTop,left:s-n.left+n.marginLeft,width:i,height:r};return g(d)}function y(e){var n=e.nodeName;if('BODY'===n||'HTML'===n)return!1;if('fixed'===t(e,'position'))return!0;var i=o(e);return!!i&&y(i)}function E(e){if(!e||!e.parentElement||r())return document.documentElement;for(var o=e.parentElement;o&&'none'===t(o,'transform');)o=o.parentElement;return o||document.documentElement}function v(e,t,r,p){var s=4<arguments.length&&void 0!==arguments[4]&&arguments[4],d={top:0,left:0},l=s?E(e):a(e,i(t));if('viewport'===p)d=w(l,s);else{var f;'scrollParent'===p?(f=n(o(t)),'BODY'===f.nodeName&&(f=e.ownerDocument.documentElement)):'window'===p?f=e.ownerDocument.documentElement:f=p;var m=b(f,l,s);if('HTML'===f.nodeName&&!y(l)){var h=c(e.ownerDocument),g=h.height,u=h.width;d.top+=m.top-m.marginTop,d.bottom=g+m.top,d.left+=m.left-m.marginLeft,d.right=u+m.left}else d=m}r=r||0;var v='number'==typeof r;return d.left+=v?r:r.left||0,d.top+=v?r:r.top||0,d.right-=v?r:r.right||0,d.bottom-=v?r:r.bottom||0,d}function x(e){var t=e.width,o=e.height;return t*o}function O(e,t,o,n,i){var r=5<arguments.length&&void 0!==arguments[5]?arguments[5]:0;if(-1===e.indexOf('auto'))return e;var p=v(o,n,r,i),s={top:{width:p.width,height:t.top-p.top},right:{width:p.right-t.right,height:p.height},bottom:{width:p.width,height:p.bottom-t.bottom},left:{width:t.left-p.left,height:p.height}},d=Object.keys(s).map(function(e){return le({key:e},s[e],{area:x(s[e])})}).sort(function(e,t){return t.area-e.area}),a=d.filter(function(e){var t=e.width,n=e.height;return t>=o.clientWidth&&n>=o.clientHeight}),l=0<a.length?a[0].key:d[0].key,f=e.split('-')[1];return l+(f?'-'+f:'')}function L(e,t,o){var n=3<arguments.length&&void 0!==arguments[3]?arguments[3]:null,r=n?E(t):a(t,i(o));return b(o,r,n)}function S(e){var t=e.ownerDocument.defaultView,o=t.getComputedStyle(e),n=parseFloat(o.marginTop||0)+parseFloat(o.marginBottom||0),i=parseFloat(o.marginLeft||0)+parseFloat(o.marginRight||0),r={width:e.offsetWidth+i,height:e.offsetHeight+n};return r}function T(e){var t={left:'right',right:'left',bottom:'top',top:'bottom'};return e.replace(/left|right|bottom|top/g,function(e){return t[e]})}function C(e,t,o){o=o.split('-')[0];var n=S(e),i={width:n.width,height:n.height},r=-1!==['right','left'].indexOf(o),p=r?'top':'left',s=r?'left':'top',d=r?'height':'width',a=r?'width':'height';return i[p]=t[p]+t[d]/2-n[d]/2,i[s]=o===s?t[s]-n[a]:t[T(s)],i}function D(e,t){return Array.prototype.find?e.find(t):e.filter(t)[0]}function N(e,t,o){if(Array.prototype.findIndex)return e.findIndex(function(e){return e[t]===o});var n=D(e,function(e){return e[t]===o});return e.indexOf(n)}function P(t,o,n){var i=void 0===n?t:t.slice(0,N(t,'name',n));return i.forEach(function(t){t['function']&&console.warn('`modifier.function` is deprecated, use `modifier.fn`!');var n=t['function']||t.fn;t.enabled&&e(n)&&(o.offsets.popper=g(o.offsets.popper),o.offsets.reference=g(o.offsets.reference),o=n(o,t))}),o}function k(){if(!this.state.isDestroyed){var e={instance:this,styles:{},arrowStyles:{},attributes:{},flipped:!1,offsets:{}};e.offsets.reference=L(this.state,this.popper,this.reference,this.options.positionFixed),e.placement=O(this.options.placement,e.offsets.reference,this.popper,this.reference,this.options.modifiers.flip.boundariesElement,this.options.modifiers.flip.padding),e.originalPlacement=e.placement,e.positionFixed=this.options.positionFixed,e.offsets.popper=C(this.popper,e.offsets.reference,e.placement),e.offsets.popper.position=this.options.positionFixed?'fixed':'absolute',e=P(this.modifiers,e),this.state.isCreated?this.options.onUpdate(e):(this.state.isCreated=!0,this.options.onCreate(e))}}function W(e,t){return e.some(function(e){var o=e.name,n=e.enabled;return n&&o===t})}function B(e){for(var t=[!1,'ms','Webkit','Moz','O'],o=e.charAt(0).toUpperCase()+e.slice(1),n=0;n<t.length;n++){var i=t[n],r=i?''+i+o:e;if('undefined'!=typeof document.body.style[r])return r}return null}function H(){return this.state.isDestroyed=!0,W(this.modifiers,'applyStyle')&&(this.popper.removeAttribute('x-placement'),this.popper.style.position='',this.popper.style.top='',this.popper.style.left='',this.popper.style.right='',this.popper.style.bottom='',this.popper.style.willChange='',this.popper.style[B('transform')]=''),this.disableEventListeners(),this.options.removeOnDestroy&&this.popper.parentNode.removeChild(this.popper),this}function A(e){var t=e.ownerDocument;return t?t.defaultView:window}function M(e,t,o,i){var r='BODY'===e.nodeName,p=r?e.ownerDocument.defaultView:e;p.addEventListener(t,o,{passive:!0}),r||M(n(p.parentNode),t,o,i),i.push(p)}function F(e,t,o,i){o.updateBound=i,A(e).addEventListener('resize',o.updateBound,{passive:!0});var r=n(e);return M(r,'scroll',o.updateBound,o.scrollParents),o.scrollElement=r,o.eventsEnabled=!0,o}function I(){this.state.eventsEnabled||(this.state=F(this.reference,this.options,this.state,this.scheduleUpdate))}function R(e,t){return A(e).removeEventListener('resize',t.updateBound),t.scrollParents.forEach(function(e){e.removeEventListener('scroll',t.updateBound)}),t.updateBound=null,t.scrollParents=[],t.scrollElement=null,t.eventsEnabled=!1,t}function U(){this.state.eventsEnabled&&(cancelAnimationFrame(this.scheduleUpdate),this.state=R(this.reference,this.state))}function Y(e){return''!==e&&!isNaN(parseFloat(e))&&isFinite(e)}function V(e,t){Object.keys(t).forEach(function(o){var n='';-1!==['width','height','top','right','bottom','left'].indexOf(o)&&Y(t[o])&&(n='px'),e.style[o]=t[o]+n})}function j(e,t){Object.keys(t).forEach(function(o){var n=t[o];!1===n?e.removeAttribute(o):e.setAttribute(o,t[o])})}function q(e,t){var o=e.offsets,n=o.popper,i=o.reference,r=$,p=function(e){return e},s=r(i.width),d=r(n.width),a=-1!==['left','right'].indexOf(e.placement),l=-1!==e.placement.indexOf('-'),f=t?a||l||s%2==d%2?r:Z:p,m=t?r:p;return{left:f(1==s%2&&1==d%2&&!l&&t?n.left-1:n.left),top:m(n.top),bottom:m(n.bottom),right:f(n.right)}}function K(e,t,o){var n=D(e,function(e){var o=e.name;return o===t}),i=!!n&&e.some(function(e){return e.name===o&&e.enabled&&e.order<n.order});if(!i){var r='`'+t+'`';console.warn('`'+o+'`'+' modifier is required by '+r+' modifier in order to work, be sure to include it before '+r+'!')}return i}function z(e){return'end'===e?'start':'start'===e?'end':e}function G(e){var t=1<arguments.length&&void 0!==arguments[1]&&arguments[1],o=he.indexOf(e),n=he.slice(o+1).concat(he.slice(0,o));return t?n.reverse():n}function _(e,t,o,n){var i=e.match(/((?:\-|\+)?\d*\.?\d*)(.*)/),r=+i[1],p=i[2];if(!r)return e;if(0===p.indexOf('%')){var s;switch(p){case'%p':s=o;break;case'%':case'%r':default:s=n;}var d=g(s);return d[t]/100*r}if('vh'===p||'vw'===p){var a;return a='vh'===p?ee(document.documentElement.clientHeight,window.innerHeight||0):ee(document.documentElement.clientWidth,window.innerWidth||0),a/100*r}return r}function X(e,t,o,n){var i=[0,0],r=-1!==['right','left'].indexOf(n),p=e.split(/(\+|\-)/).map(function(e){return e.trim()}),s=p.indexOf(D(p,function(e){return-1!==e.search(/,|\s/)}));p[s]&&-1===p[s].indexOf(',')&&console.warn('Offsets separated by white space(s) are deprecated, use a comma (,) instead.');var d=/\s*,\s*|\s+/,a=-1===s?[p]:[p.slice(0,s).concat([p[s].split(d)[0]]),[p[s].split(d)[1]].concat(p.slice(s+1))];return a=a.map(function(e,n){var i=(1===n?!r:r)?'height':'width',p=!1;return e.reduce(function(e,t){return''===e[e.length-1]&&-1!==['+','-'].indexOf(t)?(e[e.length-1]=t,p=!0,e):p?(e[e.length-1]+=t,p=!1,e):e.concat(t)},[]).map(function(e){return _(e,i,t,o)})}),a.forEach(function(e,t){e.forEach(function(o,n){Y(o)&&(i[t]+=o*('-'===e[n-1]?-1:1))})}),i}function J(e,t){var o,n=t.offset,i=e.placement,r=e.offsets,p=r.popper,s=r.reference,d=i.split('-')[0];return o=Y(+n)?[+n,0]:X(n,p,s,d),'left'===d?(p.top+=o[0],p.left-=o[1]):'right'===d?(p.top+=o[0],p.left+=o[1]):'top'===d?(p.left+=o[0],p.top-=o[1]):'bottom'===d&&(p.left+=o[0],p.top+=o[1]),e.popper=p,e}var Q=Math.min,Z=Math.floor,$=Math.round,ee=Math.max,te='undefined'!=typeof window&&'undefined'!=typeof document&&'undefined'!=typeof navigator,oe=function(){for(var e=['Edge','Trident','Firefox'],t=0;t<e.length;t+=1)if(te&&0<=navigator.userAgent.indexOf(e[t]))return 1;return 0}(),ne=te&&window.Promise,ie=ne?function(e){var t=!1;return function(){t||(t=!0,window.Promise.resolve().then(function(){t=!1,e()}))}}:function(e){var t=!1;return function(){t||(t=!0,setTimeout(function(){t=!1,e()},oe))}},re=te&&!!(window.MSInputMethodContext&&document.documentMode),pe=te&&/MSIE 10/.test(navigator.userAgent),se=function(e,t){if(!(e instanceof t))throw new TypeError('Cannot call a class as a function')},de=function(){function e(e,t){for(var o,n=0;n<t.length;n++)o=t[n],o.enumerable=o.enumerable||!1,o.configurable=!0,'value'in o&&(o.writable=!0),Object.defineProperty(e,o.key,o)}return function(t,o,n){return o&&e(t.prototype,o),n&&e(t,n),t}}(),ae=function(e,t,o){return t in e?Object.defineProperty(e,t,{value:o,enumerable:!0,configurable:!0,writable:!0}):e[t]=o,e},le=Object.assign||function(e){for(var t,o=1;o<arguments.length;o++)for(var n in t=arguments[o],t)Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n]);return e},fe=te&&/Firefox/i.test(navigator.userAgent),me=['auto-start','auto','auto-end','top-start','top','top-end','right-start','right','right-end','bottom-end','bottom','bottom-start','left-end','left','left-start'],he=me.slice(3),ce={FLIP:'flip',CLOCKWISE:'clockwise',COUNTERCLOCKWISE:'counterclockwise'},ge=function(){function t(o,n){var i=this,r=2<arguments.length&&void 0!==arguments[2]?arguments[2]:{};se(this,t),this.scheduleUpdate=function(){return requestAnimationFrame(i.update)},this.update=ie(this.update.bind(this)),this.options=le({},t.Defaults,r),this.state={isDestroyed:!1,isCreated:!1,scrollParents:[]},this.reference=o&&o.jquery?o[0]:o,this.popper=n&&n.jquery?n[0]:n,this.options.modifiers={},Object.keys(le({},t.Defaults.modifiers,r.modifiers)).forEach(function(e){i.options.modifiers[e]=le({},t.Defaults.modifiers[e]||{},r.modifiers?r.modifiers[e]:{})}),this.modifiers=Object.keys(this.options.modifiers).map(function(e){return le({name:e},i.options.modifiers[e])}).sort(function(e,t){return e.order-t.order}),this.modifiers.forEach(function(t){t.enabled&&e(t.onLoad)&&t.onLoad(i.reference,i.popper,i.options,t,i.state)}),this.update();var p=this.options.eventsEnabled;p&&this.enableEventListeners(),this.state.eventsEnabled=p}return de(t,[{key:'update',value:function(){return k.call(this)}},{key:'destroy',value:function(){return H.call(this)}},{key:'enableEventListeners',value:function(){return I.call(this)}},{key:'disableEventListeners',value:function(){return U.call(this)}}]),t}();return ge.Utils=('undefined'==typeof window?global:window).PopperUtils,ge.placements=me,ge.Defaults={placement:'bottom',positionFixed:!1,eventsEnabled:!0,removeOnDestroy:!1,onCreate:function(){},onUpdate:function(){},modifiers:{shift:{order:100,enabled:!0,fn:function(e){var t=e.placement,o=t.split('-')[0],n=t.split('-')[1];if(n){var i=e.offsets,r=i.reference,p=i.popper,s=-1!==['bottom','top'].indexOf(o),d=s?'left':'top',a=s?'width':'height',l={start:ae({},d,r[d]),end:ae({},d,r[d]+r[a]-p[a])};e.offsets.popper=le({},p,l[n])}return e}},offset:{order:200,enabled:!0,fn:J,offset:0},preventOverflow:{order:300,enabled:!0,fn:function(e,t){var o=t.boundariesElement||p(e.instance.popper);e.instance.reference===o&&(o=p(o));var n=B('transform'),i=e.instance.popper.style,r=i.top,s=i.left,d=i[n];i.top='',i.left='',i[n]='';var a=v(e.instance.popper,e.instance.reference,t.padding,o,e.positionFixed);i.top=r,i.left=s,i[n]=d,t.boundaries=a;var l=t.priority,f=e.offsets.popper,m={primary:function(e){var o=f[e];return f[e]<a[e]&&!t.escapeWithReference&&(o=ee(f[e],a[e])),ae({},e,o)},secondary:function(e){var o='right'===e?'left':'top',n=f[o];return f[e]>a[e]&&!t.escapeWithReference&&(n=Q(f[o],a[e]-('right'===e?f.width:f.height))),ae({},o,n)}};return l.forEach(function(e){var t=-1===['left','top'].indexOf(e)?'secondary':'primary';f=le({},f,m[t](e))}),e.offsets.popper=f,e},priority:['left','right','top','bottom'],padding:5,boundariesElement:'scrollParent'},keepTogether:{order:400,enabled:!0,fn:function(e){var t=e.offsets,o=t.popper,n=t.reference,i=e.placement.split('-')[0],r=Z,p=-1!==['top','bottom'].indexOf(i),s=p?'right':'bottom',d=p?'left':'top',a=p?'width':'height';return o[s]<r(n[d])&&(e.offsets.popper[d]=r(n[d])-o[a]),o[d]>r(n[s])&&(e.offsets.popper[d]=r(n[s])),e}},arrow:{order:500,enabled:!0,fn:function(e,o){var n;if(!K(e.instance.modifiers,'arrow','keepTogether'))return e;var i=o.element;if('string'==typeof i){if(i=e.instance.popper.querySelector(i),!i)return e;}else if(!e.instance.popper.contains(i))return console.warn('WARNING: `arrow.element` must be child of its popper element!'),e;var r=e.placement.split('-')[0],p=e.offsets,s=p.popper,d=p.reference,a=-1!==['left','right'].indexOf(r),l=a?'height':'width',f=a?'Top':'Left',m=f.toLowerCase(),h=a?'left':'top',c=a?'bottom':'right',u=S(i)[l];d[c]-u<s[m]&&(e.offsets.popper[m]-=s[m]-(d[c]-u)),d[m]+u>s[c]&&(e.offsets.popper[m]+=d[m]+u-s[c]),e.offsets.popper=g(e.offsets.popper);var b=d[m]+d[l]/2-u/2,w=t(e.instance.popper),y=parseFloat(w['margin'+f]),E=parseFloat(w['border'+f+'Width']),v=b-e.offsets.popper[m]-y-E;return v=ee(Q(s[l]-u,v),0),e.arrowElement=i,e.offsets.arrow=(n={},ae(n,m,$(v)),ae(n,h,''),n),e},element:'[x-arrow]'},flip:{order:600,enabled:!0,fn:function(e,t){if(W(e.instance.modifiers,'inner'))return e;if(e.flipped&&e.placement===e.originalPlacement)return e;var o=v(e.instance.popper,e.instance.reference,t.padding,t.boundariesElement,e.positionFixed),n=e.placement.split('-')[0],i=T(n),r=e.placement.split('-')[1]||'',p=[];switch(t.behavior){case ce.FLIP:p=[n,i];break;case ce.CLOCKWISE:p=G(n);break;case ce.COUNTERCLOCKWISE:p=G(n,!0);break;default:p=t.behavior;}return p.forEach(function(s,d){if(n!==s||p.length===d+1)return e;n=e.placement.split('-')[0],i=T(n);var a=e.offsets.popper,l=e.offsets.reference,f=Z,m='left'===n&&f(a.right)>f(l.left)||'right'===n&&f(a.left)<f(l.right)||'top'===n&&f(a.bottom)>f(l.top)||'bottom'===n&&f(a.top)<f(l.bottom),h=f(a.left)<f(o.left),c=f(a.right)>f(o.right),g=f(a.top)<f(o.top),u=f(a.bottom)>f(o.bottom),b='left'===n&&h||'right'===n&&c||'top'===n&&g||'bottom'===n&&u,w=-1!==['top','bottom'].indexOf(n),y=!!t.flipVariations&&(w&&'start'===r&&h||w&&'end'===r&&c||!w&&'start'===r&&g||!w&&'end'===r&&u),E=!!t.flipVariationsByContent&&(w&&'start'===r&&c||w&&'end'===r&&h||!w&&'start'===r&&u||!w&&'end'===r&&g),v=y||E;(m||b||v)&&(e.flipped=!0,(m||b)&&(n=p[d+1]),v&&(r=z(r)),e.placement=n+(r?'-'+r:''),e.offsets.popper=le({},e.offsets.popper,C(e.instance.popper,e.offsets.reference,e.placement)),e=P(e.instance.modifiers,e,'flip'))}),e},behavior:'flip',padding:5,boundariesElement:'viewport',flipVariations:!1,flipVariationsByContent:!1},inner:{order:700,enabled:!1,fn:function(e){var t=e.placement,o=t.split('-')[0],n=e.offsets,i=n.popper,r=n.reference,p=-1!==['left','right'].indexOf(o),s=-1===['top','left'].indexOf(o);return i[p?'left':'top']=r[o]-(s?i[p?'width':'height']:0),e.placement=T(t),e.offsets.popper=g(i),e}},hide:{order:800,enabled:!0,fn:function(e){if(!K(e.instance.modifiers,'hide','preventOverflow'))return e;var t=e.offsets.reference,o=D(e.instance.modifiers,function(e){return'preventOverflow'===e.name}).boundaries;if(t.bottom<o.top||t.left>o.right||t.top>o.bottom||t.right<o.left){if(!0===e.hide)return e;e.hide=!0,e.attributes['x-out-of-boundaries']=''}else{if(!1===e.hide)return e;e.hide=!1,e.attributes['x-out-of-boundaries']=!1}return e}},computeStyle:{order:850,enabled:!0,fn:function(e,t){var o=t.x,n=t.y,i=e.offsets.popper,r=D(e.instance.modifiers,function(e){return'applyStyle'===e.name}).gpuAcceleration;void 0!==r&&console.warn('WARNING: `gpuAcceleration` option moved to `computeStyle` modifier and will not be supported in future versions of Popper.js!');var s,d,a=void 0===r?t.gpuAcceleration:r,l=p(e.instance.popper),f=u(l),m={position:i.position},h=q(e,2>window.devicePixelRatio||!fe),c='bottom'===o?'top':'bottom',g='right'===n?'left':'right',b=B('transform');if(d='bottom'==c?'HTML'===l.nodeName?-l.clientHeight+h.bottom:-f.height+h.bottom:h.top,s='right'==g?'HTML'===l.nodeName?-l.clientWidth+h.right:-f.width+h.right:h.left,a&&b)m[b]='translate3d('+s+'px, '+d+'px, 0)',m[c]=0,m[g]=0,m.willChange='transform';else{var w='bottom'==c?-1:1,y='right'==g?-1:1;m[c]=d*w,m[g]=s*y,m.willChange=c+', '+g}var E={"x-placement":e.placement};return e.attributes=le({},E,e.attributes),e.styles=le({},m,e.styles),e.arrowStyles=le({},e.offsets.arrow,e.arrowStyles),e},gpuAcceleration:!0,x:'bottom',y:'right'},applyStyle:{order:900,enabled:!0,fn:function(e){return V(e.instance.popper,e.styles),j(e.instance.popper,e.attributes),e.arrowElement&&Object.keys(e.arrowStyles).length&&V(e.arrowElement,e.arrowStyles),e},onLoad:function(e,t,o,n,i){var r=L(i,t,e,o.positionFixed),p=O(o.placement,r,t,e,o.modifiers.flip.boundariesElement,o.modifiers.flip.padding);return t.setAttribute('x-placement',p),V(t,{position:o.positionFixed?'fixed':'absolute'}),o},gpuAcceleration:void 0}}},ge});
33856 //# sourceMappingURL=popper.min.js.map
33857 <tr class="{{class}} d-flex"><td {{popover}} class="col-1 text-right"><a id="{{lineNumber}}" href="#{{lineNumber}}">{{lineNumber}}</a></td><td class="col-11 codeLine">{{lineContent}}</td></tr>
33858 <table id="code" class="table table-borderless table-condensed">
33859 <tbody>
33860 {{lines}}
33861 </tbody>
33862 </table>
33863 <tr>
33864 <td class="{{lines_level}}">{{name}}</td>
33865 <td class="{{lines_level}} big">{{lines_bar}}</td>
33866 <td class="{{lines_level}} small"><div align="right">{{lines_executed_percent}}</div></td>
33867 <td class="{{lines_level}} small"><div align="right">{{lines_number}}</div></td>
33868 <td class="{{methods_level}} big">{{methods_bar}}</td>
33869 <td class="{{methods_level}} small"><div align="right">{{methods_tested_percent}}</div></td>
33870 <td class="{{methods_level}} small"><div align="right">{{methods_number}}</div></td>
33871 <td class="{{methods_level}} small">{{crap}}</td>
33872 <td class="{{methods_level}}" colspan="3"></td>
33873 </tr>
33874
33875 <tr>
33876 <td class="{{lines_level}}">{{name}}</td>
33877 <td class="{{lines_level}} big">{{lines_bar}}</td>
33878 <td class="{{lines_level}} small"><div align="right">{{lines_executed_percent}}</div></td>
33879 <td class="{{lines_level}} small"><div align="right">{{lines_number}}</div></td>
33880 <td class="{{branches_level}} big">{{branches_bar}}</td>
33881 <td class="{{branches_level}} small"><div align="right">{{branches_executed_percent}}</div></td>
33882 <td class="{{branches_level}} small"><div align="right">{{branches_number}}</div></td>
33883 <td class="{{paths_level}} big">{{paths_bar}}</td>
33884 <td class="{{paths_level}} small"><div align="right">{{paths_executed_percent}}</div></td>
33885 <td class="{{paths_level}} small"><div align="right">{{paths_number}}</div></td>
33886 <td class="{{methods_level}} big">{{methods_bar}}</td>
33887 <td class="{{methods_level}} small"><div align="right">{{methods_tested_percent}}</div></td>
33888 <td class="{{methods_level}} small"><div align="right">{{methods_number}}</div></td>
33889 <td class="{{methods_level}} small">{{crap}}</td>
33890 <td class="{{methods_level}}" colspan="3"></td>
33891 </tr>
33892
33893 <hr/>
33894 <h4>Paths</h4>
33895 <p>
33896 Below are the source code lines that represent each code path as identified by Xdebug. Please note a path is not
33897 necessarily coterminous with a line, a line may contain multiple paths and therefore show up more than once.
33898 Please also be aware that some paths may include implicit rather than explicit branches, e.g. an <code>if</code> statement
33899 <i>always</i> has an <code>else</code> as part of its logical flow even if you didn't write one.
33900 </p>
33901 {{paths}}
33902 <?php
33903
33904 declare (strict_types=1);
33905 /*
33906 * This file is part of phpunit/php-code-coverage.
33907 *
33908 * (c) Sebastian Bergmann <sebastian@phpunit.de>
33909 *
33910 * For the full copyright and license information, please view the LICENSE
33911 * file that was distributed with this source code.
33912 */
33913 namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\Report;
33914
33915 use function dirname;
33916 use function file_put_contents;
33917 use function serialize;
33918 use function str_contains;
33919 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\CodeCoverage;
33920 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Driver\WriteOperationFailedException;
33921 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Util\Filesystem;
33922 final class PHP
33923 {
33924 public function process(CodeCoverage $coverage, ?string $target = null): string
33925 {
33926 $coverage->clearCache();
33927 $buffer = "<?php\nreturn \\unserialize(<<<'END_OF_COVERAGE_SERIALIZATION'" . \PHP_EOL . serialize($coverage) . \PHP_EOL . 'END_OF_COVERAGE_SERIALIZATION' . \PHP_EOL . ');';
33928 if ($target !== null) {
33929 if (!str_contains($target, '://')) {
33930 Filesystem::createDirectory(dirname($target));
33931 }
33932 if (@file_put_contents($target, $buffer) === \false) {
33933 throw new WriteOperationFailedException($target);
33934 }
33935 }
33936 return $buffer;
33937 }
33938 }
33939 <?php
33940
33941 declare (strict_types=1);
33942 /*
33943 * This file is part of phpunit/php-code-coverage.
33944 *
33945 * (c) Sebastian Bergmann <sebastian@phpunit.de>
33946 *
33947 * For the full copyright and license information, please view the LICENSE
33948 * file that was distributed with this source code.
33949 */
33950 namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\Report;
33951
33952 use const PHP_EOL;
33953 use function array_map;
33954 use function date;
33955 use function ksort;
33956 use function max;
33957 use function sprintf;
33958 use function str_pad;
33959 use function strlen;
33960 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\CodeCoverage;
33961 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Node\File;
33962 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Util\Percentage;
33963 final class Text
33964 {
33965 /**
33966 * @var string
33967 */
33968 private const COLOR_GREEN = "\x1b[30;42m";
33969 /**
33970 * @var string
33971 */
33972 private const COLOR_YELLOW = "\x1b[30;43m";
33973 /**
33974 * @var string
33975 */
33976 private const COLOR_RED = "\x1b[37;41m";
33977 /**
33978 * @var string
33979 */
33980 private const COLOR_HEADER = "\x1b[1;37;40m";
33981 /**
33982 * @var string
33983 */
33984 private const COLOR_RESET = "\x1b[0m";
33985 private readonly Thresholds $thresholds;
33986 private readonly bool $showUncoveredFiles;
33987 private readonly bool $showOnlySummary;
33988 public function __construct(Thresholds $thresholds, bool $showUncoveredFiles = \false, bool $showOnlySummary = \false)
33989 {
33990 $this->thresholds = $thresholds;
33991 $this->showUncoveredFiles = $showUncoveredFiles;
33992 $this->showOnlySummary = $showOnlySummary;
33993 }
33994 public function process(CodeCoverage $coverage, bool $showColors = \false): string
33995 {
33996 $hasBranchCoverage = !empty($coverage->getData(\true)->functionCoverage());
33997 $output = PHP_EOL . PHP_EOL;
33998 $report = $coverage->getReport();
33999 $colors = ['header' => '', 'classes' => '', 'methods' => '', 'lines' => '', 'branches' => '', 'paths' => '', 'reset' => ''];
34000 if ($showColors) {
34001 $colors['classes'] = $this->coverageColor($report->numberOfTestedClassesAndTraits(), $report->numberOfClassesAndTraits());
34002 $colors['methods'] = $this->coverageColor($report->numberOfTestedMethods(), $report->numberOfMethods());
34003 $colors['lines'] = $this->coverageColor($report->numberOfExecutedLines(), $report->numberOfExecutableLines());
34004 $colors['branches'] = $this->coverageColor($report->numberOfExecutedBranches(), $report->numberOfExecutableBranches());
34005 $colors['paths'] = $this->coverageColor($report->numberOfExecutedPaths(), $report->numberOfExecutablePaths());
34006 $colors['reset'] = self::COLOR_RESET;
34007 $colors['header'] = self::COLOR_HEADER;
34008 }
34009 $classes = sprintf(' Classes: %6s (%d/%d)', Percentage::fromFractionAndTotal($report->numberOfTestedClassesAndTraits(), $report->numberOfClassesAndTraits())->asString(), $report->numberOfTestedClassesAndTraits(), $report->numberOfClassesAndTraits());
34010 $methods = sprintf(' Methods: %6s (%d/%d)', Percentage::fromFractionAndTotal($report->numberOfTestedMethods(), $report->numberOfMethods())->asString(), $report->numberOfTestedMethods(), $report->numberOfMethods());
34011 $paths = '';
34012 $branches = '';
34013 if ($hasBranchCoverage) {
34014 $paths = sprintf(' Paths: %6s (%d/%d)', Percentage::fromFractionAndTotal($report->numberOfExecutedPaths(), $report->numberOfExecutablePaths())->asString(), $report->numberOfExecutedPaths(), $report->numberOfExecutablePaths());
34015 $branches = sprintf(' Branches: %6s (%d/%d)', Percentage::fromFractionAndTotal($report->numberOfExecutedBranches(), $report->numberOfExecutableBranches())->asString(), $report->numberOfExecutedBranches(), $report->numberOfExecutableBranches());
34016 }
34017 $lines = sprintf(' Lines: %6s (%d/%d)', Percentage::fromFractionAndTotal($report->numberOfExecutedLines(), $report->numberOfExecutableLines())->asString(), $report->numberOfExecutedLines(), $report->numberOfExecutableLines());
34018 $padding = max(array_map('strlen', [$classes, $methods, $lines]));
34019 if ($this->showOnlySummary) {
34020 $title = 'Code Coverage Report Summary:';
34021 $padding = max($padding, strlen($title));
34022 $output .= $this->format($colors['header'], $padding, $title);
34023 } else {
34024 $date = date(' Y-m-d H:i:s');
34025 $title = 'Code Coverage Report:';
34026 $output .= $this->format($colors['header'], $padding, $title);
34027 $output .= $this->format($colors['header'], $padding, $date);
34028 $output .= $this->format($colors['header'], $padding, '');
34029 $output .= $this->format($colors['header'], $padding, ' Summary:');
34030 }
34031 $output .= $this->format($colors['classes'], $padding, $classes);
34032 $output .= $this->format($colors['methods'], $padding, $methods);
34033 if ($hasBranchCoverage) {
34034 $output .= $this->format($colors['paths'], $padding, $paths);
34035 $output .= $this->format($colors['branches'], $padding, $branches);
34036 }
34037 $output .= $this->format($colors['lines'], $padding, $lines);
34038 if ($this->showOnlySummary) {
34039 return $output . PHP_EOL;
34040 }
34041 $classCoverage = [];
34042 foreach ($report as $item) {
34043 if (!$item instanceof File) {
34044 continue;
34045 }
34046 $classes = $item->classesAndTraits();
34047 foreach ($classes as $className => $class) {
34048 $classExecutableLines = 0;
34049 $classExecutedLines = 0;
34050 $classExecutableBranches = 0;
34051 $classExecutedBranches = 0;
34052 $classExecutablePaths = 0;
34053 $classExecutedPaths = 0;
34054 $coveredMethods = 0;
34055 $classMethods = 0;
34056 foreach ($class['methods'] as $method) {
34057 if ($method['executableLines'] == 0) {
34058 continue;
34059 }
34060 $classMethods++;
34061 $classExecutableLines += $method['executableLines'];
34062 $classExecutedLines += $method['executedLines'];
34063 $classExecutableBranches += $method['executableBranches'];
34064 $classExecutedBranches += $method['executedBranches'];
34065 $classExecutablePaths += $method['executablePaths'];
34066 $classExecutedPaths += $method['executedPaths'];
34067 if ($method['coverage'] == 100) {
34068 $coveredMethods++;
34069 }
34070 }
34071 $classCoverage[$className] = ['namespace' => $class['namespace'], 'className' => $className, 'methodsCovered' => $coveredMethods, 'methodCount' => $classMethods, 'statementsCovered' => $classExecutedLines, 'statementCount' => $classExecutableLines, 'branchesCovered' => $classExecutedBranches, 'branchesCount' => $classExecutableBranches, 'pathsCovered' => $classExecutedPaths, 'pathsCount' => $classExecutablePaths];
34072 }
34073 }
34074 ksort($classCoverage);
34075 $methodColor = '';
34076 $pathsColor = '';
34077 $branchesColor = '';
34078 $linesColor = '';
34079 $resetColor = '';
34080 foreach ($classCoverage as $fullQualifiedPath => $classInfo) {
34081 if ($this->showUncoveredFiles || $classInfo['statementsCovered'] != 0) {
34082 if ($showColors) {
34083 $methodColor = $this->coverageColor($classInfo['methodsCovered'], $classInfo['methodCount']);
34084 $pathsColor = $this->coverageColor($classInfo['pathsCovered'], $classInfo['pathsCount']);
34085 $branchesColor = $this->coverageColor($classInfo['branchesCovered'], $classInfo['branchesCount']);
34086 $linesColor = $this->coverageColor($classInfo['statementsCovered'], $classInfo['statementCount']);
34087 $resetColor = $colors['reset'];
34088 }
34089 $output .= PHP_EOL . $fullQualifiedPath . PHP_EOL . ' ' . $methodColor . 'Methods: ' . $this->printCoverageCounts($classInfo['methodsCovered'], $classInfo['methodCount'], 2) . $resetColor . ' ';
34090 if ($hasBranchCoverage) {
34091 $output .= ' ' . $pathsColor . 'Paths: ' . $this->printCoverageCounts($classInfo['pathsCovered'], $classInfo['pathsCount'], 3) . $resetColor . ' ' . ' ' . $branchesColor . 'Branches: ' . $this->printCoverageCounts($classInfo['branchesCovered'], $classInfo['branchesCount'], 3) . $resetColor . ' ';
34092 }
34093 $output .= ' ' . $linesColor . 'Lines: ' . $this->printCoverageCounts($classInfo['statementsCovered'], $classInfo['statementCount'], 3) . $resetColor;
34094 }
34095 }
34096 return $output . PHP_EOL;
34097 }
34098 private function coverageColor(int $numberOfCoveredElements, int $totalNumberOfElements): string
34099 {
34100 $coverage = Percentage::fromFractionAndTotal($numberOfCoveredElements, $totalNumberOfElements);
34101 if ($coverage->asFloat() >= $this->thresholds->highLowerBound()) {
34102 return self::COLOR_GREEN;
34103 }
34104 if ($coverage->asFloat() > $this->thresholds->lowUpperBound()) {
34105 return self::COLOR_YELLOW;
34106 }
34107 return self::COLOR_RED;
34108 }
34109 private function printCoverageCounts(int $numberOfCoveredElements, int $totalNumberOfElements, int $precision): string
34110 {
34111 $format = '%' . $precision . 's';
34112 return Percentage::fromFractionAndTotal($numberOfCoveredElements, $totalNumberOfElements)->asFixedWidthString() . ' (' . sprintf($format, $numberOfCoveredElements) . '/' . sprintf($format, $totalNumberOfElements) . ')';
34113 }
34114 private function format(string $color, int $padding, false|string $string): string
34115 {
34116 if ($color === '') {
34117 return (string) $string . PHP_EOL;
34118 }
34119 return $color . str_pad((string) $string, $padding) . self::COLOR_RESET . PHP_EOL;
34120 }
34121 }
34122 <?php
34123
34124 declare (strict_types=1);
34125 /*
34126 * This file is part of phpunit/php-code-coverage.
34127 *
34128 * (c) Sebastian Bergmann <sebastian@phpunit.de>
34129 *
34130 * For the full copyright and license information, please view the LICENSE
34131 * file that was distributed with this source code.
34132 */
34133 namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\Report;
34134
34135 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\InvalidArgumentException;
34136 /**
34137 * @psalm-immutable
34138 */
34139 final class Thresholds
34140 {
34141 private readonly int $lowUpperBound;
34142 private readonly int $highLowerBound;
34143 public static function default(): self
34144 {
34145 return new self(50, 90);
34146 }
34147 /**
34148 * @throws InvalidArgumentException
34149 */
34150 public static function from(int $lowUpperBound, int $highLowerBound): self
34151 {
34152 if ($lowUpperBound > $highLowerBound) {
34153 throw new InvalidArgumentException('$lowUpperBound must not be larger than $highLowerBound');
34154 }
34155 return new self($lowUpperBound, $highLowerBound);
34156 }
34157 private function __construct(int $lowUpperBound, int $highLowerBound)
34158 {
34159 $this->lowUpperBound = $lowUpperBound;
34160 $this->highLowerBound = $highLowerBound;
34161 }
34162 public function lowUpperBound(): int
34163 {
34164 return $this->lowUpperBound;
34165 }
34166 public function highLowerBound(): int
34167 {
34168 return $this->highLowerBound;
34169 }
34170 }
34171 <?php
34172
34173 declare (strict_types=1);
34174 /*
34175 * This file is part of phpunit/php-code-coverage.
34176 *
34177 * (c) Sebastian Bergmann <sebastian@phpunit.de>
34178 *
34179 * For the full copyright and license information, please view the LICENSE
34180 * file that was distributed with this source code.
34181 */
34182 namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\Report\Xml;
34183
34184 use function phpversion;
34185 use DateTimeImmutable;
34186 use DOMElement;
34187 use PHPUnitPHAR\SebastianBergmann\Environment\Runtime;
34188 /**
34189 * @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
34190 */
34191 final class BuildInformation
34192 {
34193 private readonly DOMElement $contextNode;
34194 public function __construct(DOMElement $contextNode)
34195 {
34196 $this->contextNode = $contextNode;
34197 }
34198 public function setRuntimeInformation(Runtime $runtime): void
34199 {
34200 $runtimeNode = $this->nodeByName('runtime');
34201 $runtimeNode->setAttribute('name', $runtime->getName());
34202 $runtimeNode->setAttribute('version', $runtime->getVersion());
34203 $runtimeNode->setAttribute('url', $runtime->getVendorUrl());
34204 $driverNode = $this->nodeByName('driver');
34205 if ($runtime->hasXdebug()) {
34206 $driverNode->setAttribute('name', 'xdebug');
34207 $driverNode->setAttribute('version', phpversion('xdebug'));
34208 }
34209 if ($runtime->hasPCOV()) {
34210 $driverNode->setAttribute('name', 'pcov');
34211 $driverNode->setAttribute('version', phpversion('pcov'));
34212 }
34213 }
34214 public function setBuildTime(DateTimeImmutable $date): void
34215 {
34216 $this->contextNode->setAttribute('time', $date->format('D M j G:i:s T Y'));
34217 }
34218 public function setGeneratorVersions(string $phpUnitVersion, string $coverageVersion): void
34219 {
34220 $this->contextNode->setAttribute('phpunit', $phpUnitVersion);
34221 $this->contextNode->setAttribute('coverage', $coverageVersion);
34222 }
34223 private function nodeByName(string $name): DOMElement
34224 {
34225 $node = $this->contextNode->getElementsByTagNameNS('https://schema.phpunit.de/coverage/1.0', $name)->item(0);
34226 if (!$node) {
34227 $node = $this->contextNode->appendChild($this->contextNode->ownerDocument->createElementNS('https://schema.phpunit.de/coverage/1.0', $name));
34228 }
34229 return $node;
34230 }
34231 }
34232 <?php
34233
34234 declare (strict_types=1);
34235 /*
34236 * This file is part of phpunit/php-code-coverage.
34237 *
34238 * (c) Sebastian Bergmann <sebastian@phpunit.de>
34239 *
34240 * For the full copyright and license information, please view the LICENSE
34241 * file that was distributed with this source code.
34242 */
34243 namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\Report\Xml;
34244
34245 use DOMElement;
34246 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\ReportAlreadyFinalizedException;
34247 use XMLWriter;
34248 /**
34249 * @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
34250 */
34251 final class Coverage
34252 {
34253 private readonly XMLWriter $writer;
34254 private readonly DOMElement $contextNode;
34255 private bool $finalized = \false;
34256 public function __construct(DOMElement $context, string $line)
34257 {
34258 $this->contextNode = $context;
34259 $this->writer = new XMLWriter();
34260 $this->writer->openMemory();
34261 $this->writer->startElementNS(null, $context->nodeName, 'https://schema.phpunit.de/coverage/1.0');
34262 $this->writer->writeAttribute('nr', $line);
34263 }
34264 /**
34265 * @throws ReportAlreadyFinalizedException
34266 */
34267 public function addTest(string $test): void
34268 {
34269 if ($this->finalized) {
34270 throw new ReportAlreadyFinalizedException();
34271 }
34272 $this->writer->startElement('covered');
34273 $this->writer->writeAttribute('by', $test);
34274 $this->writer->endElement();
34275 }
34276 public function finalize(): void
34277 {
34278 $this->writer->endElement();
34279 $fragment = $this->contextNode->ownerDocument->createDocumentFragment();
34280 $fragment->appendXML($this->writer->outputMemory());
34281 $this->contextNode->parentNode->replaceChild($fragment, $this->contextNode);
34282 $this->finalized = \true;
34283 }
34284 }
34285 <?php
34286
34287 declare (strict_types=1);
34288 /*
34289 * This file is part of phpunit/php-code-coverage.
34290 *
34291 * (c) Sebastian Bergmann <sebastian@phpunit.de>
34292 *
34293 * For the full copyright and license information, please view the LICENSE
34294 * file that was distributed with this source code.
34295 */
34296 namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\Report\Xml;
34297
34298 /**
34299 * @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
34300 */
34301 final class Directory extends Node
34302 {
34303 }
34304 <?php
34305
34306 declare (strict_types=1);
34307 /*
34308 * This file is part of phpunit/php-code-coverage.
34309 *
34310 * (c) Sebastian Bergmann <sebastian@phpunit.de>
34311 *
34312 * For the full copyright and license information, please view the LICENSE
34313 * file that was distributed with this source code.
34314 */
34315 namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\Report\Xml;
34316
34317 use const DIRECTORY_SEPARATOR;
34318 use const PHP_EOL;
34319 use function count;
34320 use function dirname;
34321 use function file_get_contents;
34322 use function file_put_contents;
34323 use function is_array;
34324 use function is_dir;
34325 use function is_file;
34326 use function is_writable;
34327 use function libxml_clear_errors;
34328 use function libxml_get_errors;
34329 use function libxml_use_internal_errors;
34330 use function sprintf;
34331 use function strlen;
34332 use function substr;
34333 use DateTimeImmutable;
34334 use DOMDocument;
34335 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\CodeCoverage;
34336 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Driver\PathExistsButIsNotDirectoryException;
34337 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Driver\WriteOperationFailedException;
34338 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Node\AbstractNode;
34339 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Node\Directory as DirectoryNode;
34340 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Node\File as FileNode;
34341 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Util\Filesystem as DirectoryUtil;
34342 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Version;
34343 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\XmlException;
34344 use PHPUnitPHAR\SebastianBergmann\Environment\Runtime;
34345 final class Facade
34346 {
34347 private string $target;
34348 private Project $project;
34349 private readonly string $phpUnitVersion;
34350 public function __construct(string $version)
34351 {
34352 $this->phpUnitVersion = $version;
34353 }
34354 /**
34355 * @throws XmlException
34356 */
34357 public function process(CodeCoverage $coverage, string $target): void
34358 {
34359 if (substr($target, -1, 1) !== DIRECTORY_SEPARATOR) {
34360 $target .= DIRECTORY_SEPARATOR;
34361 }
34362 $this->target = $target;
34363 $this->initTargetDirectory($target);
34364 $report = $coverage->getReport();
34365 $this->project = new Project($coverage->getReport()->name());
34366 $this->setBuildInformation();
34367 $this->processTests($coverage->getTests());
34368 $this->processDirectory($report, $this->project);
34369 $this->saveDocument($this->project->asDom(), 'index');
34370 }
34371 private function setBuildInformation(): void
34372 {
34373 $buildNode = $this->project->buildInformation();
34374 $buildNode->setRuntimeInformation(new Runtime());
34375 $buildNode->setBuildTime(new DateTimeImmutable());
34376 $buildNode->setGeneratorVersions($this->phpUnitVersion, Version::id());
34377 }
34378 /**
34379 * @throws PathExistsButIsNotDirectoryException
34380 * @throws WriteOperationFailedException
34381 */
34382 private function initTargetDirectory(string $directory): void
34383 {
34384 if (is_file($directory)) {
34385 if (!is_dir($directory)) {
34386 throw new PathExistsButIsNotDirectoryException($directory);
34387 }
34388 if (!is_writable($directory)) {
34389 throw new WriteOperationFailedException($directory);
34390 }
34391 }
34392 DirectoryUtil::createDirectory($directory);
34393 }
34394 /**
34395 * @throws XmlException
34396 */
34397 private function processDirectory(DirectoryNode $directory, Node $context): void
34398 {
34399 $directoryName = $directory->name();
34400 if ($this->project->projectSourceDirectory() === $directoryName) {
34401 $directoryName = '/';
34402 }
34403 $directoryObject = $context->addDirectory($directoryName);
34404 $this->setTotals($directory, $directoryObject->totals());
34405 foreach ($directory->directories() as $node) {
34406 $this->processDirectory($node, $directoryObject);
34407 }
34408 foreach ($directory->files() as $node) {
34409 $this->processFile($node, $directoryObject);
34410 }
34411 }
34412 /**
34413 * @throws XmlException
34414 */
34415 private function processFile(FileNode $file, Directory $context): void
34416 {
34417 $fileObject = $context->addFile($file->name(), $file->id() . '.xml');
34418 $this->setTotals($file, $fileObject->totals());
34419 $path = substr($file->pathAsString(), strlen($this->project->projectSourceDirectory()));
34420 $fileReport = new Report($path);
34421 $this->setTotals($file, $fileReport->totals());
34422 foreach ($file->classesAndTraits() as $unit) {
34423 $this->processUnit($unit, $fileReport);
34424 }
34425 foreach ($file->functions() as $function) {
34426 $this->processFunction($function, $fileReport);
34427 }
34428 foreach ($file->lineCoverageData() as $line => $tests) {
34429 if (!is_array($tests) || count($tests) === 0) {
34430 continue;
34431 }
34432 $coverage = $fileReport->lineCoverage((string) $line);
34433 foreach ($tests as $test) {
34434 $coverage->addTest($test);
34435 }
34436 $coverage->finalize();
34437 }
34438 $fileReport->source()->setSourceCode(file_get_contents($file->pathAsString()));
34439 $this->saveDocument($fileReport->asDom(), $file->id());
34440 }
34441 private function processUnit(array $unit, Report $report): void
34442 {
34443 if (isset($unit['className'])) {
34444 $unitObject = $report->classObject($unit['className']);
34445 } else {
34446 $unitObject = $report->traitObject($unit['traitName']);
34447 }
34448 $unitObject->setLines($unit['startLine'], $unit['executableLines'], $unit['executedLines']);
34449 $unitObject->setCrap((float) $unit['crap']);
34450 $unitObject->setNamespace($unit['namespace']);
34451 foreach ($unit['methods'] as $method) {
34452 $methodObject = $unitObject->addMethod($method['methodName']);
34453 $methodObject->setSignature($method['signature']);
34454 $methodObject->setLines((string) $method['startLine'], (string) $method['endLine']);
34455 $methodObject->setCrap($method['crap']);
34456 $methodObject->setTotals((string) $method['executableLines'], (string) $method['executedLines'], (string) $method['coverage']);
34457 }
34458 }
34459 private function processFunction(array $function, Report $report): void
34460 {
34461 $functionObject = $report->functionObject($function['functionName']);
34462 $functionObject->setSignature($function['signature']);
34463 $functionObject->setLines((string) $function['startLine']);
34464 $functionObject->setCrap($function['crap']);
34465 $functionObject->setTotals((string) $function['executableLines'], (string) $function['executedLines'], (string) $function['coverage']);
34466 }
34467 private function processTests(array $tests): void
34468 {
34469 $testsObject = $this->project->tests();
34470 foreach ($tests as $test => $result) {
34471 $testsObject->addTest($test, $result);
34472 }
34473 }
34474 private function setTotals(AbstractNode $node, Totals $totals): void
34475 {
34476 $loc = $node->linesOfCode();
34477 $totals->setNumLines($loc['linesOfCode'], $loc['commentLinesOfCode'], $loc['nonCommentLinesOfCode'], $node->numberOfExecutableLines(), $node->numberOfExecutedLines());
34478 $totals->setNumClasses($node->numberOfClasses(), $node->numberOfTestedClasses());
34479 $totals->setNumTraits($node->numberOfTraits(), $node->numberOfTestedTraits());
34480 $totals->setNumMethods($node->numberOfMethods(), $node->numberOfTestedMethods());
34481 $totals->setNumFunctions($node->numberOfFunctions(), $node->numberOfTestedFunctions());
34482 }
34483 private function targetDirectory(): string
34484 {
34485 return $this->target;
34486 }
34487 /**
34488 * @throws XmlException
34489 */
34490 private function saveDocument(DOMDocument $document, string $name): void
34491 {
34492 $filename = sprintf('%s/%s.xml', $this->targetDirectory(), $name);
34493 $document->formatOutput = \true;
34494 $document->preserveWhiteSpace = \false;
34495 $this->initTargetDirectory(dirname($filename));
34496 file_put_contents($filename, $this->documentAsString($document));
34497 }
34498 /**
34499 * @throws XmlException
34500 *
34501 * @see https://bugs.php.net/bug.php?id=79191
34502 */
34503 private function documentAsString(DOMDocument $document): string
34504 {
34505 $xmlErrorHandling = libxml_use_internal_errors(\true);
34506 $xml = $document->saveXML();
34507 if ($xml === \false) {
34508 $message = 'Unable to generate the XML';
34509 foreach (libxml_get_errors() as $error) {
34510 $message .= PHP_EOL . $error->message;
34511 }
34512 throw new XmlException($message);
34513 }
34514 libxml_clear_errors();
34515 libxml_use_internal_errors($xmlErrorHandling);
34516 return $xml;
34517 }
34518 }
34519 <?php
34520
34521 declare (strict_types=1);
34522 /*
34523 * This file is part of phpunit/php-code-coverage.
34524 *
34525 * (c) Sebastian Bergmann <sebastian@phpunit.de>
34526 *
34527 * For the full copyright and license information, please view the LICENSE
34528 * file that was distributed with this source code.
34529 */
34530 namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\Report\Xml;
34531
34532 use DOMDocument;
34533 use DOMElement;
34534 /**
34535 * @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
34536 */
34537 class File
34538 {
34539 private readonly DOMDocument $dom;
34540 private readonly DOMElement $contextNode;
34541 public function __construct(DOMElement $context)
34542 {
34543 $this->dom = $context->ownerDocument;
34544 $this->contextNode = $context;
34545 }
34546 public function totals(): Totals
34547 {
34548 $totalsContainer = $this->contextNode->firstChild;
34549 if (!$totalsContainer) {
34550 $totalsContainer = $this->contextNode->appendChild($this->dom->createElementNS('https://schema.phpunit.de/coverage/1.0', 'totals'));
34551 }
34552 return new Totals($totalsContainer);
34553 }
34554 public function lineCoverage(string $line): Coverage
34555 {
34556 $coverage = $this->contextNode->getElementsByTagNameNS('https://schema.phpunit.de/coverage/1.0', 'coverage')->item(0);
34557 if (!$coverage) {
34558 $coverage = $this->contextNode->appendChild($this->dom->createElementNS('https://schema.phpunit.de/coverage/1.0', 'coverage'));
34559 }
34560 $lineNode = $coverage->appendChild($this->dom->createElementNS('https://schema.phpunit.de/coverage/1.0', 'line'));
34561 return new Coverage($lineNode, $line);
34562 }
34563 protected function contextNode(): DOMElement
34564 {
34565 return $this->contextNode;
34566 }
34567 protected function dom(): DOMDocument
34568 {
34569 return $this->dom;
34570 }
34571 }
34572 <?php
34573
34574 declare (strict_types=1);
34575 /*
34576 * This file is part of phpunit/php-code-coverage.
34577 *
34578 * (c) Sebastian Bergmann <sebastian@phpunit.de>
34579 *
34580 * For the full copyright and license information, please view the LICENSE
34581 * file that was distributed with this source code.
34582 */
34583 namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\Report\Xml;
34584
34585 use DOMElement;
34586 /**
34587 * @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
34588 */
34589 final class Method
34590 {
34591 private readonly DOMElement $contextNode;
34592 public function __construct(DOMElement $context, string $name)
34593 {
34594 $this->contextNode = $context;
34595 $this->setName($name);
34596 }
34597 public function setSignature(string $signature): void
34598 {
34599 $this->contextNode->setAttribute('signature', $signature);
34600 }
34601 public function setLines(string $start, ?string $end = null): void
34602 {
34603 $this->contextNode->setAttribute('start', $start);
34604 if ($end !== null) {
34605 $this->contextNode->setAttribute('end', $end);
34606 }
34607 }
34608 public function setTotals(string $executable, string $executed, string $coverage): void
34609 {
34610 $this->contextNode->setAttribute('executable', $executable);
34611 $this->contextNode->setAttribute('executed', $executed);
34612 $this->contextNode->setAttribute('coverage', $coverage);
34613 }
34614 public function setCrap(string $crap): void
34615 {
34616 $this->contextNode->setAttribute('crap', $crap);
34617 }
34618 private function setName(string $name): void
34619 {
34620 $this->contextNode->setAttribute('name', $name);
34621 }
34622 }
34623 <?php
34624
34625 declare (strict_types=1);
34626 /*
34627 * This file is part of phpunit/php-code-coverage.
34628 *
34629 * (c) Sebastian Bergmann <sebastian@phpunit.de>
34630 *
34631 * For the full copyright and license information, please view the LICENSE
34632 * file that was distributed with this source code.
34633 */
34634 namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\Report\Xml;
34635
34636 use DOMDocument;
34637 use DOMElement;
34638 /**
34639 * @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
34640 */
34641 abstract class Node
34642 {
34643 private DOMDocument $dom;
34644 private DOMElement $contextNode;
34645 public function __construct(DOMElement $context)
34646 {
34647 $this->setContextNode($context);
34648 }
34649 public function dom(): DOMDocument
34650 {
34651 return $this->dom;
34652 }
34653 public function totals(): Totals
34654 {
34655 $totalsContainer = $this->contextNode()->firstChild;
34656 if (!$totalsContainer) {
34657 $totalsContainer = $this->contextNode()->appendChild($this->dom->createElementNS('https://schema.phpunit.de/coverage/1.0', 'totals'));
34658 }
34659 return new Totals($totalsContainer);
34660 }
34661 public function addDirectory(string $name): Directory
34662 {
34663 $dirNode = $this->dom()->createElementNS('https://schema.phpunit.de/coverage/1.0', 'directory');
34664 $dirNode->setAttribute('name', $name);
34665 $this->contextNode()->appendChild($dirNode);
34666 return new Directory($dirNode);
34667 }
34668 public function addFile(string $name, string $href): File
34669 {
34670 $fileNode = $this->dom()->createElementNS('https://schema.phpunit.de/coverage/1.0', 'file');
34671 $fileNode->setAttribute('name', $name);
34672 $fileNode->setAttribute('href', $href);
34673 $this->contextNode()->appendChild($fileNode);
34674 return new File($fileNode);
34675 }
34676 protected function setContextNode(DOMElement $context): void
34677 {
34678 $this->dom = $context->ownerDocument;
34679 $this->contextNode = $context;
34680 }
34681 protected function contextNode(): DOMElement
34682 {
34683 return $this->contextNode;
34684 }
34685 }
34686 <?php
34687
34688 declare (strict_types=1);
34689 /*
34690 * This file is part of phpunit/php-code-coverage.
34691 *
34692 * (c) Sebastian Bergmann <sebastian@phpunit.de>
34693 *
34694 * For the full copyright and license information, please view the LICENSE
34695 * file that was distributed with this source code.
34696 */
34697 namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\Report\Xml;
34698
34699 use DOMDocument;
34700 /**
34701 * @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
34702 */
34703 final class Project extends Node
34704 {
34705 public function __construct(string $directory)
34706 {
34707 $this->init();
34708 $this->setProjectSourceDirectory($directory);
34709 }
34710 public function projectSourceDirectory(): string
34711 {
34712 return $this->contextNode()->getAttribute('source');
34713 }
34714 public function buildInformation(): BuildInformation
34715 {
34716 $buildNode = $this->dom()->getElementsByTagNameNS('https://schema.phpunit.de/coverage/1.0', 'build')->item(0);
34717 if (!$buildNode) {
34718 $buildNode = $this->dom()->documentElement->appendChild($this->dom()->createElementNS('https://schema.phpunit.de/coverage/1.0', 'build'));
34719 }
34720 return new BuildInformation($buildNode);
34721 }
34722 public function tests(): Tests
34723 {
34724 $testsNode = $this->contextNode()->getElementsByTagNameNS('https://schema.phpunit.de/coverage/1.0', 'tests')->item(0);
34725 if (!$testsNode) {
34726 $testsNode = $this->contextNode()->appendChild($this->dom()->createElementNS('https://schema.phpunit.de/coverage/1.0', 'tests'));
34727 }
34728 return new Tests($testsNode);
34729 }
34730 public function asDom(): DOMDocument
34731 {
34732 return $this->dom();
34733 }
34734 private function init(): void
34735 {
34736 $dom = new DOMDocument();
34737 $dom->loadXML('<?xml version="1.0" ?><phpunit xmlns="https://schema.phpunit.de/coverage/1.0"><build/><project/></phpunit>');
34738 $this->setContextNode($dom->getElementsByTagNameNS('https://schema.phpunit.de/coverage/1.0', 'project')->item(0));
34739 }
34740 private function setProjectSourceDirectory(string $name): void
34741 {
34742 $this->contextNode()->setAttribute('source', $name);
34743 }
34744 }
34745 <?php
34746
34747 declare (strict_types=1);
34748 /*
34749 * This file is part of phpunit/php-code-coverage.
34750 *
34751 * (c) Sebastian Bergmann <sebastian@phpunit.de>
34752 *
34753 * For the full copyright and license information, please view the LICENSE
34754 * file that was distributed with this source code.
34755 */
34756 namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\Report\Xml;
34757
34758 use function basename;
34759 use function dirname;
34760 use DOMDocument;
34761 /**
34762 * @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
34763 */
34764 final class Report extends File
34765 {
34766 public function __construct(string $name)
34767 {
34768 $dom = new DOMDocument();
34769 $dom->loadXML('<?xml version="1.0" ?><phpunit xmlns="https://schema.phpunit.de/coverage/1.0"><file /></phpunit>');
34770 $contextNode = $dom->getElementsByTagNameNS('https://schema.phpunit.de/coverage/1.0', 'file')->item(0);
34771 parent::__construct($contextNode);
34772 $this->setName($name);
34773 }
34774 public function asDom(): DOMDocument
34775 {
34776 return $this->dom();
34777 }
34778 public function functionObject($name): Method
34779 {
34780 $node = $this->contextNode()->appendChild($this->dom()->createElementNS('https://schema.phpunit.de/coverage/1.0', 'function'));
34781 return new Method($node, $name);
34782 }
34783 public function classObject($name): Unit
34784 {
34785 return $this->unitObject('class', $name);
34786 }
34787 public function traitObject($name): Unit
34788 {
34789 return $this->unitObject('trait', $name);
34790 }
34791 public function source(): Source
34792 {
34793 $source = $this->contextNode()->getElementsByTagNameNS('https://schema.phpunit.de/coverage/1.0', 'source')->item(0);
34794 if (!$source) {
34795 $source = $this->contextNode()->appendChild($this->dom()->createElementNS('https://schema.phpunit.de/coverage/1.0', 'source'));
34796 }
34797 return new Source($source);
34798 }
34799 private function setName(string $name): void
34800 {
34801 $this->contextNode()->setAttribute('name', basename($name));
34802 $this->contextNode()->setAttribute('path', dirname($name));
34803 }
34804 private function unitObject(string $tagName, $name): Unit
34805 {
34806 $node = $this->contextNode()->appendChild($this->dom()->createElementNS('https://schema.phpunit.de/coverage/1.0', $tagName));
34807 return new Unit($node, $name);
34808 }
34809 }
34810 <?php
34811
34812 declare (strict_types=1);
34813 /*
34814 * This file is part of phpunit/php-code-coverage.
34815 *
34816 * (c) Sebastian Bergmann <sebastian@phpunit.de>
34817 *
34818 * For the full copyright and license information, please view the LICENSE
34819 * file that was distributed with this source code.
34820 */
34821 namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\Report\Xml;
34822
34823 use DOMElement;
34824 use PHPUnitPHAR\TheSeer\Tokenizer\NamespaceUri;
34825 use PHPUnitPHAR\TheSeer\Tokenizer\Tokenizer;
34826 use PHPUnitPHAR\TheSeer\Tokenizer\XMLSerializer;
34827 /**
34828 * @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
34829 */
34830 final class Source
34831 {
34832 private readonly DOMElement $context;
34833 public function __construct(DOMElement $context)
34834 {
34835 $this->context = $context;
34836 }
34837 public function setSourceCode(string $source): void
34838 {
34839 $context = $this->context;
34840 $tokens = (new Tokenizer())->parse($source);
34841 $srcDom = (new XMLSerializer(new NamespaceUri($context->namespaceURI)))->toDom($tokens);
34842 $context->parentNode->replaceChild($context->ownerDocument->importNode($srcDom->documentElement, \true), $context);
34843 }
34844 }
34845 <?php
34846
34847 declare (strict_types=1);
34848 /*
34849 * This file is part of phpunit/php-code-coverage.
34850 *
34851 * (c) Sebastian Bergmann <sebastian@phpunit.de>
34852 *
34853 * For the full copyright and license information, please view the LICENSE
34854 * file that was distributed with this source code.
34855 */
34856 namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\Report\Xml;
34857
34858 use DOMElement;
34859 /**
34860 * @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
34861 *
34862 * @psalm-import-type TestType from \SebastianBergmann\CodeCoverage\CodeCoverage
34863 */
34864 final class Tests
34865 {
34866 private readonly DOMElement $contextNode;
34867 public function __construct(DOMElement $context)
34868 {
34869 $this->contextNode = $context;
34870 }
34871 /**
34872 * @param TestType $result
34873 */
34874 public function addTest(string $test, array $result): void
34875 {
34876 $node = $this->contextNode->appendChild($this->contextNode->ownerDocument->createElementNS('https://schema.phpunit.de/coverage/1.0', 'test'));
34877 $node->setAttribute('name', $test);
34878 $node->setAttribute('size', $result['size']);
34879 $node->setAttribute('status', $result['status']);
34880 }
34881 }
34882 <?php
34883
34884 declare (strict_types=1);
34885 /*
34886 * This file is part of phpunit/php-code-coverage.
34887 *
34888 * (c) Sebastian Bergmann <sebastian@phpunit.de>
34889 *
34890 * For the full copyright and license information, please view the LICENSE
34891 * file that was distributed with this source code.
34892 */
34893 namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\Report\Xml;
34894
34895 use function sprintf;
34896 use DOMElement;
34897 use DOMNode;
34898 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Util\Percentage;
34899 /**
34900 * @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
34901 */
34902 final class Totals
34903 {
34904 private readonly DOMNode $container;
34905 private readonly DOMElement $linesNode;
34906 private readonly DOMElement $methodsNode;
34907 private readonly DOMElement $functionsNode;
34908 private readonly DOMElement $classesNode;
34909 private readonly DOMElement $traitsNode;
34910 public function __construct(DOMElement $container)
34911 {
34912 $this->container = $container;
34913 $dom = $container->ownerDocument;
34914 $this->linesNode = $dom->createElementNS('https://schema.phpunit.de/coverage/1.0', 'lines');
34915 $this->methodsNode = $dom->createElementNS('https://schema.phpunit.de/coverage/1.0', 'methods');
34916 $this->functionsNode = $dom->createElementNS('https://schema.phpunit.de/coverage/1.0', 'functions');
34917 $this->classesNode = $dom->createElementNS('https://schema.phpunit.de/coverage/1.0', 'classes');
34918 $this->traitsNode = $dom->createElementNS('https://schema.phpunit.de/coverage/1.0', 'traits');
34919 $container->appendChild($this->linesNode);
34920 $container->appendChild($this->methodsNode);
34921 $container->appendChild($this->functionsNode);
34922 $container->appendChild($this->classesNode);
34923 $container->appendChild($this->traitsNode);
34924 }
34925 public function container(): DOMNode
34926 {
34927 return $this->container;
34928 }
34929 public function setNumLines(int $loc, int $cloc, int $ncloc, int $executable, int $executed): void
34930 {
34931 $this->linesNode->setAttribute('total', (string) $loc);
34932 $this->linesNode->setAttribute('comments', (string) $cloc);
34933 $this->linesNode->setAttribute('code', (string) $ncloc);
34934 $this->linesNode->setAttribute('executable', (string) $executable);
34935 $this->linesNode->setAttribute('executed', (string) $executed);
34936 $this->linesNode->setAttribute('percent', $executable === 0 ? '0' : sprintf('%01.2F', Percentage::fromFractionAndTotal($executed, $executable)->asFloat()));
34937 }
34938 public function setNumClasses(int $count, int $tested): void
34939 {
34940 $this->classesNode->setAttribute('count', (string) $count);
34941 $this->classesNode->setAttribute('tested', (string) $tested);
34942 $this->classesNode->setAttribute('percent', $count === 0 ? '0' : sprintf('%01.2F', Percentage::fromFractionAndTotal($tested, $count)->asFloat()));
34943 }
34944 public function setNumTraits(int $count, int $tested): void
34945 {
34946 $this->traitsNode->setAttribute('count', (string) $count);
34947 $this->traitsNode->setAttribute('tested', (string) $tested);
34948 $this->traitsNode->setAttribute('percent', $count === 0 ? '0' : sprintf('%01.2F', Percentage::fromFractionAndTotal($tested, $count)->asFloat()));
34949 }
34950 public function setNumMethods(int $count, int $tested): void
34951 {
34952 $this->methodsNode->setAttribute('count', (string) $count);
34953 $this->methodsNode->setAttribute('tested', (string) $tested);
34954 $this->methodsNode->setAttribute('percent', $count === 0 ? '0' : sprintf('%01.2F', Percentage::fromFractionAndTotal($tested, $count)->asFloat()));
34955 }
34956 public function setNumFunctions(int $count, int $tested): void
34957 {
34958 $this->functionsNode->setAttribute('count', (string) $count);
34959 $this->functionsNode->setAttribute('tested', (string) $tested);
34960 $this->functionsNode->setAttribute('percent', $count === 0 ? '0' : sprintf('%01.2F', Percentage::fromFractionAndTotal($tested, $count)->asFloat()));
34961 }
34962 }
34963 <?php
34964
34965 declare (strict_types=1);
34966 /*
34967 * This file is part of phpunit/php-code-coverage.
34968 *
34969 * (c) Sebastian Bergmann <sebastian@phpunit.de>
34970 *
34971 * For the full copyright and license information, please view the LICENSE
34972 * file that was distributed with this source code.
34973 */
34974 namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\Report\Xml;
34975
34976 use DOMElement;
34977 /**
34978 * @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
34979 */
34980 final class Unit
34981 {
34982 private readonly DOMElement $contextNode;
34983 public function __construct(DOMElement $context, string $name)
34984 {
34985 $this->contextNode = $context;
34986 $this->setName($name);
34987 }
34988 public function setLines(int $start, int $executable, int $executed): void
34989 {
34990 $this->contextNode->setAttribute('start', (string) $start);
34991 $this->contextNode->setAttribute('executable', (string) $executable);
34992 $this->contextNode->setAttribute('executed', (string) $executed);
34993 }
34994 public function setCrap(float $crap): void
34995 {
34996 $this->contextNode->setAttribute('crap', (string) $crap);
34997 }
34998 public function setNamespace(string $namespace): void
34999 {
35000 $node = $this->contextNode->getElementsByTagNameNS('https://schema.phpunit.de/coverage/1.0', 'namespace')->item(0);
35001 if (!$node) {
35002 $node = $this->contextNode->appendChild($this->contextNode->ownerDocument->createElementNS('https://schema.phpunit.de/coverage/1.0', 'namespace'));
35003 }
35004 $node->setAttribute('name', $namespace);
35005 }
35006 public function addMethod(string $name): Method
35007 {
35008 $node = $this->contextNode->appendChild($this->contextNode->ownerDocument->createElementNS('https://schema.phpunit.de/coverage/1.0', 'method'));
35009 return new Method($node, $name);
35010 }
35011 private function setName(string $name): void
35012 {
35013 $this->contextNode->setAttribute('name', $name);
35014 }
35015 }
35016 <?php
35017
35018 declare (strict_types=1);
35019 /*
35020 * This file is part of phpunit/php-code-coverage.
35021 *
35022 * (c) Sebastian Bergmann <sebastian@phpunit.de>
35023 *
35024 * For the full copyright and license information, please view the LICENSE
35025 * file that was distributed with this source code.
35026 */
35027 namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\StaticAnalysis;
35028
35029 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Filter;
35030 final class CacheWarmer
35031 {
35032 public function warmCache(string $cacheDirectory, bool $useAnnotationsForIgnoringCode, bool $ignoreDeprecatedCode, Filter $filter): void
35033 {
35034 $analyser = new CachingFileAnalyser($cacheDirectory, new ParsingFileAnalyser($useAnnotationsForIgnoringCode, $ignoreDeprecatedCode), $useAnnotationsForIgnoringCode, $ignoreDeprecatedCode);
35035 foreach ($filter->files() as $file) {
35036 $analyser->process($file);
35037 }
35038 }
35039 }
35040 <?php
35041
35042 declare (strict_types=1);
35043 /*
35044 * This file is part of phpunit/php-code-coverage.
35045 *
35046 * (c) Sebastian Bergmann <sebastian@phpunit.de>
35047 *
35048 * For the full copyright and license information, please view the LICENSE
35049 * file that was distributed with this source code.
35050 */
35051 namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\StaticAnalysis;
35052
35053 use function file_get_contents;
35054 use function file_put_contents;
35055 use function implode;
35056 use function is_file;
35057 use function md5;
35058 use function serialize;
35059 use function unserialize;
35060 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Util\Filesystem;
35061 use PHPUnitPHAR\SebastianBergmann\FileIterator\Facade as FileIteratorFacade;
35062 /**
35063 * @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
35064 *
35065 * @psalm-import-type LinesOfCodeType from \SebastianBergmann\CodeCoverage\StaticAnalysis\FileAnalyser
35066 */
35067 final class CachingFileAnalyser implements FileAnalyser
35068 {
35069 private static ?string $cacheVersion = null;
35070 private readonly string $directory;
35071 private readonly FileAnalyser $analyser;
35072 private readonly bool $useAnnotationsForIgnoringCode;
35073 private readonly bool $ignoreDeprecatedCode;
35074 private array $cache = [];
35075 public function __construct(string $directory, FileAnalyser $analyser, bool $useAnnotationsForIgnoringCode, bool $ignoreDeprecatedCode)
35076 {
35077 Filesystem::createDirectory($directory);
35078 $this->analyser = $analyser;
35079 $this->directory = $directory;
35080 $this->useAnnotationsForIgnoringCode = $useAnnotationsForIgnoringCode;
35081 $this->ignoreDeprecatedCode = $ignoreDeprecatedCode;
35082 }
35083 public function classesIn(string $filename): array
35084 {
35085 if (!isset($this->cache[$filename])) {
35086 $this->process($filename);
35087 }
35088 return $this->cache[$filename]['classesIn'];
35089 }
35090 public function traitsIn(string $filename): array
35091 {
35092 if (!isset($this->cache[$filename])) {
35093 $this->process($filename);
35094 }
35095 return $this->cache[$filename]['traitsIn'];
35096 }
35097 public function functionsIn(string $filename): array
35098 {
35099 if (!isset($this->cache[$filename])) {
35100 $this->process($filename);
35101 }
35102 return $this->cache[$filename]['functionsIn'];
35103 }
35104 /**
35105 * @psalm-return LinesOfCodeType
35106 */
35107 public function linesOfCodeFor(string $filename): array
35108 {
35109 if (!isset($this->cache[$filename])) {
35110 $this->process($filename);
35111 }
35112 return $this->cache[$filename]['linesOfCodeFor'];
35113 }
35114 public function executableLinesIn(string $filename): array
35115 {
35116 if (!isset($this->cache[$filename])) {
35117 $this->process($filename);
35118 }
35119 return $this->cache[$filename]['executableLinesIn'];
35120 }
35121 public function ignoredLinesFor(string $filename): array
35122 {
35123 if (!isset($this->cache[$filename])) {
35124 $this->process($filename);
35125 }
35126 return $this->cache[$filename]['ignoredLinesFor'];
35127 }
35128 public function process(string $filename): void
35129 {
35130 $cache = $this->read($filename);
35131 if ($cache !== \false) {
35132 $this->cache[$filename] = $cache;
35133 return;
35134 }
35135 $this->cache[$filename] = ['classesIn' => $this->analyser->classesIn($filename), 'traitsIn' => $this->analyser->traitsIn($filename), 'functionsIn' => $this->analyser->functionsIn($filename), 'linesOfCodeFor' => $this->analyser->linesOfCodeFor($filename), 'ignoredLinesFor' => $this->analyser->ignoredLinesFor($filename), 'executableLinesIn' => $this->analyser->executableLinesIn($filename)];
35136 $this->write($filename, $this->cache[$filename]);
35137 }
35138 private function read(string $filename): array|false
35139 {
35140 $cacheFile = $this->cacheFile($filename);
35141 if (!is_file($cacheFile)) {
35142 return \false;
35143 }
35144 return unserialize(file_get_contents($cacheFile), ['allowed_classes' => \false]);
35145 }
35146 private function write(string $filename, array $data): void
35147 {
35148 file_put_contents($this->cacheFile($filename), serialize($data));
35149 }
35150 private function cacheFile(string $filename): string
35151 {
35152 $cacheKey = md5(implode("\x00", [$filename, file_get_contents($filename), self::cacheVersion(), $this->useAnnotationsForIgnoringCode, $this->ignoreDeprecatedCode]));
35153 return $this->directory . \DIRECTORY_SEPARATOR . $cacheKey;
35154 }
35155 private static function cacheVersion(): string
35156 {
35157 if (self::$cacheVersion !== null) {
35158 return self::$cacheVersion;
35159 }
35160 $buffer = [];
35161 foreach ((new FileIteratorFacade())->getFilesAsArray(__DIR__, '.php') as $file) {
35162 $buffer[] = $file;
35163 $buffer[] = file_get_contents($file);
35164 }
35165 self::$cacheVersion = md5(implode("\x00", $buffer));
35166 return self::$cacheVersion;
35167 }
35168 }
35169 <?php
35170
35171 declare (strict_types=1);
35172 /*
35173 * This file is part of phpunit/php-code-coverage.
35174 *
35175 * (c) Sebastian Bergmann <sebastian@phpunit.de>
35176 *
35177 * For the full copyright and license information, please view the LICENSE
35178 * file that was distributed with this source code.
35179 */
35180 namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\StaticAnalysis;
35181
35182 use function assert;
35183 use function implode;
35184 use function rtrim;
35185 use function trim;
35186 use PHPUnitPHAR\PhpParser\Node;
35187 use PHPUnitPHAR\PhpParser\Node\ComplexType;
35188 use PHPUnitPHAR\PhpParser\Node\Identifier;
35189 use PHPUnitPHAR\PhpParser\Node\IntersectionType;
35190 use PHPUnitPHAR\PhpParser\Node\Name;
35191 use PHPUnitPHAR\PhpParser\Node\NullableType;
35192 use PHPUnitPHAR\PhpParser\Node\Stmt\Class_;
35193 use PHPUnitPHAR\PhpParser\Node\Stmt\ClassMethod;
35194 use PHPUnitPHAR\PhpParser\Node\Stmt\Enum_;
35195 use PHPUnitPHAR\PhpParser\Node\Stmt\Function_;
35196 use PHPUnitPHAR\PhpParser\Node\Stmt\Interface_;
35197 use PHPUnitPHAR\PhpParser\Node\Stmt\Trait_;
35198 use PHPUnitPHAR\PhpParser\Node\UnionType;
35199 use PHPUnitPHAR\PhpParser\NodeTraverser;
35200 use PHPUnitPHAR\PhpParser\NodeVisitorAbstract;
35201 use PHPUnitPHAR\SebastianBergmann\Complexity\CyclomaticComplexityCalculatingVisitor;
35202 /**
35203 * @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
35204 *
35205 * @psalm-type CodeUnitFunctionType = array{
35206 * name: string,
35207 * namespacedName: string,
35208 * namespace: string,
35209 * signature: string,
35210 * startLine: int,
35211 * endLine: int,
35212 * ccn: int
35213 * }
35214 * @psalm-type CodeUnitMethodType = array{
35215 * methodName: string,
35216 * signature: string,
35217 * visibility: string,
35218 * startLine: int,
35219 * endLine: int,
35220 * ccn: int
35221 * }
35222 * @psalm-type CodeUnitClassType = array{
35223 * name: string,
35224 * namespacedName: string,
35225 * namespace: string,
35226 * startLine: int,
35227 * endLine: int,
35228 * methods: array<string, CodeUnitMethodType>
35229 * }
35230 * @psalm-type CodeUnitTraitType = array{
35231 * name: string,
35232 * namespacedName: string,
35233 * namespace: string,
35234 * startLine: int,
35235 * endLine: int,
35236 * methods: array<string, CodeUnitMethodType>
35237 * }
35238 */
35239 final class CodeUnitFindingVisitor extends NodeVisitorAbstract
35240 {
35241 /**
35242 * @psalm-var array<string, CodeUnitClassType>
35243 */
35244 private array $classes = [];
35245 /**
35246 * @psalm-var array<string, CodeUnitTraitType>
35247 */
35248 private array $traits = [];
35249 /**
35250 * @psalm-var array<string, CodeUnitFunctionType>
35251 */
35252 private array $functions = [];
35253 public function enterNode(Node $node): void
35254 {
35255 if ($node instanceof Class_) {
35256 if ($node->isAnonymous()) {
35257 return;
35258 }
35259 $this->processClass($node);
35260 }
35261 if ($node instanceof Trait_) {
35262 $this->processTrait($node);
35263 }
35264 if (!$node instanceof ClassMethod && !$node instanceof Function_) {
35265 return;
35266 }
35267 if ($node instanceof ClassMethod) {
35268 $parentNode = $node->getAttribute('parent');
35269 if ($parentNode instanceof Class_ && $parentNode->isAnonymous()) {
35270 return;
35271 }
35272 $this->processMethod($node);
35273 return;
35274 }
35275 $this->processFunction($node);
35276 }
35277 /**
35278 * @psalm-return array<string, CodeUnitClassType>
35279 */
35280 public function classes(): array
35281 {
35282 return $this->classes;
35283 }
35284 /**
35285 * @psalm-return array<string, CodeUnitTraitType>
35286 */
35287 public function traits(): array
35288 {
35289 return $this->traits;
35290 }
35291 /**
35292 * @psalm-return array<string, CodeUnitFunctionType>
35293 */
35294 public function functions(): array
35295 {
35296 return $this->functions;
35297 }
35298 private function cyclomaticComplexity(ClassMethod|Function_ $node): int
35299 {
35300 $nodes = $node->getStmts();
35301 if ($nodes === null) {
35302 return 0;
35303 }
35304 $traverser = new NodeTraverser();
35305 $cyclomaticComplexityCalculatingVisitor = new CyclomaticComplexityCalculatingVisitor();
35306 $traverser->addVisitor($cyclomaticComplexityCalculatingVisitor);
35307 /* @noinspection UnusedFunctionResultInspection */
35308 $traverser->traverse($nodes);
35309 return $cyclomaticComplexityCalculatingVisitor->cyclomaticComplexity();
35310 }
35311 private function signature(ClassMethod|Function_ $node): string
35312 {
35313 $signature = ($node->returnsByRef() ? '&' : '') . $node->name->toString() . '(';
35314 $parameters = [];
35315 foreach ($node->getParams() as $parameter) {
35316 assert(isset($parameter->var->name));
35317 $parameterAsString = '';
35318 if ($parameter->type !== null) {
35319 $parameterAsString = $this->type($parameter->type) . ' ';
35320 }
35321 $parameterAsString .= '$' . $parameter->var->name;
35322 /* @todo Handle default values */
35323 $parameters[] = $parameterAsString;
35324 }
35325 $signature .= implode(', ', $parameters) . ')';
35326 $returnType = $node->getReturnType();
35327 if ($returnType !== null) {
35328 $signature .= ': ' . $this->type($returnType);
35329 }
35330 return $signature;
35331 }
35332 private function type(ComplexType|Identifier|Name $type): string
35333 {
35334 if ($type instanceof NullableType) {
35335 return '?' . $type->type;
35336 }
35337 if ($type instanceof UnionType) {
35338 return $this->unionTypeAsString($type);
35339 }
35340 if ($type instanceof IntersectionType) {
35341 return $this->intersectionTypeAsString($type);
35342 }
35343 return $type->toString();
35344 }
35345 private function visibility(ClassMethod $node): string
35346 {
35347 if ($node->isPrivate()) {
35348 return 'private';
35349 }
35350 if ($node->isProtected()) {
35351 return 'protected';
35352 }
35353 return 'public';
35354 }
35355 private function processClass(Class_ $node): void
35356 {
35357 $name = $node->name->toString();
35358 $namespacedName = $node->namespacedName->toString();
35359 $this->classes[$namespacedName] = ['name' => $name, 'namespacedName' => $namespacedName, 'namespace' => $this->namespace($namespacedName, $name), 'startLine' => $node->getStartLine(), 'endLine' => $node->getEndLine(), 'methods' => []];
35360 }
35361 private function processTrait(Trait_ $node): void
35362 {
35363 $name = $node->name->toString();
35364 $namespacedName = $node->namespacedName->toString();
35365 $this->traits[$namespacedName] = ['name' => $name, 'namespacedName' => $namespacedName, 'namespace' => $this->namespace($namespacedName, $name), 'startLine' => $node->getStartLine(), 'endLine' => $node->getEndLine(), 'methods' => []];
35366 }
35367 private function processMethod(ClassMethod $node): void
35368 {
35369 $parentNode = $node->getAttribute('parent');
35370 if ($parentNode instanceof Interface_) {
35371 return;
35372 }
35373 assert($parentNode instanceof Class_ || $parentNode instanceof Trait_ || $parentNode instanceof Enum_);
35374 assert(isset($parentNode->name));
35375 assert(isset($parentNode->namespacedName));
35376 assert($parentNode->namespacedName instanceof Name);
35377 $parentName = $parentNode->name->toString();
35378 $parentNamespacedName = $parentNode->namespacedName->toString();
35379 if ($parentNode instanceof Class_) {
35380 $storage =& $this->classes;
35381 } else {
35382 $storage =& $this->traits;
35383 }
35384 if (!isset($storage[$parentNamespacedName])) {
35385 $storage[$parentNamespacedName] = ['name' => $parentName, 'namespacedName' => $parentNamespacedName, 'namespace' => $this->namespace($parentNamespacedName, $parentName), 'startLine' => $parentNode->getStartLine(), 'endLine' => $parentNode->getEndLine(), 'methods' => []];
35386 }
35387 $storage[$parentNamespacedName]['methods'][$node->name->toString()] = ['methodName' => $node->name->toString(), 'signature' => $this->signature($node), 'visibility' => $this->visibility($node), 'startLine' => $node->getStartLine(), 'endLine' => $node->getEndLine(), 'ccn' => $this->cyclomaticComplexity($node)];
35388 }
35389 private function processFunction(Function_ $node): void
35390 {
35391 assert(isset($node->name));
35392 assert(isset($node->namespacedName));
35393 assert($node->namespacedName instanceof Name);
35394 $name = $node->name->toString();
35395 $namespacedName = $node->namespacedName->toString();
35396 $this->functions[$namespacedName] = ['name' => $name, 'namespacedName' => $namespacedName, 'namespace' => $this->namespace($namespacedName, $name), 'signature' => $this->signature($node), 'startLine' => $node->getStartLine(), 'endLine' => $node->getEndLine(), 'ccn' => $this->cyclomaticComplexity($node)];
35397 }
35398 private function namespace(string $namespacedName, string $name): string
35399 {
35400 return trim(rtrim($namespacedName, $name), '\\');
35401 }
35402 private function unionTypeAsString(UnionType $node): string
35403 {
35404 $types = [];
35405 foreach ($node->types as $type) {
35406 if ($type instanceof IntersectionType) {
35407 $types[] = '(' . $this->intersectionTypeAsString($type) . ')';
35408 continue;
35409 }
35410 $types[] = $this->typeAsString($type);
35411 }
35412 return implode('|', $types);
35413 }
35414 private function intersectionTypeAsString(IntersectionType $node): string
35415 {
35416 $types = [];
35417 foreach ($node->types as $type) {
35418 $types[] = $this->typeAsString($type);
35419 }
35420 return implode('&', $types);
35421 }
35422 private function typeAsString(Identifier|Name $node): string
35423 {
35424 if ($node instanceof Name) {
35425 return $node->toCodeString();
35426 }
35427 return $node->toString();
35428 }
35429 }
35430 <?php
35431
35432 declare (strict_types=1);
35433 /*
35434 * This file is part of phpunit/php-code-coverage.
35435 *
35436 * (c) Sebastian Bergmann <sebastian@phpunit.de>
35437 *
35438 * For the full copyright and license information, please view the LICENSE
35439 * file that was distributed with this source code.
35440 */
35441 namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\StaticAnalysis;
35442
35443 use function array_diff_key;
35444 use function assert;
35445 use function count;
35446 use function current;
35447 use function end;
35448 use function explode;
35449 use function max;
35450 use function preg_match;
35451 use function preg_quote;
35452 use function range;
35453 use function reset;
35454 use function sprintf;
35455 use PHPUnitPHAR\PhpParser\Node;
35456 use PHPUnitPHAR\PhpParser\NodeVisitorAbstract;
35457 /**
35458 * @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
35459 *
35460 * @psalm-import-type LinesType from \SebastianBergmann\CodeCoverage\StaticAnalysis\FileAnalyser
35461 */
35462 final class ExecutableLinesFindingVisitor extends NodeVisitorAbstract
35463 {
35464 private int $nextBranch = 0;
35465 private readonly string $source;
35466 /**
35467 * @psalm-var LinesType
35468 */
35469 private array $executableLinesGroupedByBranch = [];
35470 /**
35471 * @psalm-var array<int, bool>
35472 */
35473 private array $unsets = [];
35474 /**
35475 * @psalm-var array<int, string>
35476 */
35477 private array $commentsToCheckForUnset = [];
35478 public function __construct(string $source)
35479 {
35480 $this->source = $source;
35481 }
35482 public function enterNode(Node $node): void
35483 {
35484 foreach ($node->getComments() as $comment) {
35485 $commentLine = $comment->getStartLine();
35486 if (!isset($this->executableLinesGroupedByBranch[$commentLine])) {
35487 continue;
35488 }
35489 foreach (explode("\n", $comment->getText()) as $text) {
35490 $this->commentsToCheckForUnset[$commentLine] = $text;
35491 $commentLine++;
35492 }
35493 }
35494 if ($node instanceof Node\Scalar\String_ || $node instanceof Node\Scalar\EncapsedStringPart) {
35495 $startLine = $node->getStartLine() + 1;
35496 $endLine = $node->getEndLine() - 1;
35497 if ($startLine <= $endLine) {
35498 foreach (range($startLine, $endLine) as $line) {
35499 unset($this->executableLinesGroupedByBranch[$line]);
35500 }
35501 }
35502 return;
35503 }
35504 if ($node instanceof Node\Stmt\Interface_) {
35505 foreach (range($node->getStartLine(), $node->getEndLine()) as $line) {
35506 $this->unsets[$line] = \true;
35507 }
35508 return;
35509 }
35510 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\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) {
35511 return;
35512 }
35513 if ($node instanceof Node\Expr\Match_) {
35514 foreach ($node->arms as $arm) {
35515 $this->setLineBranch($arm->body->getStartLine(), $arm->body->getEndLine(), ++$this->nextBranch);
35516 }
35517 return;
35518 }
35519 /*
35520 * nikic/php-parser ^4.18 represents <code>throw</code> statements
35521 * as <code>Stmt\Throw_</code> objects
35522 */
35523 if ($node instanceof Node\Stmt\Throw_) {
35524 $this->setLineBranch($node->expr->getEndLine(), $node->expr->getEndLine(), ++$this->nextBranch);
35525 return;
35526 }
35527 /*
35528 * nikic/php-parser ^5 represents <code>throw</code> statements
35529 * as <code>Stmt\Expression</code> objects that contain an
35530 * <code>Expr\Throw_</code> object
35531 */
35532 if ($node instanceof Node\Stmt\Expression && $node->expr instanceof Node\Expr\Throw_) {
35533 $this->setLineBranch($node->expr->expr->getEndLine(), $node->expr->expr->getEndLine(), ++$this->nextBranch);
35534 return;
35535 }
35536 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_) {
35537 if ($node instanceof Node\Stmt\Function_ || $node instanceof Node\Stmt\ClassMethod) {
35538 $unsets = [];
35539 foreach ($node->getParams() as $param) {
35540 foreach (range($param->getStartLine(), $param->getEndLine()) as $line) {
35541 $unsets[$line] = \true;
35542 }
35543 }
35544 unset($unsets[$node->getEndLine()]);
35545 $this->unsets += $unsets;
35546 }
35547 $isConcreteClassLike = $node instanceof Node\Stmt\Enum_ || $node instanceof Node\Stmt\Class_ || $node instanceof Node\Stmt\Trait_;
35548 if (null !== $node->stmts) {
35549 foreach ($node->stmts as $stmt) {
35550 if ($stmt instanceof Node\Stmt\Nop) {
35551 continue;
35552 }
35553 foreach (range($stmt->getStartLine(), $stmt->getEndLine()) as $line) {
35554 unset($this->executableLinesGroupedByBranch[$line]);
35555 if ($isConcreteClassLike && !$stmt instanceof Node\Stmt\ClassMethod) {
35556 $this->unsets[$line] = \true;
35557 }
35558 }
35559 }
35560 }
35561 if ($isConcreteClassLike) {
35562 return;
35563 }
35564 $hasEmptyBody = [] === $node->stmts || null === $node->stmts || 1 === count($node->stmts) && $node->stmts[0] instanceof Node\Stmt\Nop;
35565 if ($hasEmptyBody) {
35566 if ($node->getEndLine() === $node->getStartLine() && isset($this->executableLinesGroupedByBranch[$node->getStartLine()])) {
35567 return;
35568 }
35569 $this->setLineBranch($node->getEndLine(), $node->getEndLine(), ++$this->nextBranch);
35570 return;
35571 }
35572 return;
35573 }
35574 if ($node instanceof Node\Expr\ArrowFunction) {
35575 $startLine = max($node->getStartLine() + 1, $node->expr->getStartLine());
35576 $endLine = $node->expr->getEndLine();
35577 if ($endLine < $startLine) {
35578 return;
35579 }
35580 $this->setLineBranch($startLine, $endLine, ++$this->nextBranch);
35581 return;
35582 }
35583 if ($node instanceof Node\Expr\Ternary) {
35584 if (null !== $node->if && $node->getStartLine() !== $node->if->getEndLine()) {
35585 $this->setLineBranch($node->if->getStartLine(), $node->if->getEndLine(), ++$this->nextBranch);
35586 }
35587 if ($node->getStartLine() !== $node->else->getEndLine()) {
35588 $this->setLineBranch($node->else->getStartLine(), $node->else->getEndLine(), ++$this->nextBranch);
35589 }
35590 return;
35591 }
35592 if ($node instanceof Node\Expr\BinaryOp\Coalesce) {
35593 if ($node->getStartLine() !== $node->getEndLine()) {
35594 $this->setLineBranch($node->getEndLine(), $node->getEndLine(), ++$this->nextBranch);
35595 }
35596 return;
35597 }
35598 if ($node instanceof Node\Stmt\If_ || $node instanceof Node\Stmt\ElseIf_ || $node instanceof Node\Stmt\Case_) {
35599 if (null === $node->cond) {
35600 return;
35601 }
35602 $this->setLineBranch($node->cond->getStartLine(), $node->cond->getStartLine(), ++$this->nextBranch);
35603 return;
35604 }
35605 if ($node instanceof Node\Stmt\For_) {
35606 $startLine = null;
35607 $endLine = null;
35608 if ([] !== $node->init) {
35609 $startLine = $node->init[0]->getStartLine();
35610 end($node->init);
35611 $endLine = current($node->init)->getEndLine();
35612 reset($node->init);
35613 }
35614 if ([] !== $node->cond) {
35615 if (null === $startLine) {
35616 $startLine = $node->cond[0]->getStartLine();
35617 }
35618 end($node->cond);
35619 $endLine = current($node->cond)->getEndLine();
35620 reset($node->cond);
35621 }
35622 if ([] !== $node->loop) {
35623 if (null === $startLine) {
35624 $startLine = $node->loop[0]->getStartLine();
35625 }
35626 end($node->loop);
35627 $endLine = current($node->loop)->getEndLine();
35628 reset($node->loop);
35629 }
35630 if (null === $startLine || null === $endLine) {
35631 return;
35632 }
35633 $this->setLineBranch($startLine, $endLine, ++$this->nextBranch);
35634 return;
35635 }
35636 if ($node instanceof Node\Stmt\Foreach_) {
35637 $this->setLineBranch($node->expr->getStartLine(), $node->valueVar->getEndLine(), ++$this->nextBranch);
35638 return;
35639 }
35640 if ($node instanceof Node\Stmt\While_ || $node instanceof Node\Stmt\Do_) {
35641 $this->setLineBranch($node->cond->getStartLine(), $node->cond->getEndLine(), ++$this->nextBranch);
35642 return;
35643 }
35644 if ($node instanceof Node\Stmt\Catch_) {
35645 assert([] !== $node->types);
35646 $startLine = $node->types[0]->getStartLine();
35647 end($node->types);
35648 $endLine = current($node->types)->getEndLine();
35649 $this->setLineBranch($startLine, $endLine, ++$this->nextBranch);
35650 return;
35651 }
35652 if ($node instanceof Node\Expr\CallLike) {
35653 if (isset($this->executableLinesGroupedByBranch[$node->getStartLine()])) {
35654 $branch = $this->executableLinesGroupedByBranch[$node->getStartLine()];
35655 } else {
35656 $branch = ++$this->nextBranch;
35657 }
35658 $this->setLineBranch($node->getStartLine(), $node->getEndLine(), $branch);
35659 return;
35660 }
35661 if (isset($this->executableLinesGroupedByBranch[$node->getStartLine()])) {
35662 return;
35663 }
35664 $this->setLineBranch($node->getStartLine(), $node->getEndLine(), ++$this->nextBranch);
35665 }
35666 public function afterTraverse(array $nodes): void
35667 {
35668 $lines = explode("\n", $this->source);
35669 foreach ($lines as $lineNumber => $line) {
35670 $lineNumber++;
35671 if (1 === preg_match('/^\s*$/', $line) || isset($this->commentsToCheckForUnset[$lineNumber]) && 1 === preg_match(sprintf('/^\s*%s\s*$/', preg_quote($this->commentsToCheckForUnset[$lineNumber], '/')), $line)) {
35672 unset($this->executableLinesGroupedByBranch[$lineNumber]);
35673 }
35674 }
35675 $this->executableLinesGroupedByBranch = array_diff_key($this->executableLinesGroupedByBranch, $this->unsets);
35676 }
35677 /**
35678 * @psalm-return LinesType
35679 */
35680 public function executableLinesGroupedByBranch(): array
35681 {
35682 return $this->executableLinesGroupedByBranch;
35683 }
35684 private function setLineBranch(int $start, int $end, int $branch): void
35685 {
35686 foreach (range($start, $end) as $line) {
35687 $this->executableLinesGroupedByBranch[$line] = $branch;
35688 }
35689 }
35690 }
35691 <?php
35692
35693 declare (strict_types=1);
35694 /*
35695 * This file is part of phpunit/php-code-coverage.
35696 *
35697 * (c) Sebastian Bergmann <sebastian@phpunit.de>
35698 *
35699 * For the full copyright and license information, please view the LICENSE
35700 * file that was distributed with this source code.
35701 */
35702 namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\StaticAnalysis;
35703
35704 /**
35705 * @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
35706 *
35707 * @psalm-import-type CodeUnitFunctionType from \SebastianBergmann\CodeCoverage\StaticAnalysis\CodeUnitFindingVisitor
35708 * @psalm-import-type CodeUnitMethodType from \SebastianBergmann\CodeCoverage\StaticAnalysis\CodeUnitFindingVisitor
35709 * @psalm-import-type CodeUnitClassType from \SebastianBergmann\CodeCoverage\StaticAnalysis\CodeUnitFindingVisitor
35710 * @psalm-import-type CodeUnitTraitType from \SebastianBergmann\CodeCoverage\StaticAnalysis\CodeUnitFindingVisitor
35711 * @psalm-import-type LinesOfCodeType from \SebastianBergmann\CodeCoverage\StaticAnalysis\FileAnalyser
35712 * @psalm-import-type LinesType from \SebastianBergmann\CodeCoverage\StaticAnalysis\FileAnalyser
35713 *
35714 * @psalm-type LinesOfCodeType = array{
35715 * linesOfCode: int,
35716 * commentLinesOfCode: int,
35717 * nonCommentLinesOfCode: int
35718 * }
35719 * @psalm-type LinesType = array<int, int>
35720 */
35721 interface FileAnalyser
35722 {
35723 /**
35724 * @psalm-return array<string, CodeUnitClassType>
35725 */
35726 public function classesIn(string $filename): array;
35727 /**
35728 * @psalm-return array<string, CodeUnitTraitType>
35729 */
35730 public function traitsIn(string $filename): array;
35731 /**
35732 * @psalm-return array<string, CodeUnitFunctionType>
35733 */
35734 public function functionsIn(string $filename): array;
35735 /**
35736 * @psalm-return LinesOfCodeType
35737 */
35738 public function linesOfCodeFor(string $filename): array;
35739 /**
35740 * @psalm-return LinesType
35741 */
35742 public function executableLinesIn(string $filename): array;
35743 /**
35744 * @psalm-return LinesType
35745 */
35746 public function ignoredLinesFor(string $filename): array;
35747 }
35748 <?php
35749
35750 declare (strict_types=1);
35751 /*
35752 * This file is part of phpunit/php-code-coverage.
35753 *
35754 * (c) Sebastian Bergmann <sebastian@phpunit.de>
35755 *
35756 * For the full copyright and license information, please view the LICENSE
35757 * file that was distributed with this source code.
35758 */
35759 namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\StaticAnalysis;
35760
35761 use function assert;
35762 use function str_contains;
35763 use PHPUnitPHAR\PhpParser\Node;
35764 use PHPUnitPHAR\PhpParser\Node\Attribute;
35765 use PHPUnitPHAR\PhpParser\Node\Stmt\Class_;
35766 use PHPUnitPHAR\PhpParser\Node\Stmt\ClassMethod;
35767 use PHPUnitPHAR\PhpParser\Node\Stmt\Enum_;
35768 use PHPUnitPHAR\PhpParser\Node\Stmt\Function_;
35769 use PHPUnitPHAR\PhpParser\Node\Stmt\Interface_;
35770 use PHPUnitPHAR\PhpParser\Node\Stmt\Trait_;
35771 use PHPUnitPHAR\PhpParser\NodeVisitorAbstract;
35772 /**
35773 * @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
35774 */
35775 final class IgnoredLinesFindingVisitor extends NodeVisitorAbstract
35776 {
35777 /**
35778 * @psalm-var array<int>
35779 */
35780 private array $ignoredLines = [];
35781 private readonly bool $useAnnotationsForIgnoringCode;
35782 private readonly bool $ignoreDeprecated;
35783 public function __construct(bool $useAnnotationsForIgnoringCode, bool $ignoreDeprecated)
35784 {
35785 $this->useAnnotationsForIgnoringCode = $useAnnotationsForIgnoringCode;
35786 $this->ignoreDeprecated = $ignoreDeprecated;
35787 }
35788 public function enterNode(Node $node): void
35789 {
35790 if (!$node instanceof Class_ && !$node instanceof Trait_ && !$node instanceof Interface_ && !$node instanceof Enum_ && !$node instanceof ClassMethod && !$node instanceof Function_ && !$node instanceof Attribute) {
35791 return;
35792 }
35793 if ($node instanceof Class_ && $node->isAnonymous()) {
35794 return;
35795 }
35796 if ($node instanceof Class_ || $node instanceof Trait_ || $node instanceof Interface_ || $node instanceof Attribute) {
35797 $this->ignoredLines[] = $node->getStartLine();
35798 assert($node->name !== null);
35799 // Workaround for https://github.com/nikic/PHP-Parser/issues/886
35800 $this->ignoredLines[] = $node->name->getStartLine();
35801 }
35802 if (!$this->useAnnotationsForIgnoringCode) {
35803 return;
35804 }
35805 if ($node instanceof Interface_) {
35806 return;
35807 }
35808 if ($node instanceof Attribute && $node->name->toString() === 'PHPUnit\Framework\Attributes\CodeCoverageIgnore') {
35809 $attributeGroup = $node->getAttribute('parent');
35810 $attributedNode = $attributeGroup->getAttribute('parent');
35811 for ($line = $attributedNode->getStartLine(); $line <= $attributedNode->getEndLine(); $line++) {
35812 $this->ignoredLines[] = $line;
35813 }
35814 return;
35815 }
35816 $this->processDocComment($node);
35817 }
35818 /**
35819 * @psalm-return array<int>
35820 */
35821 public function ignoredLines(): array
35822 {
35823 return $this->ignoredLines;
35824 }
35825 private function processDocComment(Node $node): void
35826 {
35827 $docComment = $node->getDocComment();
35828 if ($docComment === null) {
35829 return;
35830 }
35831 if (str_contains($docComment->getText(), '@codeCoverageIgnore')) {
35832 for ($line = $node->getStartLine(); $line <= $node->getEndLine(); $line++) {
35833 $this->ignoredLines[] = $line;
35834 }
35835 }
35836 if ($this->ignoreDeprecated && str_contains($docComment->getText(), '@deprecated')) {
35837 for ($line = $node->getStartLine(); $line <= $node->getEndLine(); $line++) {
35838 $this->ignoredLines[] = $line;
35839 }
35840 }
35841 }
35842 }
35843 <?php
35844
35845 declare (strict_types=1);
35846 /*
35847 * This file is part of phpunit/php-code-coverage.
35848 *
35849 * (c) Sebastian Bergmann <sebastian@phpunit.de>
35850 *
35851 * For the full copyright and license information, please view the LICENSE
35852 * file that was distributed with this source code.
35853 */
35854 namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\StaticAnalysis;
35855
35856 use function array_merge;
35857 use function array_unique;
35858 use function assert;
35859 use function file_get_contents;
35860 use function is_array;
35861 use function max;
35862 use function range;
35863 use function sort;
35864 use function sprintf;
35865 use function substr_count;
35866 use function token_get_all;
35867 use function trim;
35868 use PHPUnitPHAR\PhpParser\Error;
35869 use PHPUnitPHAR\PhpParser\NodeTraverser;
35870 use PHPUnitPHAR\PhpParser\NodeVisitor\NameResolver;
35871 use PHPUnitPHAR\PhpParser\NodeVisitor\ParentConnectingVisitor;
35872 use PHPUnitPHAR\PhpParser\ParserFactory;
35873 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\ParserException;
35874 use PHPUnitPHAR\SebastianBergmann\LinesOfCode\LineCountingVisitor;
35875 /**
35876 * @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
35877 *
35878 * @psalm-import-type CodeUnitFunctionType from \SebastianBergmann\CodeCoverage\StaticAnalysis\CodeUnitFindingVisitor
35879 * @psalm-import-type CodeUnitMethodType from \SebastianBergmann\CodeCoverage\StaticAnalysis\CodeUnitFindingVisitor
35880 * @psalm-import-type CodeUnitClassType from \SebastianBergmann\CodeCoverage\StaticAnalysis\CodeUnitFindingVisitor
35881 * @psalm-import-type CodeUnitTraitType from \SebastianBergmann\CodeCoverage\StaticAnalysis\CodeUnitFindingVisitor
35882 * @psalm-import-type LinesOfCodeType from \SebastianBergmann\CodeCoverage\StaticAnalysis\FileAnalyser
35883 * @psalm-import-type LinesType from \SebastianBergmann\CodeCoverage\StaticAnalysis\FileAnalyser
35884 */
35885 final class ParsingFileAnalyser implements FileAnalyser
35886 {
35887 /**
35888 * @psalm-var array<string, array<string, CodeUnitClassType>>
35889 */
35890 private array $classes = [];
35891 /**
35892 * @psalm-var array<string, array<string, CodeUnitTraitType>>
35893 */
35894 private array $traits = [];
35895 /**
35896 * @psalm-var array<string, array<string, CodeUnitFunctionType>>
35897 */
35898 private array $functions = [];
35899 /**
35900 * @var array<string, LinesOfCodeType>
35901 */
35902 private array $linesOfCode = [];
35903 /**
35904 * @var array<string, LinesType>
35905 */
35906 private array $ignoredLines = [];
35907 /**
35908 * @var array<string, LinesType>
35909 */
35910 private array $executableLines = [];
35911 private readonly bool $useAnnotationsForIgnoringCode;
35912 private readonly bool $ignoreDeprecatedCode;
35913 public function __construct(bool $useAnnotationsForIgnoringCode, bool $ignoreDeprecatedCode)
35914 {
35915 $this->useAnnotationsForIgnoringCode = $useAnnotationsForIgnoringCode;
35916 $this->ignoreDeprecatedCode = $ignoreDeprecatedCode;
35917 }
35918 public function classesIn(string $filename): array
35919 {
35920 $this->analyse($filename);
35921 return $this->classes[$filename];
35922 }
35923 public function traitsIn(string $filename): array
35924 {
35925 $this->analyse($filename);
35926 return $this->traits[$filename];
35927 }
35928 public function functionsIn(string $filename): array
35929 {
35930 $this->analyse($filename);
35931 return $this->functions[$filename];
35932 }
35933 public function linesOfCodeFor(string $filename): array
35934 {
35935 $this->analyse($filename);
35936 return $this->linesOfCode[$filename];
35937 }
35938 public function executableLinesIn(string $filename): array
35939 {
35940 $this->analyse($filename);
35941 return $this->executableLines[$filename];
35942 }
35943 public function ignoredLinesFor(string $filename): array
35944 {
35945 $this->analyse($filename);
35946 return $this->ignoredLines[$filename];
35947 }
35948 /**
35949 * @throws ParserException
35950 */
35951 private function analyse(string $filename): void
35952 {
35953 if (isset($this->classes[$filename])) {
35954 return;
35955 }
35956 $source = file_get_contents($filename);
35957 $linesOfCode = max(substr_count($source, "\n") + 1, substr_count($source, "\r") + 1);
35958 if ($linesOfCode === 0 && !empty($source)) {
35959 $linesOfCode = 1;
35960 }
35961 assert($linesOfCode > 0);
35962 $parser = (new ParserFactory())->createForHostVersion();
35963 try {
35964 $nodes = $parser->parse($source);
35965 assert($nodes !== null);
35966 $traverser = new NodeTraverser();
35967 $codeUnitFindingVisitor = new CodeUnitFindingVisitor();
35968 $lineCountingVisitor = new LineCountingVisitor($linesOfCode);
35969 $ignoredLinesFindingVisitor = new IgnoredLinesFindingVisitor($this->useAnnotationsForIgnoringCode, $this->ignoreDeprecatedCode);
35970 $executableLinesFindingVisitor = new ExecutableLinesFindingVisitor($source);
35971 $traverser->addVisitor(new NameResolver());
35972 $traverser->addVisitor(new ParentConnectingVisitor());
35973 $traverser->addVisitor($codeUnitFindingVisitor);
35974 $traverser->addVisitor($lineCountingVisitor);
35975 $traverser->addVisitor($ignoredLinesFindingVisitor);
35976 $traverser->addVisitor($executableLinesFindingVisitor);
35977 /* @noinspection UnusedFunctionResultInspection */
35978 $traverser->traverse($nodes);
35979 // @codeCoverageIgnoreStart
35980 } catch (Error $error) {
35981 throw new ParserException(sprintf('Cannot parse %s: %s', $filename, $error->getMessage()), $error->getCode(), $error);
35982 }
35983 // @codeCoverageIgnoreEnd
35984 $this->classes[$filename] = $codeUnitFindingVisitor->classes();
35985 $this->traits[$filename] = $codeUnitFindingVisitor->traits();
35986 $this->functions[$filename] = $codeUnitFindingVisitor->functions();
35987 $this->executableLines[$filename] = $executableLinesFindingVisitor->executableLinesGroupedByBranch();
35988 $this->ignoredLines[$filename] = [];
35989 $this->findLinesIgnoredByLineBasedAnnotations($filename, $source, $this->useAnnotationsForIgnoringCode);
35990 $this->ignoredLines[$filename] = array_unique(array_merge($this->ignoredLines[$filename], $ignoredLinesFindingVisitor->ignoredLines()));
35991 sort($this->ignoredLines[$filename]);
35992 $result = $lineCountingVisitor->result();
35993 $this->linesOfCode[$filename] = ['linesOfCode' => $result->linesOfCode(), 'commentLinesOfCode' => $result->commentLinesOfCode(), 'nonCommentLinesOfCode' => $result->nonCommentLinesOfCode()];
35994 }
35995 private function findLinesIgnoredByLineBasedAnnotations(string $filename, string $source, bool $useAnnotationsForIgnoringCode): void
35996 {
35997 if (!$useAnnotationsForIgnoringCode) {
35998 return;
35999 }
36000 $start = \false;
36001 foreach (token_get_all($source) as $token) {
36002 if (!is_array($token) || !(\T_COMMENT === $token[0] || \T_DOC_COMMENT === $token[0])) {
36003 continue;
36004 }
36005 $comment = trim($token[1]);
36006 if ($comment === '// @codeCoverageIgnore' || $comment === '//@codeCoverageIgnore') {
36007 $this->ignoredLines[$filename][] = $token[2];
36008 continue;
36009 }
36010 if ($comment === '// @codeCoverageIgnoreStart' || $comment === '//@codeCoverageIgnoreStart') {
36011 $start = $token[2];
36012 continue;
36013 }
36014 if ($comment === '// @codeCoverageIgnoreEnd' || $comment === '//@codeCoverageIgnoreEnd') {
36015 if (\false === $start) {
36016 $start = $token[2];
36017 }
36018 $this->ignoredLines[$filename] = array_merge($this->ignoredLines[$filename], range($start, $token[2]));
36019 }
36020 }
36021 }
36022 }
36023 <?php
36024
36025 declare (strict_types=1);
36026 /*
36027 * This file is part of phpunit/php-code-coverage.
36028 *
36029 * (c) Sebastian Bergmann <sebastian@phpunit.de>
36030 *
36031 * For the full copyright and license information, please view the LICENSE
36032 * file that was distributed with this source code.
36033 */
36034 namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\Test\TestSize;
36035
36036 /**
36037 * @psalm-immutable
36038 */
36039 abstract class Known extends TestSize
36040 {
36041 /**
36042 * @psalm-assert-if-true Known $this
36043 */
36044 public function isKnown(): bool
36045 {
36046 return \true;
36047 }
36048 abstract public function isGreaterThan(self $other): bool;
36049 }
36050 <?php
36051
36052 declare (strict_types=1);
36053 /*
36054 * This file is part of phpunit/php-code-coverage.
36055 *
36056 * (c) Sebastian Bergmann <sebastian@phpunit.de>
36057 *
36058 * For the full copyright and license information, please view the LICENSE
36059 * file that was distributed with this source code.
36060 */
36061 namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\Test\TestSize;
36062
36063 /**
36064 * @psalm-immutable
36065 */
36066 final class Large extends Known
36067 {
36068 /**
36069 * @psalm-assert-if-true Large $this
36070 */
36071 public function isLarge(): bool
36072 {
36073 return \true;
36074 }
36075 public function isGreaterThan(TestSize $other): bool
36076 {
36077 return !$other->isLarge();
36078 }
36079 public function asString(): string
36080 {
36081 return 'large';
36082 }
36083 }
36084 <?php
36085
36086 declare (strict_types=1);
36087 /*
36088 * This file is part of phpunit/php-code-coverage.
36089 *
36090 * (c) Sebastian Bergmann <sebastian@phpunit.de>
36091 *
36092 * For the full copyright and license information, please view the LICENSE
36093 * file that was distributed with this source code.
36094 */
36095 namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\Test\TestSize;
36096
36097 /**
36098 * @psalm-immutable
36099 */
36100 final class Medium extends Known
36101 {
36102 /**
36103 * @psalm-assert-if-true Medium $this
36104 */
36105 public function isMedium(): bool
36106 {
36107 return \true;
36108 }
36109 public function isGreaterThan(TestSize $other): bool
36110 {
36111 return $other->isSmall();
36112 }
36113 public function asString(): string
36114 {
36115 return 'medium';
36116 }
36117 }
36118 <?php
36119
36120 declare (strict_types=1);
36121 /*
36122 * This file is part of phpunit/php-code-coverage.
36123 *
36124 * (c) Sebastian Bergmann <sebastian@phpunit.de>
36125 *
36126 * For the full copyright and license information, please view the LICENSE
36127 * file that was distributed with this source code.
36128 */
36129 namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\Test\TestSize;
36130
36131 /**
36132 * @psalm-immutable
36133 */
36134 final class Small extends Known
36135 {
36136 /**
36137 * @psalm-assert-if-true Small $this
36138 */
36139 public function isSmall(): bool
36140 {
36141 return \true;
36142 }
36143 public function isGreaterThan(TestSize $other): bool
36144 {
36145 return \false;
36146 }
36147 public function asString(): string
36148 {
36149 return 'small';
36150 }
36151 }
36152 <?php
36153
36154 declare (strict_types=1);
36155 /*
36156 * This file is part of phpunit/php-code-coverage.
36157 *
36158 * (c) Sebastian Bergmann <sebastian@phpunit.de>
36159 *
36160 * For the full copyright and license information, please view the LICENSE
36161 * file that was distributed with this source code.
36162 */
36163 namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\Test\TestSize;
36164
36165 /**
36166 * @psalm-immutable
36167 */
36168 abstract class TestSize
36169 {
36170 public static function unknown(): self
36171 {
36172 return new Unknown();
36173 }
36174 public static function small(): self
36175 {
36176 return new Small();
36177 }
36178 public static function medium(): self
36179 {
36180 return new Medium();
36181 }
36182 public static function large(): self
36183 {
36184 return new Large();
36185 }
36186 /**
36187 * @psalm-assert-if-true Known $this
36188 */
36189 public function isKnown(): bool
36190 {
36191 return \false;
36192 }
36193 /**
36194 * @psalm-assert-if-true Unknown $this
36195 */
36196 public function isUnknown(): bool
36197 {
36198 return \false;
36199 }
36200 /**
36201 * @psalm-assert-if-true Small $this
36202 */
36203 public function isSmall(): bool
36204 {
36205 return \false;
36206 }
36207 /**
36208 * @psalm-assert-if-true Medium $this
36209 */
36210 public function isMedium(): bool
36211 {
36212 return \false;
36213 }
36214 /**
36215 * @psalm-assert-if-true Large $this
36216 */
36217 public function isLarge(): bool
36218 {
36219 return \false;
36220 }
36221 abstract public function asString(): string;
36222 }
36223 <?php
36224
36225 declare (strict_types=1);
36226 /*
36227 * This file is part of phpunit/php-code-coverage.
36228 *
36229 * (c) Sebastian Bergmann <sebastian@phpunit.de>
36230 *
36231 * For the full copyright and license information, please view the LICENSE
36232 * file that was distributed with this source code.
36233 */
36234 namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\Test\TestSize;
36235
36236 /**
36237 * @psalm-immutable
36238 */
36239 final class Unknown extends TestSize
36240 {
36241 /**
36242 * @psalm-assert-if-true Unknown $this
36243 */
36244 public function isUnknown(): bool
36245 {
36246 return \true;
36247 }
36248 public function asString(): string
36249 {
36250 return 'unknown';
36251 }
36252 }
36253 <?php
36254
36255 declare (strict_types=1);
36256 /*
36257 * This file is part of phpunit/php-code-coverage.
36258 *
36259 * (c) Sebastian Bergmann <sebastian@phpunit.de>
36260 *
36261 * For the full copyright and license information, please view the LICENSE
36262 * file that was distributed with this source code.
36263 */
36264 namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\Test\TestStatus;
36265
36266 /**
36267 * @psalm-immutable
36268 */
36269 final class Failure extends Known
36270 {
36271 /**
36272 * @psalm-assert-if-true Failure $this
36273 */
36274 public function isFailure(): bool
36275 {
36276 return \true;
36277 }
36278 public function asString(): string
36279 {
36280 return 'failure';
36281 }
36282 }
36283 <?php
36284
36285 declare (strict_types=1);
36286 /*
36287 * This file is part of phpunit/php-code-coverage.
36288 *
36289 * (c) Sebastian Bergmann <sebastian@phpunit.de>
36290 *
36291 * For the full copyright and license information, please view the LICENSE
36292 * file that was distributed with this source code.
36293 */
36294 namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\Test\TestStatus;
36295
36296 /**
36297 * @psalm-immutable
36298 */
36299 abstract class Known extends TestStatus
36300 {
36301 /**
36302 * @psalm-assert-if-true Known $this
36303 */
36304 public function isKnown(): bool
36305 {
36306 return \true;
36307 }
36308 }
36309 <?php
36310
36311 declare (strict_types=1);
36312 /*
36313 * This file is part of phpunit/php-code-coverage.
36314 *
36315 * (c) Sebastian Bergmann <sebastian@phpunit.de>
36316 *
36317 * For the full copyright and license information, please view the LICENSE
36318 * file that was distributed with this source code.
36319 */
36320 namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\Test\TestStatus;
36321
36322 /**
36323 * @psalm-immutable
36324 */
36325 final class Success extends Known
36326 {
36327 /**
36328 * @psalm-assert-if-true Success $this
36329 */
36330 public function isSuccess(): bool
36331 {
36332 return \true;
36333 }
36334 public function asString(): string
36335 {
36336 return 'success';
36337 }
36338 }
36339 <?php
36340
36341 declare (strict_types=1);
36342 /*
36343 * This file is part of phpunit/php-code-coverage.
36344 *
36345 * (c) Sebastian Bergmann <sebastian@phpunit.de>
36346 *
36347 * For the full copyright and license information, please view the LICENSE
36348 * file that was distributed with this source code.
36349 */
36350 namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\Test\TestStatus;
36351
36352 /**
36353 * @psalm-immutable
36354 */
36355 abstract class TestStatus
36356 {
36357 public static function unknown(): self
36358 {
36359 return new Unknown();
36360 }
36361 public static function success(): self
36362 {
36363 return new Success();
36364 }
36365 public static function failure(): self
36366 {
36367 return new Failure();
36368 }
36369 /**
36370 * @psalm-assert-if-true Known $this
36371 */
36372 public function isKnown(): bool
36373 {
36374 return \false;
36375 }
36376 /**
36377 * @psalm-assert-if-true Unknown $this
36378 */
36379 public function isUnknown(): bool
36380 {
36381 return \false;
36382 }
36383 /**
36384 * @psalm-assert-if-true Success $this
36385 */
36386 public function isSuccess(): bool
36387 {
36388 return \false;
36389 }
36390 /**
36391 * @psalm-assert-if-true Failure $this
36392 */
36393 public function isFailure(): bool
36394 {
36395 return \false;
36396 }
36397 abstract public function asString(): string;
36398 }
36399 <?php
36400
36401 declare (strict_types=1);
36402 /*
36403 * This file is part of phpunit/php-code-coverage.
36404 *
36405 * (c) Sebastian Bergmann <sebastian@phpunit.de>
36406 *
36407 * For the full copyright and license information, please view the LICENSE
36408 * file that was distributed with this source code.
36409 */
36410 namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\Test\TestStatus;
36411
36412 /**
36413 * @psalm-immutable
36414 */
36415 final class Unknown extends TestStatus
36416 {
36417 /**
36418 * @psalm-assert-if-true Unknown $this
36419 */
36420 public function isUnknown(): bool
36421 {
36422 return \true;
36423 }
36424 public function asString(): string
36425 {
36426 return 'unknown';
36427 }
36428 }
36429 <?php
36430
36431 declare (strict_types=1);
36432 /*
36433 * This file is part of phpunit/php-code-coverage.
36434 *
36435 * (c) Sebastian Bergmann <sebastian@phpunit.de>
36436 *
36437 * For the full copyright and license information, please view the LICENSE
36438 * file that was distributed with this source code.
36439 */
36440 namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\Util;
36441
36442 use function is_dir;
36443 use function mkdir;
36444 use function sprintf;
36445 /**
36446 * @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
36447 */
36448 final class Filesystem
36449 {
36450 /**
36451 * @throws DirectoryCouldNotBeCreatedException
36452 */
36453 public static function createDirectory(string $directory): void
36454 {
36455 $success = !(!is_dir($directory) && !@mkdir($directory, 0777, \true) && !is_dir($directory));
36456 if (!$success) {
36457 throw new DirectoryCouldNotBeCreatedException(sprintf('Directory "%s" could not be created', $directory));
36458 }
36459 }
36460 }
36461 <?php
36462
36463 declare (strict_types=1);
36464 /*
36465 * This file is part of phpunit/php-code-coverage.
36466 *
36467 * (c) Sebastian Bergmann <sebastian@phpunit.de>
36468 *
36469 * For the full copyright and license information, please view the LICENSE
36470 * file that was distributed with this source code.
36471 */
36472 namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage\Util;
36473
36474 use function sprintf;
36475 /**
36476 * @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
36477 */
36478 final class Percentage
36479 {
36480 private readonly float $fraction;
36481 private readonly float $total;
36482 public static function fromFractionAndTotal(float $fraction, float $total): self
36483 {
36484 return new self($fraction, $total);
36485 }
36486 private function __construct(float $fraction, float $total)
36487 {
36488 $this->fraction = $fraction;
36489 $this->total = $total;
36490 }
36491 public function asFloat(): float
36492 {
36493 if ($this->total > 0) {
36494 return $this->fraction / $this->total * 100;
36495 }
36496 return 100.0;
36497 }
36498 public function asString(): string
36499 {
36500 if ($this->total > 0) {
36501 return sprintf('%01.2F%%', $this->asFloat());
36502 }
36503 return '';
36504 }
36505 public function asFixedWidthString(): string
36506 {
36507 if ($this->total > 0) {
36508 return sprintf('%6.2F%%', $this->asFloat());
36509 }
36510 return '';
36511 }
36512 }
36513 <?php
36514
36515 declare (strict_types=1);
36516 /*
36517 * This file is part of phpunit/php-code-coverage.
36518 *
36519 * (c) Sebastian Bergmann <sebastian@phpunit.de>
36520 *
36521 * For the full copyright and license information, please view the LICENSE
36522 * file that was distributed with this source code.
36523 */
36524 namespace PHPUnitPHAR\SebastianBergmann\CodeCoverage;
36525
36526 use function dirname;
36527 use PHPUnitPHAR\SebastianBergmann\Version as VersionId;
36528 final class Version
36529 {
36530 private static string $version = '';
36531 public static function id(): string
36532 {
36533 if (self::$version === '') {
36534 self::$version = (new VersionId('10.1.16', dirname(__DIR__)))->asString();
36535 }
36536 return self::$version;
36537 }
36538 }
36539 <?php
36540
36541 declare (strict_types=1);
36542 /*
36543 * This file is part of phpunit/php-file-iterator.
36544 *
36545 * (c) Sebastian Bergmann <sebastian@phpunit.de>
36546 *
36547 * For the full copyright and license information, please view the LICENSE
36548 * file that was distributed with this source code.
36549 */
36550 namespace PHPUnitPHAR\SebastianBergmann\FileIterator;
36551
36552 use function assert;
36553 use function str_starts_with;
36554 use RecursiveDirectoryIterator;
36555 use RecursiveFilterIterator;
36556 use SplFileInfo;
36557 /**
36558 * @internal This class is not covered by the backward compatibility promise for phpunit/php-file-iterator
36559 */
36560 final class ExcludeIterator extends RecursiveFilterIterator
36561 {
36562 /**
36563 * @psalm-var list<string>
36564 */
36565 private array $exclude;
36566 /**
36567 * @psalm-param list<string> $exclude
36568 */
36569 public function __construct(RecursiveDirectoryIterator $iterator, array $exclude)
36570 {
36571 parent::__construct($iterator);
36572 $this->exclude = $exclude;
36573 }
36574 public function accept(): bool
36575 {
36576 $current = $this->current();
36577 assert($current instanceof SplFileInfo);
36578 $path = $current->getRealPath();
36579 if ($path === \false) {
36580 return \false;
36581 }
36582 foreach ($this->exclude as $exclude) {
36583 if (str_starts_with($path, $exclude)) {
36584 return \false;
36585 }
36586 }
36587 return \true;
36588 }
36589 public function hasChildren(): bool
36590 {
36591 return $this->getInnerIterator()->hasChildren();
36592 }
36593 public function getChildren(): self
36594 {
36595 return new self($this->getInnerIterator()->getChildren(), $this->exclude);
36596 }
36597 public function getInnerIterator(): RecursiveDirectoryIterator
36598 {
36599 $innerIterator = parent::getInnerIterator();
36600 assert($innerIterator instanceof RecursiveDirectoryIterator);
36601 return $innerIterator;
36602 }
36603 }
36604 <?php
36605
36606 declare (strict_types=1);
36607 /*
36608 * This file is part of phpunit/php-file-iterator.
36609 *
36610 * (c) Sebastian Bergmann <sebastian@phpunit.de>
36611 *
36612 * For the full copyright and license information, please view the LICENSE
36613 * file that was distributed with this source code.
36614 */
36615 namespace PHPUnitPHAR\SebastianBergmann\FileIterator;
36616
36617 use function array_unique;
36618 use function assert;
36619 use function sort;
36620 use SplFileInfo;
36621 /**
36622 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
36623 */
36624 final class Facade
36625 {
36626 /**
36627 * @psalm-param list<non-empty-string>|non-empty-string $paths
36628 * @psalm-param list<non-empty-string>|string $suffixes
36629 * @psalm-param list<non-empty-string>|string $prefixes
36630 * @psalm-param list<non-empty-string> $exclude
36631 *
36632 * @psalm-return list<non-empty-string>
36633 */
36634 public function getFilesAsArray(array|string $paths, array|string $suffixes = '', array|string $prefixes = '', array $exclude = []): array
36635 {
36636 $iterator = (new Factory())->getFileIterator($paths, $suffixes, $prefixes, $exclude);
36637 $files = [];
36638 foreach ($iterator as $file) {
36639 assert($file instanceof SplFileInfo);
36640 $file = $file->getRealPath();
36641 if ($file) {
36642 $files[] = $file;
36643 }
36644 }
36645 $files = array_unique($files);
36646 sort($files);
36647 return $files;
36648 }
36649 }
36650 <?php
36651
36652 declare (strict_types=1);
36653 /*
36654 * This file is part of phpunit/php-file-iterator.
36655 *
36656 * (c) Sebastian Bergmann <sebastian@phpunit.de>
36657 *
36658 * For the full copyright and license information, please view the LICENSE
36659 * file that was distributed with this source code.
36660 */
36661 namespace PHPUnitPHAR\SebastianBergmann\FileIterator;
36662
36663 use const GLOB_ONLYDIR;
36664 use function array_filter;
36665 use function array_map;
36666 use function array_merge;
36667 use function array_values;
36668 use function glob;
36669 use function is_dir;
36670 use function is_string;
36671 use function realpath;
36672 use AppendIterator;
36673 use FilesystemIterator;
36674 use RecursiveDirectoryIterator;
36675 use RecursiveIteratorIterator;
36676 /**
36677 * @internal This class is not covered by the backward compatibility promise for phpunit/php-file-iterator
36678 */
36679 final class Factory
36680 {
36681 /**
36682 * @psalm-param list<non-empty-string>|non-empty-string $paths
36683 * @psalm-param list<non-empty-string>|string $suffixes
36684 * @psalm-param list<non-empty-string>|string $prefixes
36685 * @psalm-param list<non-empty-string> $exclude
36686 */
36687 public function getFileIterator(array|string $paths, array|string $suffixes = '', array|string $prefixes = '', array $exclude = []): AppendIterator
36688 {
36689 if (is_string($paths)) {
36690 $paths = [$paths];
36691 }
36692 $paths = $this->resolveWildcards($paths);
36693 $exclude = $this->resolveWildcards($exclude);
36694 if (is_string($prefixes)) {
36695 if ($prefixes !== '') {
36696 $prefixes = [$prefixes];
36697 } else {
36698 $prefixes = [];
36699 }
36700 }
36701 if (is_string($suffixes)) {
36702 if ($suffixes !== '') {
36703 $suffixes = [$suffixes];
36704 } else {
36705 $suffixes = [];
36706 }
36707 }
36708 $iterator = new AppendIterator();
36709 foreach ($paths as $path) {
36710 if (is_dir($path)) {
36711 $iterator->append(new Iterator($path, new RecursiveIteratorIterator(new ExcludeIterator(new RecursiveDirectoryIterator($path, FilesystemIterator::FOLLOW_SYMLINKS | FilesystemIterator::SKIP_DOTS), $exclude)), $suffixes, $prefixes));
36712 }
36713 }
36714 return $iterator;
36715 }
36716 /**
36717 * @psalm-param list<non-empty-string> $paths
36718 *
36719 * @psalm-return list<non-empty-string>
36720 */
36721 private function resolveWildcards(array $paths): array
36722 {
36723 $_paths = [[]];
36724 foreach ($paths as $path) {
36725 if ($locals = glob($path, GLOB_ONLYDIR)) {
36726 $_paths[] = array_map('\realpath', $locals);
36727 } else {
36728 // @codeCoverageIgnoreStart
36729 $_paths[] = [realpath($path)];
36730 // @codeCoverageIgnoreEnd
36731 }
36732 }
36733 return array_values(array_filter(array_merge(...$_paths)));
36734 }
36735 }
36736 <?php
36737
36738 declare (strict_types=1);
36739 /*
36740 * This file is part of phpunit/php-file-iterator.
36741 *
36742 * (c) Sebastian Bergmann <sebastian@phpunit.de>
36743 *
36744 * For the full copyright and license information, please view the LICENSE
36745 * file that was distributed with this source code.
36746 */
36747 namespace PHPUnitPHAR\SebastianBergmann\FileIterator;
36748
36749 use function assert;
36750 use function preg_match;
36751 use function realpath;
36752 use function str_ends_with;
36753 use function str_replace;
36754 use function str_starts_with;
36755 use AppendIterator;
36756 use FilterIterator;
36757 use SplFileInfo;
36758 /**
36759 * @template-extends FilterIterator<int, string, AppendIterator>
36760 *
36761 * @internal This class is not covered by the backward compatibility promise for phpunit/php-file-iterator
36762 */
36763 final class Iterator extends FilterIterator
36764 {
36765 public const PREFIX = 0;
36766 public const SUFFIX = 1;
36767 private string|false $basePath;
36768 /**
36769 * @psalm-var list<string>
36770 */
36771 private array $suffixes;
36772 /**
36773 * @psalm-var list<string>
36774 */
36775 private array $prefixes;
36776 /**
36777 * @psalm-param list<string> $suffixes
36778 * @psalm-param list<string> $prefixes
36779 */
36780 public function __construct(string $basePath, \Iterator $iterator, array $suffixes = [], array $prefixes = [])
36781 {
36782 $this->basePath = realpath($basePath);
36783 $this->prefixes = $prefixes;
36784 $this->suffixes = $suffixes;
36785 parent::__construct($iterator);
36786 }
36787 public function accept(): bool
36788 {
36789 $current = $this->getInnerIterator()->current();
36790 assert($current instanceof SplFileInfo);
36791 $filename = $current->getFilename();
36792 $realPath = $current->getRealPath();
36793 if ($realPath === \false) {
36794 // @codeCoverageIgnoreStart
36795 return \false;
36796 // @codeCoverageIgnoreEnd
36797 }
36798 return $this->acceptPath($realPath) && $this->acceptPrefix($filename) && $this->acceptSuffix($filename);
36799 }
36800 private function acceptPath(string $path): bool
36801 {
36802 // Filter files in hidden directories by checking path that is relative to the base path.
36803 if (preg_match('=/\.[^/]*/=', str_replace((string) $this->basePath, '', $path))) {
36804 return \false;
36805 }
36806 return \true;
36807 }
36808 private function acceptPrefix(string $filename): bool
36809 {
36810 return $this->acceptSubString($filename, $this->prefixes, self::PREFIX);
36811 }
36812 private function acceptSuffix(string $filename): bool
36813 {
36814 return $this->acceptSubString($filename, $this->suffixes, self::SUFFIX);
36815 }
36816 /**
36817 * @psalm-param list<string> $subStrings
36818 */
36819 private function acceptSubString(string $filename, array $subStrings, int $type): bool
36820 {
36821 if (empty($subStrings)) {
36822 return \true;
36823 }
36824 foreach ($subStrings as $string) {
36825 if ($type === self::PREFIX && str_starts_with($filename, $string) || $type === self::SUFFIX && str_ends_with($filename, $string)) {
36826 return \true;
36827 }
36828 }
36829 return \false;
36830 }
36831 }
36832 BSD 3-Clause License
36833
36834 Copyright (c) 2009-2023, Sebastian Bergmann
36835 All rights reserved.
36836
36837 Redistribution and use in source and binary forms, with or without
36838 modification, are permitted provided that the following conditions are met:
36839
36840 1. Redistributions of source code must retain the above copyright notice, this
36841 list of conditions and the following disclaimer.
36842
36843 2. Redistributions in binary form must reproduce the above copyright notice,
36844 this list of conditions and the following disclaimer in the documentation
36845 and/or other materials provided with the distribution.
36846
36847 3. Neither the name of the copyright holder nor the names of its
36848 contributors may be used to endorse or promote products derived from
36849 this software without specific prior written permission.
36850
36851 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
36852 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
36853 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
36854 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
36855 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36856 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
36857 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
36858 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
36859 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
36860 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36861 <?php
36862
36863 declare (strict_types=1);
36864 /*
36865 * This file is part of phpunit/php-invoker.
36866 *
36867 * (c) Sebastian Bergmann <sebastian@phpunit.de>
36868 *
36869 * For the full copyright and license information, please view the LICENSE
36870 * file that was distributed with this source code.
36871 */
36872 namespace PHPUnitPHAR\SebastianBergmann\Invoker;
36873
36874 use const SIGALRM;
36875 use function call_user_func_array;
36876 use function function_exists;
36877 use function pcntl_alarm;
36878 use function pcntl_async_signals;
36879 use function pcntl_signal;
36880 use function sprintf;
36881 use Throwable;
36882 final class Invoker
36883 {
36884 private int $timeout;
36885 /**
36886 * @throws Throwable
36887 */
36888 public function invoke(callable $callable, array $arguments, int $timeout): mixed
36889 {
36890 if (!$this->canInvokeWithTimeout()) {
36891 throw new ProcessControlExtensionNotLoadedException('The pcntl (process control) extension for PHP is required');
36892 }
36893 pcntl_signal(SIGALRM, function (): void {
36894 throw new TimeoutException(sprintf('Execution aborted after %d second%s', $this->timeout, $this->timeout === 1 ? '' : 's'));
36895 }, \true);
36896 $this->timeout = $timeout;
36897 pcntl_async_signals(\true);
36898 pcntl_alarm($timeout);
36899 try {
36900 return call_user_func_array($callable, $arguments);
36901 } finally {
36902 pcntl_alarm(0);
36903 }
36904 }
36905 public function canInvokeWithTimeout(): bool
36906 {
36907 return function_exists('pcntl_signal') && function_exists('pcntl_async_signals') && function_exists('pcntl_alarm');
36908 }
36909 }
36910 <?php
36911
36912 declare (strict_types=1);
36913 /*
36914 * This file is part of phpunit/php-invoker.
36915 *
36916 * (c) Sebastian Bergmann <sebastian@phpunit.de>
36917 *
36918 * For the full copyright and license information, please view the LICENSE
36919 * file that was distributed with this source code.
36920 */
36921 namespace PHPUnitPHAR\SebastianBergmann\Invoker;
36922
36923 use Throwable;
36924 interface Exception extends Throwable
36925 {
36926 }
36927 <?php
36928
36929 declare (strict_types=1);
36930 /*
36931 * This file is part of phpunit/php-invoker.
36932 *
36933 * (c) Sebastian Bergmann <sebastian@phpunit.de>
36934 *
36935 * For the full copyright and license information, please view the LICENSE
36936 * file that was distributed with this source code.
36937 */
36938 namespace PHPUnitPHAR\SebastianBergmann\Invoker;
36939
36940 use RuntimeException;
36941 final class ProcessControlExtensionNotLoadedException extends RuntimeException implements Exception
36942 {
36943 }
36944 <?php
36945
36946 declare (strict_types=1);
36947 /*
36948 * This file is part of phpunit/php-invoker.
36949 *
36950 * (c) Sebastian Bergmann <sebastian@phpunit.de>
36951 *
36952 * For the full copyright and license information, please view the LICENSE
36953 * file that was distributed with this source code.
36954 */
36955 namespace PHPUnitPHAR\SebastianBergmann\Invoker;
36956
36957 use RuntimeException;
36958 final class TimeoutException extends RuntimeException implements Exception
36959 {
36960 }
36961 BSD 3-Clause License
36962
36963 Copyright (c) 2009-2023, Sebastian Bergmann
36964 All rights reserved.
36965
36966 Redistribution and use in source and binary forms, with or without
36967 modification, are permitted provided that the following conditions are met:
36968
36969 1. Redistributions of source code must retain the above copyright notice, this
36970 list of conditions and the following disclaimer.
36971
36972 2. Redistributions in binary form must reproduce the above copyright notice,
36973 this list of conditions and the following disclaimer in the documentation
36974 and/or other materials provided with the distribution.
36975
36976 3. Neither the name of the copyright holder nor the names of its
36977 contributors may be used to endorse or promote products derived from
36978 this software without specific prior written permission.
36979
36980 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
36981 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
36982 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
36983 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
36984 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36985 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
36986 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
36987 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
36988 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
36989 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36990 <?php
36991
36992 declare (strict_types=1);
36993 /*
36994 * This file is part of phpunit/php-text-template.
36995 *
36996 * (c) Sebastian Bergmann <sebastian@phpunit.de>
36997 *
36998 * For the full copyright and license information, please view the LICENSE
36999 * file that was distributed with this source code.
37000 */
37001 namespace PHPUnitPHAR\SebastianBergmann\Template;
37002
37003 use function array_keys;
37004 use function array_merge;
37005 use function file_get_contents;
37006 use function file_put_contents;
37007 use function is_file;
37008 use function sprintf;
37009 use function str_replace;
37010 final class Template
37011 {
37012 private string $template = '';
37013 private string $openDelimiter;
37014 private string $closeDelimiter;
37015 /**
37016 * @psalm-var array<string,string>
37017 */
37018 private array $values = [];
37019 /**
37020 * @throws InvalidArgumentException
37021 */
37022 public function __construct(string $file = '', string $openDelimiter = '{', string $closeDelimiter = '}')
37023 {
37024 $this->setFile($file);
37025 $this->openDelimiter = $openDelimiter;
37026 $this->closeDelimiter = $closeDelimiter;
37027 }
37028 /**
37029 * @throws InvalidArgumentException
37030 */
37031 public function setFile(string $file): void
37032 {
37033 if (is_file($file)) {
37034 $this->template = file_get_contents($file);
37035 return;
37036 }
37037 $distFile = $file . '.dist';
37038 if (is_file($distFile)) {
37039 $this->template = file_get_contents($distFile);
37040 return;
37041 }
37042 throw new InvalidArgumentException(sprintf('Failed to load template "%s"', $file));
37043 }
37044 /**
37045 * @psalm-param array<string,string> $values
37046 */
37047 public function setVar(array $values, bool $merge = \true): void
37048 {
37049 if (!$merge || empty($this->values)) {
37050 $this->values = $values;
37051 return;
37052 }
37053 $this->values = array_merge($this->values, $values);
37054 }
37055 public function render(): string
37056 {
37057 $keys = [];
37058 foreach (array_keys($this->values) as $key) {
37059 $keys[] = $this->openDelimiter . $key . $this->closeDelimiter;
37060 }
37061 return str_replace($keys, $this->values, $this->template);
37062 }
37063 /**
37064 * @codeCoverageIgnore
37065 */
37066 public function renderTo(string $target): void
37067 {
37068 if (!@file_put_contents($target, $this->render())) {
37069 throw new RuntimeException(sprintf('Writing rendered result to "%s" failed', $target));
37070 }
37071 }
37072 }
37073 <?php
37074
37075 declare (strict_types=1);
37076 /*
37077 * This file is part of phpunit/php-text-template.
37078 *
37079 * (c) Sebastian Bergmann <sebastian@phpunit.de>
37080 *
37081 * For the full copyright and license information, please view the LICENSE
37082 * file that was distributed with this source code.
37083 */
37084 namespace PHPUnitPHAR\SebastianBergmann\Template;
37085
37086 use Throwable;
37087 interface Exception extends Throwable
37088 {
37089 }
37090 <?php
37091
37092 declare (strict_types=1);
37093 /*
37094 * This file is part of phpunit/php-text-template.
37095 *
37096 * (c) Sebastian Bergmann <sebastian@phpunit.de>
37097 *
37098 * For the full copyright and license information, please view the LICENSE
37099 * file that was distributed with this source code.
37100 */
37101 namespace PHPUnitPHAR\SebastianBergmann\Template;
37102
37103 final class InvalidArgumentException extends \InvalidArgumentException implements Exception
37104 {
37105 }
37106 <?php
37107
37108 declare (strict_types=1);
37109 /*
37110 * This file is part of phpunit/php-text-template.
37111 *
37112 * (c) Sebastian Bergmann <sebastian@phpunit.de>
37113 *
37114 * For the full copyright and license information, please view the LICENSE
37115 * file that was distributed with this source code.
37116 */
37117 namespace PHPUnitPHAR\SebastianBergmann\Template;
37118
37119 use InvalidArgumentException;
37120 final class RuntimeException extends InvalidArgumentException implements Exception
37121 {
37122 }
37123 <?php
37124
37125 declare (strict_types=1);
37126 /*
37127 * This file is part of phpunit/php-timer.
37128 *
37129 * (c) Sebastian Bergmann <sebastian@phpunit.de>
37130 *
37131 * For the full copyright and license information, please view the LICENSE
37132 * file that was distributed with this source code.
37133 */
37134 namespace PHPUnitPHAR\SebastianBergmann\Timer;
37135
37136 use function floor;
37137 use function sprintf;
37138 /**
37139 * @psalm-immutable
37140 */
37141 final class Duration
37142 {
37143 private readonly float $nanoseconds;
37144 private readonly int $hours;
37145 private readonly int $minutes;
37146 private readonly int $seconds;
37147 private readonly int $milliseconds;
37148 public static function fromMicroseconds(float $microseconds): self
37149 {
37150 return new self($microseconds * 1000);
37151 }
37152 public static function fromNanoseconds(float $nanoseconds): self
37153 {
37154 return new self($nanoseconds);
37155 }
37156 private function __construct(float $nanoseconds)
37157 {
37158 $this->nanoseconds = $nanoseconds;
37159 $timeInMilliseconds = $nanoseconds / 1000000;
37160 $hours = floor($timeInMilliseconds / 60 / 60 / 1000);
37161 $hoursInMilliseconds = $hours * 60 * 60 * 1000;
37162 $minutes = floor($timeInMilliseconds / 60 / 1000) % 60;
37163 $minutesInMilliseconds = $minutes * 60 * 1000;
37164 $seconds = floor(($timeInMilliseconds - $hoursInMilliseconds - $minutesInMilliseconds) / 1000);
37165 $secondsInMilliseconds = $seconds * 1000;
37166 $milliseconds = $timeInMilliseconds - $hoursInMilliseconds - $minutesInMilliseconds - $secondsInMilliseconds;
37167 $this->hours = (int) $hours;
37168 $this->minutes = $minutes;
37169 $this->seconds = (int) $seconds;
37170 $this->milliseconds = (int) $milliseconds;
37171 }
37172 public function asNanoseconds(): float
37173 {
37174 return $this->nanoseconds;
37175 }
37176 public function asMicroseconds(): float
37177 {
37178 return $this->nanoseconds / 1000;
37179 }
37180 public function asMilliseconds(): float
37181 {
37182 return $this->nanoseconds / 1000000;
37183 }
37184 public function asSeconds(): float
37185 {
37186 return $this->nanoseconds / 1000000000;
37187 }
37188 public function asString(): string
37189 {
37190 $result = '';
37191 if ($this->hours > 0) {
37192 $result = sprintf('%02d', $this->hours) . ':';
37193 }
37194 $result .= sprintf('%02d', $this->minutes) . ':';
37195 $result .= sprintf('%02d', $this->seconds);
37196 if ($this->milliseconds > 0) {
37197 $result .= '.' . sprintf('%03d', $this->milliseconds);
37198 }
37199 return $result;
37200 }
37201 }
37202 BSD 3-Clause License
37203
37204 Copyright (c) 2010-2023, Sebastian Bergmann
37205 All rights reserved.
37206
37207 Redistribution and use in source and binary forms, with or without
37208 modification, are permitted provided that the following conditions are met:
37209
37210 1. Redistributions of source code must retain the above copyright notice, this
37211 list of conditions and the following disclaimer.
37212
37213 2. Redistributions in binary form must reproduce the above copyright notice,
37214 this list of conditions and the following disclaimer in the documentation
37215 and/or other materials provided with the distribution.
37216
37217 3. Neither the name of the copyright holder nor the names of its
37218 contributors may be used to endorse or promote products derived from
37219 this software without specific prior written permission.
37220
37221 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
37222 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
37223 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
37224 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
37225 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37226 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
37227 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
37228 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
37229 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
37230 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37231 <?php
37232
37233 declare (strict_types=1);
37234 /*
37235 * This file is part of phpunit/php-timer.
37236 *
37237 * (c) Sebastian Bergmann <sebastian@phpunit.de>
37238 *
37239 * For the full copyright and license information, please view the LICENSE
37240 * file that was distributed with this source code.
37241 */
37242 namespace PHPUnitPHAR\SebastianBergmann\Timer;
37243
37244 use function is_float;
37245 use function memory_get_peak_usage;
37246 use function microtime;
37247 use function sprintf;
37248 final class ResourceUsageFormatter
37249 {
37250 /**
37251 * @psalm-var array<string,int>
37252 */
37253 private const SIZES = ['GB' => 1073741824, 'MB' => 1048576, 'KB' => 1024];
37254 public function resourceUsage(Duration $duration): string
37255 {
37256 return sprintf('Time: %s, Memory: %s', $duration->asString(), $this->bytesToString(memory_get_peak_usage(\true)));
37257 }
37258 /**
37259 * @throws TimeSinceStartOfRequestNotAvailableException
37260 */
37261 public function resourceUsageSinceStartOfRequest(): string
37262 {
37263 if (!isset($_SERVER['REQUEST_TIME_FLOAT'])) {
37264 throw new TimeSinceStartOfRequestNotAvailableException('Cannot determine time at which the request started because $_SERVER[\'REQUEST_TIME_FLOAT\'] is not available');
37265 }
37266 if (!is_float($_SERVER['REQUEST_TIME_FLOAT'])) {
37267 throw new TimeSinceStartOfRequestNotAvailableException('Cannot determine time at which the request started because $_SERVER[\'REQUEST_TIME_FLOAT\'] is not of type float');
37268 }
37269 return $this->resourceUsage(Duration::fromMicroseconds(1000000 * (microtime(\true) - $_SERVER['REQUEST_TIME_FLOAT'])));
37270 }
37271 private function bytesToString(int $bytes): string
37272 {
37273 foreach (self::SIZES as $unit => $value) {
37274 if ($bytes >= $value) {
37275 return sprintf('%.2f %s', $bytes / $value, $unit);
37276 }
37277 }
37278 // @codeCoverageIgnoreStart
37279 return $bytes . ' byte' . ($bytes !== 1 ? 's' : '');
37280 // @codeCoverageIgnoreEnd
37281 }
37282 }
37283 <?php
37284
37285 declare (strict_types=1);
37286 /*
37287 * This file is part of phpunit/php-timer.
37288 *
37289 * (c) Sebastian Bergmann <sebastian@phpunit.de>
37290 *
37291 * For the full copyright and license information, please view the LICENSE
37292 * file that was distributed with this source code.
37293 */
37294 namespace PHPUnitPHAR\SebastianBergmann\Timer;
37295
37296 use function array_pop;
37297 use function hrtime;
37298 final class Timer
37299 {
37300 /**
37301 * @psalm-var list<float>
37302 */
37303 private array $startTimes = [];
37304 public function start(): void
37305 {
37306 $this->startTimes[] = (float) hrtime(\true);
37307 }
37308 /**
37309 * @throws NoActiveTimerException
37310 */
37311 public function stop(): Duration
37312 {
37313 if (empty($this->startTimes)) {
37314 throw new NoActiveTimerException('Timer::start() has to be called before Timer::stop()');
37315 }
37316 return Duration::fromNanoseconds((float) hrtime(\true) - array_pop($this->startTimes));
37317 }
37318 }
37319 <?php
37320
37321 declare (strict_types=1);
37322 /*
37323 * This file is part of phpunit/php-timer.
37324 *
37325 * (c) Sebastian Bergmann <sebastian@phpunit.de>
37326 *
37327 * For the full copyright and license information, please view the LICENSE
37328 * file that was distributed with this source code.
37329 */
37330 namespace PHPUnitPHAR\SebastianBergmann\Timer;
37331
37332 use Throwable;
37333 interface Exception extends Throwable
37334 {
37335 }
37336 <?php
37337
37338 declare (strict_types=1);
37339 /*
37340 * This file is part of phpunit/php-timer.
37341 *
37342 * (c) Sebastian Bergmann <sebastian@phpunit.de>
37343 *
37344 * For the full copyright and license information, please view the LICENSE
37345 * file that was distributed with this source code.
37346 */
37347 namespace PHPUnitPHAR\SebastianBergmann\Timer;
37348
37349 use LogicException;
37350 final class NoActiveTimerException extends LogicException implements Exception
37351 {
37352 }
37353 <?php
37354
37355 declare (strict_types=1);
37356 /*
37357 * This file is part of phpunit/php-timer.
37358 *
37359 * (c) Sebastian Bergmann <sebastian@phpunit.de>
37360 *
37361 * For the full copyright and license information, please view the LICENSE
37362 * file that was distributed with this source code.
37363 */
37364 namespace PHPUnitPHAR\SebastianBergmann\Timer;
37365
37366 use RuntimeException;
37367 final class TimeSinceStartOfRequestNotAvailableException extends RuntimeException implements Exception
37368 {
37369 }
37370 <?xml version="1.0" encoding="UTF-8"?>
37371 <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
37372 <xs:annotation>
37373 <xs:documentation source="https://phpunit.de/documentation.html">
37374 This Schema file defines the rules by which the XML configuration file of PHPUnit 10.5 may be structured.
37375 </xs:documentation>
37376 <xs:appinfo source="https://phpunit.de/documentation.html"/>
37377 </xs:annotation>
37378 <xs:element name="phpunit" type="phpUnitType">
37379 <xs:annotation>
37380 <xs:documentation>Root Element</xs:documentation>
37381 </xs:annotation>
37382 </xs:element>
37383 <xs:complexType name="sourceType">
37384 <xs:all>
37385 <xs:element name="include" minOccurs="0" maxOccurs="1">
37386 <xs:complexType>
37387 <xs:group ref="sourcePathGroup"/>
37388 </xs:complexType>
37389 </xs:element>
37390 <xs:element name="exclude" minOccurs="0" maxOccurs="1">
37391 <xs:complexType>
37392 <xs:group ref="sourcePathGroup"/>
37393 </xs:complexType>
37394 </xs:element>
37395 </xs:all>
37396 <xs:attribute name="baseline" type="xs:anyURI"/>
37397 <xs:attribute name="restrictDeprecations" type="xs:boolean" default="false"/>
37398 <xs:attribute name="restrictNotices" type="xs:boolean" default="false"/>
37399 <xs:attribute name="restrictWarnings" type="xs:boolean" default="false"/>
37400 <xs:attribute name="ignoreSuppressionOfDeprecations" type="xs:boolean" default="false"/>
37401 <xs:attribute name="ignoreSuppressionOfPhpDeprecations" type="xs:boolean" default="false"/>
37402 <xs:attribute name="ignoreSuppressionOfErrors" type="xs:boolean" default="false"/>
37403 <xs:attribute name="ignoreSuppressionOfNotices" type="xs:boolean" default="false"/>
37404 <xs:attribute name="ignoreSuppressionOfPhpNotices" type="xs:boolean" default="false"/>
37405 <xs:attribute name="ignoreSuppressionOfWarnings" type="xs:boolean" default="false"/>
37406 <xs:attribute name="ignoreSuppressionOfPhpWarnings" type="xs:boolean" default="false"/>
37407 </xs:complexType>
37408 <xs:group name="sourcePathGroup">
37409 <xs:sequence>
37410 <xs:choice minOccurs="0" maxOccurs="unbounded">
37411 <xs:element name="directory" type="sourceDirectoryType"/>
37412 <xs:element name="file" type="xs:anyURI"/>
37413 </xs:choice>
37414 </xs:sequence>
37415 </xs:group>
37416 <xs:complexType name="sourceDirectoryType">
37417 <xs:simpleContent>
37418 <xs:extension base="xs:string">
37419 <xs:attribute type="xs:string" name="prefix" default=""/>
37420 <xs:attribute type="xs:string" name="suffix" default=".php"/>
37421 </xs:extension>
37422 </xs:simpleContent>
37423 </xs:complexType>
37424 <xs:complexType name="coverageType">
37425 <xs:all>
37426 <xs:element name="report" minOccurs="0" maxOccurs="1">
37427 <xs:complexType>
37428 <xs:group ref="coverageReportGroup"/>
37429 </xs:complexType>
37430 </xs:element>
37431 </xs:all>
37432 <xs:attribute name="cacheDirectory" type="xs:anyURI"/>
37433 <xs:attribute name="pathCoverage" type="xs:boolean" default="false"/>
37434 <xs:attribute name="includeUncoveredFiles" type="xs:boolean" default="true"/>
37435 <xs:attribute name="ignoreDeprecatedCodeUnits" type="xs:boolean" default="false"/>
37436 <xs:attribute name="disableCodeCoverageIgnore" type="xs:boolean" default="false"/>
37437 </xs:complexType>
37438 <xs:complexType name="loggingType">
37439 <xs:group ref="loggingGroup"/>
37440 </xs:complexType>
37441 <xs:complexType name="groupsType">
37442 <xs:choice>
37443 <xs:sequence>
37444 <xs:element name="include" type="groupType"/>
37445 <xs:element name="exclude" type="groupType" minOccurs="0"/>
37446 </xs:sequence>
37447 <xs:sequence>
37448 <xs:element name="exclude" type="groupType"/>
37449 </xs:sequence>
37450 </xs:choice>
37451 </xs:complexType>
37452 <xs:complexType name="groupType">
37453 <xs:sequence>
37454 <xs:element name="group" type="xs:string" maxOccurs="unbounded"/>
37455 </xs:sequence>
37456 </xs:complexType>
37457 <xs:complexType name="extensionsType">
37458 <xs:sequence>
37459 <xs:element name="bootstrap" type="bootstrapType" minOccurs="0" maxOccurs="unbounded"/>
37460 </xs:sequence>
37461 </xs:complexType>
37462 <xs:complexType name="bootstrapType">
37463 <xs:sequence>
37464 <xs:element name="parameter" type="parameterType" minOccurs="0" maxOccurs="unbounded"/>
37465 </xs:sequence>
37466 <xs:attribute name="class" type="xs:string" use="required"/>
37467 </xs:complexType>
37468 <xs:complexType name="parameterType">
37469 <xs:attribute name="name" type="xs:string" use="required"/>
37470 <xs:attribute name="value" type="xs:string" use="required"/>
37471 </xs:complexType>
37472 <xs:simpleType name="columnsType">
37473 <xs:union>
37474 <xs:simpleType>
37475 <xs:restriction base="xs:integer"/>
37476 </xs:simpleType>
37477 <xs:simpleType>
37478 <xs:restriction base="xs:string">
37479 <xs:enumeration value="max"/>
37480 </xs:restriction>
37481 </xs:simpleType>
37482 </xs:union>
37483 </xs:simpleType>
37484 <xs:simpleType name="executionOrderType">
37485 <xs:restriction base="xs:string">
37486 <xs:enumeration value="default"/>
37487 <xs:enumeration value="defects"/>
37488 <xs:enumeration value="defects,random"/>
37489 <xs:enumeration value="depends"/>
37490 <xs:enumeration value="depends,defects"/>
37491 <xs:enumeration value="depends,duration"/>
37492 <xs:enumeration value="depends,random"/>
37493 <xs:enumeration value="depends,reverse"/>
37494 <xs:enumeration value="depends,size"/>
37495 <xs:enumeration value="duration"/>
37496 <xs:enumeration value="no-depends"/>
37497 <xs:enumeration value="no-depends,defects"/>
37498 <xs:enumeration value="no-depends,duration"/>
37499 <xs:enumeration value="no-depends,random"/>
37500 <xs:enumeration value="no-depends,reverse"/>
37501 <xs:enumeration value="no-depends,size"/>
37502 <xs:enumeration value="random"/>
37503 <xs:enumeration value="reverse"/>
37504 <xs:enumeration value="size"/>
37505 </xs:restriction>
37506 </xs:simpleType>
37507 <xs:complexType name="phpType">
37508 <xs:sequence>
37509 <xs:choice maxOccurs="unbounded">
37510 <xs:element name="includePath" type="xs:anyURI" minOccurs="0" maxOccurs="unbounded"/>
37511 <xs:element name="ini" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
37512 <xs:element name="const" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
37513 <xs:element name="var" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
37514 <xs:element name="env" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
37515 <xs:element name="post" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
37516 <xs:element name="get" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
37517 <xs:element name="cookie" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
37518 <xs:element name="server" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
37519 <xs:element name="files" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
37520 <xs:element name="request" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
37521 </xs:choice>
37522 </xs:sequence>
37523 </xs:complexType>
37524 <xs:complexType name="namedValueType">
37525 <xs:attribute name="name" use="required" type="xs:string"/>
37526 <xs:attribute name="value" use="required" type="xs:anySimpleType"/>
37527 <xs:attribute name="verbatim" use="optional" type="xs:boolean"/>
37528 <xs:attribute name="force" use="optional" type="xs:boolean"/>
37529 </xs:complexType>
37530 <xs:complexType name="phpUnitType">
37531 <xs:annotation>
37532 <xs:documentation>The main type specifying the document structure</xs:documentation>
37533 </xs:annotation>
37534 <xs:group ref="configGroup"/>
37535 <xs:attributeGroup ref="configAttributeGroup"/>
37536 </xs:complexType>
37537 <xs:attributeGroup name="configAttributeGroup">
37538 <xs:attribute name="backupGlobals" type="xs:boolean" default="false"/>
37539 <xs:attribute name="backupStaticProperties" type="xs:boolean" default="false"/>
37540 <xs:attribute name="bootstrap" type="xs:anyURI"/>
37541 <xs:attribute name="cacheDirectory" type="xs:anyURI"/>
37542 <xs:attribute name="cacheResult" type="xs:boolean" default="true"/>
37543 <xs:attribute name="cacheResultFile" type="xs:anyURI"/>
37544 <xs:attribute name="colors" type="xs:boolean" default="false"/>
37545 <xs:attribute name="columns" type="columnsType" default="80"/>
37546 <xs:attribute name="controlGarbageCollector" type="xs:boolean" default="false"/>
37547 <xs:attribute name="numberOfTestsBeforeGarbageCollection" type="xs:integer" default="100"/>
37548 <xs:attribute name="requireCoverageMetadata" type="xs:boolean" default="false"/>
37549 <xs:attribute name="processIsolation" type="xs:boolean" default="false"/>
37550 <xs:attribute name="failOnAllIssues" type="xs:boolean" default="false"/>
37551 <xs:attribute name="failOnDeprecation" type="xs:boolean" default="false"/>
37552 <xs:attribute name="failOnPhpunitDeprecation" type="xs:boolean" default="false"/>
37553 <xs:attribute name="failOnPhpunitWarning" type="xs:boolean" default="true"/>
37554 <xs:attribute name="failOnEmptyTestSuite" type="xs:boolean" default="false"/>
37555 <xs:attribute name="failOnIncomplete" type="xs:boolean" default="false"/>
37556 <xs:attribute name="failOnNotice" type="xs:boolean" default="false"/>
37557 <xs:attribute name="failOnRisky" type="xs:boolean" default="false"/>
37558 <xs:attribute name="failOnSkipped" type="xs:boolean" default="false"/>
37559 <xs:attribute name="failOnWarning" type="xs:boolean" default="false"/>
37560 <xs:attribute name="stopOnDefect" type="xs:boolean" default="false"/>
37561 <xs:attribute name="stopOnDeprecation" type="xs:boolean" default="false"/>
37562 <xs:attribute name="stopOnError" type="xs:boolean" default="false"/>
37563 <xs:attribute name="stopOnFailure" type="xs:boolean" default="false"/>
37564 <xs:attribute name="stopOnIncomplete" type="xs:boolean" default="false"/>
37565 <xs:attribute name="stopOnNotice" type="xs:boolean" default="false"/>
37566 <xs:attribute name="stopOnRisky" type="xs:boolean" default="false"/>
37567 <xs:attribute name="stopOnSkipped" type="xs:boolean" default="false"/>
37568 <xs:attribute name="stopOnWarning" type="xs:boolean" default="false"/>
37569 <xs:attribute name="beStrictAboutChangesToGlobalState" type="xs:boolean" default="false"/>
37570 <xs:attribute name="beStrictAboutOutputDuringTests" type="xs:boolean" default="false"/>
37571 <xs:attribute name="beStrictAboutTestsThatDoNotTestAnything" type="xs:boolean" default="true"/>
37572 <xs:attribute name="beStrictAboutCoverageMetadata" type="xs:boolean" default="false"/>
37573 <xs:attribute name="defaultTimeLimit" type="xs:integer" default="0"/>
37574 <xs:attribute name="enforceTimeLimit" type="xs:boolean" default="false"/>
37575 <xs:attribute name="timeoutForSmallTests" type="xs:integer" default="1"/>
37576 <xs:attribute name="timeoutForMediumTests" type="xs:integer" default="10"/>
37577 <xs:attribute name="timeoutForLargeTests" type="xs:integer" default="60"/>
37578 <xs:attribute name="defaultTestSuite" type="xs:string" default=""/>
37579 <xs:attribute name="testdox" type="xs:boolean" default="false"/>
37580 <xs:attribute name="stderr" type="xs:boolean" default="false"/>
37581 <xs:attribute name="reverseDefectList" type="xs:boolean" default="false"/>
37582 <xs:attribute name="registerMockObjectsFromTestArgumentsRecursively" type="xs:boolean" default="false"/>
37583 <xs:attribute name="extensionsDirectory" type="xs:anyURI"/>
37584 <xs:attribute name="executionOrder" type="executionOrderType" default="default"/>
37585 <xs:attribute name="resolveDependencies" type="xs:boolean" default="true"/>
37586 <xs:attribute name="displayDetailsOnAllIssues" type="xs:boolean" default="false"/>
37587 <xs:attribute name="displayDetailsOnIncompleteTests" type="xs:boolean" default="false"/>
37588 <xs:attribute name="displayDetailsOnSkippedTests" type="xs:boolean" default="false"/>
37589 <xs:attribute name="displayDetailsOnTestsThatTriggerDeprecations" type="xs:boolean" default="false"/>
37590 <xs:attribute name="displayDetailsOnPhpunitDeprecations" type="xs:boolean" default="false"/>
37591 <xs:attribute name="displayDetailsOnTestsThatTriggerErrors" type="xs:boolean" default="false"/>
37592 <xs:attribute name="displayDetailsOnTestsThatTriggerNotices" type="xs:boolean" default="false"/>
37593 <xs:attribute name="displayDetailsOnTestsThatTriggerWarnings" type="xs:boolean" default="false"/>
37594 </xs:attributeGroup>
37595 <xs:group name="configGroup">
37596 <xs:all>
37597 <xs:element ref="testSuiteFacet" minOccurs="0"/>
37598 <xs:element name="groups" type="groupsType" minOccurs="0"/>
37599 <xs:element name="source" type="sourceType" minOccurs="0"/>
37600 <xs:element name="coverage" type="coverageType" minOccurs="0"/>
37601 <xs:element name="logging" type="loggingType" minOccurs="0"/>
37602 <xs:element name="extensions" type="extensionsType" minOccurs="0"/>
37603 <xs:element name="php" type="phpType" minOccurs="0"/>
37604 </xs:all>
37605 </xs:group>
37606 <xs:element name="testSuiteFacet" abstract="true"/>
37607 <xs:element name="testsuite" type="testSuiteType" substitutionGroup="testSuiteFacet"/>
37608 <xs:element name="testsuites" type="testSuitesType" substitutionGroup="testSuiteFacet"/>
37609 <xs:complexType name="testSuitesType">
37610 <xs:sequence>
37611 <xs:element name="testsuite" type="testSuiteType" maxOccurs="unbounded"/>
37612 </xs:sequence>
37613 </xs:complexType>
37614 <xs:complexType name="testSuiteType">
37615 <xs:sequence>
37616 <xs:choice minOccurs="0" maxOccurs="unbounded">
37617 <xs:group ref="testSuitePathGroup"/>
37618 <xs:element name="exclude" type="xs:string"/>
37619 </xs:choice>
37620 </xs:sequence>
37621 <xs:attribute name="name" type="xs:string" use="required"/>
37622 </xs:complexType>
37623 <xs:group name="testSuitePathGroup">
37624 <xs:sequence>
37625 <xs:choice minOccurs="0" maxOccurs="unbounded">
37626 <xs:element name="directory" type="testSuiteDirectoryType"/>
37627 <xs:element name="file" type="testSuiteFileType"/>
37628 </xs:choice>
37629 </xs:sequence>
37630 </xs:group>
37631 <xs:complexType name="testSuiteDirectoryType">
37632 <xs:simpleContent>
37633 <xs:extension base="xs:string">
37634 <xs:attribute type="xs:string" name="prefix" default=""/>
37635 <xs:attribute type="xs:string" name="suffix" default="Test.php"/>
37636 <xs:attributeGroup ref="phpVersionGroup"/>
37637 </xs:extension>
37638 </xs:simpleContent>
37639 </xs:complexType>
37640 <xs:complexType name="testSuiteFileType">
37641 <xs:simpleContent>
37642 <xs:extension base="xs:anyURI">
37643 <xs:attributeGroup ref="phpVersionGroup"/>
37644 </xs:extension>
37645 </xs:simpleContent>
37646 </xs:complexType>
37647 <xs:attributeGroup name="phpVersionGroup">
37648 <xs:attribute name="phpVersion" type="xs:string" default="5.3.0"/>
37649 <xs:attribute name="phpVersionOperator" type="xs:string" default="&gt;="/>
37650 </xs:attributeGroup>
37651 <xs:group name="coverageReportGroup">
37652 <xs:all>
37653 <xs:element name="clover" type="logToFileType" minOccurs="0"/>
37654 <xs:element name="cobertura" type="logToFileType" minOccurs="0"/>
37655 <xs:element name="crap4j" type="coverageReportCrap4JType" minOccurs="0" />
37656 <xs:element name="html" type="coverageReportHtmlType" minOccurs="0" />
37657 <xs:element name="php" type="logToFileType" minOccurs="0" />
37658 <xs:element name="text" type="coverageReportTextType" minOccurs="0" />
37659 <xs:element name="xml" type="logToDirectoryType" minOccurs="0" />
37660 </xs:all>
37661 </xs:group>
37662 <xs:group name="loggingGroup">
37663 <xs:all>
37664 <xs:element name="junit" type="logToFileType" minOccurs="0" />
37665 <xs:element name="teamcity" type="logToFileType" minOccurs="0" />
37666 <xs:element name="testdoxHtml" type="logToFileType" minOccurs="0" />
37667 <xs:element name="testdoxText" type="logToFileType" minOccurs="0" />
37668 </xs:all>
37669 </xs:group>
37670 <xs:complexType name="logToFileType">
37671 <xs:attribute name="outputFile" type="xs:anyURI" use="required"/>
37672 </xs:complexType>
37673 <xs:complexType name="logToDirectoryType">
37674 <xs:attribute name="outputDirectory" type="xs:anyURI" use="required"/>
37675 </xs:complexType>
37676 <xs:complexType name="coverageReportCrap4JType">
37677 <xs:attribute name="outputFile" type="xs:anyURI" use="required"/>
37678 <xs:attribute name="threshold" type="xs:integer"/>
37679 </xs:complexType>
37680 <xs:complexType name="coverageReportHtmlType">
37681 <xs:attribute name="outputDirectory" type="xs:anyURI" use="required"/>
37682 <xs:attribute name="lowUpperBound" type="xs:integer" default="50"/>
37683 <xs:attribute name="highLowerBound" type="xs:integer" default="90"/>
37684 <xs:attribute name="colorSuccessLow" type="xs:string" default="#dff0d8"/>
37685 <xs:attribute name="colorSuccessMedium" type="xs:string" default="#c3e3b5"/>
37686 <xs:attribute name="colorSuccessHigh" type="xs:string" default="#99cb84"/>
37687 <xs:attribute name="colorWarning" type="xs:string" default="#fcf8e3"/>
37688 <xs:attribute name="colorDanger" type="xs:string" default="#f2dede"/>
37689 <xs:attribute name="customCssFile" type="xs:string"/>
37690 </xs:complexType>
37691 <xs:complexType name="coverageReportTextType">
37692 <xs:attribute name="outputFile" type="xs:anyURI" use="required"/>
37693 <xs:attribute name="showUncoveredFiles" type="xs:boolean" default="false"/>
37694 <xs:attribute name="showOnlySummary" type="xs:boolean" default="false"/>
37695 </xs:complexType>
37696 </xs:schema>
37697 <?php
37698
37699 declare (strict_types=1);
37700 /*
37701 * This file is part of PHPUnit.
37702 *
37703 * (c) Sebastian Bergmann <sebastian@phpunit.de>
37704 *
37705 * For the full copyright and license information, please view the LICENSE
37706 * file that was distributed with this source code.
37707 */
37708 namespace PHPUnit\Event;
37709
37710 /**
37711 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
37712 *
37713 * @internal This class is not covered by the backward compatibility promise for PHPUnit
37714 */
37715 final class CollectingDispatcher implements \PHPUnit\Event\Dispatcher
37716 {
37717 private \PHPUnit\Event\EventCollection $events;
37718 public function __construct()
37719 {
37720 $this->events = new \PHPUnit\Event\EventCollection();
37721 }
37722 public function dispatch(\PHPUnit\Event\Event $event): void
37723 {
37724 $this->events->add($event);
37725 }
37726 public function flush(): \PHPUnit\Event\EventCollection
37727 {
37728 $events = $this->events;
37729 $this->events = new \PHPUnit\Event\EventCollection();
37730 return $events;
37731 }
37732 }
37733 <?php
37734
37735 declare (strict_types=1);
37736 /*
37737 * This file is part of PHPUnit.
37738 *
37739 * (c) Sebastian Bergmann <sebastian@phpunit.de>
37740 *
37741 * For the full copyright and license information, please view the LICENSE
37742 * file that was distributed with this source code.
37743 */
37744 namespace PHPUnit\Event;
37745
37746 /**
37747 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
37748 *
37749 * @internal This class is not covered by the backward compatibility promise for PHPUnit
37750 */
37751 final class DeferringDispatcher implements \PHPUnit\Event\SubscribableDispatcher
37752 {
37753 private readonly \PHPUnit\Event\SubscribableDispatcher $dispatcher;
37754 private \PHPUnit\Event\EventCollection $events;
37755 private bool $recording = \true;
37756 public function __construct(\PHPUnit\Event\SubscribableDispatcher $dispatcher)
37757 {
37758 $this->dispatcher = $dispatcher;
37759 $this->events = new \PHPUnit\Event\EventCollection();
37760 }
37761 public function registerTracer(\PHPUnit\Event\Tracer\Tracer $tracer): void
37762 {
37763 $this->dispatcher->registerTracer($tracer);
37764 }
37765 public function registerSubscriber(\PHPUnit\Event\Subscriber $subscriber): void
37766 {
37767 $this->dispatcher->registerSubscriber($subscriber);
37768 }
37769 public function dispatch(\PHPUnit\Event\Event $event): void
37770 {
37771 if ($this->recording) {
37772 $this->events->add($event);
37773 return;
37774 }
37775 $this->dispatcher->dispatch($event);
37776 }
37777 public function flush(): void
37778 {
37779 $this->recording = \false;
37780 foreach ($this->events as $event) {
37781 $this->dispatcher->dispatch($event);
37782 }
37783 $this->events = new \PHPUnit\Event\EventCollection();
37784 }
37785 }
37786 <?php
37787
37788 declare (strict_types=1);
37789 /*
37790 * This file is part of PHPUnit.
37791 *
37792 * (c) Sebastian Bergmann <sebastian@phpunit.de>
37793 *
37794 * For the full copyright and license information, please view the LICENSE
37795 * file that was distributed with this source code.
37796 */
37797 namespace PHPUnit\Event;
37798
37799 use const PHP_EOL;
37800 use function array_key_exists;
37801 use function dirname;
37802 use function sprintf;
37803 use function str_starts_with;
37804 use Throwable;
37805 /**
37806 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
37807 *
37808 * @internal This class is not covered by the backward compatibility promise for PHPUnit
37809 */
37810 final class DirectDispatcher implements \PHPUnit\Event\SubscribableDispatcher
37811 {
37812 private readonly \PHPUnit\Event\TypeMap $typeMap;
37813 /**
37814 * @psalm-var array<class-string, list<Subscriber>>
37815 */
37816 private array $subscribers = [];
37817 /**
37818 * @psalm-var list<Tracer\Tracer>
37819 */
37820 private array $tracers = [];
37821 public function __construct(\PHPUnit\Event\TypeMap $map)
37822 {
37823 $this->typeMap = $map;
37824 }
37825 public function registerTracer(\PHPUnit\Event\Tracer\Tracer $tracer): void
37826 {
37827 $this->tracers[] = $tracer;
37828 }
37829 /**
37830 * @throws MapError
37831 * @throws UnknownSubscriberTypeException
37832 */
37833 public function registerSubscriber(\PHPUnit\Event\Subscriber $subscriber): void
37834 {
37835 if (!$this->typeMap->isKnownSubscriberType($subscriber)) {
37836 throw new \PHPUnit\Event\UnknownSubscriberTypeException(sprintf('Subscriber "%s" does not implement any known interface - did you forget to register it?', $subscriber::class));
37837 }
37838 $eventClassName = $this->typeMap->map($subscriber);
37839 if (!array_key_exists($eventClassName, $this->subscribers)) {
37840 $this->subscribers[$eventClassName] = [];
37841 }
37842 $this->subscribers[$eventClassName][] = $subscriber;
37843 }
37844 /**
37845 * @throws Throwable
37846 * @throws UnknownEventTypeException
37847 */
37848 public function dispatch(\PHPUnit\Event\Event $event): void
37849 {
37850 $eventClassName = $event::class;
37851 if (!$this->typeMap->isKnownEventType($event)) {
37852 throw new \PHPUnit\Event\UnknownEventTypeException(sprintf('Unknown event type "%s"', $eventClassName));
37853 }
37854 foreach ($this->tracers as $tracer) {
37855 try {
37856 $tracer->trace($event);
37857 // @codeCoverageIgnoreStart
37858 } catch (Throwable $t) {
37859 $this->handleThrowable($t);
37860 }
37861 // @codeCoverageIgnoreEnd
37862 }
37863 if (!array_key_exists($eventClassName, $this->subscribers)) {
37864 return;
37865 }
37866 foreach ($this->subscribers[$eventClassName] as $subscriber) {
37867 try {
37868 $subscriber->notify($event);
37869 } catch (Throwable $t) {
37870 $this->handleThrowable($t);
37871 }
37872 }
37873 }
37874 /**
37875 * @throws Throwable
37876 */
37877 public function handleThrowable(Throwable $t): void
37878 {
37879 if ($this->isThrowableFromThirdPartySubscriber($t)) {
37880 \PHPUnit\Event\Facade::emitter()->testRunnerTriggeredPhpunitWarning(sprintf('Exception in third-party event subscriber: %s%s%s', $t->getMessage(), PHP_EOL, $t->getTraceAsString()));
37881 return;
37882 }
37883 // @codeCoverageIgnoreStart
37884 throw $t;
37885 // @codeCoverageIgnoreEnd
37886 }
37887 private function isThrowableFromThirdPartySubscriber(Throwable $t): bool
37888 {
37889 return !str_starts_with($t->getFile(), dirname(__DIR__, 2));
37890 }
37891 }
37892 <?php
37893
37894 declare (strict_types=1);
37895 /*
37896 * This file is part of PHPUnit.
37897 *
37898 * (c) Sebastian Bergmann <sebastian@phpunit.de>
37899 *
37900 * For the full copyright and license information, please view the LICENSE
37901 * file that was distributed with this source code.
37902 */
37903 namespace PHPUnit\Event;
37904
37905 /**
37906 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
37907 *
37908 * @internal This interface is not covered by the backward compatibility promise for PHPUnit
37909 */
37910 interface Dispatcher
37911 {
37912 /**
37913 * @throws UnknownEventTypeException
37914 */
37915 public function dispatch(\PHPUnit\Event\Event $event): void;
37916 }
37917 <?php
37918
37919 declare (strict_types=1);
37920 /*
37921 * This file is part of PHPUnit.
37922 *
37923 * (c) Sebastian Bergmann <sebastian@phpunit.de>
37924 *
37925 * For the full copyright and license information, please view the LICENSE
37926 * file that was distributed with this source code.
37927 */
37928 namespace PHPUnit\Event;
37929
37930 /**
37931 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
37932 *
37933 * @internal This interface is not covered by the backward compatibility promise for PHPUnit
37934 */
37935 interface SubscribableDispatcher extends \PHPUnit\Event\Dispatcher
37936 {
37937 /**
37938 * @throws UnknownSubscriberTypeException
37939 */
37940 public function registerSubscriber(\PHPUnit\Event\Subscriber $subscriber): void;
37941 public function registerTracer(\PHPUnit\Event\Tracer\Tracer $tracer): void;
37942 }
37943 <?php
37944
37945 declare (strict_types=1);
37946 /*
37947 * This file is part of PHPUnit.
37948 *
37949 * (c) Sebastian Bergmann <sebastian@phpunit.de>
37950 *
37951 * For the full copyright and license information, please view the LICENSE
37952 * file that was distributed with this source code.
37953 */
37954 namespace PHPUnit\Event;
37955
37956 use PHPUnit\Event\Code\ClassMethod;
37957 use PHPUnit\Event\Code\ComparisonFailure;
37958 use PHPUnit\Event\Code\Throwable;
37959 use PHPUnit\Event\Test\DataProviderMethodCalled;
37960 use PHPUnit\Event\Test\DataProviderMethodFinished;
37961 use PHPUnit\Event\TestSuite\Filtered as TestSuiteFiltered;
37962 use PHPUnit\Event\TestSuite\Finished as TestSuiteFinished;
37963 use PHPUnit\Event\TestSuite\Loaded as TestSuiteLoaded;
37964 use PHPUnit\Event\TestSuite\Skipped as TestSuiteSkipped;
37965 use PHPUnit\Event\TestSuite\Sorted as TestSuiteSorted;
37966 use PHPUnit\Event\TestSuite\Started as TestSuiteStarted;
37967 use PHPUnit\Event\TestSuite\TestSuite;
37968 use PHPUnit\Framework\Constraint;
37969 use PHPUnit\TextUI\Configuration\Configuration;
37970 use PHPUnit\Util\Exporter;
37971 /**
37972 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
37973 *
37974 * @internal This class is not covered by the backward compatibility promise for PHPUnit
37975 */
37976 final class DispatchingEmitter implements \PHPUnit\Event\Emitter
37977 {
37978 private readonly \PHPUnit\Event\Dispatcher $dispatcher;
37979 private readonly \PHPUnit\Event\Telemetry\System $system;
37980 private readonly \PHPUnit\Event\Telemetry\Snapshot $startSnapshot;
37981 private \PHPUnit\Event\Telemetry\Snapshot $previousSnapshot;
37982 private bool $exportObjects = \false;
37983 public function __construct(\PHPUnit\Event\Dispatcher $dispatcher, \PHPUnit\Event\Telemetry\System $system)
37984 {
37985 $this->dispatcher = $dispatcher;
37986 $this->system = $system;
37987 $this->startSnapshot = $system->snapshot();
37988 $this->previousSnapshot = $this->startSnapshot;
37989 }
37990 /**
37991 * @deprecated
37992 */
37993 public function exportObjects(): void
37994 {
37995 $this->exportObjects = \true;
37996 }
37997 /**
37998 * @deprecated
37999 */
38000 public function exportsObjects(): bool
38001 {
38002 return $this->exportObjects;
38003 }
38004 /**
38005 * @throws InvalidArgumentException
38006 * @throws UnknownEventTypeException
38007 */
38008 public function applicationStarted(): void
38009 {
38010 $this->dispatcher->dispatch(new \PHPUnit\Event\Application\Started($this->telemetryInfo(), new \PHPUnit\Event\Runtime\Runtime()));
38011 }
38012 /**
38013 * @throws InvalidArgumentException
38014 * @throws UnknownEventTypeException
38015 */
38016 public function testRunnerStarted(): void
38017 {
38018 $this->dispatcher->dispatch(new \PHPUnit\Event\TestRunner\Started($this->telemetryInfo()));
38019 }
38020 /**
38021 * @throws InvalidArgumentException
38022 * @throws UnknownEventTypeException
38023 */
38024 public function testRunnerConfigured(Configuration $configuration): void
38025 {
38026 $this->dispatcher->dispatch(new \PHPUnit\Event\TestRunner\Configured($this->telemetryInfo(), $configuration));
38027 }
38028 /**
38029 * @throws InvalidArgumentException
38030 * @throws UnknownEventTypeException
38031 */
38032 public function testRunnerBootstrapFinished(string $filename): void
38033 {
38034 $this->dispatcher->dispatch(new \PHPUnit\Event\TestRunner\BootstrapFinished($this->telemetryInfo(), $filename));
38035 }
38036 /**
38037 * @throws InvalidArgumentException
38038 * @throws UnknownEventTypeException
38039 */
38040 public function testRunnerLoadedExtensionFromPhar(string $filename, string $name, string $version): void
38041 {
38042 $this->dispatcher->dispatch(new \PHPUnit\Event\TestRunner\ExtensionLoadedFromPhar($this->telemetryInfo(), $filename, $name, $version));
38043 }
38044 /**
38045 * @psalm-param class-string $className
38046 * @psalm-param array<string, string> $parameters
38047 *
38048 * @throws InvalidArgumentException
38049 * @throws UnknownEventTypeException
38050 */
38051 public function testRunnerBootstrappedExtension(string $className, array $parameters): void
38052 {
38053 $this->dispatcher->dispatch(new \PHPUnit\Event\TestRunner\ExtensionBootstrapped($this->telemetryInfo(), $className, $parameters));
38054 }
38055 /**
38056 * @throws InvalidArgumentException
38057 * @throws UnknownEventTypeException
38058 */
38059 public function dataProviderMethodCalled(ClassMethod $testMethod, ClassMethod $dataProviderMethod): void
38060 {
38061 $this->dispatcher->dispatch(new DataProviderMethodCalled($this->telemetryInfo(), $testMethod, $dataProviderMethod));
38062 }
38063 /**
38064 * @throws InvalidArgumentException
38065 * @throws UnknownEventTypeException
38066 */
38067 public function dataProviderMethodFinished(ClassMethod $testMethod, ClassMethod ...$calledMethods): void
38068 {
38069 $this->dispatcher->dispatch(new DataProviderMethodFinished($this->telemetryInfo(), $testMethod, ...$calledMethods));
38070 }
38071 /**
38072 * @throws InvalidArgumentException
38073 * @throws UnknownEventTypeException
38074 */
38075 public function testSuiteLoaded(TestSuite $testSuite): void
38076 {
38077 $this->dispatcher->dispatch(new TestSuiteLoaded($this->telemetryInfo(), $testSuite));
38078 }
38079 /**
38080 * @throws InvalidArgumentException
38081 * @throws UnknownEventTypeException
38082 */
38083 public function testSuiteFiltered(TestSuite $testSuite): void
38084 {
38085 $this->dispatcher->dispatch(new TestSuiteFiltered($this->telemetryInfo(), $testSuite));
38086 }
38087 /**
38088 * @throws InvalidArgumentException
38089 * @throws UnknownEventTypeException
38090 */
38091 public function testSuiteSorted(int $executionOrder, int $executionOrderDefects, bool $resolveDependencies): void
38092 {
38093 $this->dispatcher->dispatch(new TestSuiteSorted($this->telemetryInfo(), $executionOrder, $executionOrderDefects, $resolveDependencies));
38094 }
38095 /**
38096 * @throws InvalidArgumentException
38097 * @throws UnknownEventTypeException
38098 */
38099 public function testRunnerEventFacadeSealed(): void
38100 {
38101 $this->dispatcher->dispatch(new \PHPUnit\Event\TestRunner\EventFacadeSealed($this->telemetryInfo()));
38102 }
38103 /**
38104 * @throws InvalidArgumentException
38105 * @throws UnknownEventTypeException
38106 */
38107 public function testRunnerExecutionStarted(TestSuite $testSuite): void
38108 {
38109 $this->dispatcher->dispatch(new \PHPUnit\Event\TestRunner\ExecutionStarted($this->telemetryInfo(), $testSuite));
38110 }
38111 /**
38112 * @throws InvalidArgumentException
38113 * @throws UnknownEventTypeException
38114 */
38115 public function testRunnerDisabledGarbageCollection(): void
38116 {
38117 $this->dispatcher->dispatch(new \PHPUnit\Event\TestRunner\GarbageCollectionDisabled($this->telemetryInfo()));
38118 }
38119 /**
38120 * @throws InvalidArgumentException
38121 * @throws UnknownEventTypeException
38122 */
38123 public function testRunnerTriggeredGarbageCollection(): void
38124 {
38125 $this->dispatcher->dispatch(new \PHPUnit\Event\TestRunner\GarbageCollectionTriggered($this->telemetryInfo()));
38126 }
38127 /**
38128 * @throws InvalidArgumentException
38129 * @throws UnknownEventTypeException
38130 */
38131 public function testSuiteSkipped(TestSuite $testSuite, string $message): void
38132 {
38133 $this->dispatcher->dispatch(new TestSuiteSkipped($this->telemetryInfo(), $testSuite, $message));
38134 }
38135 /**
38136 * @throws InvalidArgumentException
38137 * @throws UnknownEventTypeException
38138 */
38139 public function testSuiteStarted(TestSuite $testSuite): void
38140 {
38141 $this->dispatcher->dispatch(new TestSuiteStarted($this->telemetryInfo(), $testSuite));
38142 }
38143 /**
38144 * @throws InvalidArgumentException
38145 * @throws UnknownEventTypeException
38146 */
38147 public function testPreparationStarted(\PHPUnit\Event\Code\Test $test): void
38148 {
38149 $this->dispatcher->dispatch(new \PHPUnit\Event\Test\PreparationStarted($this->telemetryInfo(), $test));
38150 }
38151 /**
38152 * @throws InvalidArgumentException
38153 * @throws UnknownEventTypeException
38154 */
38155 public function testPreparationFailed(\PHPUnit\Event\Code\Test $test): void
38156 {
38157 $this->dispatcher->dispatch(new \PHPUnit\Event\Test\PreparationFailed($this->telemetryInfo(), $test));
38158 }
38159 /**
38160 * @psalm-param class-string $testClassName
38161 *
38162 * @throws InvalidArgumentException
38163 * @throws UnknownEventTypeException
38164 */
38165 public function beforeFirstTestMethodCalled(string $testClassName, ClassMethod $calledMethod): void
38166 {
38167 $this->dispatcher->dispatch(new \PHPUnit\Event\Test\BeforeFirstTestMethodCalled($this->telemetryInfo(), $testClassName, $calledMethod));
38168 }
38169 /**
38170 * @psalm-param class-string $testClassName
38171 *
38172 * @throws InvalidArgumentException
38173 * @throws UnknownEventTypeException
38174 */
38175 public function beforeFirstTestMethodErrored(string $testClassName, ClassMethod $calledMethod, Throwable $throwable): void
38176 {
38177 $this->dispatcher->dispatch(new \PHPUnit\Event\Test\BeforeFirstTestMethodErrored($this->telemetryInfo(), $testClassName, $calledMethod, $throwable));
38178 }
38179 /**
38180 * @psalm-param class-string $testClassName
38181 *
38182 * @throws InvalidArgumentException
38183 * @throws UnknownEventTypeException
38184 */
38185 public function beforeFirstTestMethodFinished(string $testClassName, ClassMethod ...$calledMethods): void
38186 {
38187 $this->dispatcher->dispatch(new \PHPUnit\Event\Test\BeforeFirstTestMethodFinished($this->telemetryInfo(), $testClassName, ...$calledMethods));
38188 }
38189 /**
38190 * @psalm-param class-string $testClassName
38191 *
38192 * @throws InvalidArgumentException
38193 * @throws UnknownEventTypeException
38194 */
38195 public function beforeTestMethodCalled(string $testClassName, ClassMethod $calledMethod): void
38196 {
38197 $this->dispatcher->dispatch(new \PHPUnit\Event\Test\BeforeTestMethodCalled($this->telemetryInfo(), $testClassName, $calledMethod));
38198 }
38199 /**
38200 * @psalm-param class-string $testClassName
38201 *
38202 * @throws InvalidArgumentException
38203 * @throws UnknownEventTypeException
38204 */
38205 public function beforeTestMethodErrored(string $testClassName, ClassMethod $calledMethod, Throwable $throwable): void
38206 {
38207 $this->dispatcher->dispatch(new \PHPUnit\Event\Test\BeforeTestMethodErrored($this->telemetryInfo(), $testClassName, $calledMethod, $throwable));
38208 }
38209 /**
38210 * @psalm-param class-string $testClassName
38211 *
38212 * @throws InvalidArgumentException
38213 * @throws UnknownEventTypeException
38214 */
38215 public function beforeTestMethodFinished(string $testClassName, ClassMethod ...$calledMethods): void
38216 {
38217 $this->dispatcher->dispatch(new \PHPUnit\Event\Test\BeforeTestMethodFinished($this->telemetryInfo(), $testClassName, ...$calledMethods));
38218 }
38219 /**
38220 * @psalm-param class-string $testClassName
38221 *
38222 * @throws InvalidArgumentException
38223 * @throws UnknownEventTypeException
38224 */
38225 public function preConditionCalled(string $testClassName, ClassMethod $calledMethod): void
38226 {
38227 $this->dispatcher->dispatch(new \PHPUnit\Event\Test\PreConditionCalled($this->telemetryInfo(), $testClassName, $calledMethod));
38228 }
38229 /**
38230 * @psalm-param class-string $testClassName
38231 *
38232 * @throws InvalidArgumentException
38233 * @throws UnknownEventTypeException
38234 */
38235 public function preConditionErrored(string $testClassName, ClassMethod $calledMethod, Throwable $throwable): void
38236 {
38237 $this->dispatcher->dispatch(new \PHPUnit\Event\Test\PreConditionErrored($this->telemetryInfo(), $testClassName, $calledMethod, $throwable));
38238 }
38239 /**
38240 * @psalm-param class-string $testClassName
38241 *
38242 * @throws InvalidArgumentException
38243 * @throws UnknownEventTypeException
38244 */
38245 public function preConditionFinished(string $testClassName, ClassMethod ...$calledMethods): void
38246 {
38247 $this->dispatcher->dispatch(new \PHPUnit\Event\Test\PreConditionFinished($this->telemetryInfo(), $testClassName, ...$calledMethods));
38248 }
38249 /**
38250 * @throws InvalidArgumentException
38251 * @throws UnknownEventTypeException
38252 */
38253 public function testPrepared(\PHPUnit\Event\Code\Test $test): void
38254 {
38255 $this->dispatcher->dispatch(new \PHPUnit\Event\Test\Prepared($this->telemetryInfo(), $test));
38256 }
38257 /**
38258 * @psalm-param class-string $className
38259 *
38260 * @throws InvalidArgumentException
38261 * @throws UnknownEventTypeException
38262 */
38263 public function testRegisteredComparator(string $className): void
38264 {
38265 $this->dispatcher->dispatch(new \PHPUnit\Event\Test\ComparatorRegistered($this->telemetryInfo(), $className));
38266 }
38267 /**
38268 * @throws InvalidArgumentException
38269 * @throws UnknownEventTypeException
38270 *
38271 * @deprecated
38272 */
38273 public function testAssertionSucceeded(mixed $value, Constraint\Constraint $constraint, string $message): void
38274 {
38275 $this->dispatcher->dispatch(new \PHPUnit\Event\Test\AssertionSucceeded($this->telemetryInfo(), Exporter::export($value, $this->exportObjects), $constraint->toString($this->exportObjects), $constraint->count(), $message));
38276 }
38277 /**
38278 * @throws InvalidArgumentException
38279 * @throws UnknownEventTypeException
38280 *
38281 * @deprecated
38282 */
38283 public function testAssertionFailed(mixed $value, Constraint\Constraint $constraint, string $message): void
38284 {
38285 $this->dispatcher->dispatch(new \PHPUnit\Event\Test\AssertionFailed($this->telemetryInfo(), Exporter::export($value, $this->exportObjects), $constraint->toString($this->exportObjects), $constraint->count(), $message));
38286 }
38287 /**
38288 * @psalm-param class-string $className
38289 *
38290 * @throws InvalidArgumentException
38291 * @throws UnknownEventTypeException
38292 */
38293 public function testCreatedMockObject(string $className): void
38294 {
38295 $this->dispatcher->dispatch(new \PHPUnit\Event\Test\MockObjectCreated($this->telemetryInfo(), $className));
38296 }
38297 /**
38298 * @psalm-param list<class-string> $interfaces
38299 *
38300 * @throws InvalidArgumentException
38301 * @throws UnknownEventTypeException
38302 */
38303 public function testCreatedMockObjectForIntersectionOfInterfaces(array $interfaces): void
38304 {
38305 $this->dispatcher->dispatch(new \PHPUnit\Event\Test\MockObjectForIntersectionOfInterfacesCreated($this->telemetryInfo(), $interfaces));
38306 }
38307 /**
38308 * @psalm-param trait-string $traitName
38309 *
38310 * @throws InvalidArgumentException
38311 * @throws UnknownEventTypeException
38312 */
38313 public function testCreatedMockObjectForTrait(string $traitName): void
38314 {
38315 $this->dispatcher->dispatch(new \PHPUnit\Event\Test\MockObjectForTraitCreated($this->telemetryInfo(), $traitName));
38316 }
38317 /**
38318 * @psalm-param class-string $className
38319 *
38320 * @throws InvalidArgumentException
38321 * @throws UnknownEventTypeException
38322 */
38323 public function testCreatedMockObjectForAbstractClass(string $className): void
38324 {
38325 $this->dispatcher->dispatch(new \PHPUnit\Event\Test\MockObjectForAbstractClassCreated($this->telemetryInfo(), $className));
38326 }
38327 /**
38328 * @psalm-param class-string $originalClassName
38329 * @psalm-param class-string $mockClassName
38330 *
38331 * @throws InvalidArgumentException
38332 * @throws UnknownEventTypeException
38333 */
38334 public function testCreatedMockObjectFromWsdl(string $wsdlFile, string $originalClassName, string $mockClassName, array $methods, bool $callOriginalConstructor, array $options): void
38335 {
38336 $this->dispatcher->dispatch(new \PHPUnit\Event\Test\MockObjectFromWsdlCreated($this->telemetryInfo(), $wsdlFile, $originalClassName, $mockClassName, $methods, $callOriginalConstructor, $options));
38337 }
38338 /**
38339 * @psalm-param class-string $className
38340 *
38341 * @throws InvalidArgumentException
38342 * @throws UnknownEventTypeException
38343 */
38344 public function testCreatedPartialMockObject(string $className, string ...$methodNames): void
38345 {
38346 $this->dispatcher->dispatch(new \PHPUnit\Event\Test\PartialMockObjectCreated($this->telemetryInfo(), $className, ...$methodNames));
38347 }
38348 /**
38349 * @psalm-param class-string $className
38350 *
38351 * @throws InvalidArgumentException
38352 * @throws UnknownEventTypeException
38353 */
38354 public function testCreatedTestProxy(string $className, array $constructorArguments): void
38355 {
38356 $this->dispatcher->dispatch(new \PHPUnit\Event\Test\TestProxyCreated($this->telemetryInfo(), $className, Exporter::export($constructorArguments, $this->exportObjects)));
38357 }
38358 /**
38359 * @psalm-param class-string $className
38360 *
38361 * @throws InvalidArgumentException
38362 * @throws UnknownEventTypeException
38363 */
38364 public function testCreatedStub(string $className): void
38365 {
38366 $this->dispatcher->dispatch(new \PHPUnit\Event\Test\TestStubCreated($this->telemetryInfo(), $className));
38367 }
38368 /**
38369 * @psalm-param list<class-string> $interfaces
38370 *
38371 * @throws InvalidArgumentException
38372 * @throws UnknownEventTypeException
38373 */
38374 public function testCreatedStubForIntersectionOfInterfaces(array $interfaces): void
38375 {
38376 $this->dispatcher->dispatch(new \PHPUnit\Event\Test\TestStubForIntersectionOfInterfacesCreated($this->telemetryInfo(), $interfaces));
38377 }
38378 /**
38379 * @throws InvalidArgumentException
38380 * @throws UnknownEventTypeException
38381 */
38382 public function testErrored(\PHPUnit\Event\Code\Test $test, Throwable $throwable): void
38383 {
38384 $this->dispatcher->dispatch(new \PHPUnit\Event\Test\Errored($this->telemetryInfo(), $test, $throwable));
38385 }
38386 /**
38387 * @throws InvalidArgumentException
38388 * @throws UnknownEventTypeException
38389 */
38390 public function testFailed(\PHPUnit\Event\Code\Test $test, Throwable $throwable, ?ComparisonFailure $comparisonFailure): void
38391 {
38392 $this->dispatcher->dispatch(new \PHPUnit\Event\Test\Failed($this->telemetryInfo(), $test, $throwable, $comparisonFailure));
38393 }
38394 /**
38395 * @throws InvalidArgumentException
38396 * @throws UnknownEventTypeException
38397 */
38398 public function testPassed(\PHPUnit\Event\Code\Test $test): void
38399 {
38400 $this->dispatcher->dispatch(new \PHPUnit\Event\Test\Passed($this->telemetryInfo(), $test));
38401 }
38402 /**
38403 * @throws InvalidArgumentException
38404 * @throws UnknownEventTypeException
38405 */
38406 public function testConsideredRisky(\PHPUnit\Event\Code\Test $test, string $message): void
38407 {
38408 $this->dispatcher->dispatch(new \PHPUnit\Event\Test\ConsideredRisky($this->telemetryInfo(), $test, $message));
38409 }
38410 /**
38411 * @throws InvalidArgumentException
38412 * @throws UnknownEventTypeException
38413 */
38414 public function testMarkedAsIncomplete(\PHPUnit\Event\Code\Test $test, Throwable $throwable): void
38415 {
38416 $this->dispatcher->dispatch(new \PHPUnit\Event\Test\MarkedIncomplete($this->telemetryInfo(), $test, $throwable));
38417 }
38418 /**
38419 * @throws InvalidArgumentException
38420 * @throws UnknownEventTypeException
38421 */
38422 public function testSkipped(\PHPUnit\Event\Code\Test $test, string $message): void
38423 {
38424 $this->dispatcher->dispatch(new \PHPUnit\Event\Test\Skipped($this->telemetryInfo(), $test, $message));
38425 }
38426 /**
38427 * @psalm-param non-empty-string $message
38428 *
38429 * @throws InvalidArgumentException
38430 * @throws UnknownEventTypeException
38431 */
38432 public function testTriggeredPhpunitDeprecation(\PHPUnit\Event\Code\Test $test, string $message): void
38433 {
38434 $this->dispatcher->dispatch(new \PHPUnit\Event\Test\PhpunitDeprecationTriggered($this->telemetryInfo(), $test, $message));
38435 }
38436 /**
38437 * @psalm-param non-empty-string $message
38438 * @psalm-param non-empty-string $file
38439 * @psalm-param positive-int $line
38440 *
38441 * @throws InvalidArgumentException
38442 * @throws UnknownEventTypeException
38443 */
38444 public function testTriggeredPhpDeprecation(\PHPUnit\Event\Code\Test $test, string $message, string $file, int $line, bool $suppressed, bool $ignoredByBaseline, bool $ignoredByTest): void
38445 {
38446 $this->dispatcher->dispatch(new \PHPUnit\Event\Test\PhpDeprecationTriggered($this->telemetryInfo(), $test, $message, $file, $line, $suppressed, $ignoredByBaseline, $ignoredByTest));
38447 }
38448 /**
38449 * @psalm-param non-empty-string $message
38450 * @psalm-param non-empty-string $file
38451 * @psalm-param positive-int $line
38452 *
38453 * @throws InvalidArgumentException
38454 * @throws UnknownEventTypeException
38455 */
38456 public function testTriggeredDeprecation(\PHPUnit\Event\Code\Test $test, string $message, string $file, int $line, bool $suppressed, bool $ignoredByBaseline, bool $ignoredByTest): void
38457 {
38458 $this->dispatcher->dispatch(new \PHPUnit\Event\Test\DeprecationTriggered($this->telemetryInfo(), $test, $message, $file, $line, $suppressed, $ignoredByBaseline, $ignoredByTest));
38459 }
38460 /**
38461 * @psalm-param non-empty-string $message
38462 * @psalm-param non-empty-string $file
38463 * @psalm-param positive-int $line
38464 *
38465 * @throws InvalidArgumentException
38466 * @throws UnknownEventTypeException
38467 */
38468 public function testTriggeredError(\PHPUnit\Event\Code\Test $test, string $message, string $file, int $line, bool $suppressed): void
38469 {
38470 $this->dispatcher->dispatch(new \PHPUnit\Event\Test\ErrorTriggered($this->telemetryInfo(), $test, $message, $file, $line, $suppressed));
38471 }
38472 /**
38473 * @psalm-param non-empty-string $message
38474 * @psalm-param non-empty-string $file
38475 * @psalm-param positive-int $line
38476 *
38477 * @throws InvalidArgumentException
38478 * @throws UnknownEventTypeException
38479 */
38480 public function testTriggeredNotice(\PHPUnit\Event\Code\Test $test, string $message, string $file, int $line, bool $suppressed, bool $ignoredByBaseline): void
38481 {
38482 $this->dispatcher->dispatch(new \PHPUnit\Event\Test\NoticeTriggered($this->telemetryInfo(), $test, $message, $file, $line, $suppressed, $ignoredByBaseline));
38483 }
38484 /**
38485 * @psalm-param non-empty-string $message
38486 * @psalm-param non-empty-string $file
38487 * @psalm-param positive-int $line
38488 *
38489 * @throws InvalidArgumentException
38490 * @throws UnknownEventTypeException
38491 */
38492 public function testTriggeredPhpNotice(\PHPUnit\Event\Code\Test $test, string $message, string $file, int $line, bool $suppressed, bool $ignoredByBaseline): void
38493 {
38494 $this->dispatcher->dispatch(new \PHPUnit\Event\Test\PhpNoticeTriggered($this->telemetryInfo(), $test, $message, $file, $line, $suppressed, $ignoredByBaseline));
38495 }
38496 /**
38497 * @psalm-param non-empty-string $message
38498 * @psalm-param non-empty-string $file
38499 * @psalm-param positive-int $line
38500 *
38501 * @throws InvalidArgumentException
38502 * @throws UnknownEventTypeException
38503 */
38504 public function testTriggeredWarning(\PHPUnit\Event\Code\Test $test, string $message, string $file, int $line, bool $suppressed, bool $ignoredByBaseline): void
38505 {
38506 $this->dispatcher->dispatch(new \PHPUnit\Event\Test\WarningTriggered($this->telemetryInfo(), $test, $message, $file, $line, $suppressed, $ignoredByBaseline));
38507 }
38508 /**
38509 * @psalm-param non-empty-string $message
38510 * @psalm-param non-empty-string $file
38511 * @psalm-param positive-int $line
38512 *
38513 * @throws InvalidArgumentException
38514 * @throws UnknownEventTypeException
38515 */
38516 public function testTriggeredPhpWarning(\PHPUnit\Event\Code\Test $test, string $message, string $file, int $line, bool $suppressed, bool $ignoredByBaseline): void
38517 {
38518 $this->dispatcher->dispatch(new \PHPUnit\Event\Test\PhpWarningTriggered($this->telemetryInfo(), $test, $message, $file, $line, $suppressed, $ignoredByBaseline));
38519 }
38520 /**
38521 * @psalm-param non-empty-string $message
38522 *
38523 * @throws InvalidArgumentException
38524 * @throws UnknownEventTypeException
38525 */
38526 public function testTriggeredPhpunitError(\PHPUnit\Event\Code\Test $test, string $message): void
38527 {
38528 $this->dispatcher->dispatch(new \PHPUnit\Event\Test\PhpunitErrorTriggered($this->telemetryInfo(), $test, $message));
38529 }
38530 /**
38531 * @psalm-param non-empty-string $message
38532 *
38533 * @throws InvalidArgumentException
38534 * @throws UnknownEventTypeException
38535 */
38536 public function testTriggeredPhpunitWarning(\PHPUnit\Event\Code\Test $test, string $message): void
38537 {
38538 $this->dispatcher->dispatch(new \PHPUnit\Event\Test\PhpunitWarningTriggered($this->telemetryInfo(), $test, $message));
38539 }
38540 /**
38541 * @psalm-param non-empty-string $output
38542 *
38543 * @throws InvalidArgumentException
38544 * @throws UnknownEventTypeException
38545 */
38546 public function testPrintedUnexpectedOutput(string $output): void
38547 {
38548 $this->dispatcher->dispatch(new \PHPUnit\Event\Test\PrintedUnexpectedOutput($this->telemetryInfo(), $output));
38549 }
38550 /**
38551 * @throws InvalidArgumentException
38552 * @throws UnknownEventTypeException
38553 */
38554 public function testFinished(\PHPUnit\Event\Code\Test $test, int $numberOfAssertionsPerformed): void
38555 {
38556 $this->dispatcher->dispatch(new \PHPUnit\Event\Test\Finished($this->telemetryInfo(), $test, $numberOfAssertionsPerformed));
38557 }
38558 /**
38559 * @psalm-param class-string $testClassName
38560 *
38561 * @throws InvalidArgumentException
38562 * @throws UnknownEventTypeException
38563 */
38564 public function postConditionCalled(string $testClassName, ClassMethod $calledMethod): void
38565 {
38566 $this->dispatcher->dispatch(new \PHPUnit\Event\Test\PostConditionCalled($this->telemetryInfo(), $testClassName, $calledMethod));
38567 }
38568 /**
38569 * @psalm-param class-string $testClassName
38570 *
38571 * @throws InvalidArgumentException
38572 * @throws UnknownEventTypeException
38573 */
38574 public function postConditionErrored(string $testClassName, ClassMethod $calledMethod, Throwable $throwable): void
38575 {
38576 $this->dispatcher->dispatch(new \PHPUnit\Event\Test\PostConditionErrored($this->telemetryInfo(), $testClassName, $calledMethod, $throwable));
38577 }
38578 /**
38579 * @psalm-param class-string $testClassName
38580 *
38581 * @throws InvalidArgumentException
38582 * @throws UnknownEventTypeException
38583 */
38584 public function postConditionFinished(string $testClassName, ClassMethod ...$calledMethods): void
38585 {
38586 $this->dispatcher->dispatch(new \PHPUnit\Event\Test\PostConditionFinished($this->telemetryInfo(), $testClassName, ...$calledMethods));
38587 }
38588 /**
38589 * @psalm-param class-string $testClassName
38590 *
38591 * @throws InvalidArgumentException
38592 * @throws UnknownEventTypeException
38593 */
38594 public function afterTestMethodCalled(string $testClassName, ClassMethod $calledMethod): void
38595 {
38596 $this->dispatcher->dispatch(new \PHPUnit\Event\Test\AfterTestMethodCalled($this->telemetryInfo(), $testClassName, $calledMethod));
38597 }
38598 /**
38599 * @psalm-param class-string $testClassName
38600 *
38601 * @throws InvalidArgumentException
38602 * @throws UnknownEventTypeException
38603 */
38604 public function afterTestMethodErrored(string $testClassName, ClassMethod $calledMethod, Throwable $throwable): void
38605 {
38606 $this->dispatcher->dispatch(new \PHPUnit\Event\Test\AfterTestMethodErrored($this->telemetryInfo(), $testClassName, $calledMethod, $throwable));
38607 }
38608 /**
38609 * @psalm-param class-string $testClassName
38610 *
38611 * @throws InvalidArgumentException
38612 * @throws UnknownEventTypeException
38613 */
38614 public function afterTestMethodFinished(string $testClassName, ClassMethod ...$calledMethods): void
38615 {
38616 $this->dispatcher->dispatch(new \PHPUnit\Event\Test\AfterTestMethodFinished($this->telemetryInfo(), $testClassName, ...$calledMethods));
38617 }
38618 /**
38619 * @psalm-param class-string $testClassName
38620 *
38621 * @throws InvalidArgumentException
38622 * @throws UnknownEventTypeException
38623 */
38624 public function afterLastTestMethodCalled(string $testClassName, ClassMethod $calledMethod): void
38625 {
38626 $this->dispatcher->dispatch(new \PHPUnit\Event\Test\AfterLastTestMethodCalled($this->telemetryInfo(), $testClassName, $calledMethod));
38627 }
38628 /**
38629 * @psalm-param class-string $testClassName
38630 *
38631 * @throws InvalidArgumentException
38632 * @throws UnknownEventTypeException
38633 */
38634 public function afterLastTestMethodErrored(string $testClassName, ClassMethod $calledMethod, Throwable $throwable): void
38635 {
38636 $this->dispatcher->dispatch(new \PHPUnit\Event\Test\AfterLastTestMethodErrored($this->telemetryInfo(), $testClassName, $calledMethod, $throwable));
38637 }
38638 /**
38639 * @psalm-param class-string $testClassName
38640 *
38641 * @throws InvalidArgumentException
38642 * @throws UnknownEventTypeException
38643 */
38644 public function afterLastTestMethodFinished(string $testClassName, ClassMethod ...$calledMethods): void
38645 {
38646 $this->dispatcher->dispatch(new \PHPUnit\Event\Test\AfterLastTestMethodFinished($this->telemetryInfo(), $testClassName, ...$calledMethods));
38647 }
38648 /**
38649 * @throws InvalidArgumentException
38650 * @throws UnknownEventTypeException
38651 */
38652 public function testSuiteFinished(TestSuite $testSuite): void
38653 {
38654 $this->dispatcher->dispatch(new TestSuiteFinished($this->telemetryInfo(), $testSuite));
38655 }
38656 /**
38657 * @throws InvalidArgumentException
38658 * @throws UnknownEventTypeException
38659 */
38660 public function testRunnerTriggeredPhpunitDeprecation(string $message): void
38661 {
38662 $this->dispatcher->dispatch(new \PHPUnit\Event\TestRunner\DeprecationTriggered($this->telemetryInfo(), $message));
38663 }
38664 /**
38665 * @throws InvalidArgumentException
38666 * @throws UnknownEventTypeException
38667 */
38668 public function testRunnerTriggeredPhpunitWarning(string $message): void
38669 {
38670 $this->dispatcher->dispatch(new \PHPUnit\Event\TestRunner\WarningTriggered($this->telemetryInfo(), $message));
38671 }
38672 /**
38673 * @throws InvalidArgumentException
38674 * @throws UnknownEventTypeException
38675 */
38676 public function testRunnerEnabledGarbageCollection(): void
38677 {
38678 $this->dispatcher->dispatch(new \PHPUnit\Event\TestRunner\GarbageCollectionEnabled($this->telemetryInfo()));
38679 }
38680 /**
38681 * @throws InvalidArgumentException
38682 * @throws UnknownEventTypeException
38683 */
38684 public function testRunnerExecutionAborted(): void
38685 {
38686 $this->dispatcher->dispatch(new \PHPUnit\Event\TestRunner\ExecutionAborted($this->telemetryInfo()));
38687 }
38688 /**
38689 * @throws InvalidArgumentException
38690 * @throws UnknownEventTypeException
38691 */
38692 public function testRunnerExecutionFinished(): void
38693 {
38694 $this->dispatcher->dispatch(new \PHPUnit\Event\TestRunner\ExecutionFinished($this->telemetryInfo()));
38695 }
38696 /**
38697 * @throws InvalidArgumentException
38698 * @throws UnknownEventTypeException
38699 */
38700 public function testRunnerFinished(): void
38701 {
38702 $this->dispatcher->dispatch(new \PHPUnit\Event\TestRunner\Finished($this->telemetryInfo()));
38703 }
38704 /**
38705 * @throws InvalidArgumentException
38706 * @throws UnknownEventTypeException
38707 */
38708 public function applicationFinished(int $shellExitCode): void
38709 {
38710 $this->dispatcher->dispatch(new \PHPUnit\Event\Application\Finished($this->telemetryInfo(), $shellExitCode));
38711 }
38712 /**
38713 * @throws InvalidArgumentException
38714 */
38715 private function telemetryInfo(): \PHPUnit\Event\Telemetry\Info
38716 {
38717 $current = $this->system->snapshot();
38718 $info = new \PHPUnit\Event\Telemetry\Info($current, $current->time()->duration($this->startSnapshot->time()), $current->memoryUsage()->diff($this->startSnapshot->memoryUsage()), $current->time()->duration($this->previousSnapshot->time()), $current->memoryUsage()->diff($this->previousSnapshot->memoryUsage()));
38719 $this->previousSnapshot = $current;
38720 return $info;
38721 }
38722 }
38723 <?php
38724
38725 declare (strict_types=1);
38726 /*
38727 * This file is part of PHPUnit.
38728 *
38729 * (c) Sebastian Bergmann <sebastian@phpunit.de>
38730 *
38731 * For the full copyright and license information, please view the LICENSE
38732 * file that was distributed with this source code.
38733 */
38734 namespace PHPUnit\Event;
38735
38736 use PHPUnit\Event\Code\ClassMethod;
38737 use PHPUnit\Event\Code\ComparisonFailure;
38738 use PHPUnit\Event\Code\Throwable;
38739 use PHPUnit\Event\TestSuite\TestSuite;
38740 use PHPUnit\Framework\Constraint;
38741 use PHPUnit\TextUI\Configuration\Configuration;
38742 /**
38743 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
38744 *
38745 * @internal This interface is not covered by the backward compatibility promise for PHPUnit
38746 */
38747 interface Emitter
38748 {
38749 /**
38750 * @deprecated
38751 */
38752 public function exportObjects(): void;
38753 /**
38754 * @deprecated
38755 */
38756 public function exportsObjects(): bool;
38757 public function applicationStarted(): void;
38758 public function testRunnerStarted(): void;
38759 public function testRunnerConfigured(Configuration $configuration): void;
38760 public function testRunnerBootstrapFinished(string $filename): void;
38761 public function testRunnerLoadedExtensionFromPhar(string $filename, string $name, string $version): void;
38762 /**
38763 * @psalm-param class-string $className
38764 * @psalm-param array<string, string> $parameters
38765 */
38766 public function testRunnerBootstrappedExtension(string $className, array $parameters): void;
38767 public function dataProviderMethodCalled(ClassMethod $testMethod, ClassMethod $dataProviderMethod): void;
38768 public function dataProviderMethodFinished(ClassMethod $testMethod, ClassMethod ...$calledMethods): void;
38769 public function testSuiteLoaded(TestSuite $testSuite): void;
38770 public function testSuiteFiltered(TestSuite $testSuite): void;
38771 public function testSuiteSorted(int $executionOrder, int $executionOrderDefects, bool $resolveDependencies): void;
38772 public function testRunnerEventFacadeSealed(): void;
38773 public function testRunnerExecutionStarted(TestSuite $testSuite): void;
38774 public function testRunnerDisabledGarbageCollection(): void;
38775 public function testRunnerTriggeredGarbageCollection(): void;
38776 public function testSuiteSkipped(TestSuite $testSuite, string $message): void;
38777 public function testSuiteStarted(TestSuite $testSuite): void;
38778 public function testPreparationStarted(\PHPUnit\Event\Code\Test $test): void;
38779 public function testPreparationFailed(\PHPUnit\Event\Code\Test $test): void;
38780 /**
38781 * @psalm-param class-string $testClassName
38782 */
38783 public function beforeFirstTestMethodCalled(string $testClassName, ClassMethod $calledMethod): void;
38784 /**
38785 * @psalm-param class-string $testClassName
38786 */
38787 public function beforeFirstTestMethodErrored(string $testClassName, ClassMethod $calledMethod, Throwable $throwable): void;
38788 /**
38789 * @psalm-param class-string $testClassName
38790 */
38791 public function beforeFirstTestMethodFinished(string $testClassName, ClassMethod ...$calledMethods): void;
38792 /**
38793 * @psalm-param class-string $testClassName
38794 */
38795 public function beforeTestMethodCalled(string $testClassName, ClassMethod $calledMethod): void;
38796 /**
38797 * @psalm-param class-string $testClassName
38798 */
38799 public function beforeTestMethodErrored(string $testClassName, ClassMethod $calledMethod, Throwable $throwable): void;
38800 /**
38801 * @psalm-param class-string $testClassName
38802 */
38803 public function beforeTestMethodFinished(string $testClassName, ClassMethod ...$calledMethods): void;
38804 /**
38805 * @psalm-param class-string $testClassName
38806 */
38807 public function preConditionCalled(string $testClassName, ClassMethod $calledMethod): void;
38808 /**
38809 * @psalm-param class-string $testClassName
38810 */
38811 public function preConditionErrored(string $testClassName, ClassMethod $calledMethod, Throwable $throwable): void;
38812 /**
38813 * @psalm-param class-string $testClassName
38814 */
38815 public function preConditionFinished(string $testClassName, ClassMethod ...$calledMethods): void;
38816 public function testPrepared(\PHPUnit\Event\Code\Test $test): void;
38817 /**
38818 * @psalm-param class-string $className
38819 */
38820 public function testRegisteredComparator(string $className): void;
38821 /**
38822 * @deprecated
38823 */
38824 public function testAssertionSucceeded(mixed $value, Constraint\Constraint $constraint, string $message): void;
38825 /**
38826 * @deprecated
38827 */
38828 public function testAssertionFailed(mixed $value, Constraint\Constraint $constraint, string $message): void;
38829 /**
38830 * @psalm-param class-string $className
38831 */
38832 public function testCreatedMockObject(string $className): void;
38833 /**
38834 * @psalm-param list<class-string> $interfaces
38835 */
38836 public function testCreatedMockObjectForIntersectionOfInterfaces(array $interfaces): void;
38837 /**
38838 * @psalm-param trait-string $traitName
38839 */
38840 public function testCreatedMockObjectForTrait(string $traitName): void;
38841 /**
38842 * @psalm-param class-string $className
38843 */
38844 public function testCreatedMockObjectForAbstractClass(string $className): void;
38845 /**
38846 * @psalm-param class-string $originalClassName
38847 * @psalm-param class-string $mockClassName
38848 */
38849 public function testCreatedMockObjectFromWsdl(string $wsdlFile, string $originalClassName, string $mockClassName, array $methods, bool $callOriginalConstructor, array $options): void;
38850 /**
38851 * @psalm-param class-string $className
38852 */
38853 public function testCreatedPartialMockObject(string $className, string ...$methodNames): void;
38854 /**
38855 * @psalm-param class-string $className
38856 */
38857 public function testCreatedTestProxy(string $className, array $constructorArguments): void;
38858 /**
38859 * @psalm-param class-string $className
38860 */
38861 public function testCreatedStub(string $className): void;
38862 /**
38863 * @psalm-param list<class-string> $interfaces
38864 */
38865 public function testCreatedStubForIntersectionOfInterfaces(array $interfaces): void;
38866 public function testErrored(\PHPUnit\Event\Code\Test $test, Throwable $throwable): void;
38867 public function testFailed(\PHPUnit\Event\Code\Test $test, Throwable $throwable, ?ComparisonFailure $comparisonFailure): void;
38868 public function testPassed(\PHPUnit\Event\Code\Test $test): void;
38869 /**
38870 * @psalm-param non-empty-string $message
38871 */
38872 public function testConsideredRisky(\PHPUnit\Event\Code\Test $test, string $message): void;
38873 public function testMarkedAsIncomplete(\PHPUnit\Event\Code\Test $test, Throwable $throwable): void;
38874 /**
38875 * @psalm-param non-empty-string $message
38876 */
38877 public function testSkipped(\PHPUnit\Event\Code\Test $test, string $message): void;
38878 /**
38879 * @psalm-param non-empty-string $message
38880 */
38881 public function testTriggeredPhpunitDeprecation(\PHPUnit\Event\Code\Test $test, string $message): void;
38882 /**
38883 * @psalm-param non-empty-string $message
38884 * @psalm-param non-empty-string $file
38885 * @psalm-param positive-int $line
38886 */
38887 public function testTriggeredPhpDeprecation(\PHPUnit\Event\Code\Test $test, string $message, string $file, int $line, bool $suppressed, bool $ignoredByBaseline, bool $ignoredByTest): void;
38888 /**
38889 * @psalm-param non-empty-string $message
38890 * @psalm-param non-empty-string $file
38891 * @psalm-param positive-int $line
38892 */
38893 public function testTriggeredDeprecation(\PHPUnit\Event\Code\Test $test, string $message, string $file, int $line, bool $suppressed, bool $ignoredByBaseline, bool $ignoredByTest): void;
38894 /**
38895 * @psalm-param non-empty-string $message
38896 * @psalm-param non-empty-string $file
38897 * @psalm-param positive-int $line
38898 */
38899 public function testTriggeredError(\PHPUnit\Event\Code\Test $test, string $message, string $file, int $line, bool $suppressed): void;
38900 /**
38901 * @psalm-param non-empty-string $message
38902 * @psalm-param non-empty-string $file
38903 * @psalm-param positive-int $line
38904 */
38905 public function testTriggeredNotice(\PHPUnit\Event\Code\Test $test, string $message, string $file, int $line, bool $suppressed, bool $ignoredByBaseline): void;
38906 /**
38907 * @psalm-param non-empty-string $message
38908 * @psalm-param non-empty-string $file
38909 * @psalm-param positive-int $line
38910 */
38911 public function testTriggeredPhpNotice(\PHPUnit\Event\Code\Test $test, string $message, string $file, int $line, bool $suppressed, bool $ignoredByBaseline): void;
38912 /**
38913 * @psalm-param non-empty-string $message
38914 * @psalm-param non-empty-string $file
38915 * @psalm-param positive-int $line
38916 */
38917 public function testTriggeredWarning(\PHPUnit\Event\Code\Test $test, string $message, string $file, int $line, bool $suppressed, bool $ignoredByBaseline): void;
38918 /**
38919 * @psalm-param non-empty-string $message
38920 * @psalm-param non-empty-string $file
38921 * @psalm-param positive-int $line
38922 */
38923 public function testTriggeredPhpWarning(\PHPUnit\Event\Code\Test $test, string $message, string $file, int $line, bool $suppressed, bool $ignoredByBaseline): void;
38924 /**
38925 * @psalm-param non-empty-string $message
38926 */
38927 public function testTriggeredPhpunitError(\PHPUnit\Event\Code\Test $test, string $message): void;
38928 /**
38929 * @psalm-param non-empty-string $message
38930 */
38931 public function testTriggeredPhpunitWarning(\PHPUnit\Event\Code\Test $test, string $message): void;
38932 /**
38933 * @psalm-param non-empty-string $output
38934 */
38935 public function testPrintedUnexpectedOutput(string $output): void;
38936 public function testFinished(\PHPUnit\Event\Code\Test $test, int $numberOfAssertionsPerformed): void;
38937 /**
38938 * @psalm-param class-string $testClassName
38939 */
38940 public function postConditionCalled(string $testClassName, ClassMethod $calledMethod): void;
38941 /**
38942 * @psalm-param class-string $testClassName
38943 */
38944 public function postConditionErrored(string $testClassName, ClassMethod $calledMethod, Throwable $throwable): void;
38945 /**
38946 * @psalm-param class-string $testClassName
38947 */
38948 public function postConditionFinished(string $testClassName, ClassMethod ...$calledMethods): void;
38949 /**
38950 * @psalm-param class-string $testClassName
38951 */
38952 public function afterTestMethodCalled(string $testClassName, ClassMethod $calledMethod): void;
38953 /**
38954 * @psalm-param class-string $testClassName
38955 */
38956 public function afterTestMethodErrored(string $testClassName, ClassMethod $calledMethod, Throwable $throwable): void;
38957 /**
38958 * @psalm-param class-string $testClassName
38959 */
38960 public function afterTestMethodFinished(string $testClassName, ClassMethod ...$calledMethods): void;
38961 /**
38962 * @psalm-param class-string $testClassName
38963 */
38964 public function afterLastTestMethodCalled(string $testClassName, ClassMethod $calledMethod): void;
38965 /**
38966 * @psalm-param class-string $testClassName
38967 */
38968 public function afterLastTestMethodErrored(string $testClassName, ClassMethod $calledMethod, Throwable $throwable): void;
38969 /**
38970 * @psalm-param class-string $testClassName
38971 */
38972 public function afterLastTestMethodFinished(string $testClassName, ClassMethod ...$calledMethods): void;
38973 public function testSuiteFinished(TestSuite $testSuite): void;
38974 public function testRunnerTriggeredPhpunitDeprecation(string $message): void;
38975 public function testRunnerTriggeredPhpunitWarning(string $message): void;
38976 public function testRunnerEnabledGarbageCollection(): void;
38977 public function testRunnerExecutionAborted(): void;
38978 public function testRunnerExecutionFinished(): void;
38979 public function testRunnerFinished(): void;
38980 public function applicationFinished(int $shellExitCode): void;
38981 }
38982 <?php
38983
38984 declare (strict_types=1);
38985 /*
38986 * This file is part of PHPUnit.
38987 *
38988 * (c) Sebastian Bergmann <sebastian@phpunit.de>
38989 *
38990 * For the full copyright and license information, please view the LICENSE
38991 * file that was distributed with this source code.
38992 */
38993 namespace PHPUnit\Event\Application;
38994
38995 use function sprintf;
38996 use PHPUnit\Event\Event;
38997 use PHPUnit\Event\Telemetry;
38998 /**
38999 * @psalm-immutable
39000 *
39001 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
39002 */
39003 final class Finished implements Event
39004 {
39005 private readonly Telemetry\Info $telemetryInfo;
39006 private readonly int $shellExitCode;
39007 public function __construct(Telemetry\Info $telemetryInfo, int $shellExitCode)
39008 {
39009 $this->telemetryInfo = $telemetryInfo;
39010 $this->shellExitCode = $shellExitCode;
39011 }
39012 public function telemetryInfo(): Telemetry\Info
39013 {
39014 return $this->telemetryInfo;
39015 }
39016 public function shellExitCode(): int
39017 {
39018 return $this->shellExitCode;
39019 }
39020 public function asString(): string
39021 {
39022 return sprintf('PHPUnit Finished (Shell Exit Code: %d)', $this->shellExitCode);
39023 }
39024 }
39025 <?php
39026
39027 declare (strict_types=1);
39028 /*
39029 * This file is part of PHPUnit.
39030 *
39031 * (c) Sebastian Bergmann <sebastian@phpunit.de>
39032 *
39033 * For the full copyright and license information, please view the LICENSE
39034 * file that was distributed with this source code.
39035 */
39036 namespace PHPUnit\Event\Application;
39037
39038 use PHPUnit\Event\Subscriber;
39039 /**
39040 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
39041 */
39042 interface FinishedSubscriber extends Subscriber
39043 {
39044 public function notify(\PHPUnit\Event\Application\Finished $event): void;
39045 }
39046 <?php
39047
39048 declare (strict_types=1);
39049 /*
39050 * This file is part of PHPUnit.
39051 *
39052 * (c) Sebastian Bergmann <sebastian@phpunit.de>
39053 *
39054 * For the full copyright and license information, please view the LICENSE
39055 * file that was distributed with this source code.
39056 */
39057 namespace PHPUnit\Event\Application;
39058
39059 use function sprintf;
39060 use PHPUnit\Event\Event;
39061 use PHPUnit\Event\Runtime\Runtime;
39062 use PHPUnit\Event\Telemetry;
39063 /**
39064 * @psalm-immutable
39065 *
39066 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
39067 */
39068 final class Started implements Event
39069 {
39070 private readonly Telemetry\Info $telemetryInfo;
39071 private readonly Runtime $runtime;
39072 public function __construct(Telemetry\Info $telemetryInfo, Runtime $runtime)
39073 {
39074 $this->telemetryInfo = $telemetryInfo;
39075 $this->runtime = $runtime;
39076 }
39077 public function telemetryInfo(): Telemetry\Info
39078 {
39079 return $this->telemetryInfo;
39080 }
39081 public function runtime(): Runtime
39082 {
39083 return $this->runtime;
39084 }
39085 public function asString(): string
39086 {
39087 return sprintf('PHPUnit Started (%s)', $this->runtime->asString());
39088 }
39089 }
39090 <?php
39091
39092 declare (strict_types=1);
39093 /*
39094 * This file is part of PHPUnit.
39095 *
39096 * (c) Sebastian Bergmann <sebastian@phpunit.de>
39097 *
39098 * For the full copyright and license information, please view the LICENSE
39099 * file that was distributed with this source code.
39100 */
39101 namespace PHPUnit\Event\Application;
39102
39103 use PHPUnit\Event\Subscriber;
39104 /**
39105 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
39106 */
39107 interface StartedSubscriber extends Subscriber
39108 {
39109 public function notify(\PHPUnit\Event\Application\Started $event): void;
39110 }
39111 <?php
39112
39113 declare (strict_types=1);
39114 /*
39115 * This file is part of PHPUnit.
39116 *
39117 * (c) Sebastian Bergmann <sebastian@phpunit.de>
39118 *
39119 * For the full copyright and license information, please view the LICENSE
39120 * file that was distributed with this source code.
39121 */
39122 namespace PHPUnit\Event;
39123
39124 /**
39125 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
39126 */
39127 interface Event
39128 {
39129 public function telemetryInfo(): \PHPUnit\Event\Telemetry\Info;
39130 public function asString(): string;
39131 }
39132 <?php
39133
39134 declare (strict_types=1);
39135 /*
39136 * This file is part of PHPUnit.
39137 *
39138 * (c) Sebastian Bergmann <sebastian@phpunit.de>
39139 *
39140 * For the full copyright and license information, please view the LICENSE
39141 * file that was distributed with this source code.
39142 */
39143 namespace PHPUnit\Event;
39144
39145 use function count;
39146 use Countable;
39147 use IteratorAggregate;
39148 /**
39149 * @template-implements IteratorAggregate<int, Event>
39150 *
39151 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
39152 */
39153 final class EventCollection implements Countable, IteratorAggregate
39154 {
39155 /**
39156 * @psalm-var list<Event>
39157 */
39158 private array $events = [];
39159 public function add(\PHPUnit\Event\Event ...$events): void
39160 {
39161 foreach ($events as $event) {
39162 $this->events[] = $event;
39163 }
39164 }
39165 /**
39166 * @psalm-return list<Event>
39167 */
39168 public function asArray(): array
39169 {
39170 return $this->events;
39171 }
39172 public function count(): int
39173 {
39174 return count($this->events);
39175 }
39176 public function isEmpty(): bool
39177 {
39178 return $this->count() === 0;
39179 }
39180 public function isNotEmpty(): bool
39181 {
39182 return $this->count() > 0;
39183 }
39184 public function getIterator(): \PHPUnit\Event\EventCollectionIterator
39185 {
39186 return new \PHPUnit\Event\EventCollectionIterator($this);
39187 }
39188 }
39189 <?php
39190
39191 declare (strict_types=1);
39192 /*
39193 * This file is part of PHPUnit.
39194 *
39195 * (c) Sebastian Bergmann <sebastian@phpunit.de>
39196 *
39197 * For the full copyright and license information, please view the LICENSE
39198 * file that was distributed with this source code.
39199 */
39200 namespace PHPUnit\Event;
39201
39202 use function count;
39203 use Iterator;
39204 /**
39205 * @template-implements Iterator<int, Event>
39206 *
39207 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
39208 */
39209 final class EventCollectionIterator implements Iterator
39210 {
39211 /**
39212 * @psalm-var list<Event>
39213 */
39214 private readonly array $events;
39215 private int $position = 0;
39216 public function __construct(\PHPUnit\Event\EventCollection $events)
39217 {
39218 $this->events = $events->asArray();
39219 }
39220 public function rewind(): void
39221 {
39222 $this->position = 0;
39223 }
39224 public function valid(): bool
39225 {
39226 return $this->position < count($this->events);
39227 }
39228 public function key(): int
39229 {
39230 return $this->position;
39231 }
39232 public function current(): \PHPUnit\Event\Event
39233 {
39234 return $this->events[$this->position];
39235 }
39236 public function next(): void
39237 {
39238 $this->position++;
39239 }
39240 }
39241 <?php
39242
39243 declare (strict_types=1);
39244 /*
39245 * This file is part of PHPUnit.
39246 *
39247 * (c) Sebastian Bergmann <sebastian@phpunit.de>
39248 *
39249 * For the full copyright and license information, please view the LICENSE
39250 * file that was distributed with this source code.
39251 */
39252 namespace PHPUnit\Event\Test;
39253
39254 use function sprintf;
39255 use PHPUnit\Event\Event;
39256 use PHPUnit\Event\Telemetry;
39257 /**
39258 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
39259 *
39260 * @deprecated
39261 */
39262 final class AssertionFailed implements Event
39263 {
39264 private readonly Telemetry\Info $telemetryInfo;
39265 private readonly string $value;
39266 private readonly string $constraint;
39267 private readonly int $count;
39268 private readonly string $message;
39269 public function __construct(Telemetry\Info $telemetryInfo, string $value, string $constraint, int $count, string $message)
39270 {
39271 $this->telemetryInfo = $telemetryInfo;
39272 $this->value = $value;
39273 $this->constraint = $constraint;
39274 $this->count = $count;
39275 $this->message = $message;
39276 }
39277 public function telemetryInfo(): Telemetry\Info
39278 {
39279 return $this->telemetryInfo;
39280 }
39281 public function value(): string
39282 {
39283 return $this->value;
39284 }
39285 public function count(): int
39286 {
39287 return $this->count;
39288 }
39289 public function message(): string
39290 {
39291 return $this->message;
39292 }
39293 public function asString(): string
39294 {
39295 $message = '';
39296 if (!empty($this->message)) {
39297 $message = sprintf(', Message: %s', $this->message);
39298 }
39299 return sprintf('Assertion Failed (Constraint: %s, Value: %s%s)', $this->constraint, $this->value, $message);
39300 }
39301 }
39302 <?php
39303
39304 declare (strict_types=1);
39305 /*
39306 * This file is part of PHPUnit.
39307 *
39308 * (c) Sebastian Bergmann <sebastian@phpunit.de>
39309 *
39310 * For the full copyright and license information, please view the LICENSE
39311 * file that was distributed with this source code.
39312 */
39313 namespace PHPUnit\Event\Test;
39314
39315 use PHPUnit\Event\Subscriber;
39316 /**
39317 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
39318 *
39319 * @deprecated
39320 */
39321 interface AssertionFailedSubscriber extends Subscriber
39322 {
39323 public function notify(\PHPUnit\Event\Test\AssertionFailed $event): void;
39324 }
39325 <?php
39326
39327 declare (strict_types=1);
39328 /*
39329 * This file is part of PHPUnit.
39330 *
39331 * (c) Sebastian Bergmann <sebastian@phpunit.de>
39332 *
39333 * For the full copyright and license information, please view the LICENSE
39334 * file that was distributed with this source code.
39335 */
39336 namespace PHPUnit\Event\Test;
39337
39338 use function sprintf;
39339 use PHPUnit\Event\Event;
39340 use PHPUnit\Event\Telemetry;
39341 /**
39342 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
39343 *
39344 * @deprecated
39345 */
39346 final class AssertionSucceeded implements Event
39347 {
39348 private readonly Telemetry\Info $telemetryInfo;
39349 private readonly string $value;
39350 private readonly string $constraint;
39351 private readonly int $count;
39352 private readonly string $message;
39353 public function __construct(Telemetry\Info $telemetryInfo, string $value, string $constraint, int $count, string $message)
39354 {
39355 $this->telemetryInfo = $telemetryInfo;
39356 $this->value = $value;
39357 $this->constraint = $constraint;
39358 $this->count = $count;
39359 $this->message = $message;
39360 }
39361 public function telemetryInfo(): Telemetry\Info
39362 {
39363 return $this->telemetryInfo;
39364 }
39365 public function value(): string
39366 {
39367 return $this->value;
39368 }
39369 public function count(): int
39370 {
39371 return $this->count;
39372 }
39373 public function message(): string
39374 {
39375 return $this->message;
39376 }
39377 public function asString(): string
39378 {
39379 $message = '';
39380 if (!empty($this->message)) {
39381 $message = sprintf(', Message: %s', $this->message);
39382 }
39383 return sprintf('Assertion Succeeded (Constraint: %s, Value: %s%s)', $this->constraint, $this->value, $message);
39384 }
39385 }
39386 <?php
39387
39388 declare (strict_types=1);
39389 /*
39390 * This file is part of PHPUnit.
39391 *
39392 * (c) Sebastian Bergmann <sebastian@phpunit.de>
39393 *
39394 * For the full copyright and license information, please view the LICENSE
39395 * file that was distributed with this source code.
39396 */
39397 namespace PHPUnit\Event\Test;
39398
39399 use PHPUnit\Event\Subscriber;
39400 /**
39401 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
39402 *
39403 * @deprecated
39404 */
39405 interface AssertionSucceededSubscriber extends Subscriber
39406 {
39407 public function notify(\PHPUnit\Event\Test\AssertionSucceeded $event): void;
39408 }
39409 <?php
39410
39411 declare (strict_types=1);
39412 /*
39413 * This file is part of PHPUnit.
39414 *
39415 * (c) Sebastian Bergmann <sebastian@phpunit.de>
39416 *
39417 * For the full copyright and license information, please view the LICENSE
39418 * file that was distributed with this source code.
39419 */
39420 namespace PHPUnit\Event\Test;
39421
39422 use function sprintf;
39423 use PHPUnit\Event\Event;
39424 use PHPUnit\Event\Telemetry;
39425 /**
39426 * @psalm-immutable
39427 *
39428 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
39429 */
39430 final class ComparatorRegistered implements Event
39431 {
39432 private readonly Telemetry\Info $telemetryInfo;
39433 /**
39434 * @psalm-var class-string
39435 */
39436 private readonly string $className;
39437 /**
39438 * @psalm-param class-string $className
39439 */
39440 public function __construct(Telemetry\Info $telemetryInfo, string $className)
39441 {
39442 $this->telemetryInfo = $telemetryInfo;
39443 $this->className = $className;
39444 }
39445 public function telemetryInfo(): Telemetry\Info
39446 {
39447 return $this->telemetryInfo;
39448 }
39449 /**
39450 * @psalm-return class-string
39451 */
39452 public function className(): string
39453 {
39454 return $this->className;
39455 }
39456 public function asString(): string
39457 {
39458 return sprintf('Comparator Registered (%s)', $this->className);
39459 }
39460 }
39461 <?php
39462
39463 declare (strict_types=1);
39464 /*
39465 * This file is part of PHPUnit.
39466 *
39467 * (c) Sebastian Bergmann <sebastian@phpunit.de>
39468 *
39469 * For the full copyright and license information, please view the LICENSE
39470 * file that was distributed with this source code.
39471 */
39472 namespace PHPUnit\Event\Test;
39473
39474 use PHPUnit\Event\Subscriber;
39475 /**
39476 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
39477 */
39478 interface ComparatorRegisteredSubscriber extends Subscriber
39479 {
39480 public function notify(\PHPUnit\Event\Test\ComparatorRegistered $event): void;
39481 }
39482 <?php
39483
39484 declare (strict_types=1);
39485 /*
39486 * This file is part of PHPUnit.
39487 *
39488 * (c) Sebastian Bergmann <sebastian@phpunit.de>
39489 *
39490 * For the full copyright and license information, please view the LICENSE
39491 * file that was distributed with this source code.
39492 */
39493 namespace PHPUnit\Event\Test;
39494
39495 use function sprintf;
39496 use PHPUnit\Event\Code;
39497 use PHPUnit\Event\Event;
39498 use PHPUnit\Event\Telemetry;
39499 /**
39500 * @psalm-immutable
39501 *
39502 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
39503 */
39504 final class AfterLastTestMethodCalled implements Event
39505 {
39506 private readonly Telemetry\Info $telemetryInfo;
39507 /**
39508 * @psalm-var class-string
39509 */
39510 private readonly string $testClassName;
39511 private readonly Code\ClassMethod $calledMethod;
39512 /**
39513 * @psalm-param class-string $testClassName
39514 */
39515 public function __construct(Telemetry\Info $telemetryInfo, string $testClassName, Code\ClassMethod $calledMethod)
39516 {
39517 $this->telemetryInfo = $telemetryInfo;
39518 $this->testClassName = $testClassName;
39519 $this->calledMethod = $calledMethod;
39520 }
39521 public function telemetryInfo(): Telemetry\Info
39522 {
39523 return $this->telemetryInfo;
39524 }
39525 /**
39526 * @psalm-return class-string
39527 */
39528 public function testClassName(): string
39529 {
39530 return $this->testClassName;
39531 }
39532 public function calledMethod(): Code\ClassMethod
39533 {
39534 return $this->calledMethod;
39535 }
39536 public function asString(): string
39537 {
39538 return sprintf('After Last Test Method Called (%s::%s)', $this->calledMethod->className(), $this->calledMethod->methodName());
39539 }
39540 }
39541 <?php
39542
39543 declare (strict_types=1);
39544 /*
39545 * This file is part of PHPUnit.
39546 *
39547 * (c) Sebastian Bergmann <sebastian@phpunit.de>
39548 *
39549 * For the full copyright and license information, please view the LICENSE
39550 * file that was distributed with this source code.
39551 */
39552 namespace PHPUnit\Event\Test;
39553
39554 use PHPUnit\Event\Subscriber;
39555 /**
39556 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
39557 */
39558 interface AfterLastTestMethodCalledSubscriber extends Subscriber
39559 {
39560 public function notify(\PHPUnit\Event\Test\AfterLastTestMethodCalled $event): void;
39561 }
39562 <?php
39563
39564 declare (strict_types=1);
39565 /*
39566 * This file is part of PHPUnit.
39567 *
39568 * (c) Sebastian Bergmann <sebastian@phpunit.de>
39569 *
39570 * For the full copyright and license information, please view the LICENSE
39571 * file that was distributed with this source code.
39572 */
39573 namespace PHPUnit\Event\Test;
39574
39575 use const PHP_EOL;
39576 use function sprintf;
39577 use PHPUnit\Event\Code;
39578 use PHPUnit\Event\Code\Throwable;
39579 use PHPUnit\Event\Event;
39580 use PHPUnit\Event\Telemetry;
39581 /**
39582 * @psalm-immutable
39583 *
39584 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
39585 */
39586 final class AfterLastTestMethodErrored implements Event
39587 {
39588 private readonly Telemetry\Info $telemetryInfo;
39589 /**
39590 * @psalm-var class-string
39591 */
39592 private readonly string $testClassName;
39593 private readonly Code\ClassMethod $calledMethod;
39594 private readonly Throwable $throwable;
39595 /**
39596 * @psalm-param class-string $testClassName
39597 */
39598 public function __construct(Telemetry\Info $telemetryInfo, string $testClassName, Code\ClassMethod $calledMethod, Throwable $throwable)
39599 {
39600 $this->telemetryInfo = $telemetryInfo;
39601 $this->testClassName = $testClassName;
39602 $this->calledMethod = $calledMethod;
39603 $this->throwable = $throwable;
39604 }
39605 public function telemetryInfo(): Telemetry\Info
39606 {
39607 return $this->telemetryInfo;
39608 }
39609 /**
39610 * @psalm-return class-string
39611 */
39612 public function testClassName(): string
39613 {
39614 return $this->testClassName;
39615 }
39616 public function calledMethod(): Code\ClassMethod
39617 {
39618 return $this->calledMethod;
39619 }
39620 public function throwable(): Throwable
39621 {
39622 return $this->throwable;
39623 }
39624 public function asString(): string
39625 {
39626 $message = $this->throwable->message();
39627 if (!empty($message)) {
39628 $message = PHP_EOL . $message;
39629 }
39630 return sprintf('After Last Test Method Errored (%s::%s)%s', $this->calledMethod->className(), $this->calledMethod->methodName(), $message);
39631 }
39632 }
39633 <?php
39634
39635 declare (strict_types=1);
39636 /*
39637 * This file is part of PHPUnit.
39638 *
39639 * (c) Sebastian Bergmann <sebastian@phpunit.de>
39640 *
39641 * For the full copyright and license information, please view the LICENSE
39642 * file that was distributed with this source code.
39643 */
39644 namespace PHPUnit\Event\Test;
39645
39646 use PHPUnit\Event\Subscriber;
39647 /**
39648 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
39649 */
39650 interface AfterLastTestMethodErroredSubscriber extends Subscriber
39651 {
39652 public function notify(\PHPUnit\Event\Test\AfterLastTestMethodErrored $event): void;
39653 }
39654 <?php
39655
39656 declare (strict_types=1);
39657 /*
39658 * This file is part of PHPUnit.
39659 *
39660 * (c) Sebastian Bergmann <sebastian@phpunit.de>
39661 *
39662 * For the full copyright and license information, please view the LICENSE
39663 * file that was distributed with this source code.
39664 */
39665 namespace PHPUnit\Event\Test;
39666
39667 use const PHP_EOL;
39668 use function sprintf;
39669 use PHPUnit\Event\Code;
39670 use PHPUnit\Event\Event;
39671 use PHPUnit\Event\Telemetry;
39672 /**
39673 * @psalm-immutable
39674 *
39675 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
39676 */
39677 final class AfterLastTestMethodFinished implements Event
39678 {
39679 private readonly Telemetry\Info $telemetryInfo;
39680 /**
39681 * @psalm-var class-string
39682 */
39683 private readonly string $testClassName;
39684 /**
39685 * @psalm-var list<Code\ClassMethod>
39686 */
39687 private readonly array $calledMethods;
39688 /**
39689 * @psalm-param class-string $testClassName
39690 */
39691 public function __construct(Telemetry\Info $telemetryInfo, string $testClassName, Code\ClassMethod ...$calledMethods)
39692 {
39693 $this->telemetryInfo = $telemetryInfo;
39694 $this->testClassName = $testClassName;
39695 $this->calledMethods = $calledMethods;
39696 }
39697 public function telemetryInfo(): Telemetry\Info
39698 {
39699 return $this->telemetryInfo;
39700 }
39701 /**
39702 * @psalm-return class-string
39703 */
39704 public function testClassName(): string
39705 {
39706 return $this->testClassName;
39707 }
39708 /**
39709 * @psalm-return list<Code\ClassMethod>
39710 */
39711 public function calledMethods(): array
39712 {
39713 return $this->calledMethods;
39714 }
39715 public function asString(): string
39716 {
39717 $buffer = 'After Last Test Method Finished:';
39718 foreach ($this->calledMethods as $calledMethod) {
39719 $buffer .= sprintf(PHP_EOL . '- %s::%s', $calledMethod->className(), $calledMethod->methodName());
39720 }
39721 return $buffer;
39722 }
39723 }
39724 <?php
39725
39726 declare (strict_types=1);
39727 /*
39728 * This file is part of PHPUnit.
39729 *
39730 * (c) Sebastian Bergmann <sebastian@phpunit.de>
39731 *
39732 * For the full copyright and license information, please view the LICENSE
39733 * file that was distributed with this source code.
39734 */
39735 namespace PHPUnit\Event\Test;
39736
39737 use PHPUnit\Event\Subscriber;
39738 /**
39739 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
39740 */
39741 interface AfterLastTestMethodFinishedSubscriber extends Subscriber
39742 {
39743 public function notify(\PHPUnit\Event\Test\AfterLastTestMethodFinished $event): void;
39744 }
39745 <?php
39746
39747 declare (strict_types=1);
39748 /*
39749 * This file is part of PHPUnit.
39750 *
39751 * (c) Sebastian Bergmann <sebastian@phpunit.de>
39752 *
39753 * For the full copyright and license information, please view the LICENSE
39754 * file that was distributed with this source code.
39755 */
39756 namespace PHPUnit\Event\Test;
39757
39758 use function sprintf;
39759 use PHPUnit\Event\Code;
39760 use PHPUnit\Event\Event;
39761 use PHPUnit\Event\Telemetry;
39762 /**
39763 * @psalm-immutable
39764 *
39765 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
39766 */
39767 final class AfterTestMethodCalled implements Event
39768 {
39769 private readonly Telemetry\Info $telemetryInfo;
39770 /**
39771 * @psalm-var class-string
39772 */
39773 private readonly string $testClassName;
39774 private readonly Code\ClassMethod $calledMethod;
39775 /**
39776 * @psalm-param class-string $testClassName
39777 */
39778 public function __construct(Telemetry\Info $telemetryInfo, string $testClassName, Code\ClassMethod $calledMethod)
39779 {
39780 $this->telemetryInfo = $telemetryInfo;
39781 $this->testClassName = $testClassName;
39782 $this->calledMethod = $calledMethod;
39783 }
39784 public function telemetryInfo(): Telemetry\Info
39785 {
39786 return $this->telemetryInfo;
39787 }
39788 /**
39789 * @psalm-return class-string
39790 */
39791 public function testClassName(): string
39792 {
39793 return $this->testClassName;
39794 }
39795 public function calledMethod(): Code\ClassMethod
39796 {
39797 return $this->calledMethod;
39798 }
39799 public function asString(): string
39800 {
39801 return sprintf('After Test Method Called (%s::%s)', $this->calledMethod->className(), $this->calledMethod->methodName());
39802 }
39803 }
39804 <?php
39805
39806 declare (strict_types=1);
39807 /*
39808 * This file is part of PHPUnit.
39809 *
39810 * (c) Sebastian Bergmann <sebastian@phpunit.de>
39811 *
39812 * For the full copyright and license information, please view the LICENSE
39813 * file that was distributed with this source code.
39814 */
39815 namespace PHPUnit\Event\Test;
39816
39817 use PHPUnit\Event\Subscriber;
39818 /**
39819 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
39820 */
39821 interface AfterTestMethodCalledSubscriber extends Subscriber
39822 {
39823 public function notify(\PHPUnit\Event\Test\AfterTestMethodCalled $event): void;
39824 }
39825 <?php
39826
39827 declare (strict_types=1);
39828 /*
39829 * This file is part of PHPUnit.
39830 *
39831 * (c) Sebastian Bergmann <sebastian@phpunit.de>
39832 *
39833 * For the full copyright and license information, please view the LICENSE
39834 * file that was distributed with this source code.
39835 */
39836 namespace PHPUnit\Event\Test;
39837
39838 use const PHP_EOL;
39839 use function sprintf;
39840 use PHPUnit\Event\Code;
39841 use PHPUnit\Event\Code\Throwable;
39842 use PHPUnit\Event\Event;
39843 use PHPUnit\Event\Telemetry;
39844 /**
39845 * @psalm-immutable
39846 *
39847 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
39848 */
39849 final class AfterTestMethodErrored implements Event
39850 {
39851 private readonly Telemetry\Info $telemetryInfo;
39852 /**
39853 * @psalm-var class-string
39854 */
39855 private readonly string $testClassName;
39856 private readonly Code\ClassMethod $calledMethod;
39857 private readonly Throwable $throwable;
39858 /**
39859 * @psalm-param class-string $testClassName
39860 */
39861 public function __construct(Telemetry\Info $telemetryInfo, string $testClassName, Code\ClassMethod $calledMethod, Throwable $throwable)
39862 {
39863 $this->telemetryInfo = $telemetryInfo;
39864 $this->testClassName = $testClassName;
39865 $this->calledMethod = $calledMethod;
39866 $this->throwable = $throwable;
39867 }
39868 public function telemetryInfo(): Telemetry\Info
39869 {
39870 return $this->telemetryInfo;
39871 }
39872 /**
39873 * @psalm-return class-string
39874 */
39875 public function testClassName(): string
39876 {
39877 return $this->testClassName;
39878 }
39879 public function calledMethod(): Code\ClassMethod
39880 {
39881 return $this->calledMethod;
39882 }
39883 public function throwable(): Throwable
39884 {
39885 return $this->throwable;
39886 }
39887 public function asString(): string
39888 {
39889 $message = $this->throwable->message();
39890 if (!empty($message)) {
39891 $message = PHP_EOL . $message;
39892 }
39893 return sprintf('After Test Method Errored (%s::%s)%s', $this->calledMethod->className(), $this->calledMethod->methodName(), $message);
39894 }
39895 }
39896 <?php
39897
39898 declare (strict_types=1);
39899 /*
39900 * This file is part of PHPUnit.
39901 *
39902 * (c) Sebastian Bergmann <sebastian@phpunit.de>
39903 *
39904 * For the full copyright and license information, please view the LICENSE
39905 * file that was distributed with this source code.
39906 */
39907 namespace PHPUnit\Event\Test;
39908
39909 use PHPUnit\Event\Subscriber;
39910 /**
39911 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
39912 */
39913 interface AfterTestMethodErroredSubscriber extends Subscriber
39914 {
39915 public function notify(\PHPUnit\Event\Test\AfterTestMethodErrored $event): void;
39916 }
39917 <?php
39918
39919 declare (strict_types=1);
39920 /*
39921 * This file is part of PHPUnit.
39922 *
39923 * (c) Sebastian Bergmann <sebastian@phpunit.de>
39924 *
39925 * For the full copyright and license information, please view the LICENSE
39926 * file that was distributed with this source code.
39927 */
39928 namespace PHPUnit\Event\Test;
39929
39930 use const PHP_EOL;
39931 use function sprintf;
39932 use PHPUnit\Event\Code;
39933 use PHPUnit\Event\Event;
39934 use PHPUnit\Event\Telemetry;
39935 /**
39936 * @psalm-immutable
39937 *
39938 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
39939 */
39940 final class AfterTestMethodFinished implements Event
39941 {
39942 private readonly Telemetry\Info $telemetryInfo;
39943 /**
39944 * @psalm-var class-string
39945 */
39946 private readonly string $testClassName;
39947 /**
39948 * @psalm-var list<Code\ClassMethod>
39949 */
39950 private readonly array $calledMethods;
39951 /**
39952 * @psalm-param class-string $testClassName
39953 */
39954 public function __construct(Telemetry\Info $telemetryInfo, string $testClassName, Code\ClassMethod ...$calledMethods)
39955 {
39956 $this->telemetryInfo = $telemetryInfo;
39957 $this->testClassName = $testClassName;
39958 $this->calledMethods = $calledMethods;
39959 }
39960 public function telemetryInfo(): Telemetry\Info
39961 {
39962 return $this->telemetryInfo;
39963 }
39964 /**
39965 * @psalm-return class-string
39966 */
39967 public function testClassName(): string
39968 {
39969 return $this->testClassName;
39970 }
39971 /**
39972 * @psalm-return list<Code\ClassMethod>
39973 */
39974 public function calledMethods(): array
39975 {
39976 return $this->calledMethods;
39977 }
39978 public function asString(): string
39979 {
39980 $buffer = 'After Test Method Finished:';
39981 foreach ($this->calledMethods as $calledMethod) {
39982 $buffer .= sprintf(PHP_EOL . '- %s::%s', $calledMethod->className(), $calledMethod->methodName());
39983 }
39984 return $buffer;
39985 }
39986 }
39987 <?php
39988
39989 declare (strict_types=1);
39990 /*
39991 * This file is part of PHPUnit.
39992 *
39993 * (c) Sebastian Bergmann <sebastian@phpunit.de>
39994 *
39995 * For the full copyright and license information, please view the LICENSE
39996 * file that was distributed with this source code.
39997 */
39998 namespace PHPUnit\Event\Test;
39999
40000 use PHPUnit\Event\Subscriber;
40001 /**
40002 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
40003 */
40004 interface AfterTestMethodFinishedSubscriber extends Subscriber
40005 {
40006 public function notify(\PHPUnit\Event\Test\AfterTestMethodFinished $event): void;
40007 }
40008 <?php
40009
40010 declare (strict_types=1);
40011 /*
40012 * This file is part of PHPUnit.
40013 *
40014 * (c) Sebastian Bergmann <sebastian@phpunit.de>
40015 *
40016 * For the full copyright and license information, please view the LICENSE
40017 * file that was distributed with this source code.
40018 */
40019 namespace PHPUnit\Event\Test;
40020
40021 use function sprintf;
40022 use PHPUnit\Event\Code;
40023 use PHPUnit\Event\Event;
40024 use PHPUnit\Event\Telemetry;
40025 /**
40026 * @psalm-immutable
40027 *
40028 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
40029 */
40030 final class BeforeFirstTestMethodCalled implements Event
40031 {
40032 private readonly Telemetry\Info $telemetryInfo;
40033 /**
40034 * @psalm-var class-string
40035 */
40036 private readonly string $testClassName;
40037 private readonly Code\ClassMethod $calledMethod;
40038 /**
40039 * @psalm-param class-string $testClassName
40040 */
40041 public function __construct(Telemetry\Info $telemetryInfo, string $testClassName, Code\ClassMethod $calledMethod)
40042 {
40043 $this->telemetryInfo = $telemetryInfo;
40044 $this->testClassName = $testClassName;
40045 $this->calledMethod = $calledMethod;
40046 }
40047 public function telemetryInfo(): Telemetry\Info
40048 {
40049 return $this->telemetryInfo;
40050 }
40051 /**
40052 * @psalm-return class-string
40053 */
40054 public function testClassName(): string
40055 {
40056 return $this->testClassName;
40057 }
40058 public function calledMethod(): Code\ClassMethod
40059 {
40060 return $this->calledMethod;
40061 }
40062 public function asString(): string
40063 {
40064 return sprintf('Before First Test Method Called (%s::%s)', $this->calledMethod->className(), $this->calledMethod->methodName());
40065 }
40066 }
40067 <?php
40068
40069 declare (strict_types=1);
40070 /*
40071 * This file is part of PHPUnit.
40072 *
40073 * (c) Sebastian Bergmann <sebastian@phpunit.de>
40074 *
40075 * For the full copyright and license information, please view the LICENSE
40076 * file that was distributed with this source code.
40077 */
40078 namespace PHPUnit\Event\Test;
40079
40080 use PHPUnit\Event\Subscriber;
40081 /**
40082 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
40083 */
40084 interface BeforeFirstTestMethodCalledSubscriber extends Subscriber
40085 {
40086 public function notify(\PHPUnit\Event\Test\BeforeFirstTestMethodCalled $event): void;
40087 }
40088 <?php
40089
40090 declare (strict_types=1);
40091 /*
40092 * This file is part of PHPUnit.
40093 *
40094 * (c) Sebastian Bergmann <sebastian@phpunit.de>
40095 *
40096 * For the full copyright and license information, please view the LICENSE
40097 * file that was distributed with this source code.
40098 */
40099 namespace PHPUnit\Event\Test;
40100
40101 use const PHP_EOL;
40102 use function sprintf;
40103 use PHPUnit\Event\Code;
40104 use PHPUnit\Event\Code\Throwable;
40105 use PHPUnit\Event\Event;
40106 use PHPUnit\Event\Telemetry;
40107 /**
40108 * @psalm-immutable
40109 *
40110 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
40111 */
40112 final class BeforeFirstTestMethodErrored implements Event
40113 {
40114 private readonly Telemetry\Info $telemetryInfo;
40115 /**
40116 * @psalm-var class-string
40117 */
40118 private readonly string $testClassName;
40119 private readonly Code\ClassMethod $calledMethod;
40120 private readonly Throwable $throwable;
40121 /**
40122 * @psalm-param class-string $testClassName
40123 */
40124 public function __construct(Telemetry\Info $telemetryInfo, string $testClassName, Code\ClassMethod $calledMethod, Throwable $throwable)
40125 {
40126 $this->telemetryInfo = $telemetryInfo;
40127 $this->testClassName = $testClassName;
40128 $this->calledMethod = $calledMethod;
40129 $this->throwable = $throwable;
40130 }
40131 public function telemetryInfo(): Telemetry\Info
40132 {
40133 return $this->telemetryInfo;
40134 }
40135 /**
40136 * @psalm-return class-string
40137 */
40138 public function testClassName(): string
40139 {
40140 return $this->testClassName;
40141 }
40142 public function calledMethod(): Code\ClassMethod
40143 {
40144 return $this->calledMethod;
40145 }
40146 public function throwable(): Throwable
40147 {
40148 return $this->throwable;
40149 }
40150 public function asString(): string
40151 {
40152 $message = $this->throwable->message();
40153 if (!empty($message)) {
40154 $message = PHP_EOL . $message;
40155 }
40156 return sprintf('Before First Test Method Errored (%s::%s)%s', $this->calledMethod->className(), $this->calledMethod->methodName(), $message);
40157 }
40158 }
40159 <?php
40160
40161 declare (strict_types=1);
40162 /*
40163 * This file is part of PHPUnit.
40164 *
40165 * (c) Sebastian Bergmann <sebastian@phpunit.de>
40166 *
40167 * For the full copyright and license information, please view the LICENSE
40168 * file that was distributed with this source code.
40169 */
40170 namespace PHPUnit\Event\Test;
40171
40172 use PHPUnit\Event\Subscriber;
40173 /**
40174 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
40175 */
40176 interface BeforeFirstTestMethodErroredSubscriber extends Subscriber
40177 {
40178 public function notify(\PHPUnit\Event\Test\BeforeFirstTestMethodErrored $event): void;
40179 }
40180 <?php
40181
40182 declare (strict_types=1);
40183 /*
40184 * This file is part of PHPUnit.
40185 *
40186 * (c) Sebastian Bergmann <sebastian@phpunit.de>
40187 *
40188 * For the full copyright and license information, please view the LICENSE
40189 * file that was distributed with this source code.
40190 */
40191 namespace PHPUnit\Event\Test;
40192
40193 use const PHP_EOL;
40194 use function sprintf;
40195 use PHPUnit\Event\Code;
40196 use PHPUnit\Event\Event;
40197 use PHPUnit\Event\Telemetry;
40198 /**
40199 * @psalm-immutable
40200 *
40201 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
40202 */
40203 final class BeforeFirstTestMethodFinished implements Event
40204 {
40205 private readonly Telemetry\Info $telemetryInfo;
40206 /**
40207 * @psalm-var class-string
40208 */
40209 private readonly string $testClassName;
40210 /**
40211 * @psalm-var list<Code\ClassMethod>
40212 */
40213 private readonly array $calledMethods;
40214 /**
40215 * @psalm-param class-string $testClassName
40216 */
40217 public function __construct(Telemetry\Info $telemetryInfo, string $testClassName, Code\ClassMethod ...$calledMethods)
40218 {
40219 $this->telemetryInfo = $telemetryInfo;
40220 $this->testClassName = $testClassName;
40221 $this->calledMethods = $calledMethods;
40222 }
40223 public function telemetryInfo(): Telemetry\Info
40224 {
40225 return $this->telemetryInfo;
40226 }
40227 /**
40228 * @psalm-return class-string
40229 */
40230 public function testClassName(): string
40231 {
40232 return $this->testClassName;
40233 }
40234 /**
40235 * @psalm-return list<Code\ClassMethod>
40236 */
40237 public function calledMethods(): array
40238 {
40239 return $this->calledMethods;
40240 }
40241 public function asString(): string
40242 {
40243 $buffer = 'Before First Test Method Finished:';
40244 foreach ($this->calledMethods as $calledMethod) {
40245 $buffer .= sprintf(PHP_EOL . '- %s::%s', $calledMethod->className(), $calledMethod->methodName());
40246 }
40247 return $buffer;
40248 }
40249 }
40250 <?php
40251
40252 declare (strict_types=1);
40253 /*
40254 * This file is part of PHPUnit.
40255 *
40256 * (c) Sebastian Bergmann <sebastian@phpunit.de>
40257 *
40258 * For the full copyright and license information, please view the LICENSE
40259 * file that was distributed with this source code.
40260 */
40261 namespace PHPUnit\Event\Test;
40262
40263 use PHPUnit\Event\Subscriber;
40264 /**
40265 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
40266 */
40267 interface BeforeFirstTestMethodFinishedSubscriber extends Subscriber
40268 {
40269 public function notify(\PHPUnit\Event\Test\BeforeFirstTestMethodFinished $event): void;
40270 }
40271 <?php
40272
40273 declare (strict_types=1);
40274 /*
40275 * This file is part of PHPUnit.
40276 *
40277 * (c) Sebastian Bergmann <sebastian@phpunit.de>
40278 *
40279 * For the full copyright and license information, please view the LICENSE
40280 * file that was distributed with this source code.
40281 */
40282 namespace PHPUnit\Event\Test;
40283
40284 use function sprintf;
40285 use PHPUnit\Event\Code;
40286 use PHPUnit\Event\Event;
40287 use PHPUnit\Event\Telemetry;
40288 /**
40289 * @psalm-immutable
40290 *
40291 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
40292 */
40293 final class BeforeTestMethodCalled implements Event
40294 {
40295 private readonly Telemetry\Info $telemetryInfo;
40296 /**
40297 * @psalm-var class-string
40298 */
40299 private readonly string $testClassName;
40300 private readonly Code\ClassMethod $calledMethod;
40301 /**
40302 * @psalm-param class-string $testClassName
40303 */
40304 public function __construct(Telemetry\Info $telemetryInfo, string $testClassName, Code\ClassMethod $calledMethod)
40305 {
40306 $this->telemetryInfo = $telemetryInfo;
40307 $this->testClassName = $testClassName;
40308 $this->calledMethod = $calledMethod;
40309 }
40310 public function telemetryInfo(): Telemetry\Info
40311 {
40312 return $this->telemetryInfo;
40313 }
40314 /**
40315 * @psalm-return class-string
40316 */
40317 public function testClassName(): string
40318 {
40319 return $this->testClassName;
40320 }
40321 public function calledMethod(): Code\ClassMethod
40322 {
40323 return $this->calledMethod;
40324 }
40325 public function asString(): string
40326 {
40327 return sprintf('Before Test Method Called (%s::%s)', $this->calledMethod->className(), $this->calledMethod->methodName());
40328 }
40329 }
40330 <?php
40331
40332 declare (strict_types=1);
40333 /*
40334 * This file is part of PHPUnit.
40335 *
40336 * (c) Sebastian Bergmann <sebastian@phpunit.de>
40337 *
40338 * For the full copyright and license information, please view the LICENSE
40339 * file that was distributed with this source code.
40340 */
40341 namespace PHPUnit\Event\Test;
40342
40343 use PHPUnit\Event\Subscriber;
40344 /**
40345 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
40346 */
40347 interface BeforeTestMethodCalledSubscriber extends Subscriber
40348 {
40349 public function notify(\PHPUnit\Event\Test\BeforeTestMethodCalled $event): void;
40350 }
40351 <?php
40352
40353 declare (strict_types=1);
40354 /*
40355 * This file is part of PHPUnit.
40356 *
40357 * (c) Sebastian Bergmann <sebastian@phpunit.de>
40358 *
40359 * For the full copyright and license information, please view the LICENSE
40360 * file that was distributed with this source code.
40361 */
40362 namespace PHPUnit\Event\Test;
40363
40364 use const PHP_EOL;
40365 use function sprintf;
40366 use PHPUnit\Event\Code;
40367 use PHPUnit\Event\Code\Throwable;
40368 use PHPUnit\Event\Event;
40369 use PHPUnit\Event\Telemetry;
40370 /**
40371 * @psalm-immutable
40372 *
40373 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
40374 */
40375 final class BeforeTestMethodErrored implements Event
40376 {
40377 private readonly Telemetry\Info $telemetryInfo;
40378 /**
40379 * @psalm-var class-string
40380 */
40381 private readonly string $testClassName;
40382 private readonly Code\ClassMethod $calledMethod;
40383 private readonly Throwable $throwable;
40384 /**
40385 * @psalm-param class-string $testClassName
40386 */
40387 public function __construct(Telemetry\Info $telemetryInfo, string $testClassName, Code\ClassMethod $calledMethod, Throwable $throwable)
40388 {
40389 $this->telemetryInfo = $telemetryInfo;
40390 $this->testClassName = $testClassName;
40391 $this->calledMethod = $calledMethod;
40392 $this->throwable = $throwable;
40393 }
40394 public function telemetryInfo(): Telemetry\Info
40395 {
40396 return $this->telemetryInfo;
40397 }
40398 /**
40399 * @psalm-return class-string
40400 */
40401 public function testClassName(): string
40402 {
40403 return $this->testClassName;
40404 }
40405 public function calledMethod(): Code\ClassMethod
40406 {
40407 return $this->calledMethod;
40408 }
40409 public function throwable(): Throwable
40410 {
40411 return $this->throwable;
40412 }
40413 public function asString(): string
40414 {
40415 $message = $this->throwable->message();
40416 if (!empty($message)) {
40417 $message = PHP_EOL . $message;
40418 }
40419 return sprintf('Before Test Method Errored (%s::%s)%s', $this->calledMethod->className(), $this->calledMethod->methodName(), $message);
40420 }
40421 }
40422 <?php
40423
40424 declare (strict_types=1);
40425 /*
40426 * This file is part of PHPUnit.
40427 *
40428 * (c) Sebastian Bergmann <sebastian@phpunit.de>
40429 *
40430 * For the full copyright and license information, please view the LICENSE
40431 * file that was distributed with this source code.
40432 */
40433 namespace PHPUnit\Event\Test;
40434
40435 use PHPUnit\Event\Subscriber;
40436 /**
40437 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
40438 */
40439 interface BeforeTestMethodErroredSubscriber extends Subscriber
40440 {
40441 public function notify(\PHPUnit\Event\Test\BeforeTestMethodErrored $event): void;
40442 }
40443 <?php
40444
40445 declare (strict_types=1);
40446 /*
40447 * This file is part of PHPUnit.
40448 *
40449 * (c) Sebastian Bergmann <sebastian@phpunit.de>
40450 *
40451 * For the full copyright and license information, please view the LICENSE
40452 * file that was distributed with this source code.
40453 */
40454 namespace PHPUnit\Event\Test;
40455
40456 use const PHP_EOL;
40457 use function sprintf;
40458 use PHPUnit\Event\Code;
40459 use PHPUnit\Event\Event;
40460 use PHPUnit\Event\Telemetry;
40461 /**
40462 * @psalm-immutable
40463 *
40464 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
40465 */
40466 final class BeforeTestMethodFinished implements Event
40467 {
40468 private readonly Telemetry\Info $telemetryInfo;
40469 /**
40470 * @psalm-var class-string
40471 */
40472 private readonly string $testClassName;
40473 /**
40474 * @psalm-var list<Code\ClassMethod>
40475 */
40476 private readonly array $calledMethods;
40477 /**
40478 * @psalm-param class-string $testClassName
40479 */
40480 public function __construct(Telemetry\Info $telemetryInfo, string $testClassName, Code\ClassMethod ...$calledMethods)
40481 {
40482 $this->telemetryInfo = $telemetryInfo;
40483 $this->testClassName = $testClassName;
40484 $this->calledMethods = $calledMethods;
40485 }
40486 public function telemetryInfo(): Telemetry\Info
40487 {
40488 return $this->telemetryInfo;
40489 }
40490 /**
40491 * @psalm-return class-string
40492 */
40493 public function testClassName(): string
40494 {
40495 return $this->testClassName;
40496 }
40497 /**
40498 * @psalm-return list<Code\ClassMethod>
40499 */
40500 public function calledMethods(): array
40501 {
40502 return $this->calledMethods;
40503 }
40504 public function asString(): string
40505 {
40506 $buffer = 'Before Test Method Finished:';
40507 foreach ($this->calledMethods as $calledMethod) {
40508 $buffer .= sprintf(PHP_EOL . '- %s::%s', $calledMethod->className(), $calledMethod->methodName());
40509 }
40510 return $buffer;
40511 }
40512 }
40513 <?php
40514
40515 declare (strict_types=1);
40516 /*
40517 * This file is part of PHPUnit.
40518 *
40519 * (c) Sebastian Bergmann <sebastian@phpunit.de>
40520 *
40521 * For the full copyright and license information, please view the LICENSE
40522 * file that was distributed with this source code.
40523 */
40524 namespace PHPUnit\Event\Test;
40525
40526 use PHPUnit\Event\Subscriber;
40527 /**
40528 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
40529 */
40530 interface BeforeTestMethodFinishedSubscriber extends Subscriber
40531 {
40532 public function notify(\PHPUnit\Event\Test\BeforeTestMethodFinished $event): void;
40533 }
40534 <?php
40535
40536 declare (strict_types=1);
40537 /*
40538 * This file is part of PHPUnit.
40539 *
40540 * (c) Sebastian Bergmann <sebastian@phpunit.de>
40541 *
40542 * For the full copyright and license information, please view the LICENSE
40543 * file that was distributed with this source code.
40544 */
40545 namespace PHPUnit\Event\Test;
40546
40547 use function sprintf;
40548 use PHPUnit\Event\Code;
40549 use PHPUnit\Event\Event;
40550 use PHPUnit\Event\Telemetry;
40551 /**
40552 * @psalm-immutable
40553 *
40554 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
40555 */
40556 final class PostConditionCalled implements Event
40557 {
40558 private readonly Telemetry\Info $telemetryInfo;
40559 /**
40560 * @psalm-var class-string
40561 */
40562 private readonly string $testClassName;
40563 private readonly Code\ClassMethod $calledMethod;
40564 /**
40565 * @psalm-param class-string $testClassName
40566 */
40567 public function __construct(Telemetry\Info $telemetryInfo, string $testClassName, Code\ClassMethod $calledMethod)
40568 {
40569 $this->telemetryInfo = $telemetryInfo;
40570 $this->testClassName = $testClassName;
40571 $this->calledMethod = $calledMethod;
40572 }
40573 public function telemetryInfo(): Telemetry\Info
40574 {
40575 return $this->telemetryInfo;
40576 }
40577 /**
40578 * @psalm-return class-string
40579 */
40580 public function testClassName(): string
40581 {
40582 return $this->testClassName;
40583 }
40584 public function calledMethod(): Code\ClassMethod
40585 {
40586 return $this->calledMethod;
40587 }
40588 public function asString(): string
40589 {
40590 return sprintf('Post Condition Method Called (%s::%s)', $this->calledMethod->className(), $this->calledMethod->methodName());
40591 }
40592 }
40593 <?php
40594
40595 declare (strict_types=1);
40596 /*
40597 * This file is part of PHPUnit.
40598 *
40599 * (c) Sebastian Bergmann <sebastian@phpunit.de>
40600 *
40601 * For the full copyright and license information, please view the LICENSE
40602 * file that was distributed with this source code.
40603 */
40604 namespace PHPUnit\Event\Test;
40605
40606 use PHPUnit\Event\Subscriber;
40607 /**
40608 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
40609 */
40610 interface PostConditionCalledSubscriber extends Subscriber
40611 {
40612 public function notify(\PHPUnit\Event\Test\PostConditionCalled $event): void;
40613 }
40614 <?php
40615
40616 declare (strict_types=1);
40617 /*
40618 * This file is part of PHPUnit.
40619 *
40620 * (c) Sebastian Bergmann <sebastian@phpunit.de>
40621 *
40622 * For the full copyright and license information, please view the LICENSE
40623 * file that was distributed with this source code.
40624 */
40625 namespace PHPUnit\Event\Test;
40626
40627 use const PHP_EOL;
40628 use function sprintf;
40629 use PHPUnit\Event\Code;
40630 use PHPUnit\Event\Code\Throwable;
40631 use PHPUnit\Event\Event;
40632 use PHPUnit\Event\Telemetry;
40633 /**
40634 * @psalm-immutable
40635 *
40636 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
40637 */
40638 final class PostConditionErrored implements Event
40639 {
40640 private readonly Telemetry\Info $telemetryInfo;
40641 /**
40642 * @psalm-var class-string
40643 */
40644 private readonly string $testClassName;
40645 private readonly Code\ClassMethod $calledMethod;
40646 private readonly Throwable $throwable;
40647 /**
40648 * @psalm-param class-string $testClassName
40649 */
40650 public function __construct(Telemetry\Info $telemetryInfo, string $testClassName, Code\ClassMethod $calledMethod, Throwable $throwable)
40651 {
40652 $this->telemetryInfo = $telemetryInfo;
40653 $this->testClassName = $testClassName;
40654 $this->calledMethod = $calledMethod;
40655 $this->throwable = $throwable;
40656 }
40657 public function telemetryInfo(): Telemetry\Info
40658 {
40659 return $this->telemetryInfo;
40660 }
40661 /**
40662 * @psalm-return class-string
40663 */
40664 public function testClassName(): string
40665 {
40666 return $this->testClassName;
40667 }
40668 public function calledMethod(): Code\ClassMethod
40669 {
40670 return $this->calledMethod;
40671 }
40672 public function throwable(): Throwable
40673 {
40674 return $this->throwable;
40675 }
40676 public function asString(): string
40677 {
40678 $message = $this->throwable->message();
40679 if (!empty($message)) {
40680 $message = PHP_EOL . $message;
40681 }
40682 return sprintf('Post Condition Method Errored (%s::%s)%s', $this->calledMethod->className(), $this->calledMethod->methodName(), $message);
40683 }
40684 }
40685 <?php
40686
40687 declare (strict_types=1);
40688 /*
40689 * This file is part of PHPUnit.
40690 *
40691 * (c) Sebastian Bergmann <sebastian@phpunit.de>
40692 *
40693 * For the full copyright and license information, please view the LICENSE
40694 * file that was distributed with this source code.
40695 */
40696 namespace PHPUnit\Event\Test;
40697
40698 use PHPUnit\Event\Subscriber;
40699 /**
40700 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
40701 */
40702 interface PostConditionErroredSubscriber extends Subscriber
40703 {
40704 public function notify(\PHPUnit\Event\Test\PostConditionErrored $event): void;
40705 }
40706 <?php
40707
40708 declare (strict_types=1);
40709 /*
40710 * This file is part of PHPUnit.
40711 *
40712 * (c) Sebastian Bergmann <sebastian@phpunit.de>
40713 *
40714 * For the full copyright and license information, please view the LICENSE
40715 * file that was distributed with this source code.
40716 */
40717 namespace PHPUnit\Event\Test;
40718
40719 use const PHP_EOL;
40720 use function sprintf;
40721 use PHPUnit\Event\Code;
40722 use PHPUnit\Event\Event;
40723 use PHPUnit\Event\Telemetry;
40724 /**
40725 * @psalm-immutable
40726 *
40727 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
40728 */
40729 final class PostConditionFinished implements Event
40730 {
40731 private readonly Telemetry\Info $telemetryInfo;
40732 /**
40733 * @psalm-var class-string
40734 */
40735 private readonly string $testClassName;
40736 /**
40737 * @psalm-var list<Code\ClassMethod>
40738 */
40739 private readonly array $calledMethods;
40740 /**
40741 * @psalm-param class-string $testClassName
40742 */
40743 public function __construct(Telemetry\Info $telemetryInfo, string $testClassName, Code\ClassMethod ...$calledMethods)
40744 {
40745 $this->telemetryInfo = $telemetryInfo;
40746 $this->testClassName = $testClassName;
40747 $this->calledMethods = $calledMethods;
40748 }
40749 public function telemetryInfo(): Telemetry\Info
40750 {
40751 return $this->telemetryInfo;
40752 }
40753 /**
40754 * @psalm-return class-string
40755 */
40756 public function testClassName(): string
40757 {
40758 return $this->testClassName;
40759 }
40760 /**
40761 * @psalm-return list<Code\ClassMethod>
40762 */
40763 public function calledMethods(): array
40764 {
40765 return $this->calledMethods;
40766 }
40767 public function asString(): string
40768 {
40769 $buffer = 'Post Condition Method Finished:';
40770 foreach ($this->calledMethods as $calledMethod) {
40771 $buffer .= sprintf(PHP_EOL . '- %s::%s', $calledMethod->className(), $calledMethod->methodName());
40772 }
40773 return $buffer;
40774 }
40775 }
40776 <?php
40777
40778 declare (strict_types=1);
40779 /*
40780 * This file is part of PHPUnit.
40781 *
40782 * (c) Sebastian Bergmann <sebastian@phpunit.de>
40783 *
40784 * For the full copyright and license information, please view the LICENSE
40785 * file that was distributed with this source code.
40786 */
40787 namespace PHPUnit\Event\Test;
40788
40789 use PHPUnit\Event\Subscriber;
40790 /**
40791 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
40792 */
40793 interface PostConditionFinishedSubscriber extends Subscriber
40794 {
40795 public function notify(\PHPUnit\Event\Test\PostConditionFinished $event): void;
40796 }
40797 <?php
40798
40799 declare (strict_types=1);
40800 /*
40801 * This file is part of PHPUnit.
40802 *
40803 * (c) Sebastian Bergmann <sebastian@phpunit.de>
40804 *
40805 * For the full copyright and license information, please view the LICENSE
40806 * file that was distributed with this source code.
40807 */
40808 namespace PHPUnit\Event\Test;
40809
40810 use function sprintf;
40811 use PHPUnit\Event\Code;
40812 use PHPUnit\Event\Event;
40813 use PHPUnit\Event\Telemetry;
40814 /**
40815 * @psalm-immutable
40816 *
40817 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
40818 */
40819 final class PreConditionCalled implements Event
40820 {
40821 private readonly Telemetry\Info $telemetryInfo;
40822 /**
40823 * @psalm-var class-string
40824 */
40825 private readonly string $testClassName;
40826 private readonly Code\ClassMethod $calledMethod;
40827 /**
40828 * @psalm-param class-string $testClassName
40829 */
40830 public function __construct(Telemetry\Info $telemetryInfo, string $testClassName, Code\ClassMethod $calledMethod)
40831 {
40832 $this->telemetryInfo = $telemetryInfo;
40833 $this->testClassName = $testClassName;
40834 $this->calledMethod = $calledMethod;
40835 }
40836 public function telemetryInfo(): Telemetry\Info
40837 {
40838 return $this->telemetryInfo;
40839 }
40840 /**
40841 * @psalm-return class-string
40842 */
40843 public function testClassName(): string
40844 {
40845 return $this->testClassName;
40846 }
40847 public function calledMethod(): Code\ClassMethod
40848 {
40849 return $this->calledMethod;
40850 }
40851 public function asString(): string
40852 {
40853 return sprintf('Pre Condition Method Called (%s::%s)', $this->calledMethod->className(), $this->calledMethod->methodName());
40854 }
40855 }
40856 <?php
40857
40858 declare (strict_types=1);
40859 /*
40860 * This file is part of PHPUnit.
40861 *
40862 * (c) Sebastian Bergmann <sebastian@phpunit.de>
40863 *
40864 * For the full copyright and license information, please view the LICENSE
40865 * file that was distributed with this source code.
40866 */
40867 namespace PHPUnit\Event\Test;
40868
40869 use PHPUnit\Event\Subscriber;
40870 /**
40871 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
40872 */
40873 interface PreConditionCalledSubscriber extends Subscriber
40874 {
40875 public function notify(\PHPUnit\Event\Test\PreConditionCalled $event): void;
40876 }
40877 <?php
40878
40879 declare (strict_types=1);
40880 /*
40881 * This file is part of PHPUnit.
40882 *
40883 * (c) Sebastian Bergmann <sebastian@phpunit.de>
40884 *
40885 * For the full copyright and license information, please view the LICENSE
40886 * file that was distributed with this source code.
40887 */
40888 namespace PHPUnit\Event\Test;
40889
40890 use const PHP_EOL;
40891 use function sprintf;
40892 use PHPUnit\Event\Code;
40893 use PHPUnit\Event\Code\Throwable;
40894 use PHPUnit\Event\Event;
40895 use PHPUnit\Event\Telemetry;
40896 /**
40897 * @psalm-immutable
40898 *
40899 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
40900 */
40901 final class PreConditionErrored implements Event
40902 {
40903 private readonly Telemetry\Info $telemetryInfo;
40904 /**
40905 * @psalm-var class-string
40906 */
40907 private readonly string $testClassName;
40908 private readonly Code\ClassMethod $calledMethod;
40909 private readonly Throwable $throwable;
40910 /**
40911 * @psalm-param class-string $testClassName
40912 */
40913 public function __construct(Telemetry\Info $telemetryInfo, string $testClassName, Code\ClassMethod $calledMethod, Throwable $throwable)
40914 {
40915 $this->telemetryInfo = $telemetryInfo;
40916 $this->testClassName = $testClassName;
40917 $this->calledMethod = $calledMethod;
40918 $this->throwable = $throwable;
40919 }
40920 public function telemetryInfo(): Telemetry\Info
40921 {
40922 return $this->telemetryInfo;
40923 }
40924 /**
40925 * @psalm-return class-string
40926 */
40927 public function testClassName(): string
40928 {
40929 return $this->testClassName;
40930 }
40931 public function calledMethod(): Code\ClassMethod
40932 {
40933 return $this->calledMethod;
40934 }
40935 public function throwable(): Throwable
40936 {
40937 return $this->throwable;
40938 }
40939 public function asString(): string
40940 {
40941 $message = $this->throwable->message();
40942 if (!empty($message)) {
40943 $message = PHP_EOL . $message;
40944 }
40945 return sprintf('Pre Condition Method Errored (%s::%s)%s', $this->calledMethod->className(), $this->calledMethod->methodName(), $message);
40946 }
40947 }
40948 <?php
40949
40950 declare (strict_types=1);
40951 /*
40952 * This file is part of PHPUnit.
40953 *
40954 * (c) Sebastian Bergmann <sebastian@phpunit.de>
40955 *
40956 * For the full copyright and license information, please view the LICENSE
40957 * file that was distributed with this source code.
40958 */
40959 namespace PHPUnit\Event\Test;
40960
40961 use PHPUnit\Event\Subscriber;
40962 /**
40963 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
40964 */
40965 interface PreConditionErroredSubscriber extends Subscriber
40966 {
40967 public function notify(\PHPUnit\Event\Test\PreConditionErrored $event): void;
40968 }
40969 <?php
40970
40971 declare (strict_types=1);
40972 /*
40973 * This file is part of PHPUnit.
40974 *
40975 * (c) Sebastian Bergmann <sebastian@phpunit.de>
40976 *
40977 * For the full copyright and license information, please view the LICENSE
40978 * file that was distributed with this source code.
40979 */
40980 namespace PHPUnit\Event\Test;
40981
40982 use const PHP_EOL;
40983 use function sprintf;
40984 use PHPUnit\Event\Code;
40985 use PHPUnit\Event\Event;
40986 use PHPUnit\Event\Telemetry;
40987 /**
40988 * @psalm-immutable
40989 *
40990 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
40991 */
40992 final class PreConditionFinished implements Event
40993 {
40994 private readonly Telemetry\Info $telemetryInfo;
40995 /**
40996 * @psalm-var class-string
40997 */
40998 private readonly string $testClassName;
40999 /**
41000 * @psalm-var list<Code\ClassMethod>
41001 */
41002 private readonly array $calledMethods;
41003 /**
41004 * @psalm-param class-string $testClassName
41005 */
41006 public function __construct(Telemetry\Info $telemetryInfo, string $testClassName, Code\ClassMethod ...$calledMethods)
41007 {
41008 $this->telemetryInfo = $telemetryInfo;
41009 $this->testClassName = $testClassName;
41010 $this->calledMethods = $calledMethods;
41011 }
41012 public function telemetryInfo(): Telemetry\Info
41013 {
41014 return $this->telemetryInfo;
41015 }
41016 /**
41017 * @psalm-return class-string
41018 */
41019 public function testClassName(): string
41020 {
41021 return $this->testClassName;
41022 }
41023 /**
41024 * @psalm-return list<Code\ClassMethod>
41025 */
41026 public function calledMethods(): array
41027 {
41028 return $this->calledMethods;
41029 }
41030 public function asString(): string
41031 {
41032 $buffer = 'Pre Condition Method Finished:';
41033 foreach ($this->calledMethods as $calledMethod) {
41034 $buffer .= sprintf(PHP_EOL . '- %s::%s', $calledMethod->className(), $calledMethod->methodName());
41035 }
41036 return $buffer;
41037 }
41038 }
41039 <?php
41040
41041 declare (strict_types=1);
41042 /*
41043 * This file is part of PHPUnit.
41044 *
41045 * (c) Sebastian Bergmann <sebastian@phpunit.de>
41046 *
41047 * For the full copyright and license information, please view the LICENSE
41048 * file that was distributed with this source code.
41049 */
41050 namespace PHPUnit\Event\Test;
41051
41052 use PHPUnit\Event\Subscriber;
41053 /**
41054 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
41055 */
41056 interface PreConditionFinishedSubscriber extends Subscriber
41057 {
41058 public function notify(\PHPUnit\Event\Test\PreConditionFinished $event): void;
41059 }
41060 <?php
41061
41062 declare (strict_types=1);
41063 /*
41064 * This file is part of PHPUnit.
41065 *
41066 * (c) Sebastian Bergmann <sebastian@phpunit.de>
41067 *
41068 * For the full copyright and license information, please view the LICENSE
41069 * file that was distributed with this source code.
41070 */
41071 namespace PHPUnit\Event\Test;
41072
41073 use const PHP_EOL;
41074 use function sprintf;
41075 use PHPUnit\Event\Code;
41076 use PHPUnit\Event\Event;
41077 use PHPUnit\Event\Telemetry;
41078 /**
41079 * @psalm-immutable
41080 *
41081 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
41082 */
41083 final class ConsideredRisky implements Event
41084 {
41085 private readonly Telemetry\Info $telemetryInfo;
41086 private readonly Code\Test $test;
41087 /**
41088 * @psalm-var non-empty-string
41089 */
41090 private readonly string $message;
41091 /**
41092 * @psalm-param non-empty-string $message
41093 */
41094 public function __construct(Telemetry\Info $telemetryInfo, Code\Test $test, string $message)
41095 {
41096 $this->telemetryInfo = $telemetryInfo;
41097 $this->test = $test;
41098 $this->message = $message;
41099 }
41100 public function telemetryInfo(): Telemetry\Info
41101 {
41102 return $this->telemetryInfo;
41103 }
41104 public function test(): Code\Test
41105 {
41106 return $this->test;
41107 }
41108 /**
41109 * @psalm-return non-empty-string
41110 */
41111 public function message(): string
41112 {
41113 return $this->message;
41114 }
41115 public function asString(): string
41116 {
41117 return sprintf('Test Considered Risky (%s)%s%s', $this->test->id(), PHP_EOL, $this->message);
41118 }
41119 }
41120 <?php
41121
41122 declare (strict_types=1);
41123 /*
41124 * This file is part of PHPUnit.
41125 *
41126 * (c) Sebastian Bergmann <sebastian@phpunit.de>
41127 *
41128 * For the full copyright and license information, please view the LICENSE
41129 * file that was distributed with this source code.
41130 */
41131 namespace PHPUnit\Event\Test;
41132
41133 use PHPUnit\Event\Subscriber;
41134 /**
41135 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
41136 */
41137 interface ConsideredRiskySubscriber extends Subscriber
41138 {
41139 public function notify(\PHPUnit\Event\Test\ConsideredRisky $event): void;
41140 }
41141 <?php
41142
41143 declare (strict_types=1);
41144 /*
41145 * This file is part of PHPUnit.
41146 *
41147 * (c) Sebastian Bergmann <sebastian@phpunit.de>
41148 *
41149 * For the full copyright and license information, please view the LICENSE
41150 * file that was distributed with this source code.
41151 */
41152 namespace PHPUnit\Event\Test;
41153
41154 use const PHP_EOL;
41155 use function sprintf;
41156 use PHPUnit\Event\Code\Test;
41157 use PHPUnit\Event\Event;
41158 use PHPUnit\Event\Telemetry;
41159 /**
41160 * @psalm-immutable
41161 *
41162 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
41163 */
41164 final class DeprecationTriggered implements Event
41165 {
41166 private readonly Telemetry\Info $telemetryInfo;
41167 private readonly Test $test;
41168 /**
41169 * @psalm-var non-empty-string
41170 */
41171 private readonly string $message;
41172 /**
41173 * @psalm-var non-empty-string
41174 */
41175 private readonly string $file;
41176 /**
41177 * @psalm-var positive-int
41178 */
41179 private readonly int $line;
41180 private readonly bool $suppressed;
41181 private readonly bool $ignoredByBaseline;
41182 private readonly bool $ignoredByTest;
41183 /**
41184 * @psalm-param non-empty-string $message
41185 * @psalm-param non-empty-string $file
41186 * @psalm-param positive-int $line
41187 */
41188 public function __construct(Telemetry\Info $telemetryInfo, Test $test, string $message, string $file, int $line, bool $suppressed, bool $ignoredByBaseline, bool $ignoredByTest)
41189 {
41190 $this->telemetryInfo = $telemetryInfo;
41191 $this->test = $test;
41192 $this->message = $message;
41193 $this->file = $file;
41194 $this->line = $line;
41195 $this->suppressed = $suppressed;
41196 $this->ignoredByBaseline = $ignoredByBaseline;
41197 $this->ignoredByTest = $ignoredByTest;
41198 }
41199 public function telemetryInfo(): Telemetry\Info
41200 {
41201 return $this->telemetryInfo;
41202 }
41203 public function test(): Test
41204 {
41205 return $this->test;
41206 }
41207 /**
41208 * @psalm-return non-empty-string
41209 */
41210 public function message(): string
41211 {
41212 return $this->message;
41213 }
41214 /**
41215 * @psalm-return non-empty-string
41216 */
41217 public function file(): string
41218 {
41219 return $this->file;
41220 }
41221 /**
41222 * @psalm-return positive-int
41223 */
41224 public function line(): int
41225 {
41226 return $this->line;
41227 }
41228 public function wasSuppressed(): bool
41229 {
41230 return $this->suppressed;
41231 }
41232 public function ignoredByBaseline(): bool
41233 {
41234 return $this->ignoredByBaseline;
41235 }
41236 public function ignoredByTest(): bool
41237 {
41238 return $this->ignoredByTest;
41239 }
41240 public function asString(): string
41241 {
41242 $message = $this->message;
41243 if (!empty($message)) {
41244 $message = PHP_EOL . $message;
41245 }
41246 $status = '';
41247 if ($this->ignoredByTest) {
41248 $status = 'Test-Ignored ';
41249 } elseif ($this->ignoredByBaseline) {
41250 $status = 'Baseline-Ignored ';
41251 } elseif ($this->suppressed) {
41252 $status = 'Suppressed ';
41253 }
41254 return sprintf('Test Triggered %sDeprecation (%s) in %s:%d%s', $status, $this->test->id(), $this->file, $this->line, $message);
41255 }
41256 }
41257 <?php
41258
41259 declare (strict_types=1);
41260 /*
41261 * This file is part of PHPUnit.
41262 *
41263 * (c) Sebastian Bergmann <sebastian@phpunit.de>
41264 *
41265 * For the full copyright and license information, please view the LICENSE
41266 * file that was distributed with this source code.
41267 */
41268 namespace PHPUnit\Event\Test;
41269
41270 use PHPUnit\Event\Subscriber;
41271 /**
41272 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
41273 */
41274 interface DeprecationTriggeredSubscriber extends Subscriber
41275 {
41276 public function notify(\PHPUnit\Event\Test\DeprecationTriggered $event): void;
41277 }
41278 <?php
41279
41280 declare (strict_types=1);
41281 /*
41282 * This file is part of PHPUnit.
41283 *
41284 * (c) Sebastian Bergmann <sebastian@phpunit.de>
41285 *
41286 * For the full copyright and license information, please view the LICENSE
41287 * file that was distributed with this source code.
41288 */
41289 namespace PHPUnit\Event\Test;
41290
41291 use const PHP_EOL;
41292 use function sprintf;
41293 use PHPUnit\Event\Code\Test;
41294 use PHPUnit\Event\Event;
41295 use PHPUnit\Event\Telemetry;
41296 /**
41297 * @psalm-immutable
41298 *
41299 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
41300 */
41301 final class ErrorTriggered implements Event
41302 {
41303 private readonly Telemetry\Info $telemetryInfo;
41304 private readonly Test $test;
41305 /**
41306 * @psalm-var non-empty-string
41307 */
41308 private readonly string $message;
41309 /**
41310 * @psalm-var non-empty-string
41311 */
41312 private readonly string $file;
41313 /**
41314 * @psalm-var positive-int
41315 */
41316 private readonly int $line;
41317 private readonly bool $suppressed;
41318 /**
41319 * @psalm-param non-empty-string $message
41320 * @psalm-param non-empty-string $file
41321 * @psalm-param positive-int $line
41322 */
41323 public function __construct(Telemetry\Info $telemetryInfo, Test $test, string $message, string $file, int $line, bool $suppressed)
41324 {
41325 $this->telemetryInfo = $telemetryInfo;
41326 $this->test = $test;
41327 $this->message = $message;
41328 $this->file = $file;
41329 $this->line = $line;
41330 $this->suppressed = $suppressed;
41331 }
41332 public function telemetryInfo(): Telemetry\Info
41333 {
41334 return $this->telemetryInfo;
41335 }
41336 public function test(): Test
41337 {
41338 return $this->test;
41339 }
41340 /**
41341 * @psalm-return non-empty-string
41342 */
41343 public function message(): string
41344 {
41345 return $this->message;
41346 }
41347 /**
41348 * @psalm-return non-empty-string
41349 */
41350 public function file(): string
41351 {
41352 return $this->file;
41353 }
41354 /**
41355 * @psalm-return positive-int
41356 */
41357 public function line(): int
41358 {
41359 return $this->line;
41360 }
41361 public function wasSuppressed(): bool
41362 {
41363 return $this->suppressed;
41364 }
41365 public function asString(): string
41366 {
41367 $message = $this->message;
41368 if (!empty($message)) {
41369 $message = PHP_EOL . $message;
41370 }
41371 return sprintf('Test Triggered %sError (%s) in %s:%d%s', $this->wasSuppressed() ? 'Suppressed ' : '', $this->test->id(), $this->file, $this->line, $message);
41372 }
41373 }
41374 <?php
41375
41376 declare (strict_types=1);
41377 /*
41378 * This file is part of PHPUnit.
41379 *
41380 * (c) Sebastian Bergmann <sebastian@phpunit.de>
41381 *
41382 * For the full copyright and license information, please view the LICENSE
41383 * file that was distributed with this source code.
41384 */
41385 namespace PHPUnit\Event\Test;
41386
41387 use PHPUnit\Event\Subscriber;
41388 /**
41389 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
41390 */
41391 interface ErrorTriggeredSubscriber extends Subscriber
41392 {
41393 public function notify(\PHPUnit\Event\Test\ErrorTriggered $event): void;
41394 }
41395 <?php
41396
41397 declare (strict_types=1);
41398 /*
41399 * This file is part of PHPUnit.
41400 *
41401 * (c) Sebastian Bergmann <sebastian@phpunit.de>
41402 *
41403 * For the full copyright and license information, please view the LICENSE
41404 * file that was distributed with this source code.
41405 */
41406 namespace PHPUnit\Event\Test;
41407
41408 use const PHP_EOL;
41409 use function sprintf;
41410 use PHPUnit\Event\Code\Test;
41411 use PHPUnit\Event\Event;
41412 use PHPUnit\Event\Telemetry;
41413 /**
41414 * @psalm-immutable
41415 *
41416 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
41417 */
41418 final class NoticeTriggered implements Event
41419 {
41420 private readonly Telemetry\Info $telemetryInfo;
41421 private readonly Test $test;
41422 /**
41423 * @psalm-var non-empty-string
41424 */
41425 private readonly string $message;
41426 /**
41427 * @psalm-var non-empty-string
41428 */
41429 private readonly string $file;
41430 /**
41431 * @psalm-var positive-int
41432 */
41433 private readonly int $line;
41434 private readonly bool $suppressed;
41435 private readonly bool $ignoredByBaseline;
41436 /**
41437 * @psalm-param non-empty-string $message
41438 * @psalm-param non-empty-string $file
41439 * @psalm-param positive-int $line
41440 */
41441 public function __construct(Telemetry\Info $telemetryInfo, Test $test, string $message, string $file, int $line, bool $suppressed, bool $ignoredByBaseline)
41442 {
41443 $this->telemetryInfo = $telemetryInfo;
41444 $this->test = $test;
41445 $this->message = $message;
41446 $this->file = $file;
41447 $this->line = $line;
41448 $this->suppressed = $suppressed;
41449 $this->ignoredByBaseline = $ignoredByBaseline;
41450 }
41451 public function telemetryInfo(): Telemetry\Info
41452 {
41453 return $this->telemetryInfo;
41454 }
41455 public function test(): Test
41456 {
41457 return $this->test;
41458 }
41459 /**
41460 * @psalm-return non-empty-string
41461 */
41462 public function message(): string
41463 {
41464 return $this->message;
41465 }
41466 /**
41467 * @psalm-return non-empty-string
41468 */
41469 public function file(): string
41470 {
41471 return $this->file;
41472 }
41473 /**
41474 * @psalm-return positive-int
41475 */
41476 public function line(): int
41477 {
41478 return $this->line;
41479 }
41480 public function wasSuppressed(): bool
41481 {
41482 return $this->suppressed;
41483 }
41484 public function ignoredByBaseline(): bool
41485 {
41486 return $this->ignoredByBaseline;
41487 }
41488 public function asString(): string
41489 {
41490 $message = $this->message;
41491 if (!empty($message)) {
41492 $message = PHP_EOL . $message;
41493 }
41494 $status = '';
41495 if ($this->ignoredByBaseline) {
41496 $status = 'Baseline-Ignored ';
41497 } elseif ($this->suppressed) {
41498 $status = 'Suppressed ';
41499 }
41500 return sprintf('Test Triggered %sNotice (%s) in %s:%d%s', $status, $this->test->id(), $this->file, $this->line, $message);
41501 }
41502 }
41503 <?php
41504
41505 declare (strict_types=1);
41506 /*
41507 * This file is part of PHPUnit.
41508 *
41509 * (c) Sebastian Bergmann <sebastian@phpunit.de>
41510 *
41511 * For the full copyright and license information, please view the LICENSE
41512 * file that was distributed with this source code.
41513 */
41514 namespace PHPUnit\Event\Test;
41515
41516 use PHPUnit\Event\Subscriber;
41517 /**
41518 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
41519 */
41520 interface NoticeTriggeredSubscriber extends Subscriber
41521 {
41522 public function notify(\PHPUnit\Event\Test\NoticeTriggered $event): void;
41523 }
41524 <?php
41525
41526 declare (strict_types=1);
41527 /*
41528 * This file is part of PHPUnit.
41529 *
41530 * (c) Sebastian Bergmann <sebastian@phpunit.de>
41531 *
41532 * For the full copyright and license information, please view the LICENSE
41533 * file that was distributed with this source code.
41534 */
41535 namespace PHPUnit\Event\Test;
41536
41537 use const PHP_EOL;
41538 use function sprintf;
41539 use PHPUnit\Event\Code\Test;
41540 use PHPUnit\Event\Event;
41541 use PHPUnit\Event\Telemetry;
41542 /**
41543 * @psalm-immutable
41544 *
41545 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
41546 */
41547 final class PhpDeprecationTriggered implements Event
41548 {
41549 private readonly Telemetry\Info $telemetryInfo;
41550 private readonly Test $test;
41551 /**
41552 * @psalm-var non-empty-string
41553 */
41554 private readonly string $message;
41555 /**
41556 * @psalm-var non-empty-string
41557 */
41558 private readonly string $file;
41559 /**
41560 * @psalm-var positive-int
41561 */
41562 private readonly int $line;
41563 private readonly bool $suppressed;
41564 private readonly bool $ignoredByBaseline;
41565 private readonly bool $ignoredByTest;
41566 /**
41567 * @psalm-param non-empty-string $message
41568 * @psalm-param non-empty-string $file
41569 * @psalm-param positive-int $line
41570 */
41571 public function __construct(Telemetry\Info $telemetryInfo, Test $test, string $message, string $file, int $line, bool $suppressed, bool $ignoredByBaseline, bool $ignoredByTest)
41572 {
41573 $this->telemetryInfo = $telemetryInfo;
41574 $this->test = $test;
41575 $this->message = $message;
41576 $this->file = $file;
41577 $this->line = $line;
41578 $this->suppressed = $suppressed;
41579 $this->ignoredByBaseline = $ignoredByBaseline;
41580 $this->ignoredByTest = $ignoredByTest;
41581 }
41582 public function telemetryInfo(): Telemetry\Info
41583 {
41584 return $this->telemetryInfo;
41585 }
41586 public function test(): Test
41587 {
41588 return $this->test;
41589 }
41590 /**
41591 * @psalm-return non-empty-string
41592 */
41593 public function message(): string
41594 {
41595 return $this->message;
41596 }
41597 /**
41598 * @psalm-return non-empty-string
41599 */
41600 public function file(): string
41601 {
41602 return $this->file;
41603 }
41604 /**
41605 * @psalm-return positive-int
41606 */
41607 public function line(): int
41608 {
41609 return $this->line;
41610 }
41611 public function wasSuppressed(): bool
41612 {
41613 return $this->suppressed;
41614 }
41615 public function ignoredByBaseline(): bool
41616 {
41617 return $this->ignoredByBaseline;
41618 }
41619 public function ignoredByTest(): bool
41620 {
41621 return $this->ignoredByTest;
41622 }
41623 public function asString(): string
41624 {
41625 $message = $this->message;
41626 if (!empty($message)) {
41627 $message = PHP_EOL . $message;
41628 }
41629 $status = '';
41630 if ($this->ignoredByTest) {
41631 $status = 'Test-Ignored ';
41632 } elseif ($this->ignoredByBaseline) {
41633 $status = 'Baseline-Ignored ';
41634 } elseif ($this->suppressed) {
41635 $status = 'Suppressed ';
41636 }
41637 return sprintf('Test Triggered %sPHP Deprecation (%s) in %s:%d%s', $status, $this->test->id(), $this->file, $this->line, $message);
41638 }
41639 }
41640 <?php
41641
41642 declare (strict_types=1);
41643 /*
41644 * This file is part of PHPUnit.
41645 *
41646 * (c) Sebastian Bergmann <sebastian@phpunit.de>
41647 *
41648 * For the full copyright and license information, please view the LICENSE
41649 * file that was distributed with this source code.
41650 */
41651 namespace PHPUnit\Event\Test;
41652
41653 use PHPUnit\Event\Subscriber;
41654 /**
41655 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
41656 */
41657 interface PhpDeprecationTriggeredSubscriber extends Subscriber
41658 {
41659 public function notify(\PHPUnit\Event\Test\PhpDeprecationTriggered $event): void;
41660 }
41661 <?php
41662
41663 declare (strict_types=1);
41664 /*
41665 * This file is part of PHPUnit.
41666 *
41667 * (c) Sebastian Bergmann <sebastian@phpunit.de>
41668 *
41669 * For the full copyright and license information, please view the LICENSE
41670 * file that was distributed with this source code.
41671 */
41672 namespace PHPUnit\Event\Test;
41673
41674 use const PHP_EOL;
41675 use function sprintf;
41676 use PHPUnit\Event\Code\Test;
41677 use PHPUnit\Event\Event;
41678 use PHPUnit\Event\Telemetry;
41679 /**
41680 * @psalm-immutable
41681 *
41682 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
41683 */
41684 final class PhpNoticeTriggered implements Event
41685 {
41686 private readonly Telemetry\Info $telemetryInfo;
41687 private readonly Test $test;
41688 /**
41689 * @psalm-var non-empty-string
41690 */
41691 private readonly string $message;
41692 /**
41693 * @psalm-var non-empty-string
41694 */
41695 private readonly string $file;
41696 /**
41697 * @psalm-var positive-int
41698 */
41699 private readonly int $line;
41700 private readonly bool $suppressed;
41701 private readonly bool $ignoredByBaseline;
41702 /**
41703 * @psalm-param non-empty-string $message
41704 * @psalm-param non-empty-string $file
41705 * @psalm-param positive-int $line
41706 */
41707 public function __construct(Telemetry\Info $telemetryInfo, Test $test, string $message, string $file, int $line, bool $suppressed, bool $ignoredByBaseline)
41708 {
41709 $this->telemetryInfo = $telemetryInfo;
41710 $this->test = $test;
41711 $this->message = $message;
41712 $this->file = $file;
41713 $this->line = $line;
41714 $this->suppressed = $suppressed;
41715 $this->ignoredByBaseline = $ignoredByBaseline;
41716 }
41717 public function telemetryInfo(): Telemetry\Info
41718 {
41719 return $this->telemetryInfo;
41720 }
41721 public function test(): Test
41722 {
41723 return $this->test;
41724 }
41725 /**
41726 * @psalm-return non-empty-string
41727 */
41728 public function message(): string
41729 {
41730 return $this->message;
41731 }
41732 /**
41733 * @psalm-return non-empty-string
41734 */
41735 public function file(): string
41736 {
41737 return $this->file;
41738 }
41739 /**
41740 * @psalm-return positive-int
41741 */
41742 public function line(): int
41743 {
41744 return $this->line;
41745 }
41746 public function wasSuppressed(): bool
41747 {
41748 return $this->suppressed;
41749 }
41750 public function ignoredByBaseline(): bool
41751 {
41752 return $this->ignoredByBaseline;
41753 }
41754 public function asString(): string
41755 {
41756 $message = $this->message;
41757 if (!empty($message)) {
41758 $message = PHP_EOL . $message;
41759 }
41760 $status = '';
41761 if ($this->ignoredByBaseline) {
41762 $status = 'Baseline-Ignored ';
41763 } elseif ($this->suppressed) {
41764 $status = 'Suppressed ';
41765 }
41766 return sprintf('Test Triggered %sPHP Notice (%s) in %s:%d%s', $status, $this->test->id(), $this->file, $this->line, $message);
41767 }
41768 }
41769 <?php
41770
41771 declare (strict_types=1);
41772 /*
41773 * This file is part of PHPUnit.
41774 *
41775 * (c) Sebastian Bergmann <sebastian@phpunit.de>
41776 *
41777 * For the full copyright and license information, please view the LICENSE
41778 * file that was distributed with this source code.
41779 */
41780 namespace PHPUnit\Event\Test;
41781
41782 use PHPUnit\Event\Subscriber;
41783 /**
41784 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
41785 */
41786 interface PhpNoticeTriggeredSubscriber extends Subscriber
41787 {
41788 public function notify(\PHPUnit\Event\Test\PhpNoticeTriggered $event): void;
41789 }
41790 <?php
41791
41792 declare (strict_types=1);
41793 /*
41794 * This file is part of PHPUnit.
41795 *
41796 * (c) Sebastian Bergmann <sebastian@phpunit.de>
41797 *
41798 * For the full copyright and license information, please view the LICENSE
41799 * file that was distributed with this source code.
41800 */
41801 namespace PHPUnit\Event\Test;
41802
41803 use const PHP_EOL;
41804 use function sprintf;
41805 use PHPUnit\Event\Code\Test;
41806 use PHPUnit\Event\Event;
41807 use PHPUnit\Event\Telemetry;
41808 /**
41809 * @psalm-immutable
41810 *
41811 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
41812 */
41813 final class PhpWarningTriggered implements Event
41814 {
41815 private readonly Telemetry\Info $telemetryInfo;
41816 private readonly Test $test;
41817 /**
41818 * @psalm-var non-empty-string
41819 */
41820 private readonly string $message;
41821 /**
41822 * @psalm-var non-empty-string
41823 */
41824 private readonly string $file;
41825 /**
41826 * @psalm-var positive-int
41827 */
41828 private readonly int $line;
41829 private readonly bool $suppressed;
41830 private readonly bool $ignoredByBaseline;
41831 /**
41832 * @psalm-param non-empty-string $message
41833 * @psalm-param non-empty-string $file
41834 * @psalm-param positive-int $line
41835 */
41836 public function __construct(Telemetry\Info $telemetryInfo, Test $test, string $message, string $file, int $line, bool $suppressed, bool $ignoredByBaseline)
41837 {
41838 $this->telemetryInfo = $telemetryInfo;
41839 $this->test = $test;
41840 $this->message = $message;
41841 $this->file = $file;
41842 $this->line = $line;
41843 $this->suppressed = $suppressed;
41844 $this->ignoredByBaseline = $ignoredByBaseline;
41845 }
41846 public function telemetryInfo(): Telemetry\Info
41847 {
41848 return $this->telemetryInfo;
41849 }
41850 public function test(): Test
41851 {
41852 return $this->test;
41853 }
41854 /**
41855 * @psalm-return non-empty-string
41856 */
41857 public function message(): string
41858 {
41859 return $this->message;
41860 }
41861 /**
41862 * @psalm-return non-empty-string
41863 */
41864 public function file(): string
41865 {
41866 return $this->file;
41867 }
41868 /**
41869 * @psalm-return positive-int
41870 */
41871 public function line(): int
41872 {
41873 return $this->line;
41874 }
41875 public function wasSuppressed(): bool
41876 {
41877 return $this->suppressed;
41878 }
41879 public function ignoredByBaseline(): bool
41880 {
41881 return $this->ignoredByBaseline;
41882 }
41883 public function asString(): string
41884 {
41885 $message = $this->message;
41886 if (!empty($message)) {
41887 $message = PHP_EOL . $message;
41888 }
41889 $status = '';
41890 if ($this->ignoredByBaseline) {
41891 $status = 'Baseline-Ignored ';
41892 } elseif ($this->suppressed) {
41893 $status = 'Suppressed ';
41894 }
41895 return sprintf('Test Triggered %sPHP Warning (%s) in %s:%d%s', $status, $this->test->id(), $this->file, $this->line, $message);
41896 }
41897 }
41898 <?php
41899
41900 declare (strict_types=1);
41901 /*
41902 * This file is part of PHPUnit.
41903 *
41904 * (c) Sebastian Bergmann <sebastian@phpunit.de>
41905 *
41906 * For the full copyright and license information, please view the LICENSE
41907 * file that was distributed with this source code.
41908 */
41909 namespace PHPUnit\Event\Test;
41910
41911 use PHPUnit\Event\Subscriber;
41912 /**
41913 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
41914 */
41915 interface PhpWarningTriggeredSubscriber extends Subscriber
41916 {
41917 public function notify(\PHPUnit\Event\Test\PhpWarningTriggered $event): void;
41918 }
41919 <?php
41920
41921 declare (strict_types=1);
41922 /*
41923 * This file is part of PHPUnit.
41924 *
41925 * (c) Sebastian Bergmann <sebastian@phpunit.de>
41926 *
41927 * For the full copyright and license information, please view the LICENSE
41928 * file that was distributed with this source code.
41929 */
41930 namespace PHPUnit\Event\Test;
41931
41932 use const PHP_EOL;
41933 use function sprintf;
41934 use PHPUnit\Event\Code\Test;
41935 use PHPUnit\Event\Event;
41936 use PHPUnit\Event\Telemetry;
41937 /**
41938 * @psalm-immutable
41939 *
41940 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
41941 */
41942 final class PhpunitDeprecationTriggered implements Event
41943 {
41944 private readonly Telemetry\Info $telemetryInfo;
41945 private readonly Test $test;
41946 /**
41947 * @psalm-var non-empty-string
41948 */
41949 private readonly string $message;
41950 /**
41951 * @psalm-param non-empty-string $message
41952 */
41953 public function __construct(Telemetry\Info $telemetryInfo, Test $test, string $message)
41954 {
41955 $this->telemetryInfo = $telemetryInfo;
41956 $this->test = $test;
41957 $this->message = $message;
41958 }
41959 public function telemetryInfo(): Telemetry\Info
41960 {
41961 return $this->telemetryInfo;
41962 }
41963 public function test(): Test
41964 {
41965 return $this->test;
41966 }
41967 /**
41968 * @psalm-return non-empty-string
41969 */
41970 public function message(): string
41971 {
41972 return $this->message;
41973 }
41974 public function asString(): string
41975 {
41976 $message = $this->message;
41977 if (!empty($message)) {
41978 $message = PHP_EOL . $message;
41979 }
41980 return sprintf('Test Triggered PHPUnit Deprecation (%s)%s', $this->test->id(), $message);
41981 }
41982 }
41983 <?php
41984
41985 declare (strict_types=1);
41986 /*
41987 * This file is part of PHPUnit.
41988 *
41989 * (c) Sebastian Bergmann <sebastian@phpunit.de>
41990 *
41991 * For the full copyright and license information, please view the LICENSE
41992 * file that was distributed with this source code.
41993 */
41994 namespace PHPUnit\Event\Test;
41995
41996 use PHPUnit\Event\Subscriber;
41997 /**
41998 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
41999 */
42000 interface PhpunitDeprecationTriggeredSubscriber extends Subscriber
42001 {
42002 public function notify(\PHPUnit\Event\Test\PhpunitDeprecationTriggered $event): void;
42003 }
42004 <?php
42005
42006 declare (strict_types=1);
42007 /*
42008 * This file is part of PHPUnit.
42009 *
42010 * (c) Sebastian Bergmann <sebastian@phpunit.de>
42011 *
42012 * For the full copyright and license information, please view the LICENSE
42013 * file that was distributed with this source code.
42014 */
42015 namespace PHPUnit\Event\Test;
42016
42017 use const PHP_EOL;
42018 use function sprintf;
42019 use function trim;
42020 use PHPUnit\Event\Code\Test;
42021 use PHPUnit\Event\Event;
42022 use PHPUnit\Event\Telemetry;
42023 /**
42024 * @psalm-immutable
42025 *
42026 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
42027 */
42028 final class PhpunitErrorTriggered implements Event
42029 {
42030 private readonly Telemetry\Info $telemetryInfo;
42031 private readonly Test $test;
42032 /**
42033 * @psalm-var non-empty-string
42034 */
42035 private readonly string $message;
42036 /**
42037 * @psalm-param non-empty-string $message
42038 */
42039 public function __construct(Telemetry\Info $telemetryInfo, Test $test, string $message)
42040 {
42041 $this->telemetryInfo = $telemetryInfo;
42042 $this->test = $test;
42043 $this->message = $message;
42044 }
42045 public function telemetryInfo(): Telemetry\Info
42046 {
42047 return $this->telemetryInfo;
42048 }
42049 public function test(): Test
42050 {
42051 return $this->test;
42052 }
42053 /**
42054 * @psalm-return non-empty-string
42055 */
42056 public function message(): string
42057 {
42058 return $this->message;
42059 }
42060 public function asString(): string
42061 {
42062 $message = trim($this->message);
42063 if (!empty($message)) {
42064 $message = PHP_EOL . $message;
42065 }
42066 return sprintf('Test Triggered PHPUnit Error (%s)%s', $this->test->id(), $message);
42067 }
42068 }
42069 <?php
42070
42071 declare (strict_types=1);
42072 /*
42073 * This file is part of PHPUnit.
42074 *
42075 * (c) Sebastian Bergmann <sebastian@phpunit.de>
42076 *
42077 * For the full copyright and license information, please view the LICENSE
42078 * file that was distributed with this source code.
42079 */
42080 namespace PHPUnit\Event\Test;
42081
42082 use PHPUnit\Event\Subscriber;
42083 /**
42084 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
42085 */
42086 interface PhpunitErrorTriggeredSubscriber extends Subscriber
42087 {
42088 public function notify(\PHPUnit\Event\Test\PhpunitErrorTriggered $event): void;
42089 }
42090 <?php
42091
42092 declare (strict_types=1);
42093 /*
42094 * This file is part of PHPUnit.
42095 *
42096 * (c) Sebastian Bergmann <sebastian@phpunit.de>
42097 *
42098 * For the full copyright and license information, please view the LICENSE
42099 * file that was distributed with this source code.
42100 */
42101 namespace PHPUnit\Event\Test;
42102
42103 use const PHP_EOL;
42104 use function sprintf;
42105 use PHPUnit\Event\Code\Test;
42106 use PHPUnit\Event\Event;
42107 use PHPUnit\Event\Telemetry;
42108 /**
42109 * @psalm-immutable
42110 *
42111 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
42112 */
42113 final class PhpunitWarningTriggered implements Event
42114 {
42115 private readonly Telemetry\Info $telemetryInfo;
42116 private readonly Test $test;
42117 /**
42118 * @psalm-var non-empty-string
42119 */
42120 private readonly string $message;
42121 /**
42122 * @psalm-param non-empty-string $message
42123 */
42124 public function __construct(Telemetry\Info $telemetryInfo, Test $test, string $message)
42125 {
42126 $this->telemetryInfo = $telemetryInfo;
42127 $this->test = $test;
42128 $this->message = $message;
42129 }
42130 public function telemetryInfo(): Telemetry\Info
42131 {
42132 return $this->telemetryInfo;
42133 }
42134 public function test(): Test
42135 {
42136 return $this->test;
42137 }
42138 /**
42139 * @psalm-return non-empty-string
42140 */
42141 public function message(): string
42142 {
42143 return $this->message;
42144 }
42145 public function asString(): string
42146 {
42147 $message = $this->message;
42148 if (!empty($message)) {
42149 $message = PHP_EOL . $message;
42150 }
42151 return sprintf('Test Triggered PHPUnit Warning (%s)%s', $this->test->id(), $message);
42152 }
42153 }
42154 <?php
42155
42156 declare (strict_types=1);
42157 /*
42158 * This file is part of PHPUnit.
42159 *
42160 * (c) Sebastian Bergmann <sebastian@phpunit.de>
42161 *
42162 * For the full copyright and license information, please view the LICENSE
42163 * file that was distributed with this source code.
42164 */
42165 namespace PHPUnit\Event\Test;
42166
42167 use PHPUnit\Event\Subscriber;
42168 /**
42169 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
42170 */
42171 interface PhpunitWarningTriggeredSubscriber extends Subscriber
42172 {
42173 public function notify(\PHPUnit\Event\Test\PhpunitWarningTriggered $event): void;
42174 }
42175 <?php
42176
42177 declare (strict_types=1);
42178 /*
42179 * This file is part of PHPUnit.
42180 *
42181 * (c) Sebastian Bergmann <sebastian@phpunit.de>
42182 *
42183 * For the full copyright and license information, please view the LICENSE
42184 * file that was distributed with this source code.
42185 */
42186 namespace PHPUnit\Event\Test;
42187
42188 use const PHP_EOL;
42189 use function sprintf;
42190 use PHPUnit\Event\Code\Test;
42191 use PHPUnit\Event\Event;
42192 use PHPUnit\Event\Telemetry;
42193 /**
42194 * @psalm-immutable
42195 *
42196 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
42197 */
42198 final class WarningTriggered implements Event
42199 {
42200 private readonly Telemetry\Info $telemetryInfo;
42201 private readonly Test $test;
42202 /**
42203 * @psalm-var non-empty-string
42204 */
42205 private readonly string $message;
42206 /**
42207 * @psalm-var non-empty-string
42208 */
42209 private readonly string $file;
42210 /**
42211 * @psalm-var positive-int
42212 */
42213 private readonly int $line;
42214 private readonly bool $suppressed;
42215 private readonly bool $ignoredByBaseline;
42216 /**
42217 * @psalm-param non-empty-string $message
42218 * @psalm-param non-empty-string $file
42219 * @psalm-param positive-int $line
42220 */
42221 public function __construct(Telemetry\Info $telemetryInfo, Test $test, string $message, string $file, int $line, bool $suppressed, bool $ignoredByBaseline)
42222 {
42223 $this->telemetryInfo = $telemetryInfo;
42224 $this->test = $test;
42225 $this->message = $message;
42226 $this->file = $file;
42227 $this->line = $line;
42228 $this->suppressed = $suppressed;
42229 $this->ignoredByBaseline = $ignoredByBaseline;
42230 }
42231 public function telemetryInfo(): Telemetry\Info
42232 {
42233 return $this->telemetryInfo;
42234 }
42235 public function test(): Test
42236 {
42237 return $this->test;
42238 }
42239 /**
42240 * @psalm-return non-empty-string
42241 */
42242 public function message(): string
42243 {
42244 return $this->message;
42245 }
42246 /**
42247 * @psalm-return non-empty-string
42248 */
42249 public function file(): string
42250 {
42251 return $this->file;
42252 }
42253 /**
42254 * @psalm-return positive-int
42255 */
42256 public function line(): int
42257 {
42258 return $this->line;
42259 }
42260 public function wasSuppressed(): bool
42261 {
42262 return $this->suppressed;
42263 }
42264 public function ignoredByBaseline(): bool
42265 {
42266 return $this->ignoredByBaseline;
42267 }
42268 public function asString(): string
42269 {
42270 $message = $this->message;
42271 if (!empty($message)) {
42272 $message = PHP_EOL . $message;
42273 }
42274 $status = '';
42275 if ($this->ignoredByBaseline) {
42276 $status = 'Baseline-Ignored ';
42277 } elseif ($this->suppressed) {
42278 $status = 'Suppressed ';
42279 }
42280 return sprintf('Test Triggered %sWarning (%s) in %s:%d%s', $status, $this->test->id(), $this->file, $this->line, $message);
42281 }
42282 }
42283 <?php
42284
42285 declare (strict_types=1);
42286 /*
42287 * This file is part of PHPUnit.
42288 *
42289 * (c) Sebastian Bergmann <sebastian@phpunit.de>
42290 *
42291 * For the full copyright and license information, please view the LICENSE
42292 * file that was distributed with this source code.
42293 */
42294 namespace PHPUnit\Event\Test;
42295
42296 use PHPUnit\Event\Subscriber;
42297 /**
42298 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
42299 */
42300 interface WarningTriggeredSubscriber extends Subscriber
42301 {
42302 public function notify(\PHPUnit\Event\Test\WarningTriggered $event): void;
42303 }
42304 <?php
42305
42306 declare (strict_types=1);
42307 /*
42308 * This file is part of PHPUnit.
42309 *
42310 * (c) Sebastian Bergmann <sebastian@phpunit.de>
42311 *
42312 * For the full copyright and license information, please view the LICENSE
42313 * file that was distributed with this source code.
42314 */
42315 namespace PHPUnit\Event\Test;
42316
42317 use function sprintf;
42318 use PHPUnit\Event\Code\ClassMethod;
42319 use PHPUnit\Event\Event;
42320 use PHPUnit\Event\Telemetry\Info;
42321 /**
42322 * @psalm-immutable
42323 *
42324 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
42325 */
42326 final class DataProviderMethodCalled implements Event
42327 {
42328 private readonly Info $telemetryInfo;
42329 private readonly ClassMethod $testMethod;
42330 private readonly ClassMethod $dataProviderMethod;
42331 public function __construct(Info $telemetryInfo, ClassMethod $testMethod, ClassMethod $dataProviderMethod)
42332 {
42333 $this->telemetryInfo = $telemetryInfo;
42334 $this->testMethod = $testMethod;
42335 $this->dataProviderMethod = $dataProviderMethod;
42336 }
42337 public function telemetryInfo(): Info
42338 {
42339 return $this->telemetryInfo;
42340 }
42341 public function testMethod(): ClassMethod
42342 {
42343 return $this->testMethod;
42344 }
42345 public function dataProviderMethod(): ClassMethod
42346 {
42347 return $this->dataProviderMethod;
42348 }
42349 public function asString(): string
42350 {
42351 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());
42352 }
42353 }
42354 <?php
42355
42356 declare (strict_types=1);
42357 /*
42358 * This file is part of PHPUnit.
42359 *
42360 * (c) Sebastian Bergmann <sebastian@phpunit.de>
42361 *
42362 * For the full copyright and license information, please view the LICENSE
42363 * file that was distributed with this source code.
42364 */
42365 namespace PHPUnit\Event\Test;
42366
42367 use PHPUnit\Event\Subscriber;
42368 /**
42369 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
42370 */
42371 interface DataProviderMethodCalledSubscriber extends Subscriber
42372 {
42373 public function notify(\PHPUnit\Event\Test\DataProviderMethodCalled $event): void;
42374 }
42375 <?php
42376
42377 declare (strict_types=1);
42378 /*
42379 * This file is part of PHPUnit.
42380 *
42381 * (c) Sebastian Bergmann <sebastian@phpunit.de>
42382 *
42383 * For the full copyright and license information, please view the LICENSE
42384 * file that was distributed with this source code.
42385 */
42386 namespace PHPUnit\Event\Test;
42387
42388 use const PHP_EOL;
42389 use function sprintf;
42390 use PHPUnit\Event\Code\ClassMethod;
42391 use PHPUnit\Event\Event;
42392 use PHPUnit\Event\Telemetry;
42393 /**
42394 * @psalm-immutable
42395 *
42396 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
42397 */
42398 final class DataProviderMethodFinished implements Event
42399 {
42400 private readonly Telemetry\Info $telemetryInfo;
42401 private readonly ClassMethod $testMethod;
42402 /**
42403 * @psalm-var list<ClassMethod>
42404 */
42405 private readonly array $calledMethods;
42406 public function __construct(Telemetry\Info $telemetryInfo, ClassMethod $testMethod, ClassMethod ...$calledMethods)
42407 {
42408 $this->telemetryInfo = $telemetryInfo;
42409 $this->testMethod = $testMethod;
42410 $this->calledMethods = $calledMethods;
42411 }
42412 public function telemetryInfo(): Telemetry\Info
42413 {
42414 return $this->telemetryInfo;
42415 }
42416 public function testMethod(): ClassMethod
42417 {
42418 return $this->testMethod;
42419 }
42420 /**
42421 * @psalm-return list<ClassMethod>
42422 */
42423 public function calledMethods(): array
42424 {
42425 return $this->calledMethods;
42426 }
42427 public function asString(): string
42428 {
42429 $buffer = sprintf('Data Provider Method Finished for %s::%s:', $this->testMethod->className(), $this->testMethod->methodName());
42430 foreach ($this->calledMethods as $calledMethod) {
42431 $buffer .= sprintf(PHP_EOL . '- %s::%s', $calledMethod->className(), $calledMethod->methodName());
42432 }
42433 return $buffer;
42434 }
42435 }
42436 <?php
42437
42438 declare (strict_types=1);
42439 /*
42440 * This file is part of PHPUnit.
42441 *
42442 * (c) Sebastian Bergmann <sebastian@phpunit.de>
42443 *
42444 * For the full copyright and license information, please view the LICENSE
42445 * file that was distributed with this source code.
42446 */
42447 namespace PHPUnit\Event\Test;
42448
42449 use PHPUnit\Event\Subscriber;
42450 /**
42451 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
42452 */
42453 interface DataProviderMethodFinishedSubscriber extends Subscriber
42454 {
42455 public function notify(\PHPUnit\Event\Test\DataProviderMethodFinished $event): void;
42456 }
42457 <?php
42458
42459 declare (strict_types=1);
42460 /*
42461 * This file is part of PHPUnit.
42462 *
42463 * (c) Sebastian Bergmann <sebastian@phpunit.de>
42464 *
42465 * For the full copyright and license information, please view the LICENSE
42466 * file that was distributed with this source code.
42467 */
42468 namespace PHPUnit\Event\Test;
42469
42470 use function sprintf;
42471 use PHPUnit\Event\Code;
42472 use PHPUnit\Event\Event;
42473 use PHPUnit\Event\Telemetry;
42474 /**
42475 * @psalm-immutable
42476 *
42477 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
42478 */
42479 final class Finished implements Event
42480 {
42481 private readonly Telemetry\Info $telemetryInfo;
42482 private readonly Code\Test $test;
42483 private readonly int $numberOfAssertionsPerformed;
42484 public function __construct(Telemetry\Info $telemetryInfo, Code\Test $test, int $numberOfAssertionsPerformed)
42485 {
42486 $this->telemetryInfo = $telemetryInfo;
42487 $this->test = $test;
42488 $this->numberOfAssertionsPerformed = $numberOfAssertionsPerformed;
42489 }
42490 public function telemetryInfo(): Telemetry\Info
42491 {
42492 return $this->telemetryInfo;
42493 }
42494 public function test(): Code\Test
42495 {
42496 return $this->test;
42497 }
42498 public function numberOfAssertionsPerformed(): int
42499 {
42500 return $this->numberOfAssertionsPerformed;
42501 }
42502 public function asString(): string
42503 {
42504 return sprintf('Test Finished (%s)', $this->test->id());
42505 }
42506 }
42507 <?php
42508
42509 declare (strict_types=1);
42510 /*
42511 * This file is part of PHPUnit.
42512 *
42513 * (c) Sebastian Bergmann <sebastian@phpunit.de>
42514 *
42515 * For the full copyright and license information, please view the LICENSE
42516 * file that was distributed with this source code.
42517 */
42518 namespace PHPUnit\Event\Test;
42519
42520 use PHPUnit\Event\Subscriber;
42521 /**
42522 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
42523 */
42524 interface FinishedSubscriber extends Subscriber
42525 {
42526 public function notify(\PHPUnit\Event\Test\Finished $event): void;
42527 }
42528 <?php
42529
42530 declare (strict_types=1);
42531 /*
42532 * This file is part of PHPUnit.
42533 *
42534 * (c) Sebastian Bergmann <sebastian@phpunit.de>
42535 *
42536 * For the full copyright and license information, please view the LICENSE
42537 * file that was distributed with this source code.
42538 */
42539 namespace PHPUnit\Event\Test;
42540
42541 use function sprintf;
42542 use PHPUnit\Event\Code;
42543 use PHPUnit\Event\Event;
42544 use PHPUnit\Event\Telemetry;
42545 /**
42546 * @psalm-immutable
42547 *
42548 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
42549 */
42550 final class PreparationFailed implements Event
42551 {
42552 private readonly Telemetry\Info $telemetryInfo;
42553 private readonly Code\Test $test;
42554 public function __construct(Telemetry\Info $telemetryInfo, Code\Test $test)
42555 {
42556 $this->telemetryInfo = $telemetryInfo;
42557 $this->test = $test;
42558 }
42559 public function telemetryInfo(): Telemetry\Info
42560 {
42561 return $this->telemetryInfo;
42562 }
42563 public function test(): Code\Test
42564 {
42565 return $this->test;
42566 }
42567 public function asString(): string
42568 {
42569 return sprintf('Test Preparation Failed (%s)', $this->test->id());
42570 }
42571 }
42572 <?php
42573
42574 declare (strict_types=1);
42575 /*
42576 * This file is part of PHPUnit.
42577 *
42578 * (c) Sebastian Bergmann <sebastian@phpunit.de>
42579 *
42580 * For the full copyright and license information, please view the LICENSE
42581 * file that was distributed with this source code.
42582 */
42583 namespace PHPUnit\Event\Test;
42584
42585 use PHPUnit\Event\Subscriber;
42586 /**
42587 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
42588 */
42589 interface PreparationFailedSubscriber extends Subscriber
42590 {
42591 public function notify(\PHPUnit\Event\Test\PreparationFailed $event): void;
42592 }
42593 <?php
42594
42595 declare (strict_types=1);
42596 /*
42597 * This file is part of PHPUnit.
42598 *
42599 * (c) Sebastian Bergmann <sebastian@phpunit.de>
42600 *
42601 * For the full copyright and license information, please view the LICENSE
42602 * file that was distributed with this source code.
42603 */
42604 namespace PHPUnit\Event\Test;
42605
42606 use function sprintf;
42607 use PHPUnit\Event\Code;
42608 use PHPUnit\Event\Event;
42609 use PHPUnit\Event\Telemetry;
42610 /**
42611 * @psalm-immutable
42612 *
42613 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
42614 */
42615 final class PreparationStarted implements Event
42616 {
42617 private readonly Telemetry\Info $telemetryInfo;
42618 private readonly Code\Test $test;
42619 public function __construct(Telemetry\Info $telemetryInfo, Code\Test $test)
42620 {
42621 $this->telemetryInfo = $telemetryInfo;
42622 $this->test = $test;
42623 }
42624 public function telemetryInfo(): Telemetry\Info
42625 {
42626 return $this->telemetryInfo;
42627 }
42628 public function test(): Code\Test
42629 {
42630 return $this->test;
42631 }
42632 public function asString(): string
42633 {
42634 return sprintf('Test Preparation Started (%s)', $this->test->id());
42635 }
42636 }
42637 <?php
42638
42639 declare (strict_types=1);
42640 /*
42641 * This file is part of PHPUnit.
42642 *
42643 * (c) Sebastian Bergmann <sebastian@phpunit.de>
42644 *
42645 * For the full copyright and license information, please view the LICENSE
42646 * file that was distributed with this source code.
42647 */
42648 namespace PHPUnit\Event\Test;
42649
42650 use PHPUnit\Event\Subscriber;
42651 /**
42652 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
42653 */
42654 interface PreparationStartedSubscriber extends Subscriber
42655 {
42656 public function notify(\PHPUnit\Event\Test\PreparationStarted $event): void;
42657 }
42658 <?php
42659
42660 declare (strict_types=1);
42661 /*
42662 * This file is part of PHPUnit.
42663 *
42664 * (c) Sebastian Bergmann <sebastian@phpunit.de>
42665 *
42666 * For the full copyright and license information, please view the LICENSE
42667 * file that was distributed with this source code.
42668 */
42669 namespace PHPUnit\Event\Test;
42670
42671 use function sprintf;
42672 use PHPUnit\Event\Code;
42673 use PHPUnit\Event\Event;
42674 use PHPUnit\Event\Telemetry;
42675 /**
42676 * @psalm-immutable
42677 *
42678 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
42679 */
42680 final class Prepared implements Event
42681 {
42682 private readonly Telemetry\Info $telemetryInfo;
42683 private readonly Code\Test $test;
42684 public function __construct(Telemetry\Info $telemetryInfo, Code\Test $test)
42685 {
42686 $this->telemetryInfo = $telemetryInfo;
42687 $this->test = $test;
42688 }
42689 public function telemetryInfo(): Telemetry\Info
42690 {
42691 return $this->telemetryInfo;
42692 }
42693 public function test(): Code\Test
42694 {
42695 return $this->test;
42696 }
42697 public function asString(): string
42698 {
42699 return sprintf('Test Prepared (%s)', $this->test->id());
42700 }
42701 }
42702 <?php
42703
42704 declare (strict_types=1);
42705 /*
42706 * This file is part of PHPUnit.
42707 *
42708 * (c) Sebastian Bergmann <sebastian@phpunit.de>
42709 *
42710 * For the full copyright and license information, please view the LICENSE
42711 * file that was distributed with this source code.
42712 */
42713 namespace PHPUnit\Event\Test;
42714
42715 use PHPUnit\Event\Subscriber;
42716 /**
42717 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
42718 */
42719 interface PreparedSubscriber extends Subscriber
42720 {
42721 public function notify(\PHPUnit\Event\Test\Prepared $event): void;
42722 }
42723 <?php
42724
42725 declare (strict_types=1);
42726 /*
42727 * This file is part of PHPUnit.
42728 *
42729 * (c) Sebastian Bergmann <sebastian@phpunit.de>
42730 *
42731 * For the full copyright and license information, please view the LICENSE
42732 * file that was distributed with this source code.
42733 */
42734 namespace PHPUnit\Event\Test;
42735
42736 use const PHP_EOL;
42737 use function sprintf;
42738 use function trim;
42739 use PHPUnit\Event\Code;
42740 use PHPUnit\Event\Code\Throwable;
42741 use PHPUnit\Event\Event;
42742 use PHPUnit\Event\Telemetry;
42743 /**
42744 * @psalm-immutable
42745 *
42746 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
42747 */
42748 final class Errored implements Event
42749 {
42750 private readonly Telemetry\Info $telemetryInfo;
42751 private readonly Code\Test $test;
42752 private readonly Throwable $throwable;
42753 public function __construct(Telemetry\Info $telemetryInfo, Code\Test $test, Throwable $throwable)
42754 {
42755 $this->telemetryInfo = $telemetryInfo;
42756 $this->test = $test;
42757 $this->throwable = $throwable;
42758 }
42759 public function telemetryInfo(): Telemetry\Info
42760 {
42761 return $this->telemetryInfo;
42762 }
42763 public function test(): Code\Test
42764 {
42765 return $this->test;
42766 }
42767 public function throwable(): Throwable
42768 {
42769 return $this->throwable;
42770 }
42771 public function asString(): string
42772 {
42773 $message = trim($this->throwable->message());
42774 if (!empty($message)) {
42775 $message = PHP_EOL . $message;
42776 }
42777 return sprintf('Test Errored (%s)%s', $this->test->id(), $message);
42778 }
42779 }
42780 <?php
42781
42782 declare (strict_types=1);
42783 /*
42784 * This file is part of PHPUnit.
42785 *
42786 * (c) Sebastian Bergmann <sebastian@phpunit.de>
42787 *
42788 * For the full copyright and license information, please view the LICENSE
42789 * file that was distributed with this source code.
42790 */
42791 namespace PHPUnit\Event\Test;
42792
42793 use PHPUnit\Event\Subscriber;
42794 /**
42795 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
42796 */
42797 interface ErroredSubscriber extends Subscriber
42798 {
42799 public function notify(\PHPUnit\Event\Test\Errored $event): void;
42800 }
42801 <?php
42802
42803 declare (strict_types=1);
42804 /*
42805 * This file is part of PHPUnit.
42806 *
42807 * (c) Sebastian Bergmann <sebastian@phpunit.de>
42808 *
42809 * For the full copyright and license information, please view the LICENSE
42810 * file that was distributed with this source code.
42811 */
42812 namespace PHPUnit\Event\Test;
42813
42814 use const PHP_EOL;
42815 use function sprintf;
42816 use function trim;
42817 use PHPUnit\Event\Code;
42818 use PHPUnit\Event\Code\ComparisonFailure;
42819 use PHPUnit\Event\Code\Throwable;
42820 use PHPUnit\Event\Event;
42821 use PHPUnit\Event\Telemetry;
42822 /**
42823 * @psalm-immutable
42824 *
42825 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
42826 */
42827 final class Failed implements Event
42828 {
42829 private readonly Telemetry\Info $telemetryInfo;
42830 private readonly Code\Test $test;
42831 private readonly Throwable $throwable;
42832 private readonly ?ComparisonFailure $comparisonFailure;
42833 public function __construct(Telemetry\Info $telemetryInfo, Code\Test $test, Throwable $throwable, ?ComparisonFailure $comparisonFailure)
42834 {
42835 $this->telemetryInfo = $telemetryInfo;
42836 $this->test = $test;
42837 $this->throwable = $throwable;
42838 $this->comparisonFailure = $comparisonFailure;
42839 }
42840 public function telemetryInfo(): Telemetry\Info
42841 {
42842 return $this->telemetryInfo;
42843 }
42844 public function test(): Code\Test
42845 {
42846 return $this->test;
42847 }
42848 public function throwable(): Throwable
42849 {
42850 return $this->throwable;
42851 }
42852 /**
42853 * @psalm-assert-if-true !null $this->comparisonFailure
42854 */
42855 public function hasComparisonFailure(): bool
42856 {
42857 return $this->comparisonFailure !== null;
42858 }
42859 /**
42860 * @throws NoComparisonFailureException
42861 */
42862 public function comparisonFailure(): ComparisonFailure
42863 {
42864 if ($this->comparisonFailure === null) {
42865 throw new \PHPUnit\Event\Test\NoComparisonFailureException();
42866 }
42867 return $this->comparisonFailure;
42868 }
42869 public function asString(): string
42870 {
42871 $message = trim($this->throwable->message());
42872 if (!empty($message)) {
42873 $message = PHP_EOL . $message;
42874 }
42875 return sprintf('Test Failed (%s)%s', $this->test->id(), $message);
42876 }
42877 }
42878 <?php
42879
42880 declare (strict_types=1);
42881 /*
42882 * This file is part of PHPUnit.
42883 *
42884 * (c) Sebastian Bergmann <sebastian@phpunit.de>
42885 *
42886 * For the full copyright and license information, please view the LICENSE
42887 * file that was distributed with this source code.
42888 */
42889 namespace PHPUnit\Event\Test;
42890
42891 use PHPUnit\Event\Subscriber;
42892 /**
42893 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
42894 */
42895 interface FailedSubscriber extends Subscriber
42896 {
42897 public function notify(\PHPUnit\Event\Test\Failed $event): void;
42898 }
42899 <?php
42900
42901 declare (strict_types=1);
42902 /*
42903 * This file is part of PHPUnit.
42904 *
42905 * (c) Sebastian Bergmann <sebastian@phpunit.de>
42906 *
42907 * For the full copyright and license information, please view the LICENSE
42908 * file that was distributed with this source code.
42909 */
42910 namespace PHPUnit\Event\Test;
42911
42912 use const PHP_EOL;
42913 use function sprintf;
42914 use function trim;
42915 use PHPUnit\Event\Code;
42916 use PHPUnit\Event\Code\Throwable;
42917 use PHPUnit\Event\Event;
42918 use PHPUnit\Event\Telemetry;
42919 /**
42920 * @psalm-immutable
42921 *
42922 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
42923 */
42924 final class MarkedIncomplete implements Event
42925 {
42926 private readonly Telemetry\Info $telemetryInfo;
42927 private readonly Code\Test $test;
42928 private readonly Throwable $throwable;
42929 public function __construct(Telemetry\Info $telemetryInfo, Code\Test $test, Throwable $throwable)
42930 {
42931 $this->telemetryInfo = $telemetryInfo;
42932 $this->test = $test;
42933 $this->throwable = $throwable;
42934 }
42935 public function telemetryInfo(): Telemetry\Info
42936 {
42937 return $this->telemetryInfo;
42938 }
42939 public function test(): Code\Test
42940 {
42941 return $this->test;
42942 }
42943 public function throwable(): Throwable
42944 {
42945 return $this->throwable;
42946 }
42947 public function asString(): string
42948 {
42949 $message = trim($this->throwable->message());
42950 if (!empty($message)) {
42951 $message = PHP_EOL . $message;
42952 }
42953 return sprintf('Test Marked Incomplete (%s)%s', $this->test->id(), $message);
42954 }
42955 }
42956 <?php
42957
42958 declare (strict_types=1);
42959 /*
42960 * This file is part of PHPUnit.
42961 *
42962 * (c) Sebastian Bergmann <sebastian@phpunit.de>
42963 *
42964 * For the full copyright and license information, please view the LICENSE
42965 * file that was distributed with this source code.
42966 */
42967 namespace PHPUnit\Event\Test;
42968
42969 use PHPUnit\Event\Subscriber;
42970 /**
42971 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
42972 */
42973 interface MarkedIncompleteSubscriber extends Subscriber
42974 {
42975 public function notify(\PHPUnit\Event\Test\MarkedIncomplete $event): void;
42976 }
42977 <?php
42978
42979 declare (strict_types=1);
42980 /*
42981 * This file is part of PHPUnit.
42982 *
42983 * (c) Sebastian Bergmann <sebastian@phpunit.de>
42984 *
42985 * For the full copyright and license information, please view the LICENSE
42986 * file that was distributed with this source code.
42987 */
42988 namespace PHPUnit\Event\Test;
42989
42990 use function sprintf;
42991 use PHPUnit\Event\Code;
42992 use PHPUnit\Event\Event;
42993 use PHPUnit\Event\Telemetry;
42994 /**
42995 * @psalm-immutable
42996 *
42997 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
42998 */
42999 final class Passed implements Event
43000 {
43001 private readonly Telemetry\Info $telemetryInfo;
43002 private readonly Code\Test $test;
43003 public function __construct(Telemetry\Info $telemetryInfo, Code\Test $test)
43004 {
43005 $this->telemetryInfo = $telemetryInfo;
43006 $this->test = $test;
43007 }
43008 public function telemetryInfo(): Telemetry\Info
43009 {
43010 return $this->telemetryInfo;
43011 }
43012 public function test(): Code\Test
43013 {
43014 return $this->test;
43015 }
43016 public function asString(): string
43017 {
43018 return sprintf('Test Passed (%s)', $this->test->id());
43019 }
43020 }
43021 <?php
43022
43023 declare (strict_types=1);
43024 /*
43025 * This file is part of PHPUnit.
43026 *
43027 * (c) Sebastian Bergmann <sebastian@phpunit.de>
43028 *
43029 * For the full copyright and license information, please view the LICENSE
43030 * file that was distributed with this source code.
43031 */
43032 namespace PHPUnit\Event\Test;
43033
43034 use PHPUnit\Event\Subscriber;
43035 /**
43036 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
43037 */
43038 interface PassedSubscriber extends Subscriber
43039 {
43040 public function notify(\PHPUnit\Event\Test\Passed $event): void;
43041 }
43042 <?php
43043
43044 declare (strict_types=1);
43045 /*
43046 * This file is part of PHPUnit.
43047 *
43048 * (c) Sebastian Bergmann <sebastian@phpunit.de>
43049 *
43050 * For the full copyright and license information, please view the LICENSE
43051 * file that was distributed with this source code.
43052 */
43053 namespace PHPUnit\Event\Test;
43054
43055 use const PHP_EOL;
43056 use function sprintf;
43057 use PHPUnit\Event\Code;
43058 use PHPUnit\Event\Event;
43059 use PHPUnit\Event\Telemetry;
43060 /**
43061 * @psalm-immutable
43062 *
43063 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
43064 */
43065 final class Skipped implements Event
43066 {
43067 private readonly Telemetry\Info $telemetryInfo;
43068 private readonly Code\Test $test;
43069 private readonly string $message;
43070 public function __construct(Telemetry\Info $telemetryInfo, Code\Test $test, string $message)
43071 {
43072 $this->telemetryInfo = $telemetryInfo;
43073 $this->test = $test;
43074 $this->message = $message;
43075 }
43076 public function telemetryInfo(): Telemetry\Info
43077 {
43078 return $this->telemetryInfo;
43079 }
43080 public function test(): Code\Test
43081 {
43082 return $this->test;
43083 }
43084 public function message(): string
43085 {
43086 return $this->message;
43087 }
43088 public function asString(): string
43089 {
43090 $message = $this->message;
43091 if (!empty($message)) {
43092 $message = PHP_EOL . $message;
43093 }
43094 return sprintf('Test Skipped (%s)%s', $this->test->id(), $message);
43095 }
43096 }
43097 <?php
43098
43099 declare (strict_types=1);
43100 /*
43101 * This file is part of PHPUnit.
43102 *
43103 * (c) Sebastian Bergmann <sebastian@phpunit.de>
43104 *
43105 * For the full copyright and license information, please view the LICENSE
43106 * file that was distributed with this source code.
43107 */
43108 namespace PHPUnit\Event\Test;
43109
43110 use PHPUnit\Event\Subscriber;
43111 /**
43112 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
43113 */
43114 interface SkippedSubscriber extends Subscriber
43115 {
43116 public function notify(\PHPUnit\Event\Test\Skipped $event): void;
43117 }
43118 <?php
43119
43120 declare (strict_types=1);
43121 /*
43122 * This file is part of PHPUnit.
43123 *
43124 * (c) Sebastian Bergmann <sebastian@phpunit.de>
43125 *
43126 * For the full copyright and license information, please view the LICENSE
43127 * file that was distributed with this source code.
43128 */
43129 namespace PHPUnit\Event\Test;
43130
43131 use const PHP_EOL;
43132 use function sprintf;
43133 use PHPUnit\Event\Event;
43134 use PHPUnit\Event\Telemetry;
43135 /**
43136 * @psalm-immutable
43137 *
43138 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
43139 */
43140 final class PrintedUnexpectedOutput implements Event
43141 {
43142 private readonly Telemetry\Info $telemetryInfo;
43143 /**
43144 * @psalm-var non-empty-string
43145 */
43146 private readonly string $output;
43147 /**
43148 * @psalm-param non-empty-string $output
43149 */
43150 public function __construct(Telemetry\Info $telemetryInfo, string $output)
43151 {
43152 $this->telemetryInfo = $telemetryInfo;
43153 $this->output = $output;
43154 }
43155 public function telemetryInfo(): Telemetry\Info
43156 {
43157 return $this->telemetryInfo;
43158 }
43159 /**
43160 * @psalm-return non-empty-string
43161 */
43162 public function output(): string
43163 {
43164 return $this->output;
43165 }
43166 public function asString(): string
43167 {
43168 return sprintf('Test Printed Unexpected Output%s%s', PHP_EOL, $this->output);
43169 }
43170 }
43171 <?php
43172
43173 declare (strict_types=1);
43174 /*
43175 * This file is part of PHPUnit.
43176 *
43177 * (c) Sebastian Bergmann <sebastian@phpunit.de>
43178 *
43179 * For the full copyright and license information, please view the LICENSE
43180 * file that was distributed with this source code.
43181 */
43182 namespace PHPUnit\Event\Test;
43183
43184 use PHPUnit\Event\Subscriber;
43185 /**
43186 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
43187 */
43188 interface PrintedUnexpectedOutputSubscriber extends Subscriber
43189 {
43190 public function notify(\PHPUnit\Event\Test\PrintedUnexpectedOutput $event): void;
43191 }
43192 <?php
43193
43194 declare (strict_types=1);
43195 /*
43196 * This file is part of PHPUnit.
43197 *
43198 * (c) Sebastian Bergmann <sebastian@phpunit.de>
43199 *
43200 * For the full copyright and license information, please view the LICENSE
43201 * file that was distributed with this source code.
43202 */
43203 namespace PHPUnit\Event\Test;
43204
43205 use function sprintf;
43206 use PHPUnit\Event\Event;
43207 use PHPUnit\Event\Telemetry;
43208 /**
43209 * @psalm-immutable
43210 *
43211 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
43212 */
43213 final class MockObjectCreated implements Event
43214 {
43215 private readonly Telemetry\Info $telemetryInfo;
43216 /**
43217 * @psalm-var class-string
43218 */
43219 private readonly string $className;
43220 /**
43221 * @psalm-param class-string $className
43222 */
43223 public function __construct(Telemetry\Info $telemetryInfo, string $className)
43224 {
43225 $this->telemetryInfo = $telemetryInfo;
43226 $this->className = $className;
43227 }
43228 public function telemetryInfo(): Telemetry\Info
43229 {
43230 return $this->telemetryInfo;
43231 }
43232 /**
43233 * @psalm-return class-string
43234 */
43235 public function className(): string
43236 {
43237 return $this->className;
43238 }
43239 public function asString(): string
43240 {
43241 return sprintf('Mock Object Created (%s)', $this->className);
43242 }
43243 }
43244 <?php
43245
43246 declare (strict_types=1);
43247 /*
43248 * This file is part of PHPUnit.
43249 *
43250 * (c) Sebastian Bergmann <sebastian@phpunit.de>
43251 *
43252 * For the full copyright and license information, please view the LICENSE
43253 * file that was distributed with this source code.
43254 */
43255 namespace PHPUnit\Event\Test;
43256
43257 use PHPUnit\Event\Subscriber;
43258 /**
43259 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
43260 */
43261 interface MockObjectCreatedSubscriber extends Subscriber
43262 {
43263 public function notify(\PHPUnit\Event\Test\MockObjectCreated $event): void;
43264 }
43265 <?php
43266
43267 declare (strict_types=1);
43268 /*
43269 * This file is part of PHPUnit.
43270 *
43271 * (c) Sebastian Bergmann <sebastian@phpunit.de>
43272 *
43273 * For the full copyright and license information, please view the LICENSE
43274 * file that was distributed with this source code.
43275 */
43276 namespace PHPUnit\Event\Test;
43277
43278 use function sprintf;
43279 use PHPUnit\Event\Event;
43280 use PHPUnit\Event\Telemetry;
43281 /**
43282 * @psalm-immutable
43283 *
43284 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
43285 */
43286 final class MockObjectForAbstractClassCreated implements Event
43287 {
43288 private readonly Telemetry\Info $telemetryInfo;
43289 /**
43290 * @psalm-var class-string
43291 */
43292 private readonly string $className;
43293 /**
43294 * @psalm-param class-string $className
43295 */
43296 public function __construct(Telemetry\Info $telemetryInfo, string $className)
43297 {
43298 $this->telemetryInfo = $telemetryInfo;
43299 $this->className = $className;
43300 }
43301 public function telemetryInfo(): Telemetry\Info
43302 {
43303 return $this->telemetryInfo;
43304 }
43305 /**
43306 * @psalm-return class-string
43307 */
43308 public function className(): string
43309 {
43310 return $this->className;
43311 }
43312 public function asString(): string
43313 {
43314 return sprintf('Mock Object Created (%s)', $this->className);
43315 }
43316 }
43317 <?php
43318
43319 declare (strict_types=1);
43320 /*
43321 * This file is part of PHPUnit.
43322 *
43323 * (c) Sebastian Bergmann <sebastian@phpunit.de>
43324 *
43325 * For the full copyright and license information, please view the LICENSE
43326 * file that was distributed with this source code.
43327 */
43328 namespace PHPUnit\Event\Test;
43329
43330 use PHPUnit\Event\Subscriber;
43331 /**
43332 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
43333 */
43334 interface MockObjectForAbstractClassCreatedSubscriber extends Subscriber
43335 {
43336 public function notify(\PHPUnit\Event\Test\MockObjectForAbstractClassCreated $event): void;
43337 }
43338 <?php
43339
43340 declare (strict_types=1);
43341 /*
43342 * This file is part of PHPUnit.
43343 *
43344 * (c) Sebastian Bergmann <sebastian@phpunit.de>
43345 *
43346 * For the full copyright and license information, please view the LICENSE
43347 * file that was distributed with this source code.
43348 */
43349 namespace PHPUnit\Event\Test;
43350
43351 use function implode;
43352 use function sprintf;
43353 use PHPUnit\Event\Event;
43354 use PHPUnit\Event\Telemetry;
43355 /**
43356 * @psalm-immutable
43357 *
43358 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
43359 */
43360 final class MockObjectForIntersectionOfInterfacesCreated implements Event
43361 {
43362 private readonly Telemetry\Info $telemetryInfo;
43363 /**
43364 * @psalm-var list<class-string>
43365 */
43366 private readonly array $interfaces;
43367 /**
43368 * @psalm-param list<class-string> $interfaces
43369 */
43370 public function __construct(Telemetry\Info $telemetryInfo, array $interfaces)
43371 {
43372 $this->telemetryInfo = $telemetryInfo;
43373 $this->interfaces = $interfaces;
43374 }
43375 public function telemetryInfo(): Telemetry\Info
43376 {
43377 return $this->telemetryInfo;
43378 }
43379 /**
43380 * @return list<class-string>
43381 */
43382 public function interfaces(): array
43383 {
43384 return $this->interfaces;
43385 }
43386 public function asString(): string
43387 {
43388 return sprintf('Mock Object Created (%s)', implode('&', $this->interfaces));
43389 }
43390 }
43391 <?php
43392
43393 declare (strict_types=1);
43394 /*
43395 * This file is part of PHPUnit.
43396 *
43397 * (c) Sebastian Bergmann <sebastian@phpunit.de>
43398 *
43399 * For the full copyright and license information, please view the LICENSE
43400 * file that was distributed with this source code.
43401 */
43402 namespace PHPUnit\Event\Test;
43403
43404 use PHPUnit\Event\Subscriber;
43405 /**
43406 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
43407 */
43408 interface MockObjectForIntersectionOfInterfacesCreatedSubscriber extends Subscriber
43409 {
43410 public function notify(\PHPUnit\Event\Test\MockObjectForIntersectionOfInterfacesCreated $event): void;
43411 }
43412 <?php
43413
43414 declare (strict_types=1);
43415 /*
43416 * This file is part of PHPUnit.
43417 *
43418 * (c) Sebastian Bergmann <sebastian@phpunit.de>
43419 *
43420 * For the full copyright and license information, please view the LICENSE
43421 * file that was distributed with this source code.
43422 */
43423 namespace PHPUnit\Event\Test;
43424
43425 use function sprintf;
43426 use PHPUnit\Event\Event;
43427 use PHPUnit\Event\Telemetry;
43428 /**
43429 * @psalm-immutable
43430 *
43431 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
43432 */
43433 final class MockObjectForTraitCreated implements Event
43434 {
43435 private readonly Telemetry\Info $telemetryInfo;
43436 /**
43437 * @psalm-var trait-string
43438 */
43439 private readonly string $traitName;
43440 /**
43441 * @psalm-param trait-string $traitName
43442 */
43443 public function __construct(Telemetry\Info $telemetryInfo, string $traitName)
43444 {
43445 $this->telemetryInfo = $telemetryInfo;
43446 $this->traitName = $traitName;
43447 }
43448 public function telemetryInfo(): Telemetry\Info
43449 {
43450 return $this->telemetryInfo;
43451 }
43452 /**
43453 * @psalm-return trait-string
43454 */
43455 public function traitName(): string
43456 {
43457 return $this->traitName;
43458 }
43459 public function asString(): string
43460 {
43461 return sprintf('Mock Object Created (%s)', $this->traitName);
43462 }
43463 }
43464 <?php
43465
43466 declare (strict_types=1);
43467 /*
43468 * This file is part of PHPUnit.
43469 *
43470 * (c) Sebastian Bergmann <sebastian@phpunit.de>
43471 *
43472 * For the full copyright and license information, please view the LICENSE
43473 * file that was distributed with this source code.
43474 */
43475 namespace PHPUnit\Event\Test;
43476
43477 use PHPUnit\Event\Subscriber;
43478 /**
43479 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
43480 */
43481 interface MockObjectForTraitCreatedSubscriber extends Subscriber
43482 {
43483 public function notify(\PHPUnit\Event\Test\MockObjectForTraitCreated $event): void;
43484 }
43485 <?php
43486
43487 declare (strict_types=1);
43488 /*
43489 * This file is part of PHPUnit.
43490 *
43491 * (c) Sebastian Bergmann <sebastian@phpunit.de>
43492 *
43493 * For the full copyright and license information, please view the LICENSE
43494 * file that was distributed with this source code.
43495 */
43496 namespace PHPUnit\Event\Test;
43497
43498 use function sprintf;
43499 use PHPUnit\Event\Event;
43500 use PHPUnit\Event\Telemetry;
43501 /**
43502 * @psalm-immutable
43503 *
43504 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
43505 */
43506 final class MockObjectFromWsdlCreated implements Event
43507 {
43508 private readonly Telemetry\Info $telemetryInfo;
43509 private readonly string $wsdlFile;
43510 /**
43511 * @psalm-var class-string
43512 */
43513 private readonly string $originalClassName;
43514 /**
43515 * @psalm-var class-string
43516 */
43517 private readonly string $mockClassName;
43518 /**
43519 * @psalm-var list<string>
43520 */
43521 private readonly array $methods;
43522 private readonly bool $callOriginalConstructor;
43523 private readonly array $options;
43524 /**
43525 * @psalm-param class-string $originalClassName
43526 * @psalm-param class-string $mockClassName
43527 */
43528 public function __construct(Telemetry\Info $telemetryInfo, string $wsdlFile, string $originalClassName, string $mockClassName, array $methods, bool $callOriginalConstructor, array $options)
43529 {
43530 $this->telemetryInfo = $telemetryInfo;
43531 $this->wsdlFile = $wsdlFile;
43532 $this->originalClassName = $originalClassName;
43533 $this->mockClassName = $mockClassName;
43534 $this->methods = $methods;
43535 $this->callOriginalConstructor = $callOriginalConstructor;
43536 $this->options = $options;
43537 }
43538 public function telemetryInfo(): Telemetry\Info
43539 {
43540 return $this->telemetryInfo;
43541 }
43542 public function wsdlFile(): string
43543 {
43544 return $this->wsdlFile;
43545 }
43546 /**
43547 * @psalm-return class-string
43548 */
43549 public function originalClassName(): string
43550 {
43551 return $this->originalClassName;
43552 }
43553 /**
43554 * @psalm-return class-string
43555 */
43556 public function mockClassName(): string
43557 {
43558 return $this->mockClassName;
43559 }
43560 /**
43561 * @psalm-return list<string>
43562 */
43563 public function methods(): array
43564 {
43565 return $this->methods;
43566 }
43567 public function callOriginalConstructor(): bool
43568 {
43569 return $this->callOriginalConstructor;
43570 }
43571 public function options(): array
43572 {
43573 return $this->options;
43574 }
43575 public function asString(): string
43576 {
43577 return sprintf('Mock Object Created (%s)', $this->wsdlFile);
43578 }
43579 }
43580 <?php
43581
43582 declare (strict_types=1);
43583 /*
43584 * This file is part of PHPUnit.
43585 *
43586 * (c) Sebastian Bergmann <sebastian@phpunit.de>
43587 *
43588 * For the full copyright and license information, please view the LICENSE
43589 * file that was distributed with this source code.
43590 */
43591 namespace PHPUnit\Event\Test;
43592
43593 use PHPUnit\Event\Subscriber;
43594 /**
43595 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
43596 */
43597 interface MockObjectFromWsdlCreatedSubscriber extends Subscriber
43598 {
43599 public function notify(\PHPUnit\Event\Test\MockObjectFromWsdlCreated $event): void;
43600 }
43601 <?php
43602
43603 declare (strict_types=1);
43604 /*
43605 * This file is part of PHPUnit.
43606 *
43607 * (c) Sebastian Bergmann <sebastian@phpunit.de>
43608 *
43609 * For the full copyright and license information, please view the LICENSE
43610 * file that was distributed with this source code.
43611 */
43612 namespace PHPUnit\Event\Test;
43613
43614 use function sprintf;
43615 use PHPUnit\Event\Event;
43616 use PHPUnit\Event\Telemetry;
43617 /**
43618 * @psalm-immutable
43619 *
43620 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
43621 */
43622 final class PartialMockObjectCreated implements Event
43623 {
43624 private readonly Telemetry\Info $telemetryInfo;
43625 /**
43626 * @psalm-var class-string
43627 */
43628 private readonly string $className;
43629 /**
43630 * @psalm-var list<string>
43631 */
43632 private readonly array $methodNames;
43633 /**
43634 * @psalm-param class-string $className
43635 */
43636 public function __construct(Telemetry\Info $telemetryInfo, string $className, string ...$methodNames)
43637 {
43638 $this->telemetryInfo = $telemetryInfo;
43639 $this->className = $className;
43640 $this->methodNames = $methodNames;
43641 }
43642 public function telemetryInfo(): Telemetry\Info
43643 {
43644 return $this->telemetryInfo;
43645 }
43646 /**
43647 * @psalm-return class-string
43648 */
43649 public function className(): string
43650 {
43651 return $this->className;
43652 }
43653 /**
43654 * @psalm-return list<string>
43655 */
43656 public function methodNames(): array
43657 {
43658 return $this->methodNames;
43659 }
43660 public function asString(): string
43661 {
43662 return sprintf('Partial Mock Object Created (%s)', $this->className);
43663 }
43664 }
43665 <?php
43666
43667 declare (strict_types=1);
43668 /*
43669 * This file is part of PHPUnit.
43670 *
43671 * (c) Sebastian Bergmann <sebastian@phpunit.de>
43672 *
43673 * For the full copyright and license information, please view the LICENSE
43674 * file that was distributed with this source code.
43675 */
43676 namespace PHPUnit\Event\Test;
43677
43678 use PHPUnit\Event\Subscriber;
43679 /**
43680 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
43681 */
43682 interface PartialMockObjectCreatedSubscriber extends Subscriber
43683 {
43684 public function notify(\PHPUnit\Event\Test\PartialMockObjectCreated $event): void;
43685 }
43686 <?php
43687
43688 declare (strict_types=1);
43689 /*
43690 * This file is part of PHPUnit.
43691 *
43692 * (c) Sebastian Bergmann <sebastian@phpunit.de>
43693 *
43694 * For the full copyright and license information, please view the LICENSE
43695 * file that was distributed with this source code.
43696 */
43697 namespace PHPUnit\Event\Test;
43698
43699 use function sprintf;
43700 use PHPUnit\Event\Event;
43701 use PHPUnit\Event\Telemetry;
43702 /**
43703 * @psalm-immutable
43704 *
43705 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
43706 */
43707 final class TestProxyCreated implements Event
43708 {
43709 private readonly Telemetry\Info $telemetryInfo;
43710 /**
43711 * @psalm-var class-string
43712 */
43713 private readonly string $className;
43714 private readonly string $constructorArguments;
43715 /**
43716 * @psalm-param class-string $className
43717 */
43718 public function __construct(Telemetry\Info $telemetryInfo, string $className, string $constructorArguments)
43719 {
43720 $this->telemetryInfo = $telemetryInfo;
43721 $this->className = $className;
43722 $this->constructorArguments = $constructorArguments;
43723 }
43724 public function telemetryInfo(): Telemetry\Info
43725 {
43726 return $this->telemetryInfo;
43727 }
43728 /**
43729 * @psalm-return class-string
43730 */
43731 public function className(): string
43732 {
43733 return $this->className;
43734 }
43735 public function constructorArguments(): string
43736 {
43737 return $this->constructorArguments;
43738 }
43739 public function asString(): string
43740 {
43741 return sprintf('Test Proxy Created (%s)', $this->className);
43742 }
43743 }
43744 <?php
43745
43746 declare (strict_types=1);
43747 /*
43748 * This file is part of PHPUnit.
43749 *
43750 * (c) Sebastian Bergmann <sebastian@phpunit.de>
43751 *
43752 * For the full copyright and license information, please view the LICENSE
43753 * file that was distributed with this source code.
43754 */
43755 namespace PHPUnit\Event\Test;
43756
43757 use PHPUnit\Event\Subscriber;
43758 /**
43759 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
43760 */
43761 interface TestProxyCreatedSubscriber extends Subscriber
43762 {
43763 public function notify(\PHPUnit\Event\Test\TestProxyCreated $event): void;
43764 }
43765 <?php
43766
43767 declare (strict_types=1);
43768 /*
43769 * This file is part of PHPUnit.
43770 *
43771 * (c) Sebastian Bergmann <sebastian@phpunit.de>
43772 *
43773 * For the full copyright and license information, please view the LICENSE
43774 * file that was distributed with this source code.
43775 */
43776 namespace PHPUnit\Event\Test;
43777
43778 use function sprintf;
43779 use PHPUnit\Event\Event;
43780 use PHPUnit\Event\Telemetry;
43781 /**
43782 * @psalm-immutable
43783 *
43784 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
43785 */
43786 final class TestStubCreated implements Event
43787 {
43788 private readonly Telemetry\Info $telemetryInfo;
43789 /**
43790 * @var class-string
43791 */
43792 private readonly string $className;
43793 /**
43794 * @psalm-param class-string $className
43795 */
43796 public function __construct(Telemetry\Info $telemetryInfo, string $className)
43797 {
43798 $this->telemetryInfo = $telemetryInfo;
43799 $this->className = $className;
43800 }
43801 public function telemetryInfo(): Telemetry\Info
43802 {
43803 return $this->telemetryInfo;
43804 }
43805 /**
43806 * @return class-string
43807 */
43808 public function className(): string
43809 {
43810 return $this->className;
43811 }
43812 public function asString(): string
43813 {
43814 return sprintf('Test Stub Created (%s)', $this->className);
43815 }
43816 }
43817 <?php
43818
43819 declare (strict_types=1);
43820 /*
43821 * This file is part of PHPUnit.
43822 *
43823 * (c) Sebastian Bergmann <sebastian@phpunit.de>
43824 *
43825 * For the full copyright and license information, please view the LICENSE
43826 * file that was distributed with this source code.
43827 */
43828 namespace PHPUnit\Event\Test;
43829
43830 use PHPUnit\Event\Subscriber;
43831 /**
43832 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
43833 */
43834 interface TestStubCreatedSubscriber extends Subscriber
43835 {
43836 public function notify(\PHPUnit\Event\Test\TestStubCreated $event): void;
43837 }
43838 <?php
43839
43840 declare (strict_types=1);
43841 /*
43842 * This file is part of PHPUnit.
43843 *
43844 * (c) Sebastian Bergmann <sebastian@phpunit.de>
43845 *
43846 * For the full copyright and license information, please view the LICENSE
43847 * file that was distributed with this source code.
43848 */
43849 namespace PHPUnit\Event\Test;
43850
43851 use function implode;
43852 use function sprintf;
43853 use PHPUnit\Event\Event;
43854 use PHPUnit\Event\Telemetry;
43855 /**
43856 * @psalm-immutable
43857 *
43858 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
43859 */
43860 final class TestStubForIntersectionOfInterfacesCreated implements Event
43861 {
43862 private readonly Telemetry\Info $telemetryInfo;
43863 /**
43864 * @psalm-var list<class-string>
43865 */
43866 private readonly array $interfaces;
43867 /**
43868 * @psalm-param list<class-string> $interfaces
43869 */
43870 public function __construct(Telemetry\Info $telemetryInfo, array $interfaces)
43871 {
43872 $this->telemetryInfo = $telemetryInfo;
43873 $this->interfaces = $interfaces;
43874 }
43875 public function telemetryInfo(): Telemetry\Info
43876 {
43877 return $this->telemetryInfo;
43878 }
43879 /**
43880 * @return list<class-string>
43881 */
43882 public function interfaces(): array
43883 {
43884 return $this->interfaces;
43885 }
43886 public function asString(): string
43887 {
43888 return sprintf('Test Stub Created (%s)', implode('&', $this->interfaces));
43889 }
43890 }
43891 <?php
43892
43893 declare (strict_types=1);
43894 /*
43895 * This file is part of PHPUnit.
43896 *
43897 * (c) Sebastian Bergmann <sebastian@phpunit.de>
43898 *
43899 * For the full copyright and license information, please view the LICENSE
43900 * file that was distributed with this source code.
43901 */
43902 namespace PHPUnit\Event\Test;
43903
43904 use PHPUnit\Event\Subscriber;
43905 /**
43906 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
43907 */
43908 interface TestStubForIntersectionOfInterfacesCreatedSubscriber extends Subscriber
43909 {
43910 public function notify(\PHPUnit\Event\Test\TestStubForIntersectionOfInterfacesCreated $event): void;
43911 }
43912 <?php
43913
43914 declare (strict_types=1);
43915 /*
43916 * This file is part of PHPUnit.
43917 *
43918 * (c) Sebastian Bergmann <sebastian@phpunit.de>
43919 *
43920 * For the full copyright and license information, please view the LICENSE
43921 * file that was distributed with this source code.
43922 */
43923 namespace PHPUnit\Event\TestRunner;
43924
43925 use function sprintf;
43926 use PHPUnit\Event\Event;
43927 use PHPUnit\Event\Telemetry;
43928 /**
43929 * @psalm-immutable
43930 *
43931 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
43932 */
43933 final class BootstrapFinished implements Event
43934 {
43935 private readonly Telemetry\Info $telemetryInfo;
43936 private readonly string $filename;
43937 public function __construct(Telemetry\Info $telemetryInfo, string $filename)
43938 {
43939 $this->telemetryInfo = $telemetryInfo;
43940 $this->filename = $filename;
43941 }
43942 public function telemetryInfo(): Telemetry\Info
43943 {
43944 return $this->telemetryInfo;
43945 }
43946 public function filename(): string
43947 {
43948 return $this->filename;
43949 }
43950 public function asString(): string
43951 {
43952 return sprintf('Bootstrap Finished (%s)', $this->filename);
43953 }
43954 }
43955 <?php
43956
43957 declare (strict_types=1);
43958 /*
43959 * This file is part of PHPUnit.
43960 *
43961 * (c) Sebastian Bergmann <sebastian@phpunit.de>
43962 *
43963 * For the full copyright and license information, please view the LICENSE
43964 * file that was distributed with this source code.
43965 */
43966 namespace PHPUnit\Event\TestRunner;
43967
43968 use PHPUnit\Event\Subscriber;
43969 /**
43970 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
43971 */
43972 interface BootstrapFinishedSubscriber extends Subscriber
43973 {
43974 public function notify(\PHPUnit\Event\TestRunner\BootstrapFinished $event): void;
43975 }
43976 <?php
43977
43978 declare (strict_types=1);
43979 /*
43980 * This file is part of PHPUnit.
43981 *
43982 * (c) Sebastian Bergmann <sebastian@phpunit.de>
43983 *
43984 * For the full copyright and license information, please view the LICENSE
43985 * file that was distributed with this source code.
43986 */
43987 namespace PHPUnit\Event\TestRunner;
43988
43989 use PHPUnit\Event\Event;
43990 use PHPUnit\Event\Telemetry;
43991 use PHPUnit\TextUI\Configuration\Configuration;
43992 /**
43993 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
43994 */
43995 final class Configured implements Event
43996 {
43997 private readonly Telemetry\Info $telemetryInfo;
43998 private readonly Configuration $configuration;
43999 public function __construct(Telemetry\Info $telemetryInfo, Configuration $configuration)
44000 {
44001 $this->telemetryInfo = $telemetryInfo;
44002 $this->configuration = $configuration;
44003 }
44004 public function telemetryInfo(): Telemetry\Info
44005 {
44006 return $this->telemetryInfo;
44007 }
44008 public function configuration(): Configuration
44009 {
44010 return $this->configuration;
44011 }
44012 public function asString(): string
44013 {
44014 return 'Test Runner Configured';
44015 }
44016 }
44017 <?php
44018
44019 declare (strict_types=1);
44020 /*
44021 * This file is part of PHPUnit.
44022 *
44023 * (c) Sebastian Bergmann <sebastian@phpunit.de>
44024 *
44025 * For the full copyright and license information, please view the LICENSE
44026 * file that was distributed with this source code.
44027 */
44028 namespace PHPUnit\Event\TestRunner;
44029
44030 use PHPUnit\Event\Subscriber;
44031 /**
44032 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
44033 */
44034 interface ConfiguredSubscriber extends Subscriber
44035 {
44036 public function notify(\PHPUnit\Event\TestRunner\Configured $event): void;
44037 }
44038 <?php
44039
44040 declare (strict_types=1);
44041 /*
44042 * This file is part of PHPUnit.
44043 *
44044 * (c) Sebastian Bergmann <sebastian@phpunit.de>
44045 *
44046 * For the full copyright and license information, please view the LICENSE
44047 * file that was distributed with this source code.
44048 */
44049 namespace PHPUnit\Event\TestRunner;
44050
44051 use function sprintf;
44052 use PHPUnit\Event\Event;
44053 use PHPUnit\Event\Telemetry;
44054 /**
44055 * @psalm-immutable
44056 *
44057 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
44058 */
44059 final class DeprecationTriggered implements Event
44060 {
44061 private readonly Telemetry\Info $telemetryInfo;
44062 private readonly string $message;
44063 public function __construct(Telemetry\Info $telemetryInfo, string $message)
44064 {
44065 $this->telemetryInfo = $telemetryInfo;
44066 $this->message = $message;
44067 }
44068 public function telemetryInfo(): Telemetry\Info
44069 {
44070 return $this->telemetryInfo;
44071 }
44072 public function message(): string
44073 {
44074 return $this->message;
44075 }
44076 public function asString(): string
44077 {
44078 return sprintf('Test Runner Triggered Deprecation (%s)', $this->message);
44079 }
44080 }
44081 <?php
44082
44083 declare (strict_types=1);
44084 /*
44085 * This file is part of PHPUnit.
44086 *
44087 * (c) Sebastian Bergmann <sebastian@phpunit.de>
44088 *
44089 * For the full copyright and license information, please view the LICENSE
44090 * file that was distributed with this source code.
44091 */
44092 namespace PHPUnit\Event\TestRunner;
44093
44094 use PHPUnit\Event\Subscriber;
44095 /**
44096 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
44097 */
44098 interface DeprecationTriggeredSubscriber extends Subscriber
44099 {
44100 public function notify(\PHPUnit\Event\TestRunner\DeprecationTriggered $event): void;
44101 }
44102 <?php
44103
44104 declare (strict_types=1);
44105 /*
44106 * This file is part of PHPUnit.
44107 *
44108 * (c) Sebastian Bergmann <sebastian@phpunit.de>
44109 *
44110 * For the full copyright and license information, please view the LICENSE
44111 * file that was distributed with this source code.
44112 */
44113 namespace PHPUnit\Event\TestRunner;
44114
44115 use PHPUnit\Event\Event;
44116 use PHPUnit\Event\Telemetry;
44117 /**
44118 * @psalm-immutable
44119 *
44120 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
44121 */
44122 final class EventFacadeSealed implements Event
44123 {
44124 private readonly Telemetry\Info $telemetryInfo;
44125 public function __construct(Telemetry\Info $telemetryInfo)
44126 {
44127 $this->telemetryInfo = $telemetryInfo;
44128 }
44129 public function telemetryInfo(): Telemetry\Info
44130 {
44131 return $this->telemetryInfo;
44132 }
44133 public function asString(): string
44134 {
44135 return 'Event Facade Sealed';
44136 }
44137 }
44138 <?php
44139
44140 declare (strict_types=1);
44141 /*
44142 * This file is part of PHPUnit.
44143 *
44144 * (c) Sebastian Bergmann <sebastian@phpunit.de>
44145 *
44146 * For the full copyright and license information, please view the LICENSE
44147 * file that was distributed with this source code.
44148 */
44149 namespace PHPUnit\Event\TestRunner;
44150
44151 use PHPUnit\Event\Subscriber;
44152 /**
44153 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
44154 */
44155 interface EventFacadeSealedSubscriber extends Subscriber
44156 {
44157 public function notify(\PHPUnit\Event\TestRunner\EventFacadeSealed $event): void;
44158 }
44159 <?php
44160
44161 declare (strict_types=1);
44162 /*
44163 * This file is part of PHPUnit.
44164 *
44165 * (c) Sebastian Bergmann <sebastian@phpunit.de>
44166 *
44167 * For the full copyright and license information, please view the LICENSE
44168 * file that was distributed with this source code.
44169 */
44170 namespace PHPUnit\Event\TestRunner;
44171
44172 use PHPUnit\Event\Event;
44173 use PHPUnit\Event\Telemetry;
44174 /**
44175 * @psalm-immutable
44176 *
44177 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
44178 */
44179 final class ExecutionAborted implements Event
44180 {
44181 private readonly Telemetry\Info $telemetryInfo;
44182 public function __construct(Telemetry\Info $telemetryInfo)
44183 {
44184 $this->telemetryInfo = $telemetryInfo;
44185 }
44186 public function telemetryInfo(): Telemetry\Info
44187 {
44188 return $this->telemetryInfo;
44189 }
44190 public function asString(): string
44191 {
44192 return 'Test Runner Execution Aborted';
44193 }
44194 }
44195 <?php
44196
44197 declare (strict_types=1);
44198 /*
44199 * This file is part of PHPUnit.
44200 *
44201 * (c) Sebastian Bergmann <sebastian@phpunit.de>
44202 *
44203 * For the full copyright and license information, please view the LICENSE
44204 * file that was distributed with this source code.
44205 */
44206 namespace PHPUnit\Event\TestRunner;
44207
44208 use PHPUnit\Event\Subscriber;
44209 /**
44210 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
44211 */
44212 interface ExecutionAbortedSubscriber extends Subscriber
44213 {
44214 public function notify(\PHPUnit\Event\TestRunner\ExecutionAborted $event): void;
44215 }
44216 <?php
44217
44218 declare (strict_types=1);
44219 /*
44220 * This file is part of PHPUnit.
44221 *
44222 * (c) Sebastian Bergmann <sebastian@phpunit.de>
44223 *
44224 * For the full copyright and license information, please view the LICENSE
44225 * file that was distributed with this source code.
44226 */
44227 namespace PHPUnit\Event\TestRunner;
44228
44229 use PHPUnit\Event\Event;
44230 use PHPUnit\Event\Telemetry;
44231 /**
44232 * @psalm-immutable
44233 *
44234 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
44235 */
44236 final class ExecutionFinished implements Event
44237 {
44238 private readonly Telemetry\Info $telemetryInfo;
44239 public function __construct(Telemetry\Info $telemetryInfo)
44240 {
44241 $this->telemetryInfo = $telemetryInfo;
44242 }
44243 public function telemetryInfo(): Telemetry\Info
44244 {
44245 return $this->telemetryInfo;
44246 }
44247 public function asString(): string
44248 {
44249 return 'Test Runner Execution Finished';
44250 }
44251 }
44252 <?php
44253
44254 declare (strict_types=1);
44255 /*
44256 * This file is part of PHPUnit.
44257 *
44258 * (c) Sebastian Bergmann <sebastian@phpunit.de>
44259 *
44260 * For the full copyright and license information, please view the LICENSE
44261 * file that was distributed with this source code.
44262 */
44263 namespace PHPUnit\Event\TestRunner;
44264
44265 use PHPUnit\Event\Subscriber;
44266 /**
44267 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
44268 */
44269 interface ExecutionFinishedSubscriber extends Subscriber
44270 {
44271 public function notify(\PHPUnit\Event\TestRunner\ExecutionFinished $event): void;
44272 }
44273 <?php
44274
44275 declare (strict_types=1);
44276 /*
44277 * This file is part of PHPUnit.
44278 *
44279 * (c) Sebastian Bergmann <sebastian@phpunit.de>
44280 *
44281 * For the full copyright and license information, please view the LICENSE
44282 * file that was distributed with this source code.
44283 */
44284 namespace PHPUnit\Event\TestRunner;
44285
44286 use function sprintf;
44287 use PHPUnit\Event\Event;
44288 use PHPUnit\Event\Telemetry;
44289 use PHPUnit\Event\TestSuite\TestSuite;
44290 /**
44291 * @psalm-immutable
44292 *
44293 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
44294 */
44295 final class ExecutionStarted implements Event
44296 {
44297 private readonly Telemetry\Info $telemetryInfo;
44298 private readonly TestSuite $testSuite;
44299 public function __construct(Telemetry\Info $telemetryInfo, TestSuite $testSuite)
44300 {
44301 $this->telemetryInfo = $telemetryInfo;
44302 $this->testSuite = $testSuite;
44303 }
44304 public function telemetryInfo(): Telemetry\Info
44305 {
44306 return $this->telemetryInfo;
44307 }
44308 public function testSuite(): TestSuite
44309 {
44310 return $this->testSuite;
44311 }
44312 public function asString(): string
44313 {
44314 return sprintf('Test Runner Execution Started (%d test%s)', $this->testSuite->count(), $this->testSuite->count() !== 1 ? 's' : '');
44315 }
44316 }
44317 <?php
44318
44319 declare (strict_types=1);
44320 /*
44321 * This file is part of PHPUnit.
44322 *
44323 * (c) Sebastian Bergmann <sebastian@phpunit.de>
44324 *
44325 * For the full copyright and license information, please view the LICENSE
44326 * file that was distributed with this source code.
44327 */
44328 namespace PHPUnit\Event\TestRunner;
44329
44330 use PHPUnit\Event\Subscriber;
44331 /**
44332 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
44333 */
44334 interface ExecutionStartedSubscriber extends Subscriber
44335 {
44336 public function notify(\PHPUnit\Event\TestRunner\ExecutionStarted $event): void;
44337 }
44338 <?php
44339
44340 declare (strict_types=1);
44341 /*
44342 * This file is part of PHPUnit.
44343 *
44344 * (c) Sebastian Bergmann <sebastian@phpunit.de>
44345 *
44346 * For the full copyright and license information, please view the LICENSE
44347 * file that was distributed with this source code.
44348 */
44349 namespace PHPUnit\Event\TestRunner;
44350
44351 use function sprintf;
44352 use PHPUnit\Event\Event;
44353 use PHPUnit\Event\Telemetry;
44354 /**
44355 * @psalm-immutable
44356 *
44357 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
44358 */
44359 final class ExtensionBootstrapped implements Event
44360 {
44361 private readonly Telemetry\Info $telemetryInfo;
44362 /**
44363 * @psalm-var class-string
44364 */
44365 private readonly string $className;
44366 /**
44367 * @psalm-var array<string, string>
44368 */
44369 private readonly array $parameters;
44370 /**
44371 * @psalm-param class-string $className
44372 * @psalm-param array<string, string> $parameters
44373 */
44374 public function __construct(Telemetry\Info $telemetryInfo, string $className, array $parameters)
44375 {
44376 $this->telemetryInfo = $telemetryInfo;
44377 $this->className = $className;
44378 $this->parameters = $parameters;
44379 }
44380 public function telemetryInfo(): Telemetry\Info
44381 {
44382 return $this->telemetryInfo;
44383 }
44384 /**
44385 * @psalm-return class-string
44386 */
44387 public function className(): string
44388 {
44389 return $this->className;
44390 }
44391 /**
44392 * @psalm-return array<string, string>
44393 */
44394 public function parameters(): array
44395 {
44396 return $this->parameters;
44397 }
44398 public function asString(): string
44399 {
44400 return sprintf('Extension Bootstrapped (%s)', $this->className);
44401 }
44402 }
44403 <?php
44404
44405 declare (strict_types=1);
44406 /*
44407 * This file is part of PHPUnit.
44408 *
44409 * (c) Sebastian Bergmann <sebastian@phpunit.de>
44410 *
44411 * For the full copyright and license information, please view the LICENSE
44412 * file that was distributed with this source code.
44413 */
44414 namespace PHPUnit\Event\TestRunner;
44415
44416 use PHPUnit\Event\Subscriber;
44417 /**
44418 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
44419 */
44420 interface ExtensionBootstrappedSubscriber extends Subscriber
44421 {
44422 public function notify(\PHPUnit\Event\TestRunner\ExtensionBootstrapped $event): void;
44423 }
44424 <?php
44425
44426 declare (strict_types=1);
44427 /*
44428 * This file is part of PHPUnit.
44429 *
44430 * (c) Sebastian Bergmann <sebastian@phpunit.de>
44431 *
44432 * For the full copyright and license information, please view the LICENSE
44433 * file that was distributed with this source code.
44434 */
44435 namespace PHPUnit\Event\TestRunner;
44436
44437 use function sprintf;
44438 use PHPUnit\Event\Event;
44439 use PHPUnit\Event\Telemetry;
44440 /**
44441 * @psalm-immutable
44442 *
44443 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
44444 */
44445 final class ExtensionLoadedFromPhar implements Event
44446 {
44447 private readonly Telemetry\Info $telemetryInfo;
44448 private readonly string $filename;
44449 private readonly string $name;
44450 private readonly string $version;
44451 public function __construct(Telemetry\Info $telemetryInfo, string $filename, string $name, string $version)
44452 {
44453 $this->telemetryInfo = $telemetryInfo;
44454 $this->filename = $filename;
44455 $this->name = $name;
44456 $this->version = $version;
44457 }
44458 public function telemetryInfo(): Telemetry\Info
44459 {
44460 return $this->telemetryInfo;
44461 }
44462 public function filename(): string
44463 {
44464 return $this->filename;
44465 }
44466 public function name(): string
44467 {
44468 return $this->name;
44469 }
44470 public function version(): string
44471 {
44472 return $this->version;
44473 }
44474 public function asString(): string
44475 {
44476 return sprintf('Extension Loaded from PHAR (%s %s)', $this->name, $this->version);
44477 }
44478 }
44479 <?php
44480
44481 declare (strict_types=1);
44482 /*
44483 * This file is part of PHPUnit.
44484 *
44485 * (c) Sebastian Bergmann <sebastian@phpunit.de>
44486 *
44487 * For the full copyright and license information, please view the LICENSE
44488 * file that was distributed with this source code.
44489 */
44490 namespace PHPUnit\Event\TestRunner;
44491
44492 use PHPUnit\Event\Subscriber;
44493 /**
44494 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
44495 */
44496 interface ExtensionLoadedFromPharSubscriber extends Subscriber
44497 {
44498 public function notify(\PHPUnit\Event\TestRunner\ExtensionLoadedFromPhar $event): void;
44499 }
44500 <?php
44501
44502 declare (strict_types=1);
44503 /*
44504 * This file is part of PHPUnit.
44505 *
44506 * (c) Sebastian Bergmann <sebastian@phpunit.de>
44507 *
44508 * For the full copyright and license information, please view the LICENSE
44509 * file that was distributed with this source code.
44510 */
44511 namespace PHPUnit\Event\TestRunner;
44512
44513 use PHPUnit\Event\Event;
44514 use PHPUnit\Event\Telemetry;
44515 /**
44516 * @psalm-immutable
44517 *
44518 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
44519 */
44520 final class Finished implements Event
44521 {
44522 private readonly Telemetry\Info $telemetryInfo;
44523 public function __construct(Telemetry\Info $telemetryInfo)
44524 {
44525 $this->telemetryInfo = $telemetryInfo;
44526 }
44527 public function telemetryInfo(): Telemetry\Info
44528 {
44529 return $this->telemetryInfo;
44530 }
44531 public function asString(): string
44532 {
44533 return 'Test Runner Finished';
44534 }
44535 }
44536 <?php
44537
44538 declare (strict_types=1);
44539 /*
44540 * This file is part of PHPUnit.
44541 *
44542 * (c) Sebastian Bergmann <sebastian@phpunit.de>
44543 *
44544 * For the full copyright and license information, please view the LICENSE
44545 * file that was distributed with this source code.
44546 */
44547 namespace PHPUnit\Event\TestRunner;
44548
44549 use PHPUnit\Event\Subscriber;
44550 /**
44551 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
44552 */
44553 interface FinishedSubscriber extends Subscriber
44554 {
44555 public function notify(\PHPUnit\Event\TestRunner\Finished $event): void;
44556 }
44557 <?php
44558
44559 declare (strict_types=1);
44560 /*
44561 * This file is part of PHPUnit.
44562 *
44563 * (c) Sebastian Bergmann <sebastian@phpunit.de>
44564 *
44565 * For the full copyright and license information, please view the LICENSE
44566 * file that was distributed with this source code.
44567 */
44568 namespace PHPUnit\Event\TestRunner;
44569
44570 use PHPUnit\Event\Event;
44571 use PHPUnit\Event\Telemetry;
44572 /**
44573 * @psalm-immutable
44574 *
44575 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
44576 */
44577 final class GarbageCollectionDisabled implements Event
44578 {
44579 private readonly Telemetry\Info $telemetryInfo;
44580 public function __construct(Telemetry\Info $telemetryInfo)
44581 {
44582 $this->telemetryInfo = $telemetryInfo;
44583 }
44584 public function telemetryInfo(): Telemetry\Info
44585 {
44586 return $this->telemetryInfo;
44587 }
44588 public function asString(): string
44589 {
44590 return 'Test Runner Disabled Garbage Collection';
44591 }
44592 }
44593 <?php
44594
44595 declare (strict_types=1);
44596 /*
44597 * This file is part of PHPUnit.
44598 *
44599 * (c) Sebastian Bergmann <sebastian@phpunit.de>
44600 *
44601 * For the full copyright and license information, please view the LICENSE
44602 * file that was distributed with this source code.
44603 */
44604 namespace PHPUnit\Event\TestRunner;
44605
44606 use PHPUnit\Event\Subscriber;
44607 /**
44608 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
44609 */
44610 interface GarbageCollectionDisabledSubscriber extends Subscriber
44611 {
44612 public function notify(\PHPUnit\Event\TestRunner\GarbageCollectionDisabled $event): void;
44613 }
44614 <?php
44615
44616 declare (strict_types=1);
44617 /*
44618 * This file is part of PHPUnit.
44619 *
44620 * (c) Sebastian Bergmann <sebastian@phpunit.de>
44621 *
44622 * For the full copyright and license information, please view the LICENSE
44623 * file that was distributed with this source code.
44624 */
44625 namespace PHPUnit\Event\TestRunner;
44626
44627 use PHPUnit\Event\Event;
44628 use PHPUnit\Event\Telemetry;
44629 /**
44630 * @psalm-immutable
44631 *
44632 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
44633 */
44634 final class GarbageCollectionEnabled implements Event
44635 {
44636 private readonly Telemetry\Info $telemetryInfo;
44637 public function __construct(Telemetry\Info $telemetryInfo)
44638 {
44639 $this->telemetryInfo = $telemetryInfo;
44640 }
44641 public function telemetryInfo(): Telemetry\Info
44642 {
44643 return $this->telemetryInfo;
44644 }
44645 public function asString(): string
44646 {
44647 return 'Test Runner Enabled Garbage Collection';
44648 }
44649 }
44650 <?php
44651
44652 declare (strict_types=1);
44653 /*
44654 * This file is part of PHPUnit.
44655 *
44656 * (c) Sebastian Bergmann <sebastian@phpunit.de>
44657 *
44658 * For the full copyright and license information, please view the LICENSE
44659 * file that was distributed with this source code.
44660 */
44661 namespace PHPUnit\Event\TestRunner;
44662
44663 use PHPUnit\Event\Subscriber;
44664 /**
44665 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
44666 */
44667 interface GarbageCollectionEnabledSubscriber extends Subscriber
44668 {
44669 public function notify(\PHPUnit\Event\TestRunner\GarbageCollectionEnabled $event): void;
44670 }
44671 <?php
44672
44673 declare (strict_types=1);
44674 /*
44675 * This file is part of PHPUnit.
44676 *
44677 * (c) Sebastian Bergmann <sebastian@phpunit.de>
44678 *
44679 * For the full copyright and license information, please view the LICENSE
44680 * file that was distributed with this source code.
44681 */
44682 namespace PHPUnit\Event\TestRunner;
44683
44684 use PHPUnit\Event\Event;
44685 use PHPUnit\Event\Telemetry;
44686 /**
44687 * @psalm-immutable
44688 *
44689 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
44690 */
44691 final class GarbageCollectionTriggered implements Event
44692 {
44693 private readonly Telemetry\Info $telemetryInfo;
44694 public function __construct(Telemetry\Info $telemetryInfo)
44695 {
44696 $this->telemetryInfo = $telemetryInfo;
44697 }
44698 public function telemetryInfo(): Telemetry\Info
44699 {
44700 return $this->telemetryInfo;
44701 }
44702 public function asString(): string
44703 {
44704 return 'Test Runner Triggered Garbage Collection';
44705 }
44706 }
44707 <?php
44708
44709 declare (strict_types=1);
44710 /*
44711 * This file is part of PHPUnit.
44712 *
44713 * (c) Sebastian Bergmann <sebastian@phpunit.de>
44714 *
44715 * For the full copyright and license information, please view the LICENSE
44716 * file that was distributed with this source code.
44717 */
44718 namespace PHPUnit\Event\TestRunner;
44719
44720 use PHPUnit\Event\Subscriber;
44721 /**
44722 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
44723 */
44724 interface GarbageCollectionTriggeredSubscriber extends Subscriber
44725 {
44726 public function notify(\PHPUnit\Event\TestRunner\GarbageCollectionTriggered $event): void;
44727 }
44728 <?php
44729
44730 declare (strict_types=1);
44731 /*
44732 * This file is part of PHPUnit.
44733 *
44734 * (c) Sebastian Bergmann <sebastian@phpunit.de>
44735 *
44736 * For the full copyright and license information, please view the LICENSE
44737 * file that was distributed with this source code.
44738 */
44739 namespace PHPUnit\Event\TestRunner;
44740
44741 use PHPUnit\Event\Event;
44742 use PHPUnit\Event\Telemetry;
44743 /**
44744 * @psalm-immutable
44745 *
44746 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
44747 */
44748 final class Started implements Event
44749 {
44750 private readonly Telemetry\Info $telemetryInfo;
44751 public function __construct(Telemetry\Info $telemetryInfo)
44752 {
44753 $this->telemetryInfo = $telemetryInfo;
44754 }
44755 public function telemetryInfo(): Telemetry\Info
44756 {
44757 return $this->telemetryInfo;
44758 }
44759 public function asString(): string
44760 {
44761 return 'Test Runner Started';
44762 }
44763 }
44764 <?php
44765
44766 declare (strict_types=1);
44767 /*
44768 * This file is part of PHPUnit.
44769 *
44770 * (c) Sebastian Bergmann <sebastian@phpunit.de>
44771 *
44772 * For the full copyright and license information, please view the LICENSE
44773 * file that was distributed with this source code.
44774 */
44775 namespace PHPUnit\Event\TestRunner;
44776
44777 use PHPUnit\Event\Subscriber;
44778 /**
44779 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
44780 */
44781 interface StartedSubscriber extends Subscriber
44782 {
44783 public function notify(\PHPUnit\Event\TestRunner\Started $event): void;
44784 }
44785 <?php
44786
44787 declare (strict_types=1);
44788 /*
44789 * This file is part of PHPUnit.
44790 *
44791 * (c) Sebastian Bergmann <sebastian@phpunit.de>
44792 *
44793 * For the full copyright and license information, please view the LICENSE
44794 * file that was distributed with this source code.
44795 */
44796 namespace PHPUnit\Event\TestRunner;
44797
44798 use function sprintf;
44799 use PHPUnit\Event\Event;
44800 use PHPUnit\Event\Telemetry;
44801 /**
44802 * @psalm-immutable
44803 *
44804 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
44805 */
44806 final class WarningTriggered implements Event
44807 {
44808 private readonly Telemetry\Info $telemetryInfo;
44809 private readonly string $message;
44810 public function __construct(Telemetry\Info $telemetryInfo, string $message)
44811 {
44812 $this->telemetryInfo = $telemetryInfo;
44813 $this->message = $message;
44814 }
44815 public function telemetryInfo(): Telemetry\Info
44816 {
44817 return $this->telemetryInfo;
44818 }
44819 public function message(): string
44820 {
44821 return $this->message;
44822 }
44823 public function asString(): string
44824 {
44825 return sprintf('Test Runner Triggered Warning (%s)', $this->message);
44826 }
44827 }
44828 <?php
44829
44830 declare (strict_types=1);
44831 /*
44832 * This file is part of PHPUnit.
44833 *
44834 * (c) Sebastian Bergmann <sebastian@phpunit.de>
44835 *
44836 * For the full copyright and license information, please view the LICENSE
44837 * file that was distributed with this source code.
44838 */
44839 namespace PHPUnit\Event\TestRunner;
44840
44841 use PHPUnit\Event\Subscriber;
44842 /**
44843 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
44844 */
44845 interface WarningTriggeredSubscriber extends Subscriber
44846 {
44847 public function notify(\PHPUnit\Event\TestRunner\WarningTriggered $event): void;
44848 }
44849 <?php
44850
44851 declare (strict_types=1);
44852 /*
44853 * This file is part of PHPUnit.
44854 *
44855 * (c) Sebastian Bergmann <sebastian@phpunit.de>
44856 *
44857 * For the full copyright and license information, please view the LICENSE
44858 * file that was distributed with this source code.
44859 */
44860 namespace PHPUnit\Event\TestSuite;
44861
44862 use function sprintf;
44863 use PHPUnit\Event\Event;
44864 use PHPUnit\Event\Telemetry;
44865 /**
44866 * @psalm-immutable
44867 *
44868 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
44869 */
44870 final class Filtered implements Event
44871 {
44872 private readonly Telemetry\Info $telemetryInfo;
44873 private readonly \PHPUnit\Event\TestSuite\TestSuite $testSuite;
44874 public function __construct(Telemetry\Info $telemetryInfo, \PHPUnit\Event\TestSuite\TestSuite $testSuite)
44875 {
44876 $this->telemetryInfo = $telemetryInfo;
44877 $this->testSuite = $testSuite;
44878 }
44879 public function telemetryInfo(): Telemetry\Info
44880 {
44881 return $this->telemetryInfo;
44882 }
44883 public function testSuite(): \PHPUnit\Event\TestSuite\TestSuite
44884 {
44885 return $this->testSuite;
44886 }
44887 public function asString(): string
44888 {
44889 return sprintf('Test Suite Filtered (%d test%s)', $this->testSuite->count(), $this->testSuite->count() !== 1 ? 's' : '');
44890 }
44891 }
44892 <?php
44893
44894 declare (strict_types=1);
44895 /*
44896 * This file is part of PHPUnit.
44897 *
44898 * (c) Sebastian Bergmann <sebastian@phpunit.de>
44899 *
44900 * For the full copyright and license information, please view the LICENSE
44901 * file that was distributed with this source code.
44902 */
44903 namespace PHPUnit\Event\TestSuite;
44904
44905 use PHPUnit\Event\Subscriber;
44906 /**
44907 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
44908 */
44909 interface FilteredSubscriber extends Subscriber
44910 {
44911 public function notify(\PHPUnit\Event\TestSuite\Filtered $event): void;
44912 }
44913 <?php
44914
44915 declare (strict_types=1);
44916 /*
44917 * This file is part of PHPUnit.
44918 *
44919 * (c) Sebastian Bergmann <sebastian@phpunit.de>
44920 *
44921 * For the full copyright and license information, please view the LICENSE
44922 * file that was distributed with this source code.
44923 */
44924 namespace PHPUnit\Event\TestSuite;
44925
44926 use function sprintf;
44927 use PHPUnit\Event\Event;
44928 use PHPUnit\Event\Telemetry;
44929 /**
44930 * @psalm-immutable
44931 *
44932 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
44933 */
44934 final class Finished implements Event
44935 {
44936 private readonly Telemetry\Info $telemetryInfo;
44937 private readonly \PHPUnit\Event\TestSuite\TestSuite $testSuite;
44938 public function __construct(Telemetry\Info $telemetryInfo, \PHPUnit\Event\TestSuite\TestSuite $testSuite)
44939 {
44940 $this->telemetryInfo = $telemetryInfo;
44941 $this->testSuite = $testSuite;
44942 }
44943 public function telemetryInfo(): Telemetry\Info
44944 {
44945 return $this->telemetryInfo;
44946 }
44947 public function testSuite(): \PHPUnit\Event\TestSuite\TestSuite
44948 {
44949 return $this->testSuite;
44950 }
44951 public function asString(): string
44952 {
44953 return sprintf('Test Suite Finished (%s, %d test%s)', $this->testSuite->name(), $this->testSuite->count(), $this->testSuite->count() !== 1 ? 's' : '');
44954 }
44955 }
44956 <?php
44957
44958 declare (strict_types=1);
44959 /*
44960 * This file is part of PHPUnit.
44961 *
44962 * (c) Sebastian Bergmann <sebastian@phpunit.de>
44963 *
44964 * For the full copyright and license information, please view the LICENSE
44965 * file that was distributed with this source code.
44966 */
44967 namespace PHPUnit\Event\TestSuite;
44968
44969 use PHPUnit\Event\Subscriber;
44970 /**
44971 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
44972 */
44973 interface FinishedSubscriber extends Subscriber
44974 {
44975 public function notify(\PHPUnit\Event\TestSuite\Finished $event): void;
44976 }
44977 <?php
44978
44979 declare (strict_types=1);
44980 /*
44981 * This file is part of PHPUnit.
44982 *
44983 * (c) Sebastian Bergmann <sebastian@phpunit.de>
44984 *
44985 * For the full copyright and license information, please view the LICENSE
44986 * file that was distributed with this source code.
44987 */
44988 namespace PHPUnit\Event\TestSuite;
44989
44990 use function sprintf;
44991 use PHPUnit\Event\Event;
44992 use PHPUnit\Event\Telemetry;
44993 /**
44994 * @psalm-immutable
44995 *
44996 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
44997 */
44998 final class Loaded implements Event
44999 {
45000 private readonly Telemetry\Info $telemetryInfo;
45001 private readonly \PHPUnit\Event\TestSuite\TestSuite $testSuite;
45002 public function __construct(Telemetry\Info $telemetryInfo, \PHPUnit\Event\TestSuite\TestSuite $testSuite)
45003 {
45004 $this->telemetryInfo = $telemetryInfo;
45005 $this->testSuite = $testSuite;
45006 }
45007 public function telemetryInfo(): Telemetry\Info
45008 {
45009 return $this->telemetryInfo;
45010 }
45011 public function testSuite(): \PHPUnit\Event\TestSuite\TestSuite
45012 {
45013 return $this->testSuite;
45014 }
45015 public function asString(): string
45016 {
45017 return sprintf('Test Suite Loaded (%d test%s)', $this->testSuite->count(), $this->testSuite->count() !== 1 ? 's' : '');
45018 }
45019 }
45020 <?php
45021
45022 declare (strict_types=1);
45023 /*
45024 * This file is part of PHPUnit.
45025 *
45026 * (c) Sebastian Bergmann <sebastian@phpunit.de>
45027 *
45028 * For the full copyright and license information, please view the LICENSE
45029 * file that was distributed with this source code.
45030 */
45031 namespace PHPUnit\Event\TestSuite;
45032
45033 use PHPUnit\Event\Subscriber;
45034 /**
45035 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
45036 */
45037 interface LoadedSubscriber extends Subscriber
45038 {
45039 public function notify(\PHPUnit\Event\TestSuite\Loaded $event): void;
45040 }
45041 <?php
45042
45043 declare (strict_types=1);
45044 /*
45045 * This file is part of PHPUnit.
45046 *
45047 * (c) Sebastian Bergmann <sebastian@phpunit.de>
45048 *
45049 * For the full copyright and license information, please view the LICENSE
45050 * file that was distributed with this source code.
45051 */
45052 namespace PHPUnit\Event\TestSuite;
45053
45054 use function sprintf;
45055 use PHPUnit\Event\Event;
45056 use PHPUnit\Event\Telemetry;
45057 /**
45058 * @psalm-immutable
45059 *
45060 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
45061 */
45062 final class Skipped implements Event
45063 {
45064 private readonly Telemetry\Info $telemetryInfo;
45065 private readonly \PHPUnit\Event\TestSuite\TestSuite $testSuite;
45066 private readonly string $message;
45067 public function __construct(Telemetry\Info $telemetryInfo, \PHPUnit\Event\TestSuite\TestSuite $testSuite, string $message)
45068 {
45069 $this->telemetryInfo = $telemetryInfo;
45070 $this->testSuite = $testSuite;
45071 $this->message = $message;
45072 }
45073 public function telemetryInfo(): Telemetry\Info
45074 {
45075 return $this->telemetryInfo;
45076 }
45077 public function testSuite(): \PHPUnit\Event\TestSuite\TestSuite
45078 {
45079 return $this->testSuite;
45080 }
45081 public function message(): string
45082 {
45083 return $this->message;
45084 }
45085 public function asString(): string
45086 {
45087 return sprintf('Test Suite Skipped (%s, %s)', $this->testSuite->name(), $this->message);
45088 }
45089 }
45090 <?php
45091
45092 declare (strict_types=1);
45093 /*
45094 * This file is part of PHPUnit.
45095 *
45096 * (c) Sebastian Bergmann <sebastian@phpunit.de>
45097 *
45098 * For the full copyright and license information, please view the LICENSE
45099 * file that was distributed with this source code.
45100 */
45101 namespace PHPUnit\Event\TestSuite;
45102
45103 use PHPUnit\Event\Subscriber;
45104 /**
45105 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
45106 */
45107 interface SkippedSubscriber extends Subscriber
45108 {
45109 public function notify(\PHPUnit\Event\TestSuite\Skipped $event): void;
45110 }
45111 <?php
45112
45113 declare (strict_types=1);
45114 /*
45115 * This file is part of PHPUnit.
45116 *
45117 * (c) Sebastian Bergmann <sebastian@phpunit.de>
45118 *
45119 * For the full copyright and license information, please view the LICENSE
45120 * file that was distributed with this source code.
45121 */
45122 namespace PHPUnit\Event\TestSuite;
45123
45124 use PHPUnit\Event\Event;
45125 use PHPUnit\Event\Telemetry;
45126 /**
45127 * @psalm-immutable
45128 *
45129 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
45130 */
45131 final class Sorted implements Event
45132 {
45133 private readonly Telemetry\Info $telemetryInfo;
45134 private readonly int $executionOrder;
45135 private readonly int $executionOrderDefects;
45136 private readonly bool $resolveDependencies;
45137 public function __construct(Telemetry\Info $telemetryInfo, int $executionOrder, int $executionOrderDefects, bool $resolveDependencies)
45138 {
45139 $this->telemetryInfo = $telemetryInfo;
45140 $this->executionOrder = $executionOrder;
45141 $this->executionOrderDefects = $executionOrderDefects;
45142 $this->resolveDependencies = $resolveDependencies;
45143 }
45144 public function telemetryInfo(): Telemetry\Info
45145 {
45146 return $this->telemetryInfo;
45147 }
45148 public function executionOrder(): int
45149 {
45150 return $this->executionOrder;
45151 }
45152 public function executionOrderDefects(): int
45153 {
45154 return $this->executionOrderDefects;
45155 }
45156 public function resolveDependencies(): bool
45157 {
45158 return $this->resolveDependencies;
45159 }
45160 public function asString(): string
45161 {
45162 return 'Test Suite Sorted';
45163 }
45164 }
45165 <?php
45166
45167 declare (strict_types=1);
45168 /*
45169 * This file is part of PHPUnit.
45170 *
45171 * (c) Sebastian Bergmann <sebastian@phpunit.de>
45172 *
45173 * For the full copyright and license information, please view the LICENSE
45174 * file that was distributed with this source code.
45175 */
45176 namespace PHPUnit\Event\TestSuite;
45177
45178 use PHPUnit\Event\Subscriber;
45179 /**
45180 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
45181 */
45182 interface SortedSubscriber extends Subscriber
45183 {
45184 public function notify(\PHPUnit\Event\TestSuite\Sorted $event): void;
45185 }
45186 <?php
45187
45188 declare (strict_types=1);
45189 /*
45190 * This file is part of PHPUnit.
45191 *
45192 * (c) Sebastian Bergmann <sebastian@phpunit.de>
45193 *
45194 * For the full copyright and license information, please view the LICENSE
45195 * file that was distributed with this source code.
45196 */
45197 namespace PHPUnit\Event\TestSuite;
45198
45199 use function sprintf;
45200 use PHPUnit\Event\Event;
45201 use PHPUnit\Event\Telemetry;
45202 /**
45203 * @psalm-immutable
45204 *
45205 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
45206 */
45207 final class Started implements Event
45208 {
45209 private readonly Telemetry\Info $telemetryInfo;
45210 private readonly \PHPUnit\Event\TestSuite\TestSuite $testSuite;
45211 public function __construct(Telemetry\Info $telemetryInfo, \PHPUnit\Event\TestSuite\TestSuite $testSuite)
45212 {
45213 $this->telemetryInfo = $telemetryInfo;
45214 $this->testSuite = $testSuite;
45215 }
45216 public function telemetryInfo(): Telemetry\Info
45217 {
45218 return $this->telemetryInfo;
45219 }
45220 public function testSuite(): \PHPUnit\Event\TestSuite\TestSuite
45221 {
45222 return $this->testSuite;
45223 }
45224 public function asString(): string
45225 {
45226 return sprintf('Test Suite Started (%s, %d test%s)', $this->testSuite->name(), $this->testSuite->count(), $this->testSuite->count() !== 1 ? 's' : '');
45227 }
45228 }
45229 <?php
45230
45231 declare (strict_types=1);
45232 /*
45233 * This file is part of PHPUnit.
45234 *
45235 * (c) Sebastian Bergmann <sebastian@phpunit.de>
45236 *
45237 * For the full copyright and license information, please view the LICENSE
45238 * file that was distributed with this source code.
45239 */
45240 namespace PHPUnit\Event\TestSuite;
45241
45242 use PHPUnit\Event\Subscriber;
45243 /**
45244 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
45245 */
45246 interface StartedSubscriber extends Subscriber
45247 {
45248 public function notify(\PHPUnit\Event\TestSuite\Started $event): void;
45249 }
45250 <?php
45251
45252 declare (strict_types=1);
45253 /*
45254 * This file is part of PHPUnit.
45255 *
45256 * (c) Sebastian Bergmann <sebastian@phpunit.de>
45257 *
45258 * For the full copyright and license information, please view the LICENSE
45259 * file that was distributed with this source code.
45260 */
45261 namespace PHPUnit\Event;
45262
45263 use RuntimeException;
45264 /**
45265 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
45266 */
45267 final class EventAlreadyAssignedException extends RuntimeException implements \PHPUnit\Event\Exception
45268 {
45269 }
45270 <?php
45271
45272 declare (strict_types=1);
45273 /*
45274 * This file is part of PHPUnit.
45275 *
45276 * (c) Sebastian Bergmann <sebastian@phpunit.de>
45277 *
45278 * For the full copyright and license information, please view the LICENSE
45279 * file that was distributed with this source code.
45280 */
45281 namespace PHPUnit\Event;
45282
45283 use RuntimeException;
45284 /**
45285 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
45286 */
45287 final class EventFacadeIsSealedException extends RuntimeException implements \PHPUnit\Event\Exception
45288 {
45289 }
45290 <?php
45291
45292 declare (strict_types=1);
45293 /*
45294 * This file is part of PHPUnit.
45295 *
45296 * (c) Sebastian Bergmann <sebastian@phpunit.de>
45297 *
45298 * For the full copyright and license information, please view the LICENSE
45299 * file that was distributed with this source code.
45300 */
45301 namespace PHPUnit\Event;
45302
45303 interface Exception extends \PHPUnit\Exception
45304 {
45305 }
45306 <?php
45307
45308 declare (strict_types=1);
45309 /*
45310 * This file is part of PHPUnit.
45311 *
45312 * (c) Sebastian Bergmann <sebastian@phpunit.de>
45313 *
45314 * For the full copyright and license information, please view the LICENSE
45315 * file that was distributed with this source code.
45316 */
45317 namespace PHPUnit\Event;
45318
45319 /**
45320 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
45321 */
45322 final class InvalidArgumentException extends \InvalidArgumentException implements \PHPUnit\Event\Exception
45323 {
45324 }
45325 <?php
45326
45327 declare (strict_types=1);
45328 /*
45329 * This file is part of PHPUnit.
45330 *
45331 * (c) Sebastian Bergmann <sebastian@phpunit.de>
45332 *
45333 * For the full copyright and license information, please view the LICENSE
45334 * file that was distributed with this source code.
45335 */
45336 namespace PHPUnit\Event;
45337
45338 use RuntimeException;
45339 /**
45340 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
45341 */
45342 final class InvalidEventException extends RuntimeException implements \PHPUnit\Event\Exception
45343 {
45344 }
45345 <?php
45346
45347 declare (strict_types=1);
45348 /*
45349 * This file is part of PHPUnit.
45350 *
45351 * (c) Sebastian Bergmann <sebastian@phpunit.de>
45352 *
45353 * For the full copyright and license information, please view the LICENSE
45354 * file that was distributed with this source code.
45355 */
45356 namespace PHPUnit\Event;
45357
45358 use RuntimeException;
45359 /**
45360 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
45361 */
45362 final class InvalidSubscriberException extends RuntimeException implements \PHPUnit\Event\Exception
45363 {
45364 }
45365 <?php
45366
45367 declare (strict_types=1);
45368 /*
45369 * This file is part of PHPUnit.
45370 *
45371 * (c) Sebastian Bergmann <sebastian@phpunit.de>
45372 *
45373 * For the full copyright and license information, please view the LICENSE
45374 * file that was distributed with this source code.
45375 */
45376 namespace PHPUnit\Event;
45377
45378 use RuntimeException;
45379 /**
45380 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
45381 */
45382 final class MapError extends RuntimeException implements \PHPUnit\Event\Exception
45383 {
45384 }
45385 <?php
45386
45387 declare (strict_types=1);
45388 /*
45389 * This file is part of PHPUnit.
45390 *
45391 * (c) Sebastian Bergmann <sebastian@phpunit.de>
45392 *
45393 * For the full copyright and license information, please view the LICENSE
45394 * file that was distributed with this source code.
45395 */
45396 namespace PHPUnit\Event\TestData;
45397
45398 use PHPUnit\Event\Exception;
45399 use RuntimeException;
45400 /**
45401 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
45402 */
45403 final class MoreThanOneDataSetFromDataProviderException extends RuntimeException implements Exception
45404 {
45405 }
45406 <?php
45407
45408 declare (strict_types=1);
45409 /*
45410 * This file is part of PHPUnit.
45411 *
45412 * (c) Sebastian Bergmann <sebastian@phpunit.de>
45413 *
45414 * For the full copyright and license information, please view the LICENSE
45415 * file that was distributed with this source code.
45416 */
45417 namespace PHPUnit\Event\Test;
45418
45419 use PHPUnit\Event\Exception;
45420 use RuntimeException;
45421 /**
45422 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
45423 */
45424 final class NoComparisonFailureException extends RuntimeException implements Exception
45425 {
45426 }
45427 <?php
45428
45429 declare (strict_types=1);
45430 /*
45431 * This file is part of PHPUnit.
45432 *
45433 * (c) Sebastian Bergmann <sebastian@phpunit.de>
45434 *
45435 * For the full copyright and license information, please view the LICENSE
45436 * file that was distributed with this source code.
45437 */
45438 namespace PHPUnit\Event\TestData;
45439
45440 use PHPUnit\Event\Exception;
45441 use RuntimeException;
45442 /**
45443 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
45444 */
45445 final class NoDataSetFromDataProviderException extends RuntimeException implements Exception
45446 {
45447 }
45448 <?php
45449
45450 declare (strict_types=1);
45451 /*
45452 * This file is part of PHPUnit.
45453 *
45454 * (c) Sebastian Bergmann <sebastian@phpunit.de>
45455 *
45456 * For the full copyright and license information, please view the LICENSE
45457 * file that was distributed with this source code.
45458 */
45459 namespace PHPUnit\Event;
45460
45461 use RuntimeException;
45462 /**
45463 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
45464 */
45465 final class NoPreviousThrowableException extends RuntimeException implements \PHPUnit\Event\Exception
45466 {
45467 }
45468 <?php
45469
45470 declare (strict_types=1);
45471 /*
45472 * This file is part of PHPUnit.
45473 *
45474 * (c) Sebastian Bergmann <sebastian@phpunit.de>
45475 *
45476 * For the full copyright and license information, please view the LICENSE
45477 * file that was distributed with this source code.
45478 */
45479 namespace PHPUnit\Event\Code;
45480
45481 use PHPUnit\Event\Exception;
45482 use RuntimeException;
45483 /**
45484 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
45485 *
45486 * @internal This class is not covered by the backward compatibility promise for PHPUnit
45487 */
45488 final class NoTestCaseObjectOnCallStackException extends RuntimeException implements Exception
45489 {
45490 public function __construct()
45491 {
45492 parent::__construct('Cannot find TestCase object on call stack');
45493 }
45494 }
45495 <?php
45496
45497 declare (strict_types=1);
45498 /*
45499 * This file is part of PHPUnit.
45500 *
45501 * (c) Sebastian Bergmann <sebastian@phpunit.de>
45502 *
45503 * For the full copyright and license information, please view the LICENSE
45504 * file that was distributed with this source code.
45505 */
45506 namespace PHPUnit\Event;
45507
45508 /**
45509 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
45510 */
45511 final class RuntimeException extends \RuntimeException implements \PHPUnit\Event\Exception
45512 {
45513 }
45514 <?php
45515
45516 declare (strict_types=1);
45517 /*
45518 * This file is part of PHPUnit.
45519 *
45520 * (c) Sebastian Bergmann <sebastian@phpunit.de>
45521 *
45522 * For the full copyright and license information, please view the LICENSE
45523 * file that was distributed with this source code.
45524 */
45525 namespace PHPUnit\Event;
45526
45527 use RuntimeException;
45528 /**
45529 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
45530 */
45531 final class SubscriberTypeAlreadyRegisteredException extends RuntimeException implements \PHPUnit\Event\Exception
45532 {
45533 }
45534 <?php
45535
45536 declare (strict_types=1);
45537 /*
45538 * This file is part of PHPUnit.
45539 *
45540 * (c) Sebastian Bergmann <sebastian@phpunit.de>
45541 *
45542 * For the full copyright and license information, please view the LICENSE
45543 * file that was distributed with this source code.
45544 */
45545 namespace PHPUnit\Event;
45546
45547 use RuntimeException;
45548 /**
45549 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
45550 */
45551 final class UnknownEventException extends RuntimeException implements \PHPUnit\Event\Exception
45552 {
45553 }
45554 <?php
45555
45556 declare (strict_types=1);
45557 /*
45558 * This file is part of PHPUnit.
45559 *
45560 * (c) Sebastian Bergmann <sebastian@phpunit.de>
45561 *
45562 * For the full copyright and license information, please view the LICENSE
45563 * file that was distributed with this source code.
45564 */
45565 namespace PHPUnit\Event;
45566
45567 use RuntimeException;
45568 /**
45569 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
45570 */
45571 final class UnknownEventTypeException extends RuntimeException implements \PHPUnit\Event\Exception
45572 {
45573 }
45574 <?php
45575
45576 declare (strict_types=1);
45577 /*
45578 * This file is part of PHPUnit.
45579 *
45580 * (c) Sebastian Bergmann <sebastian@phpunit.de>
45581 *
45582 * For the full copyright and license information, please view the LICENSE
45583 * file that was distributed with this source code.
45584 */
45585 namespace PHPUnit\Event;
45586
45587 use RuntimeException;
45588 /**
45589 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
45590 */
45591 final class UnknownSubscriberException extends RuntimeException implements \PHPUnit\Event\Exception
45592 {
45593 }
45594 <?php
45595
45596 declare (strict_types=1);
45597 /*
45598 * This file is part of PHPUnit.
45599 *
45600 * (c) Sebastian Bergmann <sebastian@phpunit.de>
45601 *
45602 * For the full copyright and license information, please view the LICENSE
45603 * file that was distributed with this source code.
45604 */
45605 namespace PHPUnit\Event;
45606
45607 use RuntimeException;
45608 /**
45609 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
45610 */
45611 final class UnknownSubscriberTypeException extends RuntimeException implements \PHPUnit\Event\Exception
45612 {
45613 }
45614 <?php
45615
45616 declare (strict_types=1);
45617 /*
45618 * This file is part of PHPUnit.
45619 *
45620 * (c) Sebastian Bergmann <sebastian@phpunit.de>
45621 *
45622 * For the full copyright and license information, please view the LICENSE
45623 * file that was distributed with this source code.
45624 */
45625 namespace PHPUnit\Event;
45626
45627 use function gc_status;
45628 use PHPUnit\Event\Telemetry\HRTime;
45629 use PHPUnit\Event\Telemetry\Php81GarbageCollectorStatusProvider;
45630 use PHPUnit\Event\Telemetry\Php83GarbageCollectorStatusProvider;
45631 /**
45632 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
45633 *
45634 * @internal This class is not covered by the backward compatibility promise for PHPUnit
45635 */
45636 final class Facade
45637 {
45638 private static ?self $instance = null;
45639 private \PHPUnit\Event\Emitter $emitter;
45640 private ?\PHPUnit\Event\TypeMap $typeMap = null;
45641 private ?\PHPUnit\Event\DeferringDispatcher $deferringDispatcher = null;
45642 private bool $sealed = \false;
45643 public static function instance(): self
45644 {
45645 if (self::$instance === null) {
45646 self::$instance = new self();
45647 }
45648 return self::$instance;
45649 }
45650 public static function emitter(): \PHPUnit\Event\Emitter
45651 {
45652 return self::instance()->emitter;
45653 }
45654 public function __construct()
45655 {
45656 $this->emitter = $this->createDispatchingEmitter();
45657 }
45658 /**
45659 * @throws EventFacadeIsSealedException
45660 * @throws UnknownSubscriberTypeException
45661 */
45662 public function registerSubscribers(\PHPUnit\Event\Subscriber ...$subscribers): void
45663 {
45664 foreach ($subscribers as $subscriber) {
45665 $this->registerSubscriber($subscriber);
45666 }
45667 }
45668 /**
45669 * @throws EventFacadeIsSealedException
45670 * @throws UnknownSubscriberTypeException
45671 */
45672 public function registerSubscriber(\PHPUnit\Event\Subscriber $subscriber): void
45673 {
45674 if ($this->sealed) {
45675 throw new \PHPUnit\Event\EventFacadeIsSealedException();
45676 }
45677 $this->deferredDispatcher()->registerSubscriber($subscriber);
45678 }
45679 /**
45680 * @throws EventFacadeIsSealedException
45681 */
45682 public function registerTracer(\PHPUnit\Event\Tracer\Tracer $tracer): void
45683 {
45684 if ($this->sealed) {
45685 throw new \PHPUnit\Event\EventFacadeIsSealedException();
45686 }
45687 $this->deferredDispatcher()->registerTracer($tracer);
45688 }
45689 /**
45690 * @codeCoverageIgnore
45691 *
45692 * @noinspection PhpUnused
45693 */
45694 public function initForIsolation(HRTime $offset, bool $exportObjects): \PHPUnit\Event\CollectingDispatcher
45695 {
45696 $dispatcher = new \PHPUnit\Event\CollectingDispatcher();
45697 $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()));
45698 if ($exportObjects) {
45699 $this->emitter->exportObjects();
45700 }
45701 $this->sealed = \true;
45702 return $dispatcher;
45703 }
45704 public function forward(\PHPUnit\Event\EventCollection $events): void
45705 {
45706 $dispatcher = $this->deferredDispatcher();
45707 foreach ($events as $event) {
45708 $dispatcher->dispatch($event);
45709 }
45710 }
45711 public function seal(): void
45712 {
45713 $this->deferredDispatcher()->flush();
45714 $this->sealed = \true;
45715 $this->emitter->testRunnerEventFacadeSealed();
45716 }
45717 private function createDispatchingEmitter(): \PHPUnit\Event\DispatchingEmitter
45718 {
45719 return new \PHPUnit\Event\DispatchingEmitter($this->deferredDispatcher(), $this->createTelemetrySystem());
45720 }
45721 private function createTelemetrySystem(): \PHPUnit\Event\Telemetry\System
45722 {
45723 return new \PHPUnit\Event\Telemetry\System(new \PHPUnit\Event\Telemetry\SystemStopWatch(), new \PHPUnit\Event\Telemetry\SystemMemoryMeter(), $this->garbageCollectorStatusProvider());
45724 }
45725 private function deferredDispatcher(): \PHPUnit\Event\DeferringDispatcher
45726 {
45727 if ($this->deferringDispatcher === null) {
45728 $this->deferringDispatcher = new \PHPUnit\Event\DeferringDispatcher(new \PHPUnit\Event\DirectDispatcher($this->typeMap()));
45729 }
45730 return $this->deferringDispatcher;
45731 }
45732 private function typeMap(): \PHPUnit\Event\TypeMap
45733 {
45734 if ($this->typeMap === null) {
45735 $typeMap = new \PHPUnit\Event\TypeMap();
45736 $this->registerDefaultTypes($typeMap);
45737 $this->typeMap = $typeMap;
45738 }
45739 return $this->typeMap;
45740 }
45741 private function registerDefaultTypes(\PHPUnit\Event\TypeMap $typeMap): void
45742 {
45743 $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\AfterLastTestMethodErrored::class, \PHPUnit\Event\Test\AfterLastTestMethodFinished::class, \PHPUnit\Event\Test\AfterTestMethodCalled::class, \PHPUnit\Event\Test\AfterTestMethodErrored::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\BeforeTestMethodErrored::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\PostConditionErrored::class, \PHPUnit\Event\Test\PostConditionFinished::class, \PHPUnit\Event\Test\PreConditionCalled::class, \PHPUnit\Event\Test\PreConditionErrored::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];
45744 foreach ($defaultEvents as $eventClass) {
45745 $typeMap->addMapping($eventClass . 'Subscriber', $eventClass);
45746 }
45747 }
45748 private function garbageCollectorStatusProvider(): \PHPUnit\Event\Telemetry\GarbageCollectorStatusProvider
45749 {
45750 if (!isset(gc_status()['running'])) {
45751 // @codeCoverageIgnoreStart
45752 return new Php81GarbageCollectorStatusProvider();
45753 // @codeCoverageIgnoreEnd
45754 }
45755 return new Php83GarbageCollectorStatusProvider();
45756 }
45757 }
45758 <?php
45759
45760 declare (strict_types=1);
45761 /*
45762 * This file is part of PHPUnit.
45763 *
45764 * (c) Sebastian Bergmann <sebastian@phpunit.de>
45765 *
45766 * For the full copyright and license information, please view the LICENSE
45767 * file that was distributed with this source code.
45768 */
45769 namespace PHPUnit\Event;
45770
45771 /**
45772 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
45773 */
45774 interface Subscriber
45775 {
45776 }
45777 <?php
45778
45779 declare (strict_types=1);
45780 /*
45781 * This file is part of PHPUnit.
45782 *
45783 * (c) Sebastian Bergmann <sebastian@phpunit.de>
45784 *
45785 * For the full copyright and license information, please view the LICENSE
45786 * file that was distributed with this source code.
45787 */
45788 namespace PHPUnit\Event\Tracer;
45789
45790 use PHPUnit\Event\Event;
45791 /**
45792 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
45793 */
45794 interface Tracer
45795 {
45796 public function trace(Event $event): void;
45797 }
45798 <?php
45799
45800 declare (strict_types=1);
45801 /*
45802 * This file is part of PHPUnit.
45803 *
45804 * (c) Sebastian Bergmann <sebastian@phpunit.de>
45805 *
45806 * For the full copyright and license information, please view the LICENSE
45807 * file that was distributed with this source code.
45808 */
45809 namespace PHPUnit\Event;
45810
45811 use function array_key_exists;
45812 use function class_exists;
45813 use function class_implements;
45814 use function in_array;
45815 use function interface_exists;
45816 use function sprintf;
45817 /**
45818 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
45819 *
45820 * @internal This class is not covered by the backward compatibility promise for PHPUnit
45821 */
45822 final class TypeMap
45823 {
45824 /**
45825 * @psalm-var array<class-string, class-string>
45826 */
45827 private array $mapping = [];
45828 /**
45829 * @psalm-param class-string $subscriberInterface
45830 * @psalm-param class-string $eventClass
45831 *
45832 * @throws EventAlreadyAssignedException
45833 * @throws InvalidEventException
45834 * @throws InvalidSubscriberException
45835 * @throws SubscriberTypeAlreadyRegisteredException
45836 * @throws UnknownEventException
45837 * @throws UnknownSubscriberException
45838 */
45839 public function addMapping(string $subscriberInterface, string $eventClass): void
45840 {
45841 $this->ensureSubscriberInterfaceExists($subscriberInterface);
45842 $this->ensureSubscriberInterfaceExtendsInterface($subscriberInterface);
45843 $this->ensureEventClassExists($eventClass);
45844 $this->ensureEventClassImplementsEventInterface($eventClass);
45845 $this->ensureSubscriberWasNotAlreadyRegistered($subscriberInterface);
45846 $this->ensureEventWasNotAlreadyAssigned($eventClass);
45847 $this->mapping[$subscriberInterface] = $eventClass;
45848 }
45849 public function isKnownSubscriberType(\PHPUnit\Event\Subscriber $subscriber): bool
45850 {
45851 foreach (class_implements($subscriber) as $interface) {
45852 if (array_key_exists($interface, $this->mapping)) {
45853 return \true;
45854 }
45855 }
45856 return \false;
45857 }
45858 public function isKnownEventType(\PHPUnit\Event\Event $event): bool
45859 {
45860 return in_array($event::class, $this->mapping, \true);
45861 }
45862 /**
45863 * @throws MapError
45864 *
45865 * @psalm-return class-string
45866 */
45867 public function map(\PHPUnit\Event\Subscriber $subscriber): string
45868 {
45869 foreach (class_implements($subscriber) as $interface) {
45870 if (array_key_exists($interface, $this->mapping)) {
45871 return $this->mapping[$interface];
45872 }
45873 }
45874 throw new \PHPUnit\Event\MapError(sprintf('Subscriber "%s" does not implement a known interface', $subscriber::class));
45875 }
45876 /**
45877 * @psalm-param class-string $subscriberInterface
45878 *
45879 * @throws UnknownSubscriberException
45880 */
45881 private function ensureSubscriberInterfaceExists(string $subscriberInterface): void
45882 {
45883 if (!interface_exists($subscriberInterface)) {
45884 throw new \PHPUnit\Event\UnknownSubscriberException(sprintf('Subscriber "%s" does not exist or is not an interface', $subscriberInterface));
45885 }
45886 }
45887 /**
45888 * @psalm-param class-string $eventClass
45889 *
45890 * @throws UnknownEventException
45891 */
45892 private function ensureEventClassExists(string $eventClass): void
45893 {
45894 if (!class_exists($eventClass)) {
45895 throw new \PHPUnit\Event\UnknownEventException(sprintf('Event class "%s" does not exist', $eventClass));
45896 }
45897 }
45898 /**
45899 * @psalm-param class-string $subscriberInterface
45900 *
45901 * @throws InvalidSubscriberException
45902 */
45903 private function ensureSubscriberInterfaceExtendsInterface(string $subscriberInterface): void
45904 {
45905 if (!in_array(\PHPUnit\Event\Subscriber::class, class_implements($subscriberInterface), \true)) {
45906 throw new \PHPUnit\Event\InvalidSubscriberException(sprintf('Subscriber "%s" does not extend Subscriber interface', $subscriberInterface));
45907 }
45908 }
45909 /**
45910 * @psalm-param class-string $eventClass
45911 *
45912 * @throws InvalidEventException
45913 */
45914 private function ensureEventClassImplementsEventInterface(string $eventClass): void
45915 {
45916 if (!in_array(\PHPUnit\Event\Event::class, class_implements($eventClass), \true)) {
45917 throw new \PHPUnit\Event\InvalidEventException(sprintf('Event "%s" does not implement Event interface', $eventClass));
45918 }
45919 }
45920 /**
45921 * @psalm-param class-string $subscriberInterface
45922 *
45923 * @throws SubscriberTypeAlreadyRegisteredException
45924 */
45925 private function ensureSubscriberWasNotAlreadyRegistered(string $subscriberInterface): void
45926 {
45927 if (array_key_exists($subscriberInterface, $this->mapping)) {
45928 throw new \PHPUnit\Event\SubscriberTypeAlreadyRegisteredException(sprintf('Subscriber type "%s" already registered', $subscriberInterface));
45929 }
45930 }
45931 /**
45932 * @psalm-param class-string $eventClass
45933 *
45934 * @throws EventAlreadyAssignedException
45935 */
45936 private function ensureEventWasNotAlreadyAssigned(string $eventClass): void
45937 {
45938 if (in_array($eventClass, $this->mapping, \true)) {
45939 throw new \PHPUnit\Event\EventAlreadyAssignedException(sprintf('Event "%s" already assigned', $eventClass));
45940 }
45941 }
45942 }
45943 <?php
45944
45945 declare (strict_types=1);
45946 /*
45947 * This file is part of PHPUnit.
45948 *
45949 * (c) Sebastian Bergmann <sebastian@phpunit.de>
45950 *
45951 * For the full copyright and license information, please view the LICENSE
45952 * file that was distributed with this source code.
45953 */
45954 namespace PHPUnit\Event\Code;
45955
45956 /**
45957 * @psalm-immutable
45958 *
45959 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
45960 */
45961 final class ClassMethod
45962 {
45963 /**
45964 * @psalm-var class-string
45965 */
45966 private readonly string $className;
45967 /**
45968 * @psalm-var non-empty-string
45969 */
45970 private readonly string $methodName;
45971 /**
45972 * @psalm-param class-string $className
45973 * @psalm-param non-empty-string $methodName
45974 */
45975 public function __construct(string $className, string $methodName)
45976 {
45977 $this->className = $className;
45978 $this->methodName = $methodName;
45979 }
45980 /**
45981 * @psalm-return class-string
45982 */
45983 public function className(): string
45984 {
45985 return $this->className;
45986 }
45987 /**
45988 * @psalm-return non-empty-string
45989 */
45990 public function methodName(): string
45991 {
45992 return $this->methodName;
45993 }
45994 }
45995 <?php
45996
45997 declare (strict_types=1);
45998 /*
45999 * This file is part of PHPUnit.
46000 *
46001 * (c) Sebastian Bergmann <sebastian@phpunit.de>
46002 *
46003 * For the full copyright and license information, please view the LICENSE
46004 * file that was distributed with this source code.
46005 */
46006 namespace PHPUnit\Event\Code;
46007
46008 /**
46009 * @psalm-immutable
46010 *
46011 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
46012 */
46013 final class ComparisonFailure
46014 {
46015 private readonly string $expected;
46016 private readonly string $actual;
46017 private readonly string $diff;
46018 public function __construct(string $expected, string $actual, string $diff)
46019 {
46020 $this->expected = $expected;
46021 $this->actual = $actual;
46022 $this->diff = $diff;
46023 }
46024 public function expected(): string
46025 {
46026 return $this->expected;
46027 }
46028 public function actual(): string
46029 {
46030 return $this->actual;
46031 }
46032 public function diff(): string
46033 {
46034 return $this->diff;
46035 }
46036 }
46037 <?php
46038
46039 declare (strict_types=1);
46040 /*
46041 * This file is part of PHPUnit.
46042 *
46043 * (c) Sebastian Bergmann <sebastian@phpunit.de>
46044 *
46045 * For the full copyright and license information, please view the LICENSE
46046 * file that was distributed with this source code.
46047 */
46048 namespace PHPUnit\Event\Code;
46049
46050 use function is_bool;
46051 use function is_scalar;
46052 use function print_r;
46053 use PHPUnit\Framework\ExpectationFailedException;
46054 use Throwable;
46055 /**
46056 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
46057 *
46058 * @internal This class is not covered by the backward compatibility promise for PHPUnit
46059 */
46060 final class ComparisonFailureBuilder
46061 {
46062 public static function from(Throwable $t): ?\PHPUnit\Event\Code\ComparisonFailure
46063 {
46064 if (!$t instanceof ExpectationFailedException) {
46065 return null;
46066 }
46067 if (!$t->getComparisonFailure()) {
46068 return null;
46069 }
46070 $expectedAsString = $t->getComparisonFailure()->getExpectedAsString();
46071 if (empty($expectedAsString)) {
46072 $expectedAsString = self::mapScalarValueToString($t->getComparisonFailure()->getExpected());
46073 }
46074 $actualAsString = $t->getComparisonFailure()->getActualAsString();
46075 if (empty($actualAsString)) {
46076 $actualAsString = self::mapScalarValueToString($t->getComparisonFailure()->getActual());
46077 }
46078 return new \PHPUnit\Event\Code\ComparisonFailure($expectedAsString, $actualAsString, $t->getComparisonFailure()->getDiff());
46079 }
46080 private static function mapScalarValueToString(mixed $value): string
46081 {
46082 if ($value === null) {
46083 return 'null';
46084 }
46085 if (is_bool($value)) {
46086 return $value ? 'true' : 'false';
46087 }
46088 if (is_scalar($value)) {
46089 return print_r($value, \true);
46090 }
46091 return '';
46092 }
46093 }
46094 <?php
46095
46096 declare (strict_types=1);
46097 /*
46098 * This file is part of PHPUnit.
46099 *
46100 * (c) Sebastian Bergmann <sebastian@phpunit.de>
46101 *
46102 * For the full copyright and license information, please view the LICENSE
46103 * file that was distributed with this source code.
46104 */
46105 namespace PHPUnit\Event\Runtime;
46106
46107 use const PHP_OS;
46108 use const PHP_OS_FAMILY;
46109 /**
46110 * @psalm-immutable
46111 *
46112 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
46113 */
46114 final class OperatingSystem
46115 {
46116 private readonly string $operatingSystem;
46117 private readonly string $operatingSystemFamily;
46118 public function __construct()
46119 {
46120 $this->operatingSystem = PHP_OS;
46121 $this->operatingSystemFamily = PHP_OS_FAMILY;
46122 }
46123 public function operatingSystem(): string
46124 {
46125 return $this->operatingSystem;
46126 }
46127 public function operatingSystemFamily(): string
46128 {
46129 return $this->operatingSystemFamily;
46130 }
46131 }
46132 <?php
46133
46134 declare (strict_types=1);
46135 /*
46136 * This file is part of PHPUnit.
46137 *
46138 * (c) Sebastian Bergmann <sebastian@phpunit.de>
46139 *
46140 * For the full copyright and license information, please view the LICENSE
46141 * file that was distributed with this source code.
46142 */
46143 namespace PHPUnit\Event\Runtime;
46144
46145 use const PHP_EXTRA_VERSION;
46146 use const PHP_MAJOR_VERSION;
46147 use const PHP_MINOR_VERSION;
46148 use const PHP_RELEASE_VERSION;
46149 use const PHP_SAPI;
46150 use const PHP_VERSION;
46151 use const PHP_VERSION_ID;
46152 use function array_merge;
46153 use function get_loaded_extensions;
46154 use function sort;
46155 /**
46156 * @psalm-immutable
46157 *
46158 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
46159 */
46160 final class PHP
46161 {
46162 private readonly string $version;
46163 private readonly int $versionId;
46164 private readonly int $majorVersion;
46165 private readonly int $minorVersion;
46166 private readonly int $releaseVersion;
46167 private readonly string $extraVersion;
46168 private readonly string $sapi;
46169 /**
46170 * @psalm-var list<string>
46171 */
46172 private readonly array $extensions;
46173 public function __construct()
46174 {
46175 $this->version = PHP_VERSION;
46176 $this->versionId = PHP_VERSION_ID;
46177 $this->majorVersion = PHP_MAJOR_VERSION;
46178 $this->minorVersion = PHP_MINOR_VERSION;
46179 $this->releaseVersion = PHP_RELEASE_VERSION;
46180 $this->extraVersion = PHP_EXTRA_VERSION;
46181 $this->sapi = PHP_SAPI;
46182 $extensions = array_merge(get_loaded_extensions(\true), get_loaded_extensions());
46183 sort($extensions);
46184 $this->extensions = $extensions;
46185 }
46186 public function version(): string
46187 {
46188 return $this->version;
46189 }
46190 public function sapi(): string
46191 {
46192 return $this->sapi;
46193 }
46194 public function majorVersion(): int
46195 {
46196 return $this->majorVersion;
46197 }
46198 public function minorVersion(): int
46199 {
46200 return $this->minorVersion;
46201 }
46202 public function releaseVersion(): int
46203 {
46204 return $this->releaseVersion;
46205 }
46206 public function extraVersion(): string
46207 {
46208 return $this->extraVersion;
46209 }
46210 public function versionId(): int
46211 {
46212 return $this->versionId;
46213 }
46214 /**
46215 * @psalm-return list<string>
46216 */
46217 public function extensions(): array
46218 {
46219 return $this->extensions;
46220 }
46221 }
46222 <?php
46223
46224 declare (strict_types=1);
46225 /*
46226 * This file is part of PHPUnit.
46227 *
46228 * (c) Sebastian Bergmann <sebastian@phpunit.de>
46229 *
46230 * For the full copyright and license information, please view the LICENSE
46231 * file that was distributed with this source code.
46232 */
46233 namespace PHPUnit\Event\Runtime;
46234
46235 use PHPUnit\Runner\Version;
46236 /**
46237 * @psalm-immutable
46238 *
46239 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
46240 */
46241 final class PHPUnit
46242 {
46243 private readonly string $versionId;
46244 private readonly string $releaseSeries;
46245 public function __construct()
46246 {
46247 $this->versionId = Version::id();
46248 $this->releaseSeries = Version::series();
46249 }
46250 public function versionId(): string
46251 {
46252 return $this->versionId;
46253 }
46254 public function releaseSeries(): string
46255 {
46256 return $this->releaseSeries;
46257 }
46258 }
46259 <?php
46260
46261 declare (strict_types=1);
46262 /*
46263 * This file is part of PHPUnit.
46264 *
46265 * (c) Sebastian Bergmann <sebastian@phpunit.de>
46266 *
46267 * For the full copyright and license information, please view the LICENSE
46268 * file that was distributed with this source code.
46269 */
46270 namespace PHPUnit\Event\Runtime;
46271
46272 use function sprintf;
46273 /**
46274 * @psalm-immutable
46275 *
46276 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
46277 */
46278 final class Runtime
46279 {
46280 private readonly \PHPUnit\Event\Runtime\OperatingSystem $operatingSystem;
46281 private readonly \PHPUnit\Event\Runtime\PHP $php;
46282 private readonly \PHPUnit\Event\Runtime\PHPUnit $phpunit;
46283 public function __construct()
46284 {
46285 $this->operatingSystem = new \PHPUnit\Event\Runtime\OperatingSystem();
46286 $this->php = new \PHPUnit\Event\Runtime\PHP();
46287 $this->phpunit = new \PHPUnit\Event\Runtime\PHPUnit();
46288 }
46289 public function asString(): string
46290 {
46291 $php = $this->php();
46292 return sprintf('PHPUnit %s using PHP %s (%s) on %s', $this->phpunit()->versionId(), $php->version(), $php->sapi(), $this->operatingSystem()->operatingSystem());
46293 }
46294 public function operatingSystem(): \PHPUnit\Event\Runtime\OperatingSystem
46295 {
46296 return $this->operatingSystem;
46297 }
46298 public function php(): \PHPUnit\Event\Runtime\PHP
46299 {
46300 return $this->php;
46301 }
46302 public function phpunit(): \PHPUnit\Event\Runtime\PHPUnit
46303 {
46304 return $this->phpunit;
46305 }
46306 }
46307 <?php
46308
46309 declare (strict_types=1);
46310 /*
46311 * This file is part of PHPUnit.
46312 *
46313 * (c) Sebastian Bergmann <sebastian@phpunit.de>
46314 *
46315 * For the full copyright and license information, please view the LICENSE
46316 * file that was distributed with this source code.
46317 */
46318 namespace PHPUnit\Event\Telemetry;
46319
46320 use function floor;
46321 use function sprintf;
46322 use PHPUnit\Event\InvalidArgumentException;
46323 /**
46324 * @psalm-immutable
46325 *
46326 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
46327 */
46328 final class Duration
46329 {
46330 private readonly int $seconds;
46331 private readonly int $nanoseconds;
46332 /**
46333 * @throws InvalidArgumentException
46334 */
46335 public static function fromSecondsAndNanoseconds(int $seconds, int $nanoseconds): self
46336 {
46337 return new self($seconds, $nanoseconds);
46338 }
46339 /**
46340 * @throws InvalidArgumentException
46341 */
46342 private function __construct(int $seconds, int $nanoseconds)
46343 {
46344 $this->ensureNotNegative($seconds, 'seconds');
46345 $this->ensureNotNegative($nanoseconds, 'nanoseconds');
46346 $this->ensureNanoSecondsInRange($nanoseconds);
46347 $this->seconds = $seconds;
46348 $this->nanoseconds = $nanoseconds;
46349 }
46350 public function seconds(): int
46351 {
46352 return $this->seconds;
46353 }
46354 public function nanoseconds(): int
46355 {
46356 return $this->nanoseconds;
46357 }
46358 public function asFloat(): float
46359 {
46360 return $this->seconds() + $this->nanoseconds() / 1000000000;
46361 }
46362 public function asString(): string
46363 {
46364 $seconds = $this->seconds();
46365 $minutes = 0;
46366 $hours = 0;
46367 if ($seconds > 60 * 60) {
46368 $hours = floor($seconds / 60 / 60);
46369 $seconds -= $hours * 60 * 60;
46370 }
46371 if ($seconds > 60) {
46372 $minutes = floor($seconds / 60);
46373 $seconds -= $minutes * 60;
46374 }
46375 return sprintf('%02d:%02d:%02d.%09d', $hours, $minutes, $seconds, $this->nanoseconds());
46376 }
46377 public function equals(self $other): bool
46378 {
46379 return $this->seconds === $other->seconds && $this->nanoseconds === $other->nanoseconds;
46380 }
46381 public function isLessThan(self $other): bool
46382 {
46383 if ($this->seconds < $other->seconds) {
46384 return \true;
46385 }
46386 if ($this->seconds > $other->seconds) {
46387 return \false;
46388 }
46389 return $this->nanoseconds < $other->nanoseconds;
46390 }
46391 public function isGreaterThan(self $other): bool
46392 {
46393 if ($this->seconds > $other->seconds) {
46394 return \true;
46395 }
46396 if ($this->seconds < $other->seconds) {
46397 return \false;
46398 }
46399 return $this->nanoseconds > $other->nanoseconds;
46400 }
46401 /**
46402 * @throws InvalidArgumentException
46403 */
46404 private function ensureNotNegative(int $value, string $type): void
46405 {
46406 if ($value < 0) {
46407 throw new InvalidArgumentException(sprintf('Value for %s must not be negative.', $type));
46408 }
46409 }
46410 /**
46411 * @throws InvalidArgumentException
46412 */
46413 private function ensureNanoSecondsInRange(int $nanoseconds): void
46414 {
46415 if ($nanoseconds > 999999999) {
46416 throw new InvalidArgumentException('Value for nanoseconds must not be greater than 999999999.');
46417 }
46418 }
46419 }
46420 <?php
46421
46422 declare (strict_types=1);
46423 /*
46424 * This file is part of PHPUnit.
46425 *
46426 * (c) Sebastian Bergmann <sebastian@phpunit.de>
46427 *
46428 * For the full copyright and license information, please view the LICENSE
46429 * file that was distributed with this source code.
46430 */
46431 namespace PHPUnit\Event\Telemetry;
46432
46433 use PHPUnit\Event\RuntimeException;
46434 /**
46435 * @psalm-immutable
46436 *
46437 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
46438 */
46439 final class GarbageCollectorStatus
46440 {
46441 private readonly int $runs;
46442 private readonly int $collected;
46443 private readonly int $threshold;
46444 private readonly int $roots;
46445 private readonly ?float $applicationTime;
46446 private readonly ?float $collectorTime;
46447 private readonly ?float $destructorTime;
46448 private readonly ?float $freeTime;
46449 private readonly ?bool $running;
46450 private readonly ?bool $protected;
46451 private readonly ?bool $full;
46452 private readonly ?int $bufferSize;
46453 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)
46454 {
46455 $this->runs = $runs;
46456 $this->collected = $collected;
46457 $this->threshold = $threshold;
46458 $this->roots = $roots;
46459 $this->applicationTime = $applicationTime;
46460 $this->collectorTime = $collectorTime;
46461 $this->destructorTime = $destructorTime;
46462 $this->freeTime = $freeTime;
46463 $this->running = $running;
46464 $this->protected = $protected;
46465 $this->full = $full;
46466 $this->bufferSize = $bufferSize;
46467 }
46468 public function runs(): int
46469 {
46470 return $this->runs;
46471 }
46472 public function collected(): int
46473 {
46474 return $this->collected;
46475 }
46476 public function threshold(): int
46477 {
46478 return $this->threshold;
46479 }
46480 public function roots(): int
46481 {
46482 return $this->roots;
46483 }
46484 /**
46485 * @psalm-assert-if-true !null $this->applicationTime
46486 * @psalm-assert-if-true !null $this->collectorTime
46487 * @psalm-assert-if-true !null $this->destructorTime
46488 * @psalm-assert-if-true !null $this->freeTime
46489 * @psalm-assert-if-true !null $this->running
46490 * @psalm-assert-if-true !null $this->protected
46491 * @psalm-assert-if-true !null $this->full
46492 * @psalm-assert-if-true !null $this->bufferSize
46493 */
46494 public function hasExtendedInformation(): bool
46495 {
46496 return $this->running !== null;
46497 }
46498 /**
46499 * @throws RuntimeException on PHP < 8.3
46500 */
46501 public function applicationTime(): float
46502 {
46503 if ($this->applicationTime === null) {
46504 throw new RuntimeException('Information not available');
46505 }
46506 return $this->applicationTime;
46507 }
46508 /**
46509 * @throws RuntimeException on PHP < 8.3
46510 */
46511 public function collectorTime(): float
46512 {
46513 if ($this->collectorTime === null) {
46514 throw new RuntimeException('Information not available');
46515 }
46516 return $this->collectorTime;
46517 }
46518 /**
46519 * @throws RuntimeException on PHP < 8.3
46520 */
46521 public function destructorTime(): float
46522 {
46523 if ($this->destructorTime === null) {
46524 throw new RuntimeException('Information not available');
46525 }
46526 return $this->destructorTime;
46527 }
46528 /**
46529 * @throws RuntimeException on PHP < 8.3
46530 */
46531 public function freeTime(): float
46532 {
46533 if ($this->freeTime === null) {
46534 throw new RuntimeException('Information not available');
46535 }
46536 return $this->freeTime;
46537 }
46538 /**
46539 * @throws RuntimeException on PHP < 8.3
46540 */
46541 public function isRunning(): bool
46542 {
46543 if ($this->running === null) {
46544 throw new RuntimeException('Information not available');
46545 }
46546 return $this->running;
46547 }
46548 /**
46549 * @throws RuntimeException on PHP < 8.3
46550 */
46551 public function isProtected(): bool
46552 {
46553 if ($this->protected === null) {
46554 throw new RuntimeException('Information not available');
46555 }
46556 return $this->protected;
46557 }
46558 /**
46559 * @throws RuntimeException on PHP < 8.3
46560 */
46561 public function isFull(): bool
46562 {
46563 if ($this->full === null) {
46564 throw new RuntimeException('Information not available');
46565 }
46566 return $this->full;
46567 }
46568 /**
46569 * @throws RuntimeException on PHP < 8.3
46570 */
46571 public function bufferSize(): int
46572 {
46573 if ($this->bufferSize === null) {
46574 throw new RuntimeException('Information not available');
46575 }
46576 return $this->bufferSize;
46577 }
46578 }
46579 <?php
46580
46581 declare (strict_types=1);
46582 /*
46583 * This file is part of PHPUnit.
46584 *
46585 * (c) Sebastian Bergmann <sebastian@phpunit.de>
46586 *
46587 * For the full copyright and license information, please view the LICENSE
46588 * file that was distributed with this source code.
46589 */
46590 namespace PHPUnit\Event\Telemetry;
46591
46592 /**
46593 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
46594 *
46595 * @internal This interface is not covered by the backward compatibility promise for PHPUnit
46596 */
46597 interface GarbageCollectorStatusProvider
46598 {
46599 public function status(): \PHPUnit\Event\Telemetry\GarbageCollectorStatus;
46600 }
46601 <?php
46602
46603 declare (strict_types=1);
46604 /*
46605 * This file is part of PHPUnit.
46606 *
46607 * (c) Sebastian Bergmann <sebastian@phpunit.de>
46608 *
46609 * For the full copyright and license information, please view the LICENSE
46610 * file that was distributed with this source code.
46611 */
46612 namespace PHPUnit\Event\Telemetry;
46613
46614 use function sprintf;
46615 use PHPUnit\Event\InvalidArgumentException;
46616 /**
46617 * @psalm-immutable
46618 *
46619 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
46620 */
46621 final class HRTime
46622 {
46623 private readonly int $seconds;
46624 private readonly int $nanoseconds;
46625 /**
46626 * @throws InvalidArgumentException
46627 */
46628 public static function fromSecondsAndNanoseconds(int $seconds, int $nanoseconds): self
46629 {
46630 return new self($seconds, $nanoseconds);
46631 }
46632 /**
46633 * @throws InvalidArgumentException
46634 */
46635 private function __construct(int $seconds, int $nanoseconds)
46636 {
46637 $this->ensureNotNegative($seconds, 'seconds');
46638 $this->ensureNotNegative($nanoseconds, 'nanoseconds');
46639 $this->ensureNanoSecondsInRange($nanoseconds);
46640 $this->seconds = $seconds;
46641 $this->nanoseconds = $nanoseconds;
46642 }
46643 public function seconds(): int
46644 {
46645 return $this->seconds;
46646 }
46647 public function nanoseconds(): int
46648 {
46649 return $this->nanoseconds;
46650 }
46651 public function duration(self $start): \PHPUnit\Event\Telemetry\Duration
46652 {
46653 $seconds = $this->seconds - $start->seconds();
46654 $nanoseconds = $this->nanoseconds - $start->nanoseconds();
46655 if ($nanoseconds < 0) {
46656 $seconds--;
46657 $nanoseconds += 1000000000;
46658 }
46659 if ($seconds < 0) {
46660 return \PHPUnit\Event\Telemetry\Duration::fromSecondsAndNanoseconds(0, 0);
46661 }
46662 return \PHPUnit\Event\Telemetry\Duration::fromSecondsAndNanoseconds($seconds, $nanoseconds);
46663 }
46664 /**
46665 * @throws InvalidArgumentException
46666 */
46667 private function ensureNotNegative(int $value, string $type): void
46668 {
46669 if ($value < 0) {
46670 throw new InvalidArgumentException(sprintf('Value for %s must not be negative.', $type));
46671 }
46672 }
46673 /**
46674 * @throws InvalidArgumentException
46675 */
46676 private function ensureNanoSecondsInRange(int $nanoseconds): void
46677 {
46678 if ($nanoseconds > 999999999) {
46679 throw new InvalidArgumentException('Value for nanoseconds must not be greater than 999999999.');
46680 }
46681 }
46682 }
46683 <?php
46684
46685 declare (strict_types=1);
46686 /*
46687 * This file is part of PHPUnit.
46688 *
46689 * (c) Sebastian Bergmann <sebastian@phpunit.de>
46690 *
46691 * For the full copyright and license information, please view the LICENSE
46692 * file that was distributed with this source code.
46693 */
46694 namespace PHPUnit\Event\Telemetry;
46695
46696 use function sprintf;
46697 /**
46698 * @psalm-immutable
46699 *
46700 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
46701 */
46702 final class Info
46703 {
46704 private readonly \PHPUnit\Event\Telemetry\Snapshot $current;
46705 private readonly \PHPUnit\Event\Telemetry\Duration $durationSinceStart;
46706 private readonly \PHPUnit\Event\Telemetry\MemoryUsage $memorySinceStart;
46707 private readonly \PHPUnit\Event\Telemetry\Duration $durationSincePrevious;
46708 private readonly \PHPUnit\Event\Telemetry\MemoryUsage $memorySincePrevious;
46709 public function __construct(\PHPUnit\Event\Telemetry\Snapshot $current, \PHPUnit\Event\Telemetry\Duration $durationSinceStart, \PHPUnit\Event\Telemetry\MemoryUsage $memorySinceStart, \PHPUnit\Event\Telemetry\Duration $durationSincePrevious, \PHPUnit\Event\Telemetry\MemoryUsage $memorySincePrevious)
46710 {
46711 $this->current = $current;
46712 $this->durationSinceStart = $durationSinceStart;
46713 $this->memorySinceStart = $memorySinceStart;
46714 $this->durationSincePrevious = $durationSincePrevious;
46715 $this->memorySincePrevious = $memorySincePrevious;
46716 }
46717 public function time(): \PHPUnit\Event\Telemetry\HRTime
46718 {
46719 return $this->current->time();
46720 }
46721 public function memoryUsage(): \PHPUnit\Event\Telemetry\MemoryUsage
46722 {
46723 return $this->current->memoryUsage();
46724 }
46725 public function peakMemoryUsage(): \PHPUnit\Event\Telemetry\MemoryUsage
46726 {
46727 return $this->current->peakMemoryUsage();
46728 }
46729 public function durationSinceStart(): \PHPUnit\Event\Telemetry\Duration
46730 {
46731 return $this->durationSinceStart;
46732 }
46733 public function memoryUsageSinceStart(): \PHPUnit\Event\Telemetry\MemoryUsage
46734 {
46735 return $this->memorySinceStart;
46736 }
46737 public function durationSincePrevious(): \PHPUnit\Event\Telemetry\Duration
46738 {
46739 return $this->durationSincePrevious;
46740 }
46741 public function memoryUsageSincePrevious(): \PHPUnit\Event\Telemetry\MemoryUsage
46742 {
46743 return $this->memorySincePrevious;
46744 }
46745 public function garbageCollectorStatus(): \PHPUnit\Event\Telemetry\GarbageCollectorStatus
46746 {
46747 return $this->current->garbageCollectorStatus();
46748 }
46749 public function asString(): string
46750 {
46751 return sprintf('[%s / %s] [%d bytes]', $this->durationSinceStart()->asString(), $this->durationSincePrevious()->asString(), $this->memoryUsage()->bytes());
46752 }
46753 }
46754 <?php
46755
46756 declare (strict_types=1);
46757 /*
46758 * This file is part of PHPUnit.
46759 *
46760 * (c) Sebastian Bergmann <sebastian@phpunit.de>
46761 *
46762 * For the full copyright and license information, please view the LICENSE
46763 * file that was distributed with this source code.
46764 */
46765 namespace PHPUnit\Event\Telemetry;
46766
46767 /**
46768 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
46769 *
46770 * @internal This interface is not covered by the backward compatibility promise for PHPUnit
46771 */
46772 interface MemoryMeter
46773 {
46774 public function memoryUsage(): \PHPUnit\Event\Telemetry\MemoryUsage;
46775 public function peakMemoryUsage(): \PHPUnit\Event\Telemetry\MemoryUsage;
46776 }
46777 <?php
46778
46779 declare (strict_types=1);
46780 /*
46781 * This file is part of PHPUnit.
46782 *
46783 * (c) Sebastian Bergmann <sebastian@phpunit.de>
46784 *
46785 * For the full copyright and license information, please view the LICENSE
46786 * file that was distributed with this source code.
46787 */
46788 namespace PHPUnit\Event\Telemetry;
46789
46790 /**
46791 * @psalm-immutable
46792 *
46793 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
46794 */
46795 final class MemoryUsage
46796 {
46797 private readonly int $bytes;
46798 public static function fromBytes(int $bytes): self
46799 {
46800 return new self($bytes);
46801 }
46802 private function __construct(int $bytes)
46803 {
46804 $this->bytes = $bytes;
46805 }
46806 public function bytes(): int
46807 {
46808 return $this->bytes;
46809 }
46810 public function diff(self $other): self
46811 {
46812 return self::fromBytes($this->bytes - $other->bytes);
46813 }
46814 }
46815 <?php
46816
46817 declare (strict_types=1);
46818 /*
46819 * This file is part of PHPUnit.
46820 *
46821 * (c) Sebastian Bergmann <sebastian@phpunit.de>
46822 *
46823 * For the full copyright and license information, please view the LICENSE
46824 * file that was distributed with this source code.
46825 */
46826 namespace PHPUnit\Event\Telemetry;
46827
46828 use function gc_status;
46829 /**
46830 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
46831 *
46832 * @internal This class is not covered by the backward compatibility promise for PHPUnit
46833 *
46834 * @codeCoverageIgnore
46835 */
46836 final class Php81GarbageCollectorStatusProvider implements \PHPUnit\Event\Telemetry\GarbageCollectorStatusProvider
46837 {
46838 public function status(): \PHPUnit\Event\Telemetry\GarbageCollectorStatus
46839 {
46840 $status = gc_status();
46841 return new \PHPUnit\Event\Telemetry\GarbageCollectorStatus($status['runs'], $status['collected'], $status['threshold'], $status['roots'], null, null, null, null, null, null, null, null);
46842 }
46843 }
46844 <?php
46845
46846 declare (strict_types=1);
46847 /*
46848 * This file is part of PHPUnit.
46849 *
46850 * (c) Sebastian Bergmann <sebastian@phpunit.de>
46851 *
46852 * For the full copyright and license information, please view the LICENSE
46853 * file that was distributed with this source code.
46854 */
46855 namespace PHPUnit\Event\Telemetry;
46856
46857 use function gc_status;
46858 /**
46859 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
46860 *
46861 * @internal This class is not covered by the backward compatibility promise for PHPUnit
46862 */
46863 final class Php83GarbageCollectorStatusProvider implements \PHPUnit\Event\Telemetry\GarbageCollectorStatusProvider
46864 {
46865 public function status(): \PHPUnit\Event\Telemetry\GarbageCollectorStatus
46866 {
46867 $status = gc_status();
46868 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']);
46869 }
46870 }
46871 <?php
46872
46873 declare (strict_types=1);
46874 /*
46875 * This file is part of PHPUnit.
46876 *
46877 * (c) Sebastian Bergmann <sebastian@phpunit.de>
46878 *
46879 * For the full copyright and license information, please view the LICENSE
46880 * file that was distributed with this source code.
46881 */
46882 namespace PHPUnit\Event\Telemetry;
46883
46884 /**
46885 * @psalm-immutable
46886 *
46887 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
46888 */
46889 final class Snapshot
46890 {
46891 private readonly \PHPUnit\Event\Telemetry\HRTime $time;
46892 private readonly \PHPUnit\Event\Telemetry\MemoryUsage $memoryUsage;
46893 private readonly \PHPUnit\Event\Telemetry\MemoryUsage $peakMemoryUsage;
46894 private readonly \PHPUnit\Event\Telemetry\GarbageCollectorStatus $garbageCollectorStatus;
46895 public function __construct(\PHPUnit\Event\Telemetry\HRTime $time, \PHPUnit\Event\Telemetry\MemoryUsage $memoryUsage, \PHPUnit\Event\Telemetry\MemoryUsage $peakMemoryUsage, \PHPUnit\Event\Telemetry\GarbageCollectorStatus $garbageCollectorStatus)
46896 {
46897 $this->time = $time;
46898 $this->memoryUsage = $memoryUsage;
46899 $this->peakMemoryUsage = $peakMemoryUsage;
46900 $this->garbageCollectorStatus = $garbageCollectorStatus;
46901 }
46902 public function time(): \PHPUnit\Event\Telemetry\HRTime
46903 {
46904 return $this->time;
46905 }
46906 public function memoryUsage(): \PHPUnit\Event\Telemetry\MemoryUsage
46907 {
46908 return $this->memoryUsage;
46909 }
46910 public function peakMemoryUsage(): \PHPUnit\Event\Telemetry\MemoryUsage
46911 {
46912 return $this->peakMemoryUsage;
46913 }
46914 public function garbageCollectorStatus(): \PHPUnit\Event\Telemetry\GarbageCollectorStatus
46915 {
46916 return $this->garbageCollectorStatus;
46917 }
46918 }
46919 <?php
46920
46921 declare (strict_types=1);
46922 /*
46923 * This file is part of PHPUnit.
46924 *
46925 * (c) Sebastian Bergmann <sebastian@phpunit.de>
46926 *
46927 * For the full copyright and license information, please view the LICENSE
46928 * file that was distributed with this source code.
46929 */
46930 namespace PHPUnit\Event\Telemetry;
46931
46932 /**
46933 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
46934 *
46935 * @internal This interface is not covered by the backward compatibility promise for PHPUnit
46936 */
46937 interface StopWatch
46938 {
46939 public function current(): \PHPUnit\Event\Telemetry\HRTime;
46940 }
46941 <?php
46942
46943 declare (strict_types=1);
46944 /*
46945 * This file is part of PHPUnit.
46946 *
46947 * (c) Sebastian Bergmann <sebastian@phpunit.de>
46948 *
46949 * For the full copyright and license information, please view the LICENSE
46950 * file that was distributed with this source code.
46951 */
46952 namespace PHPUnit\Event\Telemetry;
46953
46954 /**
46955 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
46956 *
46957 * @internal This class is not covered by the backward compatibility promise for PHPUnit
46958 */
46959 final class System
46960 {
46961 private readonly \PHPUnit\Event\Telemetry\StopWatch $stopWatch;
46962 private readonly \PHPUnit\Event\Telemetry\MemoryMeter $memoryMeter;
46963 private readonly \PHPUnit\Event\Telemetry\GarbageCollectorStatusProvider $garbageCollectorStatusProvider;
46964 public function __construct(\PHPUnit\Event\Telemetry\StopWatch $stopWatch, \PHPUnit\Event\Telemetry\MemoryMeter $memoryMeter, \PHPUnit\Event\Telemetry\GarbageCollectorStatusProvider $garbageCollectorStatusProvider)
46965 {
46966 $this->stopWatch = $stopWatch;
46967 $this->memoryMeter = $memoryMeter;
46968 $this->garbageCollectorStatusProvider = $garbageCollectorStatusProvider;
46969 }
46970 public function snapshot(): \PHPUnit\Event\Telemetry\Snapshot
46971 {
46972 return new \PHPUnit\Event\Telemetry\Snapshot($this->stopWatch->current(), $this->memoryMeter->memoryUsage(), $this->memoryMeter->peakMemoryUsage(), $this->garbageCollectorStatusProvider->status());
46973 }
46974 }
46975 <?php
46976
46977 declare (strict_types=1);
46978 /*
46979 * This file is part of PHPUnit.
46980 *
46981 * (c) Sebastian Bergmann <sebastian@phpunit.de>
46982 *
46983 * For the full copyright and license information, please view the LICENSE
46984 * file that was distributed with this source code.
46985 */
46986 namespace PHPUnit\Event\Telemetry;
46987
46988 use function memory_get_peak_usage;
46989 use function memory_get_usage;
46990 /**
46991 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
46992 *
46993 * @internal This class is not covered by the backward compatibility promise for PHPUnit
46994 */
46995 final class SystemMemoryMeter implements \PHPUnit\Event\Telemetry\MemoryMeter
46996 {
46997 public function memoryUsage(): \PHPUnit\Event\Telemetry\MemoryUsage
46998 {
46999 return \PHPUnit\Event\Telemetry\MemoryUsage::fromBytes(memory_get_usage(\true));
47000 }
47001 public function peakMemoryUsage(): \PHPUnit\Event\Telemetry\MemoryUsage
47002 {
47003 return \PHPUnit\Event\Telemetry\MemoryUsage::fromBytes(memory_get_peak_usage(\true));
47004 }
47005 }
47006 <?php
47007
47008 declare (strict_types=1);
47009 /*
47010 * This file is part of PHPUnit.
47011 *
47012 * (c) Sebastian Bergmann <sebastian@phpunit.de>
47013 *
47014 * For the full copyright and license information, please view the LICENSE
47015 * file that was distributed with this source code.
47016 */
47017 namespace PHPUnit\Event\Telemetry;
47018
47019 use function hrtime;
47020 use PHPUnit\Event\InvalidArgumentException;
47021 /**
47022 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
47023 *
47024 * @internal This class is not covered by the backward compatibility promise for PHPUnit
47025 */
47026 final class SystemStopWatch implements \PHPUnit\Event\Telemetry\StopWatch
47027 {
47028 /**
47029 * @throws InvalidArgumentException
47030 */
47031 public function current(): \PHPUnit\Event\Telemetry\HRTime
47032 {
47033 return \PHPUnit\Event\Telemetry\HRTime::fromSecondsAndNanoseconds(...hrtime());
47034 }
47035 }
47036 <?php
47037
47038 declare (strict_types=1);
47039 /*
47040 * This file is part of PHPUnit.
47041 *
47042 * (c) Sebastian Bergmann <sebastian@phpunit.de>
47043 *
47044 * For the full copyright and license information, please view the LICENSE
47045 * file that was distributed with this source code.
47046 */
47047 namespace PHPUnit\Event\Telemetry;
47048
47049 use function hrtime;
47050 use PHPUnit\Event\InvalidArgumentException;
47051 /**
47052 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
47053 *
47054 * @internal This class is not covered by the backward compatibility promise for PHPUnit
47055 *
47056 * @codeCoverageIgnore
47057 */
47058 final class SystemStopWatchWithOffset implements \PHPUnit\Event\Telemetry\StopWatch
47059 {
47060 private ?\PHPUnit\Event\Telemetry\HRTime $offset;
47061 public function __construct(\PHPUnit\Event\Telemetry\HRTime $offset)
47062 {
47063 $this->offset = $offset;
47064 }
47065 /**
47066 * @throws InvalidArgumentException
47067 */
47068 public function current(): \PHPUnit\Event\Telemetry\HRTime
47069 {
47070 if ($this->offset !== null) {
47071 $offset = $this->offset;
47072 $this->offset = null;
47073 return $offset;
47074 }
47075 return \PHPUnit\Event\Telemetry\HRTime::fromSecondsAndNanoseconds(...hrtime());
47076 }
47077 }
47078 <?php
47079
47080 declare (strict_types=1);
47081 /*
47082 * This file is part of PHPUnit.
47083 *
47084 * (c) Sebastian Bergmann <sebastian@phpunit.de>
47085 *
47086 * For the full copyright and license information, please view the LICENSE
47087 * file that was distributed with this source code.
47088 */
47089 namespace PHPUnit\Event\Code;
47090
47091 /**
47092 * @psalm-immutable
47093 *
47094 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
47095 */
47096 final class Phpt extends \PHPUnit\Event\Code\Test
47097 {
47098 /**
47099 * @psalm-assert-if-true Phpt $this
47100 */
47101 public function isPhpt(): bool
47102 {
47103 return \true;
47104 }
47105 /**
47106 * @psalm-return non-empty-string
47107 */
47108 public function id(): string
47109 {
47110 return $this->file();
47111 }
47112 /**
47113 * @psalm-return non-empty-string
47114 */
47115 public function name(): string
47116 {
47117 return $this->file();
47118 }
47119 }
47120 <?php
47121
47122 declare (strict_types=1);
47123 /*
47124 * This file is part of PHPUnit.
47125 *
47126 * (c) Sebastian Bergmann <sebastian@phpunit.de>
47127 *
47128 * For the full copyright and license information, please view the LICENSE
47129 * file that was distributed with this source code.
47130 */
47131 namespace PHPUnit\Event\Code;
47132
47133 /**
47134 * @psalm-immutable
47135 *
47136 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
47137 */
47138 abstract class Test
47139 {
47140 /**
47141 * @psalm-var non-empty-string
47142 */
47143 private readonly string $file;
47144 /**
47145 * @psalm-param non-empty-string $file
47146 */
47147 public function __construct(string $file)
47148 {
47149 $this->file = $file;
47150 }
47151 /**
47152 * @psalm-return non-empty-string
47153 */
47154 public function file(): string
47155 {
47156 return $this->file;
47157 }
47158 /**
47159 * @psalm-assert-if-true TestMethod $this
47160 */
47161 public function isTestMethod(): bool
47162 {
47163 return \false;
47164 }
47165 /**
47166 * @psalm-assert-if-true Phpt $this
47167 */
47168 public function isPhpt(): bool
47169 {
47170 return \false;
47171 }
47172 /**
47173 * @psalm-return non-empty-string
47174 */
47175 abstract public function id(): string;
47176 /**
47177 * @psalm-return non-empty-string
47178 */
47179 abstract public function name(): string;
47180 }
47181 <?php
47182
47183 declare (strict_types=1);
47184 /*
47185 * This file is part of PHPUnit.
47186 *
47187 * (c) Sebastian Bergmann <sebastian@phpunit.de>
47188 *
47189 * For the full copyright and license information, please view the LICENSE
47190 * file that was distributed with this source code.
47191 */
47192 namespace PHPUnit\Event\Code;
47193
47194 use function count;
47195 use Countable;
47196 use IteratorAggregate;
47197 /**
47198 * @template-implements IteratorAggregate<int, Test>
47199 *
47200 * @psalm-immutable
47201 *
47202 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
47203 */
47204 final class TestCollection implements Countable, IteratorAggregate
47205 {
47206 /**
47207 * @psalm-var list<Test>
47208 */
47209 private readonly array $tests;
47210 /**
47211 * @psalm-param list<Test> $tests
47212 */
47213 public static function fromArray(array $tests): self
47214 {
47215 return new self(...$tests);
47216 }
47217 private function __construct(\PHPUnit\Event\Code\Test ...$tests)
47218 {
47219 $this->tests = $tests;
47220 }
47221 /**
47222 * @psalm-return list<Test>
47223 */
47224 public function asArray(): array
47225 {
47226 return $this->tests;
47227 }
47228 public function count(): int
47229 {
47230 return count($this->tests);
47231 }
47232 public function getIterator(): \PHPUnit\Event\Code\TestCollectionIterator
47233 {
47234 return new \PHPUnit\Event\Code\TestCollectionIterator($this);
47235 }
47236 }
47237 <?php
47238
47239 declare (strict_types=1);
47240 /*
47241 * This file is part of PHPUnit.
47242 *
47243 * (c) Sebastian Bergmann <sebastian@phpunit.de>
47244 *
47245 * For the full copyright and license information, please view the LICENSE
47246 * file that was distributed with this source code.
47247 */
47248 namespace PHPUnit\Event\Code;
47249
47250 use function count;
47251 use Iterator;
47252 /**
47253 * @template-implements Iterator<int, Test>
47254 *
47255 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
47256 */
47257 final class TestCollectionIterator implements Iterator
47258 {
47259 /**
47260 * @psalm-var list<Test>
47261 */
47262 private readonly array $tests;
47263 private int $position = 0;
47264 public function __construct(\PHPUnit\Event\Code\TestCollection $tests)
47265 {
47266 $this->tests = $tests->asArray();
47267 }
47268 public function rewind(): void
47269 {
47270 $this->position = 0;
47271 }
47272 public function valid(): bool
47273 {
47274 return $this->position < count($this->tests);
47275 }
47276 public function key(): int
47277 {
47278 return $this->position;
47279 }
47280 public function current(): \PHPUnit\Event\Code\Test
47281 {
47282 return $this->tests[$this->position];
47283 }
47284 public function next(): void
47285 {
47286 $this->position++;
47287 }
47288 }
47289 <?php
47290
47291 declare (strict_types=1);
47292 /*
47293 * This file is part of PHPUnit.
47294 *
47295 * (c) Sebastian Bergmann <sebastian@phpunit.de>
47296 *
47297 * For the full copyright and license information, please view the LICENSE
47298 * file that was distributed with this source code.
47299 */
47300 namespace PHPUnit\Event\TestData;
47301
47302 /**
47303 * @psalm-immutable
47304 *
47305 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
47306 */
47307 final class DataFromDataProvider extends \PHPUnit\Event\TestData\TestData
47308 {
47309 private readonly int|string $dataSetName;
47310 private readonly string $dataAsStringForResultOutput;
47311 public static function from(int|string $dataSetName, string $data, string $dataAsStringForResultOutput): self
47312 {
47313 return new self($dataSetName, $data, $dataAsStringForResultOutput);
47314 }
47315 protected function __construct(int|string $dataSetName, string $data, string $dataAsStringForResultOutput)
47316 {
47317 $this->dataSetName = $dataSetName;
47318 $this->dataAsStringForResultOutput = $dataAsStringForResultOutput;
47319 parent::__construct($data);
47320 }
47321 public function dataSetName(): int|string
47322 {
47323 return $this->dataSetName;
47324 }
47325 /**
47326 * @internal This method is not covered by the backward compatibility promise for PHPUnit
47327 */
47328 public function dataAsStringForResultOutput(): string
47329 {
47330 return $this->dataAsStringForResultOutput;
47331 }
47332 /**
47333 * @psalm-assert-if-true DataFromDataProvider $this
47334 */
47335 public function isFromDataProvider(): bool
47336 {
47337 return \true;
47338 }
47339 }
47340 <?php
47341
47342 declare (strict_types=1);
47343 /*
47344 * This file is part of PHPUnit.
47345 *
47346 * (c) Sebastian Bergmann <sebastian@phpunit.de>
47347 *
47348 * For the full copyright and license information, please view the LICENSE
47349 * file that was distributed with this source code.
47350 */
47351 namespace PHPUnit\Event\TestData;
47352
47353 /**
47354 * @psalm-immutable
47355 *
47356 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
47357 */
47358 final class DataFromTestDependency extends \PHPUnit\Event\TestData\TestData
47359 {
47360 public static function from(string $data): self
47361 {
47362 return new self($data);
47363 }
47364 /**
47365 * @psalm-assert-if-true DataFromTestDependency $this
47366 */
47367 public function isFromTestDependency(): bool
47368 {
47369 return \true;
47370 }
47371 }
47372 <?php
47373
47374 declare (strict_types=1);
47375 /*
47376 * This file is part of PHPUnit.
47377 *
47378 * (c) Sebastian Bergmann <sebastian@phpunit.de>
47379 *
47380 * For the full copyright and license information, please view the LICENSE
47381 * file that was distributed with this source code.
47382 */
47383 namespace PHPUnit\Event\TestData;
47384
47385 /**
47386 * @psalm-immutable
47387 *
47388 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
47389 */
47390 abstract class TestData
47391 {
47392 private readonly string $data;
47393 protected function __construct(string $data)
47394 {
47395 $this->data = $data;
47396 }
47397 public function data(): string
47398 {
47399 return $this->data;
47400 }
47401 /**
47402 * @psalm-assert-if-true DataFromDataProvider $this
47403 */
47404 public function isFromDataProvider(): bool
47405 {
47406 return \false;
47407 }
47408 /**
47409 * @psalm-assert-if-true DataFromTestDependency $this
47410 */
47411 public function isFromTestDependency(): bool
47412 {
47413 return \false;
47414 }
47415 }
47416 <?php
47417
47418 declare (strict_types=1);
47419 /*
47420 * This file is part of PHPUnit.
47421 *
47422 * (c) Sebastian Bergmann <sebastian@phpunit.de>
47423 *
47424 * For the full copyright and license information, please view the LICENSE
47425 * file that was distributed with this source code.
47426 */
47427 namespace PHPUnit\Event\TestData;
47428
47429 use function count;
47430 use Countable;
47431 use IteratorAggregate;
47432 /**
47433 * @template-implements IteratorAggregate<int, TestData>
47434 *
47435 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
47436 */
47437 final class TestDataCollection implements Countable, IteratorAggregate
47438 {
47439 /**
47440 * @psalm-var list<TestData>
47441 */
47442 private readonly array $data;
47443 private ?\PHPUnit\Event\TestData\DataFromDataProvider $fromDataProvider = null;
47444 /**
47445 * @psalm-param list<TestData> $data
47446 *
47447 * @throws MoreThanOneDataSetFromDataProviderException
47448 */
47449 public static function fromArray(array $data): self
47450 {
47451 return new self(...$data);
47452 }
47453 /**
47454 * @throws MoreThanOneDataSetFromDataProviderException
47455 */
47456 private function __construct(\PHPUnit\Event\TestData\TestData ...$data)
47457 {
47458 $this->ensureNoMoreThanOneDataFromDataProvider($data);
47459 $this->data = $data;
47460 }
47461 /**
47462 * @psalm-return list<TestData>
47463 */
47464 public function asArray(): array
47465 {
47466 return $this->data;
47467 }
47468 public function count(): int
47469 {
47470 return count($this->data);
47471 }
47472 /**
47473 * @psalm-assert-if-true !null $this->fromDataProvider
47474 */
47475 public function hasDataFromDataProvider(): bool
47476 {
47477 return $this->fromDataProvider !== null;
47478 }
47479 /**
47480 * @throws NoDataSetFromDataProviderException
47481 */
47482 public function dataFromDataProvider(): \PHPUnit\Event\TestData\DataFromDataProvider
47483 {
47484 if (!$this->hasDataFromDataProvider()) {
47485 throw new \PHPUnit\Event\TestData\NoDataSetFromDataProviderException();
47486 }
47487 return $this->fromDataProvider;
47488 }
47489 public function getIterator(): \PHPUnit\Event\TestData\TestDataCollectionIterator
47490 {
47491 return new \PHPUnit\Event\TestData\TestDataCollectionIterator($this);
47492 }
47493 /**
47494 * @psalm-param list<TestData> $data
47495 *
47496 * @throws MoreThanOneDataSetFromDataProviderException
47497 */
47498 private function ensureNoMoreThanOneDataFromDataProvider(array $data): void
47499 {
47500 foreach ($data as $_data) {
47501 if ($_data->isFromDataProvider()) {
47502 if ($this->fromDataProvider !== null) {
47503 throw new \PHPUnit\Event\TestData\MoreThanOneDataSetFromDataProviderException();
47504 }
47505 $this->fromDataProvider = $_data;
47506 }
47507 }
47508 }
47509 }
47510 <?php
47511
47512 declare (strict_types=1);
47513 /*
47514 * This file is part of PHPUnit.
47515 *
47516 * (c) Sebastian Bergmann <sebastian@phpunit.de>
47517 *
47518 * For the full copyright and license information, please view the LICENSE
47519 * file that was distributed with this source code.
47520 */
47521 namespace PHPUnit\Event\TestData;
47522
47523 use function count;
47524 use Iterator;
47525 /**
47526 * @template-implements Iterator<int, TestData>
47527 *
47528 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
47529 */
47530 final class TestDataCollectionIterator implements Iterator
47531 {
47532 /**
47533 * @psalm-var list<TestData>
47534 */
47535 private readonly array $data;
47536 private int $position = 0;
47537 public function __construct(\PHPUnit\Event\TestData\TestDataCollection $data)
47538 {
47539 $this->data = $data->asArray();
47540 }
47541 public function rewind(): void
47542 {
47543 $this->position = 0;
47544 }
47545 public function valid(): bool
47546 {
47547 return $this->position < count($this->data);
47548 }
47549 public function key(): int
47550 {
47551 return $this->position;
47552 }
47553 public function current(): \PHPUnit\Event\TestData\TestData
47554 {
47555 return $this->data[$this->position];
47556 }
47557 public function next(): void
47558 {
47559 $this->position++;
47560 }
47561 }
47562 <?php
47563
47564 declare (strict_types=1);
47565 /*
47566 * This file is part of PHPUnit.
47567 *
47568 * (c) Sebastian Bergmann <sebastian@phpunit.de>
47569 *
47570 * For the full copyright and license information, please view the LICENSE
47571 * file that was distributed with this source code.
47572 */
47573 namespace PHPUnit\Event\Code;
47574
47575 /**
47576 * @psalm-immutable
47577 *
47578 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
47579 */
47580 final class TestDox
47581 {
47582 private readonly string $prettifiedClassName;
47583 private readonly string $prettifiedMethodName;
47584 private readonly string $prettifiedAndColorizedMethodName;
47585 public function __construct(string $prettifiedClassName, string $prettifiedMethodName, string $prettifiedAndColorizedMethodName)
47586 {
47587 $this->prettifiedClassName = $prettifiedClassName;
47588 $this->prettifiedMethodName = $prettifiedMethodName;
47589 $this->prettifiedAndColorizedMethodName = $prettifiedAndColorizedMethodName;
47590 }
47591 public function prettifiedClassName(): string
47592 {
47593 return $this->prettifiedClassName;
47594 }
47595 public function prettifiedMethodName(bool $colorize = \false): string
47596 {
47597 if ($colorize) {
47598 return $this->prettifiedAndColorizedMethodName;
47599 }
47600 return $this->prettifiedMethodName;
47601 }
47602 }
47603 <?php
47604
47605 declare (strict_types=1);
47606 /*
47607 * This file is part of PHPUnit.
47608 *
47609 * (c) Sebastian Bergmann <sebastian@phpunit.de>
47610 *
47611 * For the full copyright and license information, please view the LICENSE
47612 * file that was distributed with this source code.
47613 */
47614 namespace PHPUnit\Event\Code;
47615
47616 use PHPUnit\Event\TestData\MoreThanOneDataSetFromDataProviderException;
47617 use PHPUnit\Framework\TestCase;
47618 use PHPUnit\Logging\TestDox\NamePrettifier;
47619 /**
47620 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
47621 *
47622 * @internal This class is not covered by the backward compatibility promise for PHPUnit
47623 */
47624 final class TestDoxBuilder
47625 {
47626 /**
47627 * @throws MoreThanOneDataSetFromDataProviderException
47628 */
47629 public static function fromTestCase(TestCase $testCase): \PHPUnit\Event\Code\TestDox
47630 {
47631 $prettifier = new NamePrettifier();
47632 return new \PHPUnit\Event\Code\TestDox($prettifier->prettifyTestClassName($testCase::class), $prettifier->prettifyTestCase($testCase, \false), $prettifier->prettifyTestCase($testCase, \true));
47633 }
47634 /**
47635 * @psalm-param class-string $className
47636 * @psalm-param non-empty-string $methodName
47637 */
47638 public static function fromClassNameAndMethodName(string $className, string $methodName): \PHPUnit\Event\Code\TestDox
47639 {
47640 $prettifier = new NamePrettifier();
47641 $prettifiedMethodName = $prettifier->prettifyTestMethodName($methodName);
47642 return new \PHPUnit\Event\Code\TestDox($prettifier->prettifyTestClassName($className), $prettifiedMethodName, $prettifiedMethodName);
47643 }
47644 }
47645 <?php
47646
47647 declare (strict_types=1);
47648 /*
47649 * This file is part of PHPUnit.
47650 *
47651 * (c) Sebastian Bergmann <sebastian@phpunit.de>
47652 *
47653 * For the full copyright and license information, please view the LICENSE
47654 * file that was distributed with this source code.
47655 */
47656 namespace PHPUnit\Event\Code;
47657
47658 use function assert;
47659 use function is_int;
47660 use function sprintf;
47661 use PHPUnit\Event\TestData\TestDataCollection;
47662 use PHPUnit\Metadata\MetadataCollection;
47663 /**
47664 * @psalm-immutable
47665 *
47666 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
47667 */
47668 final class TestMethod extends \PHPUnit\Event\Code\Test
47669 {
47670 /**
47671 * @psalm-var class-string
47672 */
47673 private readonly string $className;
47674 /**
47675 * @psalm-var non-empty-string
47676 */
47677 private readonly string $methodName;
47678 /**
47679 * @psalm-var non-negative-int
47680 */
47681 private readonly int $line;
47682 private readonly \PHPUnit\Event\Code\TestDox $testDox;
47683 private readonly MetadataCollection $metadata;
47684 private readonly TestDataCollection $testData;
47685 /**
47686 * @psalm-param class-string $className
47687 * @psalm-param non-empty-string $methodName
47688 * @psalm-param non-empty-string $file
47689 * @psalm-param non-negative-int $line
47690 */
47691 public function __construct(string $className, string $methodName, string $file, int $line, \PHPUnit\Event\Code\TestDox $testDox, MetadataCollection $metadata, TestDataCollection $testData)
47692 {
47693 parent::__construct($file);
47694 $this->className = $className;
47695 $this->methodName = $methodName;
47696 $this->line = $line;
47697 $this->testDox = $testDox;
47698 $this->metadata = $metadata;
47699 $this->testData = $testData;
47700 }
47701 /**
47702 * @psalm-return class-string
47703 */
47704 public function className(): string
47705 {
47706 return $this->className;
47707 }
47708 /**
47709 * @psalm-return non-empty-string
47710 */
47711 public function methodName(): string
47712 {
47713 return $this->methodName;
47714 }
47715 /**
47716 * @psalm-return non-negative-int
47717 */
47718 public function line(): int
47719 {
47720 return $this->line;
47721 }
47722 public function testDox(): \PHPUnit\Event\Code\TestDox
47723 {
47724 return $this->testDox;
47725 }
47726 public function metadata(): MetadataCollection
47727 {
47728 return $this->metadata;
47729 }
47730 public function testData(): TestDataCollection
47731 {
47732 return $this->testData;
47733 }
47734 /**
47735 * @psalm-assert-if-true TestMethod $this
47736 */
47737 public function isTestMethod(): bool
47738 {
47739 return \true;
47740 }
47741 /**
47742 * @psalm-return non-empty-string
47743 */
47744 public function id(): string
47745 {
47746 $buffer = $this->className . '::' . $this->methodName;
47747 if ($this->testData()->hasDataFromDataProvider()) {
47748 $buffer .= '#' . $this->testData->dataFromDataProvider()->dataSetName();
47749 }
47750 return $buffer;
47751 }
47752 /**
47753 * @psalm-return non-empty-string
47754 */
47755 public function nameWithClass(): string
47756 {
47757 return $this->className . '::' . $this->name();
47758 }
47759 /**
47760 * @psalm-return non-empty-string
47761 */
47762 public function name(): string
47763 {
47764 if (!$this->testData->hasDataFromDataProvider()) {
47765 return $this->methodName;
47766 }
47767 $dataSetName = $this->testData->dataFromDataProvider()->dataSetName();
47768 if (is_int($dataSetName)) {
47769 $dataSetName = sprintf(' with data set #%d', $dataSetName);
47770 } else {
47771 $dataSetName = sprintf(' with data set "%s"', $dataSetName);
47772 }
47773 return $this->methodName . $dataSetName;
47774 }
47775 }
47776 <?php
47777
47778 declare (strict_types=1);
47779 /*
47780 * This file is part of PHPUnit.
47781 *
47782 * (c) Sebastian Bergmann <sebastian@phpunit.de>
47783 *
47784 * For the full copyright and license information, please view the LICENSE
47785 * file that was distributed with this source code.
47786 */
47787 namespace PHPUnit\Event\Code;
47788
47789 use const DEBUG_BACKTRACE_IGNORE_ARGS;
47790 use const DEBUG_BACKTRACE_PROVIDE_OBJECT;
47791 use function assert;
47792 use function debug_backtrace;
47793 use function is_numeric;
47794 use PHPUnit\Event\Facade as EventFacade;
47795 use PHPUnit\Event\TestData\DataFromDataProvider;
47796 use PHPUnit\Event\TestData\DataFromTestDependency;
47797 use PHPUnit\Event\TestData\MoreThanOneDataSetFromDataProviderException;
47798 use PHPUnit\Event\TestData\TestDataCollection;
47799 use PHPUnit\Framework\TestCase;
47800 use PHPUnit\Metadata\Parser\Registry as MetadataRegistry;
47801 use PHPUnit\Util\Exporter;
47802 use PHPUnit\Util\Reflection;
47803 /**
47804 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
47805 *
47806 * @internal This class is not covered by the backward compatibility promise for PHPUnit
47807 */
47808 final class TestMethodBuilder
47809 {
47810 /**
47811 * @throws MoreThanOneDataSetFromDataProviderException
47812 */
47813 public static function fromTestCase(TestCase $testCase): \PHPUnit\Event\Code\TestMethod
47814 {
47815 $methodName = $testCase->name();
47816 assert(!empty($methodName));
47817 $location = Reflection::sourceLocationFor($testCase::class, $methodName);
47818 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));
47819 }
47820 /**
47821 * @throws NoTestCaseObjectOnCallStackException
47822 */
47823 public static function fromCallStack(): \PHPUnit\Event\Code\TestMethod
47824 {
47825 foreach (debug_backtrace(DEBUG_BACKTRACE_PROVIDE_OBJECT | DEBUG_BACKTRACE_IGNORE_ARGS) as $frame) {
47826 if (isset($frame['object']) && $frame['object'] instanceof TestCase) {
47827 return $frame['object']->valueObjectForEvents();
47828 }
47829 }
47830 throw new \PHPUnit\Event\Code\NoTestCaseObjectOnCallStackException();
47831 }
47832 /**
47833 * @throws MoreThanOneDataSetFromDataProviderException
47834 */
47835 private static function dataFor(TestCase $testCase): TestDataCollection
47836 {
47837 $testData = [];
47838 if ($testCase->usesDataProvider()) {
47839 $dataSetName = $testCase->dataName();
47840 if (is_numeric($dataSetName)) {
47841 $dataSetName = (int) $dataSetName;
47842 }
47843 $testData[] = DataFromDataProvider::from($dataSetName, Exporter::export($testCase->providedData(), EventFacade::emitter()->exportsObjects()), $testCase->dataSetAsStringWithData());
47844 }
47845 if ($testCase->hasDependencyInput()) {
47846 $testData[] = DataFromTestDependency::from(Exporter::export($testCase->dependencyInput(), EventFacade::emitter()->exportsObjects()));
47847 }
47848 return TestDataCollection::fromArray($testData);
47849 }
47850 }
47851 <?php
47852
47853 declare (strict_types=1);
47854 /*
47855 * This file is part of PHPUnit.
47856 *
47857 * (c) Sebastian Bergmann <sebastian@phpunit.de>
47858 *
47859 * For the full copyright and license information, please view the LICENSE
47860 * file that was distributed with this source code.
47861 */
47862 namespace PHPUnit\Event\TestSuite;
47863
47864 use PHPUnit\Event\Code\TestCollection;
47865 /**
47866 * @psalm-immutable
47867 *
47868 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
47869 */
47870 abstract class TestSuite
47871 {
47872 /**
47873 * @psalm-var non-empty-string
47874 */
47875 private readonly string $name;
47876 private readonly int $count;
47877 private readonly TestCollection $tests;
47878 /**
47879 * @psalm-param non-empty-string $name
47880 */
47881 public function __construct(string $name, int $size, TestCollection $tests)
47882 {
47883 $this->name = $name;
47884 $this->count = $size;
47885 $this->tests = $tests;
47886 }
47887 /**
47888 * @psalm-return non-empty-string
47889 */
47890 public function name(): string
47891 {
47892 return $this->name;
47893 }
47894 public function count(): int
47895 {
47896 return $this->count;
47897 }
47898 public function tests(): TestCollection
47899 {
47900 return $this->tests;
47901 }
47902 /**
47903 * @psalm-assert-if-true TestSuiteWithName $this
47904 */
47905 public function isWithName(): bool
47906 {
47907 return \false;
47908 }
47909 /**
47910 * @psalm-assert-if-true TestSuiteForTestClass $this
47911 */
47912 public function isForTestClass(): bool
47913 {
47914 return \false;
47915 }
47916 /**
47917 * @psalm-assert-if-true TestSuiteForTestMethodWithDataProvider $this
47918 */
47919 public function isForTestMethodWithDataProvider(): bool
47920 {
47921 return \false;
47922 }
47923 }
47924 <?php
47925
47926 declare (strict_types=1);
47927 /*
47928 * This file is part of PHPUnit.
47929 *
47930 * (c) Sebastian Bergmann <sebastian@phpunit.de>
47931 *
47932 * For the full copyright and license information, please view the LICENSE
47933 * file that was distributed with this source code.
47934 */
47935 namespace PHPUnit\Event\TestSuite;
47936
47937 use function explode;
47938 use PHPUnit\Event\Code\Test;
47939 use PHPUnit\Event\Code\TestCollection;
47940 use PHPUnit\Event\RuntimeException;
47941 use PHPUnit\Framework\DataProviderTestSuite;
47942 use PHPUnit\Framework\TestCase;
47943 use PHPUnit\Framework\TestSuite as FrameworkTestSuite;
47944 use PHPUnit\Runner\PhptTestCase;
47945 use ReflectionClass;
47946 use ReflectionException;
47947 use ReflectionMethod;
47948 /**
47949 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
47950 *
47951 * @internal This class is not covered by the backward compatibility promise for PHPUnit
47952 */
47953 final class TestSuiteBuilder
47954 {
47955 /**
47956 * @throws RuntimeException
47957 */
47958 public static function from(FrameworkTestSuite $testSuite): \PHPUnit\Event\TestSuite\TestSuite
47959 {
47960 $tests = [];
47961 self::process($testSuite, $tests);
47962 if ($testSuite instanceof DataProviderTestSuite) {
47963 [$className, $methodName] = explode('::', $testSuite->name());
47964 try {
47965 $reflector = new ReflectionMethod($className, $methodName);
47966 return new \PHPUnit\Event\TestSuite\TestSuiteForTestMethodWithDataProvider($testSuite->name(), $testSuite->count(), TestCollection::fromArray($tests), $className, $methodName, $reflector->getFileName(), $reflector->getStartLine());
47967 // @codeCoverageIgnoreStart
47968 } catch (ReflectionException $e) {
47969 throw new RuntimeException($e->getMessage(), $e->getCode(), $e);
47970 }
47971 // @codeCoverageIgnoreEnd
47972 }
47973 if ($testSuite->isForTestClass()) {
47974 try {
47975 $reflector = new ReflectionClass($testSuite->name());
47976 return new \PHPUnit\Event\TestSuite\TestSuiteForTestClass($testSuite->name(), $testSuite->count(), TestCollection::fromArray($tests), $reflector->getFileName(), $reflector->getStartLine());
47977 // @codeCoverageIgnoreStart
47978 } catch (ReflectionException $e) {
47979 throw new RuntimeException($e->getMessage(), $e->getCode(), $e);
47980 }
47981 // @codeCoverageIgnoreEnd
47982 }
47983 return new \PHPUnit\Event\TestSuite\TestSuiteWithName($testSuite->name(), $testSuite->count(), TestCollection::fromArray($tests));
47984 }
47985 /**
47986 * @psalm-param list<Test> $tests
47987 */
47988 private static function process(FrameworkTestSuite $testSuite, array &$tests): void
47989 {
47990 foreach ($testSuite->getIterator() as $test) {
47991 if ($test instanceof FrameworkTestSuite) {
47992 self::process($test, $tests);
47993 continue;
47994 }
47995 if ($test instanceof TestCase || $test instanceof PhptTestCase) {
47996 $tests[] = $test->valueObjectForEvents();
47997 }
47998 }
47999 }
48000 }
48001 <?php
48002
48003 declare (strict_types=1);
48004 /*
48005 * This file is part of PHPUnit.
48006 *
48007 * (c) Sebastian Bergmann <sebastian@phpunit.de>
48008 *
48009 * For the full copyright and license information, please view the LICENSE
48010 * file that was distributed with this source code.
48011 */
48012 namespace PHPUnit\Event\TestSuite;
48013
48014 use PHPUnit\Event\Code\TestCollection;
48015 /**
48016 * @psalm-immutable
48017 *
48018 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
48019 */
48020 final class TestSuiteForTestClass extends \PHPUnit\Event\TestSuite\TestSuite
48021 {
48022 /**
48023 * @psalm-var class-string
48024 */
48025 private readonly string $className;
48026 private readonly string $file;
48027 private readonly int $line;
48028 /**
48029 * @psalm-param class-string $name
48030 */
48031 public function __construct(string $name, int $size, TestCollection $tests, string $file, int $line)
48032 {
48033 parent::__construct($name, $size, $tests);
48034 $this->className = $name;
48035 $this->file = $file;
48036 $this->line = $line;
48037 }
48038 /**
48039 * @psalm-return class-string
48040 */
48041 public function className(): string
48042 {
48043 return $this->className;
48044 }
48045 public function file(): string
48046 {
48047 return $this->file;
48048 }
48049 public function line(): int
48050 {
48051 return $this->line;
48052 }
48053 /**
48054 * @psalm-assert-if-true TestSuiteForTestClass $this
48055 */
48056 public function isForTestClass(): bool
48057 {
48058 return \true;
48059 }
48060 }
48061 <?php
48062
48063 declare (strict_types=1);
48064 /*
48065 * This file is part of PHPUnit.
48066 *
48067 * (c) Sebastian Bergmann <sebastian@phpunit.de>
48068 *
48069 * For the full copyright and license information, please view the LICENSE
48070 * file that was distributed with this source code.
48071 */
48072 namespace PHPUnit\Event\TestSuite;
48073
48074 use PHPUnit\Event\Code\TestCollection;
48075 /**
48076 * @psalm-immutable
48077 *
48078 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
48079 */
48080 final class TestSuiteForTestMethodWithDataProvider extends \PHPUnit\Event\TestSuite\TestSuite
48081 {
48082 /**
48083 * @psalm-var class-string
48084 */
48085 private readonly string $className;
48086 /**
48087 * @psalm-var non-empty-string
48088 */
48089 private readonly string $methodName;
48090 private readonly string $file;
48091 private readonly int $line;
48092 /**
48093 * @psalm-param non-empty-string $name
48094 * @psalm-param class-string $className
48095 * @psalm-param non-empty-string $methodName
48096 */
48097 public function __construct(string $name, int $size, TestCollection $tests, string $className, string $methodName, string $file, int $line)
48098 {
48099 parent::__construct($name, $size, $tests);
48100 $this->className = $className;
48101 $this->methodName = $methodName;
48102 $this->file = $file;
48103 $this->line = $line;
48104 }
48105 /**
48106 * @psalm-return class-string
48107 */
48108 public function className(): string
48109 {
48110 return $this->className;
48111 }
48112 /**
48113 * @psalm-return non-empty-string
48114 */
48115 public function methodName(): string
48116 {
48117 return $this->methodName;
48118 }
48119 public function file(): string
48120 {
48121 return $this->file;
48122 }
48123 public function line(): int
48124 {
48125 return $this->line;
48126 }
48127 /**
48128 * @psalm-assert-if-true TestSuiteForTestMethodWithDataProvider $this
48129 */
48130 public function isForTestMethodWithDataProvider(): bool
48131 {
48132 return \true;
48133 }
48134 }
48135 <?php
48136
48137 declare (strict_types=1);
48138 /*
48139 * This file is part of PHPUnit.
48140 *
48141 * (c) Sebastian Bergmann <sebastian@phpunit.de>
48142 *
48143 * For the full copyright and license information, please view the LICENSE
48144 * file that was distributed with this source code.
48145 */
48146 namespace PHPUnit\Event\TestSuite;
48147
48148 /**
48149 * @psalm-immutable
48150 *
48151 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
48152 */
48153 final class TestSuiteWithName extends \PHPUnit\Event\TestSuite\TestSuite
48154 {
48155 /**
48156 * @psalm-assert-if-true TestSuiteWithName $this
48157 */
48158 public function isWithName(): bool
48159 {
48160 return \true;
48161 }
48162 }
48163 <?php
48164
48165 declare (strict_types=1);
48166 /*
48167 * This file is part of PHPUnit.
48168 *
48169 * (c) Sebastian Bergmann <sebastian@phpunit.de>
48170 *
48171 * For the full copyright and license information, please view the LICENSE
48172 * file that was distributed with this source code.
48173 */
48174 namespace PHPUnit\Event\Code;
48175
48176 use const PHP_EOL;
48177 use PHPUnit\Event\NoPreviousThrowableException;
48178 /**
48179 * @psalm-immutable
48180 *
48181 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
48182 */
48183 final class Throwable
48184 {
48185 /**
48186 * @psalm-var class-string
48187 */
48188 private readonly string $className;
48189 private readonly string $message;
48190 private readonly string $description;
48191 private readonly string $stackTrace;
48192 private readonly ?\PHPUnit\Event\Code\Throwable $previous;
48193 /**
48194 * @psalm-param class-string $className
48195 */
48196 public function __construct(string $className, string $message, string $description, string $stackTrace, ?self $previous)
48197 {
48198 $this->className = $className;
48199 $this->message = $message;
48200 $this->description = $description;
48201 $this->stackTrace = $stackTrace;
48202 $this->previous = $previous;
48203 }
48204 /**
48205 * @throws NoPreviousThrowableException
48206 */
48207 public function asString(): string
48208 {
48209 $buffer = $this->description();
48210 if (!empty($this->stackTrace())) {
48211 $buffer .= PHP_EOL . $this->stackTrace();
48212 }
48213 if ($this->hasPrevious()) {
48214 $buffer .= PHP_EOL . 'Caused by' . PHP_EOL . $this->previous()->asString();
48215 }
48216 return $buffer;
48217 }
48218 /**
48219 * @psalm-return class-string
48220 */
48221 public function className(): string
48222 {
48223 return $this->className;
48224 }
48225 public function message(): string
48226 {
48227 return $this->message;
48228 }
48229 public function description(): string
48230 {
48231 return $this->description;
48232 }
48233 public function stackTrace(): string
48234 {
48235 return $this->stackTrace;
48236 }
48237 /**
48238 * @psalm-assert-if-true !null $this->previous
48239 */
48240 public function hasPrevious(): bool
48241 {
48242 return $this->previous !== null;
48243 }
48244 /**
48245 * @throws NoPreviousThrowableException
48246 */
48247 public function previous(): self
48248 {
48249 if ($this->previous === null) {
48250 throw new NoPreviousThrowableException();
48251 }
48252 return $this->previous;
48253 }
48254 }
48255 <?php
48256
48257 declare (strict_types=1);
48258 /*
48259 * This file is part of PHPUnit.
48260 *
48261 * (c) Sebastian Bergmann <sebastian@phpunit.de>
48262 *
48263 * For the full copyright and license information, please view the LICENSE
48264 * file that was distributed with this source code.
48265 */
48266 namespace PHPUnit\Event\Code;
48267
48268 use PHPUnit\Event\NoPreviousThrowableException;
48269 use PHPUnit\Framework\Exception;
48270 use PHPUnit\Util\Filter;
48271 use PHPUnit\Util\ThrowableToStringMapper;
48272 /**
48273 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
48274 *
48275 * @internal This class is not covered by the backward compatibility promise for PHPUnit
48276 */
48277 final class ThrowableBuilder
48278 {
48279 /**
48280 * @throws Exception
48281 * @throws NoPreviousThrowableException
48282 */
48283 public static function from(\Throwable $t): \PHPUnit\Event\Code\Throwable
48284 {
48285 $previous = $t->getPrevious();
48286 if ($previous !== null) {
48287 $previous = self::from($previous);
48288 }
48289 return new \PHPUnit\Event\Code\Throwable($t::class, $t->getMessage(), ThrowableToStringMapper::map($t), Filter::getFilteredStacktrace($t, \false), $previous);
48290 }
48291 }
48292 <?php
48293
48294 declare (strict_types=1);
48295 /*
48296 * This file is part of PHPUnit.
48297 *
48298 * (c) Sebastian Bergmann <sebastian@phpunit.de>
48299 *
48300 * For the full copyright and license information, please view the LICENSE
48301 * file that was distributed with this source code.
48302 */
48303 namespace PHPUnit;
48304
48305 use Throwable;
48306 interface Exception extends Throwable
48307 {
48308 }
48309 <?php
48310
48311 declare (strict_types=1);
48312 /*
48313 * This file is part of PHPUnit.
48314 *
48315 * (c) Sebastian Bergmann <sebastian@phpunit.de>
48316 *
48317 * For the full copyright and license information, please view the LICENSE
48318 * file that was distributed with this source code.
48319 */
48320 namespace PHPUnit\Framework;
48321
48322 use function class_exists;
48323 use function count;
48324 use function file_get_contents;
48325 use function interface_exists;
48326 use function is_bool;
48327 use ArrayAccess;
48328 use Countable;
48329 use Generator;
48330 use PHPUnit\Event;
48331 use PHPUnit\Framework\Constraint\ArrayHasKey;
48332 use PHPUnit\Framework\Constraint\Callback;
48333 use PHPUnit\Framework\Constraint\Constraint;
48334 use PHPUnit\Framework\Constraint\Count;
48335 use PHPUnit\Framework\Constraint\DirectoryExists;
48336 use PHPUnit\Framework\Constraint\FileExists;
48337 use PHPUnit\Framework\Constraint\GreaterThan;
48338 use PHPUnit\Framework\Constraint\IsAnything;
48339 use PHPUnit\Framework\Constraint\IsEmpty;
48340 use PHPUnit\Framework\Constraint\IsEqual;
48341 use PHPUnit\Framework\Constraint\IsEqualCanonicalizing;
48342 use PHPUnit\Framework\Constraint\IsEqualIgnoringCase;
48343 use PHPUnit\Framework\Constraint\IsEqualWithDelta;
48344 use PHPUnit\Framework\Constraint\IsFalse;
48345 use PHPUnit\Framework\Constraint\IsFinite;
48346 use PHPUnit\Framework\Constraint\IsIdentical;
48347 use PHPUnit\Framework\Constraint\IsInfinite;
48348 use PHPUnit\Framework\Constraint\IsInstanceOf;
48349 use PHPUnit\Framework\Constraint\IsJson;
48350 use PHPUnit\Framework\Constraint\IsList;
48351 use PHPUnit\Framework\Constraint\IsNan;
48352 use PHPUnit\Framework\Constraint\IsNull;
48353 use PHPUnit\Framework\Constraint\IsReadable;
48354 use PHPUnit\Framework\Constraint\IsTrue;
48355 use PHPUnit\Framework\Constraint\IsType;
48356 use PHPUnit\Framework\Constraint\IsWritable;
48357 use PHPUnit\Framework\Constraint\JsonMatches;
48358 use PHPUnit\Framework\Constraint\LessThan;
48359 use PHPUnit\Framework\Constraint\LogicalAnd;
48360 use PHPUnit\Framework\Constraint\LogicalNot;
48361 use PHPUnit\Framework\Constraint\LogicalOr;
48362 use PHPUnit\Framework\Constraint\LogicalXor;
48363 use PHPUnit\Framework\Constraint\ObjectEquals;
48364 use PHPUnit\Framework\Constraint\ObjectHasProperty;
48365 use PHPUnit\Framework\Constraint\RegularExpression;
48366 use PHPUnit\Framework\Constraint\SameSize;
48367 use PHPUnit\Framework\Constraint\StringContains;
48368 use PHPUnit\Framework\Constraint\StringEndsWith;
48369 use PHPUnit\Framework\Constraint\StringEqualsStringIgnoringLineEndings;
48370 use PHPUnit\Framework\Constraint\StringMatchesFormatDescription;
48371 use PHPUnit\Framework\Constraint\StringStartsWith;
48372 use PHPUnit\Framework\Constraint\TraversableContainsEqual;
48373 use PHPUnit\Framework\Constraint\TraversableContainsIdentical;
48374 use PHPUnit\Framework\Constraint\TraversableContainsOnly;
48375 use PHPUnit\Util\Xml\Loader as XmlLoader;
48376 use PHPUnit\Util\Xml\XmlException;
48377 /**
48378 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
48379 */
48380 abstract class Assert
48381 {
48382 private static int $count = 0;
48383 /**
48384 * Asserts that an array has a specified key.
48385 *
48386 * @throws Exception
48387 * @throws ExpectationFailedException
48388 */
48389 final public static function assertArrayHasKey(mixed $key, array|ArrayAccess $array, string $message = ''): void
48390 {
48391 $constraint = new ArrayHasKey($key);
48392 static::assertThat($array, $constraint, $message);
48393 }
48394 /**
48395 * Asserts that an array does not have a specified key.
48396 *
48397 * @throws Exception
48398 * @throws ExpectationFailedException
48399 */
48400 final public static function assertArrayNotHasKey(mixed $key, array|ArrayAccess $array, string $message = ''): void
48401 {
48402 $constraint = new LogicalNot(new ArrayHasKey($key));
48403 static::assertThat($array, $constraint, $message);
48404 }
48405 /**
48406 * @throws ExpectationFailedException
48407 */
48408 final public static function assertIsList(mixed $array, string $message = ''): void
48409 {
48410 static::assertThat($array, new IsList(), $message);
48411 }
48412 /**
48413 * Asserts that a haystack contains a needle.
48414 *
48415 * @throws Exception
48416 * @throws ExpectationFailedException
48417 */
48418 final public static function assertContains(mixed $needle, iterable $haystack, string $message = ''): void
48419 {
48420 $constraint = new TraversableContainsIdentical($needle);
48421 static::assertThat($haystack, $constraint, $message);
48422 }
48423 /**
48424 * @throws ExpectationFailedException
48425 */
48426 final public static function assertContainsEquals(mixed $needle, iterable $haystack, string $message = ''): void
48427 {
48428 $constraint = new TraversableContainsEqual($needle);
48429 static::assertThat($haystack, $constraint, $message);
48430 }
48431 /**
48432 * Asserts that a haystack does not contain a needle.
48433 *
48434 * @throws Exception
48435 * @throws ExpectationFailedException
48436 */
48437 final public static function assertNotContains(mixed $needle, iterable $haystack, string $message = ''): void
48438 {
48439 $constraint = new LogicalNot(new TraversableContainsIdentical($needle));
48440 static::assertThat($haystack, $constraint, $message);
48441 }
48442 /**
48443 * @throws ExpectationFailedException
48444 */
48445 final public static function assertNotContainsEquals(mixed $needle, iterable $haystack, string $message = ''): void
48446 {
48447 $constraint = new LogicalNot(new TraversableContainsEqual($needle));
48448 static::assertThat($haystack, $constraint, $message);
48449 }
48450 /**
48451 * Asserts that a haystack contains only values of a given type.
48452 *
48453 * @throws Exception
48454 * @throws ExpectationFailedException
48455 */
48456 final public static function assertContainsOnly(string $type, iterable $haystack, ?bool $isNativeType = null, string $message = ''): void
48457 {
48458 if ($isNativeType === null) {
48459 $isNativeType = self::isNativeType($type);
48460 }
48461 static::assertThat($haystack, new TraversableContainsOnly($type, $isNativeType), $message);
48462 }
48463 /**
48464 * Asserts that a haystack contains only instances of a given class name.
48465 *
48466 * @throws Exception
48467 * @throws ExpectationFailedException
48468 */
48469 final public static function assertContainsOnlyInstancesOf(string $className, iterable $haystack, string $message = ''): void
48470 {
48471 static::assertThat($haystack, new TraversableContainsOnly($className, \false), $message);
48472 }
48473 /**
48474 * Asserts that a haystack does not contain only values of a given type.
48475 *
48476 * @throws Exception
48477 * @throws ExpectationFailedException
48478 */
48479 final public static function assertNotContainsOnly(string $type, iterable $haystack, ?bool $isNativeType = null, string $message = ''): void
48480 {
48481 if ($isNativeType === null) {
48482 $isNativeType = self::isNativeType($type);
48483 }
48484 static::assertThat($haystack, new LogicalNot(new TraversableContainsOnly($type, $isNativeType)), $message);
48485 }
48486 /**
48487 * Asserts the number of elements of an array, Countable or Traversable.
48488 *
48489 * @throws Exception
48490 * @throws ExpectationFailedException
48491 * @throws GeneratorNotSupportedException
48492 */
48493 final public static function assertCount(int $expectedCount, Countable|iterable $haystack, string $message = ''): void
48494 {
48495 if ($haystack instanceof Generator) {
48496 throw \PHPUnit\Framework\GeneratorNotSupportedException::fromParameterName('$haystack');
48497 }
48498 static::assertThat($haystack, new Count($expectedCount), $message);
48499 }
48500 /**
48501 * Asserts the number of elements of an array, Countable or Traversable.
48502 *
48503 * @throws Exception
48504 * @throws ExpectationFailedException
48505 * @throws GeneratorNotSupportedException
48506 */
48507 final public static function assertNotCount(int $expectedCount, Countable|iterable $haystack, string $message = ''): void
48508 {
48509 if ($haystack instanceof Generator) {
48510 throw \PHPUnit\Framework\GeneratorNotSupportedException::fromParameterName('$haystack');
48511 }
48512 $constraint = new LogicalNot(new Count($expectedCount));
48513 static::assertThat($haystack, $constraint, $message);
48514 }
48515 /**
48516 * Asserts that two variables are equal.
48517 *
48518 * @throws ExpectationFailedException
48519 */
48520 final public static function assertEquals(mixed $expected, mixed $actual, string $message = ''): void
48521 {
48522 $constraint = new IsEqual($expected);
48523 static::assertThat($actual, $constraint, $message);
48524 }
48525 /**
48526 * Asserts that two variables are equal (canonicalizing).
48527 *
48528 * @throws ExpectationFailedException
48529 */
48530 final public static function assertEqualsCanonicalizing(mixed $expected, mixed $actual, string $message = ''): void
48531 {
48532 $constraint = new IsEqualCanonicalizing($expected);
48533 static::assertThat($actual, $constraint, $message);
48534 }
48535 /**
48536 * Asserts that two variables are equal (ignoring case).
48537 *
48538 * @throws ExpectationFailedException
48539 */
48540 final public static function assertEqualsIgnoringCase(mixed $expected, mixed $actual, string $message = ''): void
48541 {
48542 $constraint = new IsEqualIgnoringCase($expected);
48543 static::assertThat($actual, $constraint, $message);
48544 }
48545 /**
48546 * Asserts that two variables are equal (with delta).
48547 *
48548 * @throws ExpectationFailedException
48549 */
48550 final public static function assertEqualsWithDelta(mixed $expected, mixed $actual, float $delta, string $message = ''): void
48551 {
48552 $constraint = new IsEqualWithDelta($expected, $delta);
48553 static::assertThat($actual, $constraint, $message);
48554 }
48555 /**
48556 * Asserts that two variables are not equal.
48557 *
48558 * @throws ExpectationFailedException
48559 */
48560 final public static function assertNotEquals(mixed $expected, mixed $actual, string $message = ''): void
48561 {
48562 $constraint = new LogicalNot(new IsEqual($expected));
48563 static::assertThat($actual, $constraint, $message);
48564 }
48565 /**
48566 * Asserts that two variables are not equal (canonicalizing).
48567 *
48568 * @throws ExpectationFailedException
48569 */
48570 final public static function assertNotEqualsCanonicalizing(mixed $expected, mixed $actual, string $message = ''): void
48571 {
48572 $constraint = new LogicalNot(new IsEqualCanonicalizing($expected));
48573 static::assertThat($actual, $constraint, $message);
48574 }
48575 /**
48576 * Asserts that two variables are not equal (ignoring case).
48577 *
48578 * @throws ExpectationFailedException
48579 */
48580 final public static function assertNotEqualsIgnoringCase(mixed $expected, mixed $actual, string $message = ''): void
48581 {
48582 $constraint = new LogicalNot(new IsEqualIgnoringCase($expected));
48583 static::assertThat($actual, $constraint, $message);
48584 }
48585 /**
48586 * Asserts that two variables are not equal (with delta).
48587 *
48588 * @throws ExpectationFailedException
48589 */
48590 final public static function assertNotEqualsWithDelta(mixed $expected, mixed $actual, float $delta, string $message = ''): void
48591 {
48592 $constraint = new LogicalNot(new IsEqualWithDelta($expected, $delta));
48593 static::assertThat($actual, $constraint, $message);
48594 }
48595 /**
48596 * @throws ExpectationFailedException
48597 */
48598 final public static function assertObjectEquals(object $expected, object $actual, string $method = 'equals', string $message = ''): void
48599 {
48600 static::assertThat($actual, static::objectEquals($expected, $method), $message);
48601 }
48602 /**
48603 * Asserts that a variable is empty.
48604 *
48605 * @throws ExpectationFailedException
48606 * @throws GeneratorNotSupportedException
48607 *
48608 * @psalm-assert empty $actual
48609 */
48610 final public static function assertEmpty(mixed $actual, string $message = ''): void
48611 {
48612 if ($actual instanceof Generator) {
48613 throw \PHPUnit\Framework\GeneratorNotSupportedException::fromParameterName('$actual');
48614 }
48615 static::assertThat($actual, static::isEmpty(), $message);
48616 }
48617 /**
48618 * Asserts that a variable is not empty.
48619 *
48620 * @throws ExpectationFailedException
48621 * @throws GeneratorNotSupportedException
48622 *
48623 * @psalm-assert !empty $actual
48624 */
48625 final public static function assertNotEmpty(mixed $actual, string $message = ''): void
48626 {
48627 if ($actual instanceof Generator) {
48628 throw \PHPUnit\Framework\GeneratorNotSupportedException::fromParameterName('$actual');
48629 }
48630 static::assertThat($actual, static::logicalNot(static::isEmpty()), $message);
48631 }
48632 /**
48633 * Asserts that a value is greater than another value.
48634 *
48635 * @throws ExpectationFailedException
48636 */
48637 final public static function assertGreaterThan(mixed $expected, mixed $actual, string $message = ''): void
48638 {
48639 static::assertThat($actual, static::greaterThan($expected), $message);
48640 }
48641 /**
48642 * Asserts that a value is greater than or equal to another value.
48643 *
48644 * @throws ExpectationFailedException
48645 */
48646 final public static function assertGreaterThanOrEqual(mixed $expected, mixed $actual, string $message = ''): void
48647 {
48648 static::assertThat($actual, static::greaterThanOrEqual($expected), $message);
48649 }
48650 /**
48651 * Asserts that a value is smaller than another value.
48652 *
48653 * @throws ExpectationFailedException
48654 */
48655 final public static function assertLessThan(mixed $expected, mixed $actual, string $message = ''): void
48656 {
48657 static::assertThat($actual, static::lessThan($expected), $message);
48658 }
48659 /**
48660 * Asserts that a value is smaller than or equal to another value.
48661 *
48662 * @throws ExpectationFailedException
48663 */
48664 final public static function assertLessThanOrEqual(mixed $expected, mixed $actual, string $message = ''): void
48665 {
48666 static::assertThat($actual, static::lessThanOrEqual($expected), $message);
48667 }
48668 /**
48669 * Asserts that the contents of one file is equal to the contents of another
48670 * file.
48671 *
48672 * @throws ExpectationFailedException
48673 */
48674 final public static function assertFileEquals(string $expected, string $actual, string $message = ''): void
48675 {
48676 static::assertFileExists($expected, $message);
48677 static::assertFileExists($actual, $message);
48678 $constraint = new IsEqual(file_get_contents($expected));
48679 static::assertThat(file_get_contents($actual), $constraint, $message);
48680 }
48681 /**
48682 * Asserts that the contents of one file is equal to the contents of another
48683 * file (canonicalizing).
48684 *
48685 * @throws ExpectationFailedException
48686 */
48687 final public static function assertFileEqualsCanonicalizing(string $expected, string $actual, string $message = ''): void
48688 {
48689 static::assertFileExists($expected, $message);
48690 static::assertFileExists($actual, $message);
48691 $constraint = new IsEqualCanonicalizing(file_get_contents($expected));
48692 static::assertThat(file_get_contents($actual), $constraint, $message);
48693 }
48694 /**
48695 * Asserts that the contents of one file is equal to the contents of another
48696 * file (ignoring case).
48697 *
48698 * @throws ExpectationFailedException
48699 */
48700 final public static function assertFileEqualsIgnoringCase(string $expected, string $actual, string $message = ''): void
48701 {
48702 static::assertFileExists($expected, $message);
48703 static::assertFileExists($actual, $message);
48704 $constraint = new IsEqualIgnoringCase(file_get_contents($expected));
48705 static::assertThat(file_get_contents($actual), $constraint, $message);
48706 }
48707 /**
48708 * Asserts that the contents of one file is not equal to the contents of
48709 * another file.
48710 *
48711 * @throws ExpectationFailedException
48712 */
48713 final public static function assertFileNotEquals(string $expected, string $actual, string $message = ''): void
48714 {
48715 static::assertFileExists($expected, $message);
48716 static::assertFileExists($actual, $message);
48717 $constraint = new LogicalNot(new IsEqual(file_get_contents($expected)));
48718 static::assertThat(file_get_contents($actual), $constraint, $message);
48719 }
48720 /**
48721 * Asserts that the contents of one file is not equal to the contents of another
48722 * file (canonicalizing).
48723 *
48724 * @throws ExpectationFailedException
48725 */
48726 final public static function assertFileNotEqualsCanonicalizing(string $expected, string $actual, string $message = ''): void
48727 {
48728 static::assertFileExists($expected, $message);
48729 static::assertFileExists($actual, $message);
48730 $constraint = new LogicalNot(new IsEqualCanonicalizing(file_get_contents($expected)));
48731 static::assertThat(file_get_contents($actual), $constraint, $message);
48732 }
48733 /**
48734 * Asserts that the contents of one file is not equal to the contents of another
48735 * file (ignoring case).
48736 *
48737 * @throws ExpectationFailedException
48738 */
48739 final public static function assertFileNotEqualsIgnoringCase(string $expected, string $actual, string $message = ''): void
48740 {
48741 static::assertFileExists($expected, $message);
48742 static::assertFileExists($actual, $message);
48743 $constraint = new LogicalNot(new IsEqualIgnoringCase(file_get_contents($expected)));
48744 static::assertThat(file_get_contents($actual), $constraint, $message);
48745 }
48746 /**
48747 * Asserts that the contents of a string is equal
48748 * to the contents of a file.
48749 *
48750 * @throws ExpectationFailedException
48751 */
48752 final public static function assertStringEqualsFile(string $expectedFile, string $actualString, string $message = ''): void
48753 {
48754 static::assertFileExists($expectedFile, $message);
48755 $constraint = new IsEqual(file_get_contents($expectedFile));
48756 static::assertThat($actualString, $constraint, $message);
48757 }
48758 /**
48759 * Asserts that the contents of a string is equal
48760 * to the contents of a file (canonicalizing).
48761 *
48762 * @throws ExpectationFailedException
48763 */
48764 final public static function assertStringEqualsFileCanonicalizing(string $expectedFile, string $actualString, string $message = ''): void
48765 {
48766 static::assertFileExists($expectedFile, $message);
48767 $constraint = new IsEqualCanonicalizing(file_get_contents($expectedFile));
48768 static::assertThat($actualString, $constraint, $message);
48769 }
48770 /**
48771 * Asserts that the contents of a string is equal
48772 * to the contents of a file (ignoring case).
48773 *
48774 * @throws ExpectationFailedException
48775 */
48776 final public static function assertStringEqualsFileIgnoringCase(string $expectedFile, string $actualString, string $message = ''): void
48777 {
48778 static::assertFileExists($expectedFile, $message);
48779 $constraint = new IsEqualIgnoringCase(file_get_contents($expectedFile));
48780 static::assertThat($actualString, $constraint, $message);
48781 }
48782 /**
48783 * Asserts that the contents of a string is not equal
48784 * to the contents of a file.
48785 *
48786 * @throws ExpectationFailedException
48787 */
48788 final public static function assertStringNotEqualsFile(string $expectedFile, string $actualString, string $message = ''): void
48789 {
48790 static::assertFileExists($expectedFile, $message);
48791 $constraint = new LogicalNot(new IsEqual(file_get_contents($expectedFile)));
48792 static::assertThat($actualString, $constraint, $message);
48793 }
48794 /**
48795 * Asserts that the contents of a string is not equal
48796 * to the contents of a file (canonicalizing).
48797 *
48798 * @throws ExpectationFailedException
48799 */
48800 final public static function assertStringNotEqualsFileCanonicalizing(string $expectedFile, string $actualString, string $message = ''): void
48801 {
48802 static::assertFileExists($expectedFile, $message);
48803 $constraint = new LogicalNot(new IsEqualCanonicalizing(file_get_contents($expectedFile)));
48804 static::assertThat($actualString, $constraint, $message);
48805 }
48806 /**
48807 * Asserts that the contents of a string is not equal
48808 * to the contents of a file (ignoring case).
48809 *
48810 * @throws ExpectationFailedException
48811 */
48812 final public static function assertStringNotEqualsFileIgnoringCase(string $expectedFile, string $actualString, string $message = ''): void
48813 {
48814 static::assertFileExists($expectedFile, $message);
48815 $constraint = new LogicalNot(new IsEqualIgnoringCase(file_get_contents($expectedFile)));
48816 static::assertThat($actualString, $constraint, $message);
48817 }
48818 /**
48819 * Asserts that a file/dir is readable.
48820 *
48821 * @throws ExpectationFailedException
48822 */
48823 final public static function assertIsReadable(string $filename, string $message = ''): void
48824 {
48825 static::assertThat($filename, new IsReadable(), $message);
48826 }
48827 /**
48828 * Asserts that a file/dir exists and is not readable.
48829 *
48830 * @throws ExpectationFailedException
48831 */
48832 final public static function assertIsNotReadable(string $filename, string $message = ''): void
48833 {
48834 static::assertThat($filename, new LogicalNot(new IsReadable()), $message);
48835 }
48836 /**
48837 * Asserts that a file/dir exists and is writable.
48838 *
48839 * @throws ExpectationFailedException
48840 */
48841 final public static function assertIsWritable(string $filename, string $message = ''): void
48842 {
48843 static::assertThat($filename, new IsWritable(), $message);
48844 }
48845 /**
48846 * Asserts that a file/dir exists and is not writable.
48847 *
48848 * @throws ExpectationFailedException
48849 */
48850 final public static function assertIsNotWritable(string $filename, string $message = ''): void
48851 {
48852 static::assertThat($filename, new LogicalNot(new IsWritable()), $message);
48853 }
48854 /**
48855 * Asserts that a directory exists.
48856 *
48857 * @throws ExpectationFailedException
48858 */
48859 final public static function assertDirectoryExists(string $directory, string $message = ''): void
48860 {
48861 static::assertThat($directory, new DirectoryExists(), $message);
48862 }
48863 /**
48864 * Asserts that a directory does not exist.
48865 *
48866 * @throws ExpectationFailedException
48867 */
48868 final public static function assertDirectoryDoesNotExist(string $directory, string $message = ''): void
48869 {
48870 static::assertThat($directory, new LogicalNot(new DirectoryExists()), $message);
48871 }
48872 /**
48873 * Asserts that a directory exists and is readable.
48874 *
48875 * @throws ExpectationFailedException
48876 */
48877 final public static function assertDirectoryIsReadable(string $directory, string $message = ''): void
48878 {
48879 self::assertDirectoryExists($directory, $message);
48880 self::assertIsReadable($directory, $message);
48881 }
48882 /**
48883 * Asserts that a directory exists and is not readable.
48884 *
48885 * @throws ExpectationFailedException
48886 */
48887 final public static function assertDirectoryIsNotReadable(string $directory, string $message = ''): void
48888 {
48889 self::assertDirectoryExists($directory, $message);
48890 self::assertIsNotReadable($directory, $message);
48891 }
48892 /**
48893 * Asserts that a directory exists and is writable.
48894 *
48895 * @throws ExpectationFailedException
48896 */
48897 final public static function assertDirectoryIsWritable(string $directory, string $message = ''): void
48898 {
48899 self::assertDirectoryExists($directory, $message);
48900 self::assertIsWritable($directory, $message);
48901 }
48902 /**
48903 * Asserts that a directory exists and is not writable.
48904 *
48905 * @throws ExpectationFailedException
48906 */
48907 final public static function assertDirectoryIsNotWritable(string $directory, string $message = ''): void
48908 {
48909 self::assertDirectoryExists($directory, $message);
48910 self::assertIsNotWritable($directory, $message);
48911 }
48912 /**
48913 * Asserts that a file exists.
48914 *
48915 * @throws ExpectationFailedException
48916 */
48917 final public static function assertFileExists(string $filename, string $message = ''): void
48918 {
48919 static::assertThat($filename, new FileExists(), $message);
48920 }
48921 /**
48922 * Asserts that a file does not exist.
48923 *
48924 * @throws ExpectationFailedException
48925 */
48926 final public static function assertFileDoesNotExist(string $filename, string $message = ''): void
48927 {
48928 static::assertThat($filename, new LogicalNot(new FileExists()), $message);
48929 }
48930 /**
48931 * Asserts that a file exists and is readable.
48932 *
48933 * @throws ExpectationFailedException
48934 */
48935 final public static function assertFileIsReadable(string $file, string $message = ''): void
48936 {
48937 self::assertFileExists($file, $message);
48938 self::assertIsReadable($file, $message);
48939 }
48940 /**
48941 * Asserts that a file exists and is not readable.
48942 *
48943 * @throws ExpectationFailedException
48944 */
48945 final public static function assertFileIsNotReadable(string $file, string $message = ''): void
48946 {
48947 self::assertFileExists($file, $message);
48948 self::assertIsNotReadable($file, $message);
48949 }
48950 /**
48951 * Asserts that a file exists and is writable.
48952 *
48953 * @throws ExpectationFailedException
48954 */
48955 final public static function assertFileIsWritable(string $file, string $message = ''): void
48956 {
48957 self::assertFileExists($file, $message);
48958 self::assertIsWritable($file, $message);
48959 }
48960 /**
48961 * Asserts that a file exists and is not writable.
48962 *
48963 * @throws ExpectationFailedException
48964 */
48965 final public static function assertFileIsNotWritable(string $file, string $message = ''): void
48966 {
48967 self::assertFileExists($file, $message);
48968 self::assertIsNotWritable($file, $message);
48969 }
48970 /**
48971 * Asserts that a condition is true.
48972 *
48973 * @throws ExpectationFailedException
48974 *
48975 * @psalm-assert true $condition
48976 */
48977 final public static function assertTrue(mixed $condition, string $message = ''): void
48978 {
48979 static::assertThat($condition, static::isTrue(), $message);
48980 }
48981 /**
48982 * Asserts that a condition is not true.
48983 *
48984 * @throws ExpectationFailedException
48985 *
48986 * @psalm-assert !true $condition
48987 */
48988 final public static function assertNotTrue(mixed $condition, string $message = ''): void
48989 {
48990 static::assertThat($condition, static::logicalNot(static::isTrue()), $message);
48991 }
48992 /**
48993 * Asserts that a condition is false.
48994 *
48995 * @throws ExpectationFailedException
48996 *
48997 * @psalm-assert false $condition
48998 */
48999 final public static function assertFalse(mixed $condition, string $message = ''): void
49000 {
49001 static::assertThat($condition, static::isFalse(), $message);
49002 }
49003 /**
49004 * Asserts that a condition is not false.
49005 *
49006 * @throws ExpectationFailedException
49007 *
49008 * @psalm-assert !false $condition
49009 */
49010 final public static function assertNotFalse(mixed $condition, string $message = ''): void
49011 {
49012 static::assertThat($condition, static::logicalNot(static::isFalse()), $message);
49013 }
49014 /**
49015 * Asserts that a variable is null.
49016 *
49017 * @throws ExpectationFailedException
49018 *
49019 * @psalm-assert null $actual
49020 */
49021 final public static function assertNull(mixed $actual, string $message = ''): void
49022 {
49023 static::assertThat($actual, static::isNull(), $message);
49024 }
49025 /**
49026 * Asserts that a variable is not null.
49027 *
49028 * @throws ExpectationFailedException
49029 *
49030 * @psalm-assert !null $actual
49031 */
49032 final public static function assertNotNull(mixed $actual, string $message = ''): void
49033 {
49034 static::assertThat($actual, static::logicalNot(static::isNull()), $message);
49035 }
49036 /**
49037 * Asserts that a variable is finite.
49038 *
49039 * @throws ExpectationFailedException
49040 */
49041 final public static function assertFinite(mixed $actual, string $message = ''): void
49042 {
49043 static::assertThat($actual, static::isFinite(), $message);
49044 }
49045 /**
49046 * Asserts that a variable is infinite.
49047 *
49048 * @throws ExpectationFailedException
49049 */
49050 final public static function assertInfinite(mixed $actual, string $message = ''): void
49051 {
49052 static::assertThat($actual, static::isInfinite(), $message);
49053 }
49054 /**
49055 * Asserts that a variable is nan.
49056 *
49057 * @throws ExpectationFailedException
49058 */
49059 final public static function assertNan(mixed $actual, string $message = ''): void
49060 {
49061 static::assertThat($actual, static::isNan(), $message);
49062 }
49063 /**
49064 * Asserts that an object has a specified property.
49065 *
49066 * @throws ExpectationFailedException
49067 */
49068 final public static function assertObjectHasProperty(string $propertyName, object $object, string $message = ''): void
49069 {
49070 static::assertThat($object, new ObjectHasProperty($propertyName), $message);
49071 }
49072 /**
49073 * Asserts that an object does not have a specified property.
49074 *
49075 * @throws ExpectationFailedException
49076 */
49077 final public static function assertObjectNotHasProperty(string $propertyName, object $object, string $message = ''): void
49078 {
49079 static::assertThat($object, new LogicalNot(new ObjectHasProperty($propertyName)), $message);
49080 }
49081 /**
49082 * Asserts that two variables have the same type and value.
49083 * Used on objects, it asserts that two variables reference
49084 * the same object.
49085 *
49086 * @psalm-template ExpectedType
49087 *
49088 * @psalm-param ExpectedType $expected
49089 *
49090 * @throws ExpectationFailedException
49091 *
49092 * @psalm-assert =ExpectedType $actual
49093 */
49094 final public static function assertSame(mixed $expected, mixed $actual, string $message = ''): void
49095 {
49096 static::assertThat($actual, new IsIdentical($expected), $message);
49097 }
49098 /**
49099 * Asserts that two variables do not have the same type and value.
49100 * Used on objects, it asserts that two variables do not reference
49101 * the same object.
49102 *
49103 * @throws ExpectationFailedException
49104 */
49105 final public static function assertNotSame(mixed $expected, mixed $actual, string $message = ''): void
49106 {
49107 if (is_bool($expected) && is_bool($actual)) {
49108 static::assertNotEquals($expected, $actual, $message);
49109 }
49110 static::assertThat($actual, new LogicalNot(new IsIdentical($expected)), $message);
49111 }
49112 /**
49113 * Asserts that a variable is of a given type.
49114 *
49115 * @psalm-template ExpectedType of object
49116 *
49117 * @psalm-param class-string<ExpectedType> $expected
49118 *
49119 * @throws Exception
49120 * @throws ExpectationFailedException
49121 * @throws UnknownClassOrInterfaceException
49122 *
49123 * @psalm-assert =ExpectedType $actual
49124 */
49125 final public static function assertInstanceOf(string $expected, mixed $actual, string $message = ''): void
49126 {
49127 if (!class_exists($expected) && !interface_exists($expected)) {
49128 throw new \PHPUnit\Framework\UnknownClassOrInterfaceException($expected);
49129 }
49130 static::assertThat($actual, new IsInstanceOf($expected), $message);
49131 }
49132 /**
49133 * Asserts that a variable is not of a given type.
49134 *
49135 * @psalm-template ExpectedType of object
49136 *
49137 * @psalm-param class-string<ExpectedType> $expected
49138 *
49139 * @throws Exception
49140 * @throws ExpectationFailedException
49141 *
49142 * @psalm-assert !ExpectedType $actual
49143 */
49144 final public static function assertNotInstanceOf(string $expected, mixed $actual, string $message = ''): void
49145 {
49146 if (!class_exists($expected) && !interface_exists($expected)) {
49147 throw new \PHPUnit\Framework\UnknownClassOrInterfaceException($expected);
49148 }
49149 static::assertThat($actual, new LogicalNot(new IsInstanceOf($expected)), $message);
49150 }
49151 /**
49152 * Asserts that a variable is of type array.
49153 *
49154 * @throws Exception
49155 * @throws ExpectationFailedException
49156 *
49157 * @psalm-assert array $actual
49158 */
49159 final public static function assertIsArray(mixed $actual, string $message = ''): void
49160 {
49161 static::assertThat($actual, new IsType(IsType::TYPE_ARRAY), $message);
49162 }
49163 /**
49164 * Asserts that a variable is of type bool.
49165 *
49166 * @throws Exception
49167 * @throws ExpectationFailedException
49168 *
49169 * @psalm-assert bool $actual
49170 */
49171 final public static function assertIsBool(mixed $actual, string $message = ''): void
49172 {
49173 static::assertThat($actual, new IsType(IsType::TYPE_BOOL), $message);
49174 }
49175 /**
49176 * Asserts that a variable is of type float.
49177 *
49178 * @throws Exception
49179 * @throws ExpectationFailedException
49180 *
49181 * @psalm-assert float $actual
49182 */
49183 final public static function assertIsFloat(mixed $actual, string $message = ''): void
49184 {
49185 static::assertThat($actual, new IsType(IsType::TYPE_FLOAT), $message);
49186 }
49187 /**
49188 * Asserts that a variable is of type int.
49189 *
49190 * @throws Exception
49191 * @throws ExpectationFailedException
49192 *
49193 * @psalm-assert int $actual
49194 */
49195 final public static function assertIsInt(mixed $actual, string $message = ''): void
49196 {
49197 static::assertThat($actual, new IsType(IsType::TYPE_INT), $message);
49198 }
49199 /**
49200 * Asserts that a variable is of type numeric.
49201 *
49202 * @throws Exception
49203 * @throws ExpectationFailedException
49204 *
49205 * @psalm-assert numeric $actual
49206 */
49207 final public static function assertIsNumeric(mixed $actual, string $message = ''): void
49208 {
49209 static::assertThat($actual, new IsType(IsType::TYPE_NUMERIC), $message);
49210 }
49211 /**
49212 * Asserts that a variable is of type object.
49213 *
49214 * @throws Exception
49215 * @throws ExpectationFailedException
49216 *
49217 * @psalm-assert object $actual
49218 */
49219 final public static function assertIsObject(mixed $actual, string $message = ''): void
49220 {
49221 static::assertThat($actual, new IsType(IsType::TYPE_OBJECT), $message);
49222 }
49223 /**
49224 * Asserts that a variable is of type resource.
49225 *
49226 * @throws Exception
49227 * @throws ExpectationFailedException
49228 *
49229 * @psalm-assert resource $actual
49230 */
49231 final public static function assertIsResource(mixed $actual, string $message = ''): void
49232 {
49233 static::assertThat($actual, new IsType(IsType::TYPE_RESOURCE), $message);
49234 }
49235 /**
49236 * Asserts that a variable is of type resource and is closed.
49237 *
49238 * @throws Exception
49239 * @throws ExpectationFailedException
49240 *
49241 * @psalm-assert resource $actual
49242 */
49243 final public static function assertIsClosedResource(mixed $actual, string $message = ''): void
49244 {
49245 static::assertThat($actual, new IsType(IsType::TYPE_CLOSED_RESOURCE), $message);
49246 }
49247 /**
49248 * Asserts that a variable is of type string.
49249 *
49250 * @throws Exception
49251 * @throws ExpectationFailedException
49252 *
49253 * @psalm-assert string $actual
49254 */
49255 final public static function assertIsString(mixed $actual, string $message = ''): void
49256 {
49257 static::assertThat($actual, new IsType(IsType::TYPE_STRING), $message);
49258 }
49259 /**
49260 * Asserts that a variable is of type scalar.
49261 *
49262 * @throws Exception
49263 * @throws ExpectationFailedException
49264 *
49265 * @psalm-assert scalar $actual
49266 */
49267 final public static function assertIsScalar(mixed $actual, string $message = ''): void
49268 {
49269 static::assertThat($actual, new IsType(IsType::TYPE_SCALAR), $message);
49270 }
49271 /**
49272 * Asserts that a variable is of type callable.
49273 *
49274 * @throws Exception
49275 * @throws ExpectationFailedException
49276 *
49277 * @psalm-assert callable $actual
49278 */
49279 final public static function assertIsCallable(mixed $actual, string $message = ''): void
49280 {
49281 static::assertThat($actual, new IsType(IsType::TYPE_CALLABLE), $message);
49282 }
49283 /**
49284 * Asserts that a variable is of type iterable.
49285 *
49286 * @throws Exception
49287 * @throws ExpectationFailedException
49288 *
49289 * @psalm-assert iterable $actual
49290 */
49291 final public static function assertIsIterable(mixed $actual, string $message = ''): void
49292 {
49293 static::assertThat($actual, new IsType(IsType::TYPE_ITERABLE), $message);
49294 }
49295 /**
49296 * Asserts that a variable is not of type array.
49297 *
49298 * @throws Exception
49299 * @throws ExpectationFailedException
49300 *
49301 * @psalm-assert !array $actual
49302 */
49303 final public static function assertIsNotArray(mixed $actual, string $message = ''): void
49304 {
49305 static::assertThat($actual, new LogicalNot(new IsType(IsType::TYPE_ARRAY)), $message);
49306 }
49307 /**
49308 * Asserts that a variable is not of type bool.
49309 *
49310 * @throws Exception
49311 * @throws ExpectationFailedException
49312 *
49313 * @psalm-assert !bool $actual
49314 */
49315 final public static function assertIsNotBool(mixed $actual, string $message = ''): void
49316 {
49317 static::assertThat($actual, new LogicalNot(new IsType(IsType::TYPE_BOOL)), $message);
49318 }
49319 /**
49320 * Asserts that a variable is not of type float.
49321 *
49322 * @throws Exception
49323 * @throws ExpectationFailedException
49324 *
49325 * @psalm-assert !float $actual
49326 */
49327 final public static function assertIsNotFloat(mixed $actual, string $message = ''): void
49328 {
49329 static::assertThat($actual, new LogicalNot(new IsType(IsType::TYPE_FLOAT)), $message);
49330 }
49331 /**
49332 * Asserts that a variable is not of type int.
49333 *
49334 * @throws Exception
49335 * @throws ExpectationFailedException
49336 *
49337 * @psalm-assert !int $actual
49338 */
49339 final public static function assertIsNotInt(mixed $actual, string $message = ''): void
49340 {
49341 static::assertThat($actual, new LogicalNot(new IsType(IsType::TYPE_INT)), $message);
49342 }
49343 /**
49344 * Asserts that a variable is not of type numeric.
49345 *
49346 * @throws Exception
49347 * @throws ExpectationFailedException
49348 *
49349 * @psalm-assert !numeric $actual
49350 */
49351 final public static function assertIsNotNumeric(mixed $actual, string $message = ''): void
49352 {
49353 static::assertThat($actual, new LogicalNot(new IsType(IsType::TYPE_NUMERIC)), $message);
49354 }
49355 /**
49356 * Asserts that a variable is not of type object.
49357 *
49358 * @throws Exception
49359 * @throws ExpectationFailedException
49360 *
49361 * @psalm-assert !object $actual
49362 */
49363 final public static function assertIsNotObject(mixed $actual, string $message = ''): void
49364 {
49365 static::assertThat($actual, new LogicalNot(new IsType(IsType::TYPE_OBJECT)), $message);
49366 }
49367 /**
49368 * Asserts that a variable is not of type resource.
49369 *
49370 * @throws Exception
49371 * @throws ExpectationFailedException
49372 *
49373 * @psalm-assert !resource $actual
49374 */
49375 final public static function assertIsNotResource(mixed $actual, string $message = ''): void
49376 {
49377 static::assertThat($actual, new LogicalNot(new IsType(IsType::TYPE_RESOURCE)), $message);
49378 }
49379 /**
49380 * Asserts that a variable is not of type resource.
49381 *
49382 * @throws Exception
49383 * @throws ExpectationFailedException
49384 *
49385 * @psalm-assert !resource $actual
49386 */
49387 final public static function assertIsNotClosedResource(mixed $actual, string $message = ''): void
49388 {
49389 static::assertThat($actual, new LogicalNot(new IsType(IsType::TYPE_CLOSED_RESOURCE)), $message);
49390 }
49391 /**
49392 * Asserts that a variable is not of type string.
49393 *
49394 * @throws Exception
49395 * @throws ExpectationFailedException
49396 *
49397 * @psalm-assert !string $actual
49398 */
49399 final public static function assertIsNotString(mixed $actual, string $message = ''): void
49400 {
49401 static::assertThat($actual, new LogicalNot(new IsType(IsType::TYPE_STRING)), $message);
49402 }
49403 /**
49404 * Asserts that a variable is not of type scalar.
49405 *
49406 * @throws Exception
49407 * @throws ExpectationFailedException
49408 *
49409 * @psalm-assert !scalar $actual
49410 */
49411 final public static function assertIsNotScalar(mixed $actual, string $message = ''): void
49412 {
49413 static::assertThat($actual, new LogicalNot(new IsType(IsType::TYPE_SCALAR)), $message);
49414 }
49415 /**
49416 * Asserts that a variable is not of type callable.
49417 *
49418 * @throws Exception
49419 * @throws ExpectationFailedException
49420 *
49421 * @psalm-assert !callable $actual
49422 */
49423 final public static function assertIsNotCallable(mixed $actual, string $message = ''): void
49424 {
49425 static::assertThat($actual, new LogicalNot(new IsType(IsType::TYPE_CALLABLE)), $message);
49426 }
49427 /**
49428 * Asserts that a variable is not of type iterable.
49429 *
49430 * @throws Exception
49431 * @throws ExpectationFailedException
49432 *
49433 * @psalm-assert !iterable $actual
49434 */
49435 final public static function assertIsNotIterable(mixed $actual, string $message = ''): void
49436 {
49437 static::assertThat($actual, new LogicalNot(new IsType(IsType::TYPE_ITERABLE)), $message);
49438 }
49439 /**
49440 * Asserts that a string matches a given regular expression.
49441 *
49442 * @throws ExpectationFailedException
49443 */
49444 final public static function assertMatchesRegularExpression(string $pattern, string $string, string $message = ''): void
49445 {
49446 static::assertThat($string, new RegularExpression($pattern), $message);
49447 }
49448 /**
49449 * Asserts that a string does not match a given regular expression.
49450 *
49451 * @throws ExpectationFailedException
49452 */
49453 final public static function assertDoesNotMatchRegularExpression(string $pattern, string $string, string $message = ''): void
49454 {
49455 static::assertThat($string, new LogicalNot(new RegularExpression($pattern)), $message);
49456 }
49457 /**
49458 * Assert that the size of two arrays (or `Countable` or `Traversable` objects)
49459 * is the same.
49460 *
49461 * @throws Exception
49462 * @throws ExpectationFailedException
49463 * @throws GeneratorNotSupportedException
49464 */
49465 final public static function assertSameSize(Countable|iterable $expected, Countable|iterable $actual, string $message = ''): void
49466 {
49467 if ($expected instanceof Generator) {
49468 throw \PHPUnit\Framework\GeneratorNotSupportedException::fromParameterName('$expected');
49469 }
49470 if ($actual instanceof Generator) {
49471 throw \PHPUnit\Framework\GeneratorNotSupportedException::fromParameterName('$actual');
49472 }
49473 static::assertThat($actual, new SameSize($expected), $message);
49474 }
49475 /**
49476 * Assert that the size of two arrays (or `Countable` or `Traversable` objects)
49477 * is not the same.
49478 *
49479 * @throws Exception
49480 * @throws ExpectationFailedException
49481 * @throws GeneratorNotSupportedException
49482 */
49483 final public static function assertNotSameSize(Countable|iterable $expected, Countable|iterable $actual, string $message = ''): void
49484 {
49485 if ($expected instanceof Generator) {
49486 throw \PHPUnit\Framework\GeneratorNotSupportedException::fromParameterName('$expected');
49487 }
49488 if ($actual instanceof Generator) {
49489 throw \PHPUnit\Framework\GeneratorNotSupportedException::fromParameterName('$actual');
49490 }
49491 static::assertThat($actual, new LogicalNot(new SameSize($expected)), $message);
49492 }
49493 /**
49494 * @throws ExpectationFailedException
49495 */
49496 final public static function assertStringContainsStringIgnoringLineEndings(string $needle, string $haystack, string $message = ''): void
49497 {
49498 static::assertThat($haystack, new StringContains($needle, \false, \true), $message);
49499 }
49500 /**
49501 * Asserts that two strings are equal except for line endings.
49502 *
49503 * @throws ExpectationFailedException
49504 */
49505 final public static function assertStringEqualsStringIgnoringLineEndings(string $expected, string $actual, string $message = ''): void
49506 {
49507 static::assertThat($actual, new StringEqualsStringIgnoringLineEndings($expected), $message);
49508 }
49509 /**
49510 * Asserts that a string matches a given format string.
49511 *
49512 * @throws ExpectationFailedException
49513 */
49514 final public static function assertFileMatchesFormat(string $format, string $actualFile, string $message = ''): void
49515 {
49516 static::assertFileExists($actualFile, $message);
49517 static::assertThat(file_get_contents($actualFile), new StringMatchesFormatDescription($format), $message);
49518 }
49519 /**
49520 * Asserts that a string matches a given format string.
49521 *
49522 * @throws ExpectationFailedException
49523 */
49524 final public static function assertFileMatchesFormatFile(string $formatFile, string $actualFile, string $message = ''): void
49525 {
49526 static::assertFileExists($formatFile, $message);
49527 static::assertFileExists($actualFile, $message);
49528 static::assertThat(file_get_contents($actualFile), new StringMatchesFormatDescription(file_get_contents($formatFile)), $message);
49529 }
49530 /**
49531 * Asserts that a string matches a given format string.
49532 *
49533 * @throws ExpectationFailedException
49534 */
49535 final public static function assertStringMatchesFormat(string $format, string $string, string $message = ''): void
49536 {
49537 static::assertThat($string, new StringMatchesFormatDescription($format), $message);
49538 }
49539 /**
49540 * Asserts that a string does not match a given format string.
49541 *
49542 * @throws ExpectationFailedException
49543 *
49544 * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5472
49545 */
49546 final public static function assertStringNotMatchesFormat(string $format, string $string, string $message = ''): void
49547 {
49548 static::assertThat($string, new LogicalNot(new StringMatchesFormatDescription($format)), $message);
49549 }
49550 /**
49551 * Asserts that a string matches a given format file.
49552 *
49553 * @throws ExpectationFailedException
49554 */
49555 final public static function assertStringMatchesFormatFile(string $formatFile, string $string, string $message = ''): void
49556 {
49557 static::assertFileExists($formatFile, $message);
49558 static::assertThat($string, new StringMatchesFormatDescription(file_get_contents($formatFile)), $message);
49559 }
49560 /**
49561 * Asserts that a string does not match a given format string.
49562 *
49563 * @throws ExpectationFailedException
49564 *
49565 * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5472
49566 */
49567 final public static function assertStringNotMatchesFormatFile(string $formatFile, string $string, string $message = ''): void
49568 {
49569 static::assertFileExists($formatFile, $message);
49570 static::assertThat($string, new LogicalNot(new StringMatchesFormatDescription(file_get_contents($formatFile))), $message);
49571 }
49572 /**
49573 * Asserts that a string starts with a given prefix.
49574 *
49575 * @psalm-param non-empty-string $prefix
49576 *
49577 * @throws ExpectationFailedException
49578 * @throws InvalidArgumentException
49579 */
49580 final public static function assertStringStartsWith(string $prefix, string $string, string $message = ''): void
49581 {
49582 static::assertThat($string, new StringStartsWith($prefix), $message);
49583 }
49584 /**
49585 * Asserts that a string starts not with a given prefix.
49586 *
49587 * @psalm-param non-empty-string $prefix
49588 *
49589 * @throws ExpectationFailedException
49590 * @throws InvalidArgumentException
49591 */
49592 final public static function assertStringStartsNotWith(string $prefix, string $string, string $message = ''): void
49593 {
49594 static::assertThat($string, new LogicalNot(new StringStartsWith($prefix)), $message);
49595 }
49596 /**
49597 * @throws ExpectationFailedException
49598 */
49599 final public static function assertStringContainsString(string $needle, string $haystack, string $message = ''): void
49600 {
49601 $constraint = new StringContains($needle);
49602 static::assertThat($haystack, $constraint, $message);
49603 }
49604 /**
49605 * @throws ExpectationFailedException
49606 */
49607 final public static function assertStringContainsStringIgnoringCase(string $needle, string $haystack, string $message = ''): void
49608 {
49609 $constraint = new StringContains($needle, \true);
49610 static::assertThat($haystack, $constraint, $message);
49611 }
49612 /**
49613 * @throws ExpectationFailedException
49614 */
49615 final public static function assertStringNotContainsString(string $needle, string $haystack, string $message = ''): void
49616 {
49617 $constraint = new LogicalNot(new StringContains($needle));
49618 static::assertThat($haystack, $constraint, $message);
49619 }
49620 /**
49621 * @throws ExpectationFailedException
49622 */
49623 final public static function assertStringNotContainsStringIgnoringCase(string $needle, string $haystack, string $message = ''): void
49624 {
49625 $constraint = new LogicalNot(new StringContains($needle, \true));
49626 static::assertThat($haystack, $constraint, $message);
49627 }
49628 /**
49629 * Asserts that a string ends with a given suffix.
49630 *
49631 * @psalm-param non-empty-string $suffix
49632 *
49633 * @throws ExpectationFailedException
49634 * @throws InvalidArgumentException
49635 */
49636 final public static function assertStringEndsWith(string $suffix, string $string, string $message = ''): void
49637 {
49638 static::assertThat($string, new StringEndsWith($suffix), $message);
49639 }
49640 /**
49641 * Asserts that a string ends not with a given suffix.
49642 *
49643 * @psalm-param non-empty-string $suffix
49644 *
49645 * @throws ExpectationFailedException
49646 * @throws InvalidArgumentException
49647 */
49648 final public static function assertStringEndsNotWith(string $suffix, string $string, string $message = ''): void
49649 {
49650 static::assertThat($string, new LogicalNot(new StringEndsWith($suffix)), $message);
49651 }
49652 /**
49653 * Asserts that two XML files are equal.
49654 *
49655 * @throws Exception
49656 * @throws ExpectationFailedException
49657 * @throws XmlException
49658 */
49659 final public static function assertXmlFileEqualsXmlFile(string $expectedFile, string $actualFile, string $message = ''): void
49660 {
49661 $expected = (new XmlLoader())->loadFile($expectedFile);
49662 $actual = (new XmlLoader())->loadFile($actualFile);
49663 static::assertEquals($expected, $actual, $message);
49664 }
49665 /**
49666 * Asserts that two XML files are not equal.
49667 *
49668 * @throws \PHPUnit\Util\Exception
49669 * @throws ExpectationFailedException
49670 */
49671 final public static function assertXmlFileNotEqualsXmlFile(string $expectedFile, string $actualFile, string $message = ''): void
49672 {
49673 $expected = (new XmlLoader())->loadFile($expectedFile);
49674 $actual = (new XmlLoader())->loadFile($actualFile);
49675 static::assertNotEquals($expected, $actual, $message);
49676 }
49677 /**
49678 * Asserts that two XML documents are equal.
49679 *
49680 * @throws ExpectationFailedException
49681 * @throws XmlException
49682 */
49683 final public static function assertXmlStringEqualsXmlFile(string $expectedFile, string $actualXml, string $message = ''): void
49684 {
49685 $expected = (new XmlLoader())->loadFile($expectedFile);
49686 $actual = (new XmlLoader())->load($actualXml);
49687 static::assertEquals($expected, $actual, $message);
49688 }
49689 /**
49690 * Asserts that two XML documents are not equal.
49691 *
49692 * @throws ExpectationFailedException
49693 * @throws XmlException
49694 */
49695 final public static function assertXmlStringNotEqualsXmlFile(string $expectedFile, string $actualXml, string $message = ''): void
49696 {
49697 $expected = (new XmlLoader())->loadFile($expectedFile);
49698 $actual = (new XmlLoader())->load($actualXml);
49699 static::assertNotEquals($expected, $actual, $message);
49700 }
49701 /**
49702 * Asserts that two XML documents are equal.
49703 *
49704 * @throws ExpectationFailedException
49705 * @throws XmlException
49706 */
49707 final public static function assertXmlStringEqualsXmlString(string $expectedXml, string $actualXml, string $message = ''): void
49708 {
49709 $expected = (new XmlLoader())->load($expectedXml);
49710 $actual = (new XmlLoader())->load($actualXml);
49711 static::assertEquals($expected, $actual, $message);
49712 }
49713 /**
49714 * Asserts that two XML documents are not equal.
49715 *
49716 * @throws ExpectationFailedException
49717 * @throws XmlException
49718 */
49719 final public static function assertXmlStringNotEqualsXmlString(string $expectedXml, string $actualXml, string $message = ''): void
49720 {
49721 $expected = (new XmlLoader())->load($expectedXml);
49722 $actual = (new XmlLoader())->load($actualXml);
49723 static::assertNotEquals($expected, $actual, $message);
49724 }
49725 /**
49726 * Evaluates a PHPUnit\Framework\Constraint matcher object.
49727 *
49728 * @throws ExpectationFailedException
49729 */
49730 final public static function assertThat(mixed $value, Constraint $constraint, string $message = ''): void
49731 {
49732 self::$count += count($constraint);
49733 $hasFailed = \true;
49734 try {
49735 $constraint->evaluate($value, $message);
49736 $hasFailed = \false;
49737 } finally {
49738 if ($hasFailed) {
49739 Event\Facade::emitter()->testAssertionFailed($value, $constraint, $message);
49740 } else {
49741 Event\Facade::emitter()->testAssertionSucceeded($value, $constraint, $message);
49742 }
49743 }
49744 }
49745 /**
49746 * Asserts that a string is a valid JSON string.
49747 *
49748 * @throws ExpectationFailedException
49749 */
49750 final public static function assertJson(string $actual, string $message = ''): void
49751 {
49752 static::assertThat($actual, static::isJson(), $message);
49753 }
49754 /**
49755 * Asserts that two given JSON encoded objects or arrays are equal.
49756 *
49757 * @throws ExpectationFailedException
49758 */
49759 final public static function assertJsonStringEqualsJsonString(string $expectedJson, string $actualJson, string $message = ''): void
49760 {
49761 static::assertJson($expectedJson, $message);
49762 static::assertJson($actualJson, $message);
49763 static::assertThat($actualJson, new JsonMatches($expectedJson), $message);
49764 }
49765 /**
49766 * Asserts that two given JSON encoded objects or arrays are not equal.
49767 *
49768 * @throws ExpectationFailedException
49769 */
49770 final public static function assertJsonStringNotEqualsJsonString(string $expectedJson, string $actualJson, string $message = ''): void
49771 {
49772 static::assertJson($expectedJson, $message);
49773 static::assertJson($actualJson, $message);
49774 static::assertThat($actualJson, new LogicalNot(new JsonMatches($expectedJson)), $message);
49775 }
49776 /**
49777 * Asserts that the generated JSON encoded object and the content of the given file are equal.
49778 *
49779 * @throws ExpectationFailedException
49780 */
49781 final public static function assertJsonStringEqualsJsonFile(string $expectedFile, string $actualJson, string $message = ''): void
49782 {
49783 static::assertFileExists($expectedFile, $message);
49784 $expectedJson = file_get_contents($expectedFile);
49785 static::assertJson($expectedJson, $message);
49786 static::assertJson($actualJson, $message);
49787 static::assertThat($actualJson, new JsonMatches($expectedJson), $message);
49788 }
49789 /**
49790 * Asserts that the generated JSON encoded object and the content of the given file are not equal.
49791 *
49792 * @throws ExpectationFailedException
49793 */
49794 final public static function assertJsonStringNotEqualsJsonFile(string $expectedFile, string $actualJson, string $message = ''): void
49795 {
49796 static::assertFileExists($expectedFile, $message);
49797 $expectedJson = file_get_contents($expectedFile);
49798 static::assertJson($expectedJson, $message);
49799 static::assertJson($actualJson, $message);
49800 static::assertThat($actualJson, new LogicalNot(new JsonMatches($expectedJson)), $message);
49801 }
49802 /**
49803 * Asserts that two JSON files are equal.
49804 *
49805 * @throws ExpectationFailedException
49806 */
49807 final public static function assertJsonFileEqualsJsonFile(string $expectedFile, string $actualFile, string $message = ''): void
49808 {
49809 static::assertFileExists($expectedFile, $message);
49810 static::assertFileExists($actualFile, $message);
49811 $actualJson = file_get_contents($actualFile);
49812 $expectedJson = file_get_contents($expectedFile);
49813 static::assertJson($expectedJson, $message);
49814 static::assertJson($actualJson, $message);
49815 $constraintExpected = new JsonMatches($expectedJson);
49816 $constraintActual = new JsonMatches($actualJson);
49817 static::assertThat($expectedJson, $constraintActual, $message);
49818 static::assertThat($actualJson, $constraintExpected, $message);
49819 }
49820 /**
49821 * Asserts that two JSON files are not equal.
49822 *
49823 * @throws ExpectationFailedException
49824 */
49825 final public static function assertJsonFileNotEqualsJsonFile(string $expectedFile, string $actualFile, string $message = ''): void
49826 {
49827 static::assertFileExists($expectedFile, $message);
49828 static::assertFileExists($actualFile, $message);
49829 $actualJson = file_get_contents($actualFile);
49830 $expectedJson = file_get_contents($expectedFile);
49831 static::assertJson($expectedJson, $message);
49832 static::assertJson($actualJson, $message);
49833 $constraintExpected = new JsonMatches($expectedJson);
49834 $constraintActual = new JsonMatches($actualJson);
49835 static::assertThat($expectedJson, new LogicalNot($constraintActual), $message);
49836 static::assertThat($actualJson, new LogicalNot($constraintExpected), $message);
49837 }
49838 /**
49839 * @throws Exception
49840 */
49841 final public static function logicalAnd(mixed ...$constraints): LogicalAnd
49842 {
49843 return LogicalAnd::fromConstraints(...$constraints);
49844 }
49845 final public static function logicalOr(mixed ...$constraints): LogicalOr
49846 {
49847 return LogicalOr::fromConstraints(...$constraints);
49848 }
49849 final public static function logicalNot(Constraint $constraint): LogicalNot
49850 {
49851 return new LogicalNot($constraint);
49852 }
49853 final public static function logicalXor(mixed ...$constraints): LogicalXor
49854 {
49855 return LogicalXor::fromConstraints(...$constraints);
49856 }
49857 final public static function anything(): IsAnything
49858 {
49859 return new IsAnything();
49860 }
49861 final public static function isTrue(): IsTrue
49862 {
49863 return new IsTrue();
49864 }
49865 /**
49866 * @psalm-template CallbackInput of mixed
49867 *
49868 * @psalm-param callable(CallbackInput $callback): bool $callback
49869 *
49870 * @psalm-return Callback<CallbackInput>
49871 */
49872 final public static function callback(callable $callback): Callback
49873 {
49874 return new Callback($callback);
49875 }
49876 final public static function isFalse(): IsFalse
49877 {
49878 return new IsFalse();
49879 }
49880 final public static function isJson(): IsJson
49881 {
49882 return new IsJson();
49883 }
49884 final public static function isNull(): IsNull
49885 {
49886 return new IsNull();
49887 }
49888 final public static function isFinite(): IsFinite
49889 {
49890 return new IsFinite();
49891 }
49892 final public static function isInfinite(): IsInfinite
49893 {
49894 return new IsInfinite();
49895 }
49896 final public static function isNan(): IsNan
49897 {
49898 return new IsNan();
49899 }
49900 final public static function containsEqual(mixed $value): TraversableContainsEqual
49901 {
49902 return new TraversableContainsEqual($value);
49903 }
49904 final public static function containsIdentical(mixed $value): TraversableContainsIdentical
49905 {
49906 return new TraversableContainsIdentical($value);
49907 }
49908 /**
49909 * @throws Exception
49910 */
49911 final public static function containsOnly(string $type): TraversableContainsOnly
49912 {
49913 return new TraversableContainsOnly($type);
49914 }
49915 /**
49916 * @throws Exception
49917 */
49918 final public static function containsOnlyInstancesOf(string $className): TraversableContainsOnly
49919 {
49920 return new TraversableContainsOnly($className, \false);
49921 }
49922 final public static function arrayHasKey(mixed $key): ArrayHasKey
49923 {
49924 return new ArrayHasKey($key);
49925 }
49926 final public static function isList(): IsList
49927 {
49928 return new IsList();
49929 }
49930 final public static function equalTo(mixed $value): IsEqual
49931 {
49932 return new IsEqual($value, 0.0, \false, \false);
49933 }
49934 final public static function equalToCanonicalizing(mixed $value): IsEqualCanonicalizing
49935 {
49936 return new IsEqualCanonicalizing($value);
49937 }
49938 final public static function equalToIgnoringCase(mixed $value): IsEqualIgnoringCase
49939 {
49940 return new IsEqualIgnoringCase($value);
49941 }
49942 final public static function equalToWithDelta(mixed $value, float $delta): IsEqualWithDelta
49943 {
49944 return new IsEqualWithDelta($value, $delta);
49945 }
49946 final public static function isEmpty(): IsEmpty
49947 {
49948 return new IsEmpty();
49949 }
49950 final public static function isWritable(): IsWritable
49951 {
49952 return new IsWritable();
49953 }
49954 final public static function isReadable(): IsReadable
49955 {
49956 return new IsReadable();
49957 }
49958 final public static function directoryExists(): DirectoryExists
49959 {
49960 return new DirectoryExists();
49961 }
49962 final public static function fileExists(): FileExists
49963 {
49964 return new FileExists();
49965 }
49966 final public static function greaterThan(mixed $value): GreaterThan
49967 {
49968 return new GreaterThan($value);
49969 }
49970 final public static function greaterThanOrEqual(mixed $value): LogicalOr
49971 {
49972 return static::logicalOr(new IsEqual($value), new GreaterThan($value));
49973 }
49974 final public static function identicalTo(mixed $value): IsIdentical
49975 {
49976 return new IsIdentical($value);
49977 }
49978 /**
49979 * @throws UnknownClassOrInterfaceException
49980 */
49981 final public static function isInstanceOf(string $className): IsInstanceOf
49982 {
49983 return new IsInstanceOf($className);
49984 }
49985 /**
49986 * @psalm-param 'array'|'boolean'|'bool'|'double'|'float'|'integer'|'int'|'null'|'numeric'|'object'|'real'|'resource'|'resource (closed)'|'string'|'scalar'|'callable'|'iterable' $type
49987 *
49988 * @throws Exception
49989 */
49990 final public static function isType(string $type): IsType
49991 {
49992 return new IsType($type);
49993 }
49994 final public static function lessThan(mixed $value): LessThan
49995 {
49996 return new LessThan($value);
49997 }
49998 final public static function lessThanOrEqual(mixed $value): LogicalOr
49999 {
50000 return static::logicalOr(new IsEqual($value), new LessThan($value));
50001 }
50002 final public static function matchesRegularExpression(string $pattern): RegularExpression
50003 {
50004 return new RegularExpression($pattern);
50005 }
50006 final public static function matches(string $string): StringMatchesFormatDescription
50007 {
50008 return new StringMatchesFormatDescription($string);
50009 }
50010 /**
50011 * @psalm-param non-empty-string $prefix
50012 *
50013 * @throws InvalidArgumentException
50014 */
50015 final public static function stringStartsWith(string $prefix): StringStartsWith
50016 {
50017 return new StringStartsWith($prefix);
50018 }
50019 final public static function stringContains(string $string, bool $case = \true): StringContains
50020 {
50021 return new StringContains($string, $case);
50022 }
50023 /**
50024 * @psalm-param non-empty-string $suffix
50025 *
50026 * @throws InvalidArgumentException
50027 */
50028 final public static function stringEndsWith(string $suffix): StringEndsWith
50029 {
50030 return new StringEndsWith($suffix);
50031 }
50032 final public static function stringEqualsStringIgnoringLineEndings(string $string): StringEqualsStringIgnoringLineEndings
50033 {
50034 return new StringEqualsStringIgnoringLineEndings($string);
50035 }
50036 final public static function countOf(int $count): Count
50037 {
50038 return new Count($count);
50039 }
50040 final public static function objectEquals(object $object, string $method = 'equals'): ObjectEquals
50041 {
50042 return new ObjectEquals($object, $method);
50043 }
50044 /**
50045 * Fails a test with the given message.
50046 *
50047 * @throws AssertionFailedError
50048 */
50049 final public static function fail(string $message = ''): never
50050 {
50051 self::$count++;
50052 throw new \PHPUnit\Framework\AssertionFailedError($message);
50053 }
50054 /**
50055 * Mark the test as incomplete.
50056 *
50057 * @throws IncompleteTestError
50058 */
50059 final public static function markTestIncomplete(string $message = ''): never
50060 {
50061 throw new \PHPUnit\Framework\IncompleteTestError($message);
50062 }
50063 /**
50064 * Mark the test as skipped.
50065 *
50066 * @throws SkippedWithMessageException
50067 */
50068 final public static function markTestSkipped(string $message = ''): never
50069 {
50070 throw new \PHPUnit\Framework\SkippedWithMessageException($message);
50071 }
50072 /**
50073 * Return the current assertion count.
50074 */
50075 final public static function getCount(): int
50076 {
50077 return self::$count;
50078 }
50079 /**
50080 * Reset the assertion counter.
50081 */
50082 final public static function resetCount(): void
50083 {
50084 self::$count = 0;
50085 }
50086 private static function isNativeType(string $type): bool
50087 {
50088 return match ($type) {
50089 'numeric', 'integer', 'int', 'iterable', 'float', 'string', 'boolean', 'bool', 'null', 'array', 'object', 'resource', 'scalar' => \true,
50090 default => \false,
50091 };
50092 }
50093 }
50094 <?php
50095
50096 declare (strict_types=1);
50097 /*
50098 * This file is part of PHPUnit.
50099 *
50100 * (c) Sebastian Bergmann <sebastian@phpunit.de>
50101 *
50102 * For the full copyright and license information, please view the LICENSE
50103 * file that was distributed with this source code.
50104 */
50105 namespace PHPUnit\Framework;
50106
50107 use function func_get_args;
50108 use function function_exists;
50109 use ArrayAccess;
50110 use Countable;
50111 use PHPUnit\Framework\Constraint\ArrayHasKey;
50112 use PHPUnit\Framework\Constraint\Callback;
50113 use PHPUnit\Framework\Constraint\Constraint;
50114 use PHPUnit\Framework\Constraint\Count;
50115 use PHPUnit\Framework\Constraint\DirectoryExists;
50116 use PHPUnit\Framework\Constraint\FileExists;
50117 use PHPUnit\Framework\Constraint\GreaterThan;
50118 use PHPUnit\Framework\Constraint\IsAnything;
50119 use PHPUnit\Framework\Constraint\IsEmpty;
50120 use PHPUnit\Framework\Constraint\IsEqual;
50121 use PHPUnit\Framework\Constraint\IsEqualCanonicalizing;
50122 use PHPUnit\Framework\Constraint\IsEqualIgnoringCase;
50123 use PHPUnit\Framework\Constraint\IsEqualWithDelta;
50124 use PHPUnit\Framework\Constraint\IsFalse;
50125 use PHPUnit\Framework\Constraint\IsFinite;
50126 use PHPUnit\Framework\Constraint\IsIdentical;
50127 use PHPUnit\Framework\Constraint\IsInfinite;
50128 use PHPUnit\Framework\Constraint\IsInstanceOf;
50129 use PHPUnit\Framework\Constraint\IsJson;
50130 use PHPUnit\Framework\Constraint\IsList;
50131 use PHPUnit\Framework\Constraint\IsNan;
50132 use PHPUnit\Framework\Constraint\IsNull;
50133 use PHPUnit\Framework\Constraint\IsReadable;
50134 use PHPUnit\Framework\Constraint\IsTrue;
50135 use PHPUnit\Framework\Constraint\IsType;
50136 use PHPUnit\Framework\Constraint\IsWritable;
50137 use PHPUnit\Framework\Constraint\LessThan;
50138 use PHPUnit\Framework\Constraint\LogicalAnd;
50139 use PHPUnit\Framework\Constraint\LogicalNot;
50140 use PHPUnit\Framework\Constraint\LogicalOr;
50141 use PHPUnit\Framework\Constraint\LogicalXor;
50142 use PHPUnit\Framework\Constraint\ObjectEquals;
50143 use PHPUnit\Framework\Constraint\RegularExpression;
50144 use PHPUnit\Framework\Constraint\StringContains;
50145 use PHPUnit\Framework\Constraint\StringEndsWith;
50146 use PHPUnit\Framework\Constraint\StringEqualsStringIgnoringLineEndings;
50147 use PHPUnit\Framework\Constraint\StringMatchesFormatDescription;
50148 use PHPUnit\Framework\Constraint\StringStartsWith;
50149 use PHPUnit\Framework\Constraint\TraversableContainsEqual;
50150 use PHPUnit\Framework\Constraint\TraversableContainsIdentical;
50151 use PHPUnit\Framework\Constraint\TraversableContainsOnly;
50152 use PHPUnit\Framework\MockObject\Rule\AnyInvokedCount as AnyInvokedCountMatcher;
50153 use PHPUnit\Framework\MockObject\Rule\InvokedAtLeastCount as InvokedAtLeastCountMatcher;
50154 use PHPUnit\Framework\MockObject\Rule\InvokedAtLeastOnce as InvokedAtLeastOnceMatcher;
50155 use PHPUnit\Framework\MockObject\Rule\InvokedAtMostCount as InvokedAtMostCountMatcher;
50156 use PHPUnit\Framework\MockObject\Rule\InvokedCount as InvokedCountMatcher;
50157 use PHPUnit\Framework\MockObject\Stub\ConsecutiveCalls as ConsecutiveCallsStub;
50158 use PHPUnit\Framework\MockObject\Stub\Exception as ExceptionStub;
50159 use PHPUnit\Framework\MockObject\Stub\ReturnArgument as ReturnArgumentStub;
50160 use PHPUnit\Framework\MockObject\Stub\ReturnCallback as ReturnCallbackStub;
50161 use PHPUnit\Framework\MockObject\Stub\ReturnSelf as ReturnSelfStub;
50162 use PHPUnit\Framework\MockObject\Stub\ReturnStub;
50163 use PHPUnit\Framework\MockObject\Stub\ReturnValueMap as ReturnValueMapStub;
50164 use PHPUnit\Util\Xml\XmlException;
50165 use Throwable;
50166 if (!function_exists('PHPUnit\Framework\assertArrayHasKey')) {
50167 /**
50168 * Asserts that an array has a specified key.
50169 *
50170 * @throws Exception
50171 * @throws ExpectationFailedException
50172 *
50173 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
50174 *
50175 * @see Assert::assertArrayHasKey
50176 */
50177 function assertArrayHasKey(mixed $key, array|ArrayAccess $array, string $message = ''): void
50178 {
50179 \PHPUnit\Framework\Assert::assertArrayHasKey(...func_get_args());
50180 }
50181 }
50182 if (!function_exists('PHPUnit\Framework\assertArrayNotHasKey')) {
50183 /**
50184 * Asserts that an array does not have a specified key.
50185 *
50186 * @throws Exception
50187 * @throws ExpectationFailedException
50188 *
50189 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
50190 *
50191 * @see Assert::assertArrayNotHasKey
50192 */
50193 function assertArrayNotHasKey(mixed $key, array|ArrayAccess $array, string $message = ''): void
50194 {
50195 \PHPUnit\Framework\Assert::assertArrayNotHasKey(...func_get_args());
50196 }
50197 }
50198 if (!function_exists('PHPUnit\Framework\assertIsList')) {
50199 /**
50200 * @throws ExpectationFailedException
50201 *
50202 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
50203 *
50204 * @see Assert::assertIsList
50205 */
50206 function assertIsList(mixed $array, string $message = ''): void
50207 {
50208 \PHPUnit\Framework\Assert::assertIsList(...func_get_args());
50209 }
50210 }
50211 if (!function_exists('PHPUnit\Framework\assertContains')) {
50212 /**
50213 * Asserts that a haystack contains a needle.
50214 *
50215 * @throws Exception
50216 * @throws ExpectationFailedException
50217 *
50218 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
50219 *
50220 * @see Assert::assertContains
50221 */
50222 function assertContains(mixed $needle, iterable $haystack, string $message = ''): void
50223 {
50224 \PHPUnit\Framework\Assert::assertContains(...func_get_args());
50225 }
50226 }
50227 if (!function_exists('PHPUnit\Framework\assertContainsEquals')) {
50228 /**
50229 * @throws ExpectationFailedException
50230 *
50231 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
50232 *
50233 * @see Assert::assertContainsEquals
50234 */
50235 function assertContainsEquals(mixed $needle, iterable $haystack, string $message = ''): void
50236 {
50237 \PHPUnit\Framework\Assert::assertContainsEquals(...func_get_args());
50238 }
50239 }
50240 if (!function_exists('PHPUnit\Framework\assertNotContains')) {
50241 /**
50242 * Asserts that a haystack does not contain a needle.
50243 *
50244 * @throws Exception
50245 * @throws ExpectationFailedException
50246 *
50247 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
50248 *
50249 * @see Assert::assertNotContains
50250 */
50251 function assertNotContains(mixed $needle, iterable $haystack, string $message = ''): void
50252 {
50253 \PHPUnit\Framework\Assert::assertNotContains(...func_get_args());
50254 }
50255 }
50256 if (!function_exists('PHPUnit\Framework\assertNotContainsEquals')) {
50257 /**
50258 * @throws ExpectationFailedException
50259 *
50260 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
50261 *
50262 * @see Assert::assertNotContainsEquals
50263 */
50264 function assertNotContainsEquals(mixed $needle, iterable $haystack, string $message = ''): void
50265 {
50266 \PHPUnit\Framework\Assert::assertNotContainsEquals(...func_get_args());
50267 }
50268 }
50269 if (!function_exists('PHPUnit\Framework\assertContainsOnly')) {
50270 /**
50271 * Asserts that a haystack contains only values of a given type.
50272 *
50273 * @throws Exception
50274 * @throws ExpectationFailedException
50275 *
50276 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
50277 *
50278 * @see Assert::assertContainsOnly
50279 */
50280 function assertContainsOnly(string $type, iterable $haystack, ?bool $isNativeType = null, string $message = ''): void
50281 {
50282 \PHPUnit\Framework\Assert::assertContainsOnly(...func_get_args());
50283 }
50284 }
50285 if (!function_exists('PHPUnit\Framework\assertContainsOnlyInstancesOf')) {
50286 /**
50287 * Asserts that a haystack contains only instances of a given class name.
50288 *
50289 * @throws Exception
50290 * @throws ExpectationFailedException
50291 *
50292 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
50293 *
50294 * @see Assert::assertContainsOnlyInstancesOf
50295 */
50296 function assertContainsOnlyInstancesOf(string $className, iterable $haystack, string $message = ''): void
50297 {
50298 \PHPUnit\Framework\Assert::assertContainsOnlyInstancesOf(...func_get_args());
50299 }
50300 }
50301 if (!function_exists('PHPUnit\Framework\assertNotContainsOnly')) {
50302 /**
50303 * Asserts that a haystack does not contain only values of a given type.
50304 *
50305 * @throws Exception
50306 * @throws ExpectationFailedException
50307 *
50308 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
50309 *
50310 * @see Assert::assertNotContainsOnly
50311 */
50312 function assertNotContainsOnly(string $type, iterable $haystack, ?bool $isNativeType = null, string $message = ''): void
50313 {
50314 \PHPUnit\Framework\Assert::assertNotContainsOnly(...func_get_args());
50315 }
50316 }
50317 if (!function_exists('PHPUnit\Framework\assertCount')) {
50318 /**
50319 * Asserts the number of elements of an array, Countable or Traversable.
50320 *
50321 * @throws Exception
50322 * @throws ExpectationFailedException
50323 * @throws GeneratorNotSupportedException
50324 *
50325 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
50326 *
50327 * @see Assert::assertCount
50328 */
50329 function assertCount(int $expectedCount, Countable|iterable $haystack, string $message = ''): void
50330 {
50331 \PHPUnit\Framework\Assert::assertCount(...func_get_args());
50332 }
50333 }
50334 if (!function_exists('PHPUnit\Framework\assertNotCount')) {
50335 /**
50336 * Asserts the number of elements of an array, Countable or Traversable.
50337 *
50338 * @throws Exception
50339 * @throws ExpectationFailedException
50340 * @throws GeneratorNotSupportedException
50341 *
50342 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
50343 *
50344 * @see Assert::assertNotCount
50345 */
50346 function assertNotCount(int $expectedCount, Countable|iterable $haystack, string $message = ''): void
50347 {
50348 \PHPUnit\Framework\Assert::assertNotCount(...func_get_args());
50349 }
50350 }
50351 if (!function_exists('PHPUnit\Framework\assertEquals')) {
50352 /**
50353 * Asserts that two variables are equal.
50354 *
50355 * @throws ExpectationFailedException
50356 *
50357 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
50358 *
50359 * @see Assert::assertEquals
50360 */
50361 function assertEquals(mixed $expected, mixed $actual, string $message = ''): void
50362 {
50363 \PHPUnit\Framework\Assert::assertEquals(...func_get_args());
50364 }
50365 }
50366 if (!function_exists('PHPUnit\Framework\assertEqualsCanonicalizing')) {
50367 /**
50368 * Asserts that two variables are equal (canonicalizing).
50369 *
50370 * @throws ExpectationFailedException
50371 *
50372 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
50373 *
50374 * @see Assert::assertEqualsCanonicalizing
50375 */
50376 function assertEqualsCanonicalizing(mixed $expected, mixed $actual, string $message = ''): void
50377 {
50378 \PHPUnit\Framework\Assert::assertEqualsCanonicalizing(...func_get_args());
50379 }
50380 }
50381 if (!function_exists('PHPUnit\Framework\assertEqualsIgnoringCase')) {
50382 /**
50383 * Asserts that two variables are equal (ignoring case).
50384 *
50385 * @throws ExpectationFailedException
50386 *
50387 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
50388 *
50389 * @see Assert::assertEqualsIgnoringCase
50390 */
50391 function assertEqualsIgnoringCase(mixed $expected, mixed $actual, string $message = ''): void
50392 {
50393 \PHPUnit\Framework\Assert::assertEqualsIgnoringCase(...func_get_args());
50394 }
50395 }
50396 if (!function_exists('PHPUnit\Framework\assertEqualsWithDelta')) {
50397 /**
50398 * Asserts that two variables are equal (with delta).
50399 *
50400 * @throws ExpectationFailedException
50401 *
50402 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
50403 *
50404 * @see Assert::assertEqualsWithDelta
50405 */
50406 function assertEqualsWithDelta(mixed $expected, mixed $actual, float $delta, string $message = ''): void
50407 {
50408 \PHPUnit\Framework\Assert::assertEqualsWithDelta(...func_get_args());
50409 }
50410 }
50411 if (!function_exists('PHPUnit\Framework\assertNotEquals')) {
50412 /**
50413 * Asserts that two variables are not equal.
50414 *
50415 * @throws ExpectationFailedException
50416 *
50417 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
50418 *
50419 * @see Assert::assertNotEquals
50420 */
50421 function assertNotEquals(mixed $expected, mixed $actual, string $message = ''): void
50422 {
50423 \PHPUnit\Framework\Assert::assertNotEquals(...func_get_args());
50424 }
50425 }
50426 if (!function_exists('PHPUnit\Framework\assertNotEqualsCanonicalizing')) {
50427 /**
50428 * Asserts that two variables are not equal (canonicalizing).
50429 *
50430 * @throws ExpectationFailedException
50431 *
50432 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
50433 *
50434 * @see Assert::assertNotEqualsCanonicalizing
50435 */
50436 function assertNotEqualsCanonicalizing(mixed $expected, mixed $actual, string $message = ''): void
50437 {
50438 \PHPUnit\Framework\Assert::assertNotEqualsCanonicalizing(...func_get_args());
50439 }
50440 }
50441 if (!function_exists('PHPUnit\Framework\assertNotEqualsIgnoringCase')) {
50442 /**
50443 * Asserts that two variables are not equal (ignoring case).
50444 *
50445 * @throws ExpectationFailedException
50446 *
50447 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
50448 *
50449 * @see Assert::assertNotEqualsIgnoringCase
50450 */
50451 function assertNotEqualsIgnoringCase(mixed $expected, mixed $actual, string $message = ''): void
50452 {
50453 \PHPUnit\Framework\Assert::assertNotEqualsIgnoringCase(...func_get_args());
50454 }
50455 }
50456 if (!function_exists('PHPUnit\Framework\assertNotEqualsWithDelta')) {
50457 /**
50458 * Asserts that two variables are not equal (with delta).
50459 *
50460 * @throws ExpectationFailedException
50461 *
50462 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
50463 *
50464 * @see Assert::assertNotEqualsWithDelta
50465 */
50466 function assertNotEqualsWithDelta(mixed $expected, mixed $actual, float $delta, string $message = ''): void
50467 {
50468 \PHPUnit\Framework\Assert::assertNotEqualsWithDelta(...func_get_args());
50469 }
50470 }
50471 if (!function_exists('PHPUnit\Framework\assertObjectEquals')) {
50472 /**
50473 * @throws ExpectationFailedException
50474 *
50475 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
50476 *
50477 * @see Assert::assertObjectEquals
50478 */
50479 function assertObjectEquals(object $expected, object $actual, string $method = 'equals', string $message = ''): void
50480 {
50481 \PHPUnit\Framework\Assert::assertObjectEquals(...func_get_args());
50482 }
50483 }
50484 if (!function_exists('PHPUnit\Framework\assertEmpty')) {
50485 /**
50486 * Asserts that a variable is empty.
50487 *
50488 * @throws ExpectationFailedException
50489 * @throws GeneratorNotSupportedException
50490 *
50491 * @psalm-assert empty $actual
50492 *
50493 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
50494 *
50495 * @see Assert::assertEmpty
50496 */
50497 function assertEmpty(mixed $actual, string $message = ''): void
50498 {
50499 \PHPUnit\Framework\Assert::assertEmpty(...func_get_args());
50500 }
50501 }
50502 if (!function_exists('PHPUnit\Framework\assertNotEmpty')) {
50503 /**
50504 * Asserts that a variable is not empty.
50505 *
50506 * @throws ExpectationFailedException
50507 * @throws GeneratorNotSupportedException
50508 *
50509 * @psalm-assert !empty $actual
50510 *
50511 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
50512 *
50513 * @see Assert::assertNotEmpty
50514 */
50515 function assertNotEmpty(mixed $actual, string $message = ''): void
50516 {
50517 \PHPUnit\Framework\Assert::assertNotEmpty(...func_get_args());
50518 }
50519 }
50520 if (!function_exists('PHPUnit\Framework\assertGreaterThan')) {
50521 /**
50522 * Asserts that a value is greater than another value.
50523 *
50524 * @throws ExpectationFailedException
50525 *
50526 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
50527 *
50528 * @see Assert::assertGreaterThan
50529 */
50530 function assertGreaterThan(mixed $expected, mixed $actual, string $message = ''): void
50531 {
50532 \PHPUnit\Framework\Assert::assertGreaterThan(...func_get_args());
50533 }
50534 }
50535 if (!function_exists('PHPUnit\Framework\assertGreaterThanOrEqual')) {
50536 /**
50537 * Asserts that a value is greater than or equal to another value.
50538 *
50539 * @throws ExpectationFailedException
50540 *
50541 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
50542 *
50543 * @see Assert::assertGreaterThanOrEqual
50544 */
50545 function assertGreaterThanOrEqual(mixed $expected, mixed $actual, string $message = ''): void
50546 {
50547 \PHPUnit\Framework\Assert::assertGreaterThanOrEqual(...func_get_args());
50548 }
50549 }
50550 if (!function_exists('PHPUnit\Framework\assertLessThan')) {
50551 /**
50552 * Asserts that a value is smaller than another value.
50553 *
50554 * @throws ExpectationFailedException
50555 *
50556 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
50557 *
50558 * @see Assert::assertLessThan
50559 */
50560 function assertLessThan(mixed $expected, mixed $actual, string $message = ''): void
50561 {
50562 \PHPUnit\Framework\Assert::assertLessThan(...func_get_args());
50563 }
50564 }
50565 if (!function_exists('PHPUnit\Framework\assertLessThanOrEqual')) {
50566 /**
50567 * Asserts that a value is smaller than or equal to another value.
50568 *
50569 * @throws ExpectationFailedException
50570 *
50571 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
50572 *
50573 * @see Assert::assertLessThanOrEqual
50574 */
50575 function assertLessThanOrEqual(mixed $expected, mixed $actual, string $message = ''): void
50576 {
50577 \PHPUnit\Framework\Assert::assertLessThanOrEqual(...func_get_args());
50578 }
50579 }
50580 if (!function_exists('PHPUnit\Framework\assertFileEquals')) {
50581 /**
50582 * Asserts that the contents of one file is equal to the contents of another
50583 * file.
50584 *
50585 * @throws ExpectationFailedException
50586 *
50587 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
50588 *
50589 * @see Assert::assertFileEquals
50590 */
50591 function assertFileEquals(string $expected, string $actual, string $message = ''): void
50592 {
50593 \PHPUnit\Framework\Assert::assertFileEquals(...func_get_args());
50594 }
50595 }
50596 if (!function_exists('PHPUnit\Framework\assertFileEqualsCanonicalizing')) {
50597 /**
50598 * Asserts that the contents of one file is equal to the contents of another
50599 * file (canonicalizing).
50600 *
50601 * @throws ExpectationFailedException
50602 *
50603 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
50604 *
50605 * @see Assert::assertFileEqualsCanonicalizing
50606 */
50607 function assertFileEqualsCanonicalizing(string $expected, string $actual, string $message = ''): void
50608 {
50609 \PHPUnit\Framework\Assert::assertFileEqualsCanonicalizing(...func_get_args());
50610 }
50611 }
50612 if (!function_exists('PHPUnit\Framework\assertFileEqualsIgnoringCase')) {
50613 /**
50614 * Asserts that the contents of one file is equal to the contents of another
50615 * file (ignoring case).
50616 *
50617 * @throws ExpectationFailedException
50618 *
50619 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
50620 *
50621 * @see Assert::assertFileEqualsIgnoringCase
50622 */
50623 function assertFileEqualsIgnoringCase(string $expected, string $actual, string $message = ''): void
50624 {
50625 \PHPUnit\Framework\Assert::assertFileEqualsIgnoringCase(...func_get_args());
50626 }
50627 }
50628 if (!function_exists('PHPUnit\Framework\assertFileNotEquals')) {
50629 /**
50630 * Asserts that the contents of one file is not equal to the contents of
50631 * another file.
50632 *
50633 * @throws ExpectationFailedException
50634 *
50635 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
50636 *
50637 * @see Assert::assertFileNotEquals
50638 */
50639 function assertFileNotEquals(string $expected, string $actual, string $message = ''): void
50640 {
50641 \PHPUnit\Framework\Assert::assertFileNotEquals(...func_get_args());
50642 }
50643 }
50644 if (!function_exists('PHPUnit\Framework\assertFileNotEqualsCanonicalizing')) {
50645 /**
50646 * Asserts that the contents of one file is not equal to the contents of another
50647 * file (canonicalizing).
50648 *
50649 * @throws ExpectationFailedException
50650 *
50651 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
50652 *
50653 * @see Assert::assertFileNotEqualsCanonicalizing
50654 */
50655 function assertFileNotEqualsCanonicalizing(string $expected, string $actual, string $message = ''): void
50656 {
50657 \PHPUnit\Framework\Assert::assertFileNotEqualsCanonicalizing(...func_get_args());
50658 }
50659 }
50660 if (!function_exists('PHPUnit\Framework\assertFileNotEqualsIgnoringCase')) {
50661 /**
50662 * Asserts that the contents of one file is not equal to the contents of another
50663 * file (ignoring case).
50664 *
50665 * @throws ExpectationFailedException
50666 *
50667 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
50668 *
50669 * @see Assert::assertFileNotEqualsIgnoringCase
50670 */
50671 function assertFileNotEqualsIgnoringCase(string $expected, string $actual, string $message = ''): void
50672 {
50673 \PHPUnit\Framework\Assert::assertFileNotEqualsIgnoringCase(...func_get_args());
50674 }
50675 }
50676 if (!function_exists('PHPUnit\Framework\assertStringEqualsFile')) {
50677 /**
50678 * Asserts that the contents of a string is equal
50679 * to the contents of a file.
50680 *
50681 * @throws ExpectationFailedException
50682 *
50683 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
50684 *
50685 * @see Assert::assertStringEqualsFile
50686 */
50687 function assertStringEqualsFile(string $expectedFile, string $actualString, string $message = ''): void
50688 {
50689 \PHPUnit\Framework\Assert::assertStringEqualsFile(...func_get_args());
50690 }
50691 }
50692 if (!function_exists('PHPUnit\Framework\assertStringEqualsFileCanonicalizing')) {
50693 /**
50694 * Asserts that the contents of a string is equal
50695 * to the contents of a file (canonicalizing).
50696 *
50697 * @throws ExpectationFailedException
50698 *
50699 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
50700 *
50701 * @see Assert::assertStringEqualsFileCanonicalizing
50702 */
50703 function assertStringEqualsFileCanonicalizing(string $expectedFile, string $actualString, string $message = ''): void
50704 {
50705 \PHPUnit\Framework\Assert::assertStringEqualsFileCanonicalizing(...func_get_args());
50706 }
50707 }
50708 if (!function_exists('PHPUnit\Framework\assertStringEqualsFileIgnoringCase')) {
50709 /**
50710 * Asserts that the contents of a string is equal
50711 * to the contents of a file (ignoring case).
50712 *
50713 * @throws ExpectationFailedException
50714 *
50715 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
50716 *
50717 * @see Assert::assertStringEqualsFileIgnoringCase
50718 */
50719 function assertStringEqualsFileIgnoringCase(string $expectedFile, string $actualString, string $message = ''): void
50720 {
50721 \PHPUnit\Framework\Assert::assertStringEqualsFileIgnoringCase(...func_get_args());
50722 }
50723 }
50724 if (!function_exists('PHPUnit\Framework\assertStringNotEqualsFile')) {
50725 /**
50726 * Asserts that the contents of a string is not equal
50727 * to the contents of a file.
50728 *
50729 * @throws ExpectationFailedException
50730 *
50731 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
50732 *
50733 * @see Assert::assertStringNotEqualsFile
50734 */
50735 function assertStringNotEqualsFile(string $expectedFile, string $actualString, string $message = ''): void
50736 {
50737 \PHPUnit\Framework\Assert::assertStringNotEqualsFile(...func_get_args());
50738 }
50739 }
50740 if (!function_exists('PHPUnit\Framework\assertStringNotEqualsFileCanonicalizing')) {
50741 /**
50742 * Asserts that the contents of a string is not equal
50743 * to the contents of a file (canonicalizing).
50744 *
50745 * @throws ExpectationFailedException
50746 *
50747 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
50748 *
50749 * @see Assert::assertStringNotEqualsFileCanonicalizing
50750 */
50751 function assertStringNotEqualsFileCanonicalizing(string $expectedFile, string $actualString, string $message = ''): void
50752 {
50753 \PHPUnit\Framework\Assert::assertStringNotEqualsFileCanonicalizing(...func_get_args());
50754 }
50755 }
50756 if (!function_exists('PHPUnit\Framework\assertStringNotEqualsFileIgnoringCase')) {
50757 /**
50758 * Asserts that the contents of a string is not equal
50759 * to the contents of a file (ignoring case).
50760 *
50761 * @throws ExpectationFailedException
50762 *
50763 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
50764 *
50765 * @see Assert::assertStringNotEqualsFileIgnoringCase
50766 */
50767 function assertStringNotEqualsFileIgnoringCase(string $expectedFile, string $actualString, string $message = ''): void
50768 {
50769 \PHPUnit\Framework\Assert::assertStringNotEqualsFileIgnoringCase(...func_get_args());
50770 }
50771 }
50772 if (!function_exists('PHPUnit\Framework\assertIsReadable')) {
50773 /**
50774 * Asserts that a file/dir is readable.
50775 *
50776 * @throws ExpectationFailedException
50777 *
50778 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
50779 *
50780 * @see Assert::assertIsReadable
50781 */
50782 function assertIsReadable(string $filename, string $message = ''): void
50783 {
50784 \PHPUnit\Framework\Assert::assertIsReadable(...func_get_args());
50785 }
50786 }
50787 if (!function_exists('PHPUnit\Framework\assertIsNotReadable')) {
50788 /**
50789 * Asserts that a file/dir exists and is not readable.
50790 *
50791 * @throws ExpectationFailedException
50792 *
50793 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
50794 *
50795 * @see Assert::assertIsNotReadable
50796 */
50797 function assertIsNotReadable(string $filename, string $message = ''): void
50798 {
50799 \PHPUnit\Framework\Assert::assertIsNotReadable(...func_get_args());
50800 }
50801 }
50802 if (!function_exists('PHPUnit\Framework\assertIsWritable')) {
50803 /**
50804 * Asserts that a file/dir exists and is writable.
50805 *
50806 * @throws ExpectationFailedException
50807 *
50808 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
50809 *
50810 * @see Assert::assertIsWritable
50811 */
50812 function assertIsWritable(string $filename, string $message = ''): void
50813 {
50814 \PHPUnit\Framework\Assert::assertIsWritable(...func_get_args());
50815 }
50816 }
50817 if (!function_exists('PHPUnit\Framework\assertIsNotWritable')) {
50818 /**
50819 * Asserts that a file/dir exists and is not writable.
50820 *
50821 * @throws ExpectationFailedException
50822 *
50823 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
50824 *
50825 * @see Assert::assertIsNotWritable
50826 */
50827 function assertIsNotWritable(string $filename, string $message = ''): void
50828 {
50829 \PHPUnit\Framework\Assert::assertIsNotWritable(...func_get_args());
50830 }
50831 }
50832 if (!function_exists('PHPUnit\Framework\assertDirectoryExists')) {
50833 /**
50834 * Asserts that a directory exists.
50835 *
50836 * @throws ExpectationFailedException
50837 *
50838 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
50839 *
50840 * @see Assert::assertDirectoryExists
50841 */
50842 function assertDirectoryExists(string $directory, string $message = ''): void
50843 {
50844 \PHPUnit\Framework\Assert::assertDirectoryExists(...func_get_args());
50845 }
50846 }
50847 if (!function_exists('PHPUnit\Framework\assertDirectoryDoesNotExist')) {
50848 /**
50849 * Asserts that a directory does not exist.
50850 *
50851 * @throws ExpectationFailedException
50852 *
50853 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
50854 *
50855 * @see Assert::assertDirectoryDoesNotExist
50856 */
50857 function assertDirectoryDoesNotExist(string $directory, string $message = ''): void
50858 {
50859 \PHPUnit\Framework\Assert::assertDirectoryDoesNotExist(...func_get_args());
50860 }
50861 }
50862 if (!function_exists('PHPUnit\Framework\assertDirectoryIsReadable')) {
50863 /**
50864 * Asserts that a directory exists and is readable.
50865 *
50866 * @throws ExpectationFailedException
50867 *
50868 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
50869 *
50870 * @see Assert::assertDirectoryIsReadable
50871 */
50872 function assertDirectoryIsReadable(string $directory, string $message = ''): void
50873 {
50874 \PHPUnit\Framework\Assert::assertDirectoryIsReadable(...func_get_args());
50875 }
50876 }
50877 if (!function_exists('PHPUnit\Framework\assertDirectoryIsNotReadable')) {
50878 /**
50879 * Asserts that a directory exists and is not readable.
50880 *
50881 * @throws ExpectationFailedException
50882 *
50883 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
50884 *
50885 * @see Assert::assertDirectoryIsNotReadable
50886 */
50887 function assertDirectoryIsNotReadable(string $directory, string $message = ''): void
50888 {
50889 \PHPUnit\Framework\Assert::assertDirectoryIsNotReadable(...func_get_args());
50890 }
50891 }
50892 if (!function_exists('PHPUnit\Framework\assertDirectoryIsWritable')) {
50893 /**
50894 * Asserts that a directory exists and is writable.
50895 *
50896 * @throws ExpectationFailedException
50897 *
50898 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
50899 *
50900 * @see Assert::assertDirectoryIsWritable
50901 */
50902 function assertDirectoryIsWritable(string $directory, string $message = ''): void
50903 {
50904 \PHPUnit\Framework\Assert::assertDirectoryIsWritable(...func_get_args());
50905 }
50906 }
50907 if (!function_exists('PHPUnit\Framework\assertDirectoryIsNotWritable')) {
50908 /**
50909 * Asserts that a directory exists and is not writable.
50910 *
50911 * @throws ExpectationFailedException
50912 *
50913 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
50914 *
50915 * @see Assert::assertDirectoryIsNotWritable
50916 */
50917 function assertDirectoryIsNotWritable(string $directory, string $message = ''): void
50918 {
50919 \PHPUnit\Framework\Assert::assertDirectoryIsNotWritable(...func_get_args());
50920 }
50921 }
50922 if (!function_exists('PHPUnit\Framework\assertFileExists')) {
50923 /**
50924 * Asserts that a file exists.
50925 *
50926 * @throws ExpectationFailedException
50927 *
50928 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
50929 *
50930 * @see Assert::assertFileExists
50931 */
50932 function assertFileExists(string $filename, string $message = ''): void
50933 {
50934 \PHPUnit\Framework\Assert::assertFileExists(...func_get_args());
50935 }
50936 }
50937 if (!function_exists('PHPUnit\Framework\assertFileDoesNotExist')) {
50938 /**
50939 * Asserts that a file does not exist.
50940 *
50941 * @throws ExpectationFailedException
50942 *
50943 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
50944 *
50945 * @see Assert::assertFileDoesNotExist
50946 */
50947 function assertFileDoesNotExist(string $filename, string $message = ''): void
50948 {
50949 \PHPUnit\Framework\Assert::assertFileDoesNotExist(...func_get_args());
50950 }
50951 }
50952 if (!function_exists('PHPUnit\Framework\assertFileIsReadable')) {
50953 /**
50954 * Asserts that a file exists and is readable.
50955 *
50956 * @throws ExpectationFailedException
50957 *
50958 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
50959 *
50960 * @see Assert::assertFileIsReadable
50961 */
50962 function assertFileIsReadable(string $file, string $message = ''): void
50963 {
50964 \PHPUnit\Framework\Assert::assertFileIsReadable(...func_get_args());
50965 }
50966 }
50967 if (!function_exists('PHPUnit\Framework\assertFileIsNotReadable')) {
50968 /**
50969 * Asserts that a file exists and is not readable.
50970 *
50971 * @throws ExpectationFailedException
50972 *
50973 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
50974 *
50975 * @see Assert::assertFileIsNotReadable
50976 */
50977 function assertFileIsNotReadable(string $file, string $message = ''): void
50978 {
50979 \PHPUnit\Framework\Assert::assertFileIsNotReadable(...func_get_args());
50980 }
50981 }
50982 if (!function_exists('PHPUnit\Framework\assertFileIsWritable')) {
50983 /**
50984 * Asserts that a file exists and is writable.
50985 *
50986 * @throws ExpectationFailedException
50987 *
50988 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
50989 *
50990 * @see Assert::assertFileIsWritable
50991 */
50992 function assertFileIsWritable(string $file, string $message = ''): void
50993 {
50994 \PHPUnit\Framework\Assert::assertFileIsWritable(...func_get_args());
50995 }
50996 }
50997 if (!function_exists('PHPUnit\Framework\assertFileIsNotWritable')) {
50998 /**
50999 * Asserts that a file exists and is not writable.
51000 *
51001 * @throws ExpectationFailedException
51002 *
51003 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
51004 *
51005 * @see Assert::assertFileIsNotWritable
51006 */
51007 function assertFileIsNotWritable(string $file, string $message = ''): void
51008 {
51009 \PHPUnit\Framework\Assert::assertFileIsNotWritable(...func_get_args());
51010 }
51011 }
51012 if (!function_exists('PHPUnit\Framework\assertTrue')) {
51013 /**
51014 * Asserts that a condition is true.
51015 *
51016 * @throws ExpectationFailedException
51017 *
51018 * @psalm-assert true $condition
51019 *
51020 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
51021 *
51022 * @see Assert::assertTrue
51023 */
51024 function assertTrue(mixed $condition, string $message = ''): void
51025 {
51026 \PHPUnit\Framework\Assert::assertTrue(...func_get_args());
51027 }
51028 }
51029 if (!function_exists('PHPUnit\Framework\assertNotTrue')) {
51030 /**
51031 * Asserts that a condition is not true.
51032 *
51033 * @throws ExpectationFailedException
51034 *
51035 * @psalm-assert !true $condition
51036 *
51037 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
51038 *
51039 * @see Assert::assertNotTrue
51040 */
51041 function assertNotTrue(mixed $condition, string $message = ''): void
51042 {
51043 \PHPUnit\Framework\Assert::assertNotTrue(...func_get_args());
51044 }
51045 }
51046 if (!function_exists('PHPUnit\Framework\assertFalse')) {
51047 /**
51048 * Asserts that a condition is false.
51049 *
51050 * @throws ExpectationFailedException
51051 *
51052 * @psalm-assert false $condition
51053 *
51054 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
51055 *
51056 * @see Assert::assertFalse
51057 */
51058 function assertFalse(mixed $condition, string $message = ''): void
51059 {
51060 \PHPUnit\Framework\Assert::assertFalse(...func_get_args());
51061 }
51062 }
51063 if (!function_exists('PHPUnit\Framework\assertNotFalse')) {
51064 /**
51065 * Asserts that a condition is not false.
51066 *
51067 * @throws ExpectationFailedException
51068 *
51069 * @psalm-assert !false $condition
51070 *
51071 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
51072 *
51073 * @see Assert::assertNotFalse
51074 */
51075 function assertNotFalse(mixed $condition, string $message = ''): void
51076 {
51077 \PHPUnit\Framework\Assert::assertNotFalse(...func_get_args());
51078 }
51079 }
51080 if (!function_exists('PHPUnit\Framework\assertNull')) {
51081 /**
51082 * Asserts that a variable is null.
51083 *
51084 * @throws ExpectationFailedException
51085 *
51086 * @psalm-assert null $actual
51087 *
51088 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
51089 *
51090 * @see Assert::assertNull
51091 */
51092 function assertNull(mixed $actual, string $message = ''): void
51093 {
51094 \PHPUnit\Framework\Assert::assertNull(...func_get_args());
51095 }
51096 }
51097 if (!function_exists('PHPUnit\Framework\assertNotNull')) {
51098 /**
51099 * Asserts that a variable is not null.
51100 *
51101 * @throws ExpectationFailedException
51102 *
51103 * @psalm-assert !null $actual
51104 *
51105 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
51106 *
51107 * @see Assert::assertNotNull
51108 */
51109 function assertNotNull(mixed $actual, string $message = ''): void
51110 {
51111 \PHPUnit\Framework\Assert::assertNotNull(...func_get_args());
51112 }
51113 }
51114 if (!function_exists('PHPUnit\Framework\assertFinite')) {
51115 /**
51116 * Asserts that a variable is finite.
51117 *
51118 * @throws ExpectationFailedException
51119 *
51120 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
51121 *
51122 * @see Assert::assertFinite
51123 */
51124 function assertFinite(mixed $actual, string $message = ''): void
51125 {
51126 \PHPUnit\Framework\Assert::assertFinite(...func_get_args());
51127 }
51128 }
51129 if (!function_exists('PHPUnit\Framework\assertInfinite')) {
51130 /**
51131 * Asserts that a variable is infinite.
51132 *
51133 * @throws ExpectationFailedException
51134 *
51135 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
51136 *
51137 * @see Assert::assertInfinite
51138 */
51139 function assertInfinite(mixed $actual, string $message = ''): void
51140 {
51141 \PHPUnit\Framework\Assert::assertInfinite(...func_get_args());
51142 }
51143 }
51144 if (!function_exists('PHPUnit\Framework\assertNan')) {
51145 /**
51146 * Asserts that a variable is nan.
51147 *
51148 * @throws ExpectationFailedException
51149 *
51150 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
51151 *
51152 * @see Assert::assertNan
51153 */
51154 function assertNan(mixed $actual, string $message = ''): void
51155 {
51156 \PHPUnit\Framework\Assert::assertNan(...func_get_args());
51157 }
51158 }
51159 if (!function_exists('PHPUnit\Framework\assertObjectHasProperty')) {
51160 /**
51161 * Asserts that an object has a specified property.
51162 *
51163 * @throws ExpectationFailedException
51164 *
51165 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
51166 *
51167 * @see Assert::assertObjectHasProperty
51168 */
51169 function assertObjectHasProperty(string $propertyName, object $object, string $message = ''): void
51170 {
51171 \PHPUnit\Framework\Assert::assertObjectHasProperty(...func_get_args());
51172 }
51173 }
51174 if (!function_exists('PHPUnit\Framework\assertObjectNotHasProperty')) {
51175 /**
51176 * Asserts that an object does not have a specified property.
51177 *
51178 * @throws ExpectationFailedException
51179 *
51180 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
51181 *
51182 * @see Assert::assertObjectNotHasProperty
51183 */
51184 function assertObjectNotHasProperty(string $propertyName, object $object, string $message = ''): void
51185 {
51186 \PHPUnit\Framework\Assert::assertObjectNotHasProperty(...func_get_args());
51187 }
51188 }
51189 if (!function_exists('PHPUnit\Framework\assertSame')) {
51190 /**
51191 * Asserts that two variables have the same type and value.
51192 * Used on objects, it asserts that two variables reference
51193 * the same object.
51194 *
51195 * @psalm-template ExpectedType
51196 *
51197 * @psalm-param ExpectedType $expected
51198 *
51199 * @throws ExpectationFailedException
51200 *
51201 * @psalm-assert =ExpectedType $actual
51202 *
51203 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
51204 *
51205 * @see Assert::assertSame
51206 */
51207 function assertSame(mixed $expected, mixed $actual, string $message = ''): void
51208 {
51209 \PHPUnit\Framework\Assert::assertSame(...func_get_args());
51210 }
51211 }
51212 if (!function_exists('PHPUnit\Framework\assertNotSame')) {
51213 /**
51214 * Asserts that two variables do not have the same type and value.
51215 * Used on objects, it asserts that two variables do not reference
51216 * the same object.
51217 *
51218 * @throws ExpectationFailedException
51219 *
51220 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
51221 *
51222 * @see Assert::assertNotSame
51223 */
51224 function assertNotSame(mixed $expected, mixed $actual, string $message = ''): void
51225 {
51226 \PHPUnit\Framework\Assert::assertNotSame(...func_get_args());
51227 }
51228 }
51229 if (!function_exists('PHPUnit\Framework\assertInstanceOf')) {
51230 /**
51231 * Asserts that a variable is of a given type.
51232 *
51233 * @psalm-template ExpectedType of object
51234 *
51235 * @psalm-param class-string<ExpectedType> $expected
51236 *
51237 * @throws Exception
51238 * @throws ExpectationFailedException
51239 * @throws UnknownClassOrInterfaceException
51240 *
51241 * @psalm-assert =ExpectedType $actual
51242 *
51243 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
51244 *
51245 * @see Assert::assertInstanceOf
51246 */
51247 function assertInstanceOf(string $expected, mixed $actual, string $message = ''): void
51248 {
51249 \PHPUnit\Framework\Assert::assertInstanceOf(...func_get_args());
51250 }
51251 }
51252 if (!function_exists('PHPUnit\Framework\assertNotInstanceOf')) {
51253 /**
51254 * Asserts that a variable is not of a given type.
51255 *
51256 * @psalm-template ExpectedType of object
51257 *
51258 * @psalm-param class-string<ExpectedType> $expected
51259 *
51260 * @throws Exception
51261 * @throws ExpectationFailedException
51262 *
51263 * @psalm-assert !ExpectedType $actual
51264 *
51265 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
51266 *
51267 * @see Assert::assertNotInstanceOf
51268 */
51269 function assertNotInstanceOf(string $expected, mixed $actual, string $message = ''): void
51270 {
51271 \PHPUnit\Framework\Assert::assertNotInstanceOf(...func_get_args());
51272 }
51273 }
51274 if (!function_exists('PHPUnit\Framework\assertIsArray')) {
51275 /**
51276 * Asserts that a variable is of type array.
51277 *
51278 * @throws Exception
51279 * @throws ExpectationFailedException
51280 *
51281 * @psalm-assert array $actual
51282 *
51283 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
51284 *
51285 * @see Assert::assertIsArray
51286 */
51287 function assertIsArray(mixed $actual, string $message = ''): void
51288 {
51289 \PHPUnit\Framework\Assert::assertIsArray(...func_get_args());
51290 }
51291 }
51292 if (!function_exists('PHPUnit\Framework\assertIsBool')) {
51293 /**
51294 * Asserts that a variable is of type bool.
51295 *
51296 * @throws Exception
51297 * @throws ExpectationFailedException
51298 *
51299 * @psalm-assert bool $actual
51300 *
51301 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
51302 *
51303 * @see Assert::assertIsBool
51304 */
51305 function assertIsBool(mixed $actual, string $message = ''): void
51306 {
51307 \PHPUnit\Framework\Assert::assertIsBool(...func_get_args());
51308 }
51309 }
51310 if (!function_exists('PHPUnit\Framework\assertIsFloat')) {
51311 /**
51312 * Asserts that a variable is of type float.
51313 *
51314 * @throws Exception
51315 * @throws ExpectationFailedException
51316 *
51317 * @psalm-assert float $actual
51318 *
51319 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
51320 *
51321 * @see Assert::assertIsFloat
51322 */
51323 function assertIsFloat(mixed $actual, string $message = ''): void
51324 {
51325 \PHPUnit\Framework\Assert::assertIsFloat(...func_get_args());
51326 }
51327 }
51328 if (!function_exists('PHPUnit\Framework\assertIsInt')) {
51329 /**
51330 * Asserts that a variable is of type int.
51331 *
51332 * @throws Exception
51333 * @throws ExpectationFailedException
51334 *
51335 * @psalm-assert int $actual
51336 *
51337 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
51338 *
51339 * @see Assert::assertIsInt
51340 */
51341 function assertIsInt(mixed $actual, string $message = ''): void
51342 {
51343 \PHPUnit\Framework\Assert::assertIsInt(...func_get_args());
51344 }
51345 }
51346 if (!function_exists('PHPUnit\Framework\assertIsNumeric')) {
51347 /**
51348 * Asserts that a variable is of type numeric.
51349 *
51350 * @throws Exception
51351 * @throws ExpectationFailedException
51352 *
51353 * @psalm-assert numeric $actual
51354 *
51355 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
51356 *
51357 * @see Assert::assertIsNumeric
51358 */
51359 function assertIsNumeric(mixed $actual, string $message = ''): void
51360 {
51361 \PHPUnit\Framework\Assert::assertIsNumeric(...func_get_args());
51362 }
51363 }
51364 if (!function_exists('PHPUnit\Framework\assertIsObject')) {
51365 /**
51366 * Asserts that a variable is of type object.
51367 *
51368 * @throws Exception
51369 * @throws ExpectationFailedException
51370 *
51371 * @psalm-assert object $actual
51372 *
51373 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
51374 *
51375 * @see Assert::assertIsObject
51376 */
51377 function assertIsObject(mixed $actual, string $message = ''): void
51378 {
51379 \PHPUnit\Framework\Assert::assertIsObject(...func_get_args());
51380 }
51381 }
51382 if (!function_exists('PHPUnit\Framework\assertIsResource')) {
51383 /**
51384 * Asserts that a variable is of type resource.
51385 *
51386 * @throws Exception
51387 * @throws ExpectationFailedException
51388 *
51389 * @psalm-assert resource $actual
51390 *
51391 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
51392 *
51393 * @see Assert::assertIsResource
51394 */
51395 function assertIsResource(mixed $actual, string $message = ''): void
51396 {
51397 \PHPUnit\Framework\Assert::assertIsResource(...func_get_args());
51398 }
51399 }
51400 if (!function_exists('PHPUnit\Framework\assertIsClosedResource')) {
51401 /**
51402 * Asserts that a variable is of type resource and is closed.
51403 *
51404 * @throws Exception
51405 * @throws ExpectationFailedException
51406 *
51407 * @psalm-assert resource $actual
51408 *
51409 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
51410 *
51411 * @see Assert::assertIsClosedResource
51412 */
51413 function assertIsClosedResource(mixed $actual, string $message = ''): void
51414 {
51415 \PHPUnit\Framework\Assert::assertIsClosedResource(...func_get_args());
51416 }
51417 }
51418 if (!function_exists('PHPUnit\Framework\assertIsString')) {
51419 /**
51420 * Asserts that a variable is of type string.
51421 *
51422 * @throws Exception
51423 * @throws ExpectationFailedException
51424 *
51425 * @psalm-assert string $actual
51426 *
51427 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
51428 *
51429 * @see Assert::assertIsString
51430 */
51431 function assertIsString(mixed $actual, string $message = ''): void
51432 {
51433 \PHPUnit\Framework\Assert::assertIsString(...func_get_args());
51434 }
51435 }
51436 if (!function_exists('PHPUnit\Framework\assertIsScalar')) {
51437 /**
51438 * Asserts that a variable is of type scalar.
51439 *
51440 * @throws Exception
51441 * @throws ExpectationFailedException
51442 *
51443 * @psalm-assert scalar $actual
51444 *
51445 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
51446 *
51447 * @see Assert::assertIsScalar
51448 */
51449 function assertIsScalar(mixed $actual, string $message = ''): void
51450 {
51451 \PHPUnit\Framework\Assert::assertIsScalar(...func_get_args());
51452 }
51453 }
51454 if (!function_exists('PHPUnit\Framework\assertIsCallable')) {
51455 /**
51456 * Asserts that a variable is of type callable.
51457 *
51458 * @throws Exception
51459 * @throws ExpectationFailedException
51460 *
51461 * @psalm-assert callable $actual
51462 *
51463 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
51464 *
51465 * @see Assert::assertIsCallable
51466 */
51467 function assertIsCallable(mixed $actual, string $message = ''): void
51468 {
51469 \PHPUnit\Framework\Assert::assertIsCallable(...func_get_args());
51470 }
51471 }
51472 if (!function_exists('PHPUnit\Framework\assertIsIterable')) {
51473 /**
51474 * Asserts that a variable is of type iterable.
51475 *
51476 * @throws Exception
51477 * @throws ExpectationFailedException
51478 *
51479 * @psalm-assert iterable $actual
51480 *
51481 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
51482 *
51483 * @see Assert::assertIsIterable
51484 */
51485 function assertIsIterable(mixed $actual, string $message = ''): void
51486 {
51487 \PHPUnit\Framework\Assert::assertIsIterable(...func_get_args());
51488 }
51489 }
51490 if (!function_exists('PHPUnit\Framework\assertIsNotArray')) {
51491 /**
51492 * Asserts that a variable is not of type array.
51493 *
51494 * @throws Exception
51495 * @throws ExpectationFailedException
51496 *
51497 * @psalm-assert !array $actual
51498 *
51499 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
51500 *
51501 * @see Assert::assertIsNotArray
51502 */
51503 function assertIsNotArray(mixed $actual, string $message = ''): void
51504 {
51505 \PHPUnit\Framework\Assert::assertIsNotArray(...func_get_args());
51506 }
51507 }
51508 if (!function_exists('PHPUnit\Framework\assertIsNotBool')) {
51509 /**
51510 * Asserts that a variable is not of type bool.
51511 *
51512 * @throws Exception
51513 * @throws ExpectationFailedException
51514 *
51515 * @psalm-assert !bool $actual
51516 *
51517 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
51518 *
51519 * @see Assert::assertIsNotBool
51520 */
51521 function assertIsNotBool(mixed $actual, string $message = ''): void
51522 {
51523 \PHPUnit\Framework\Assert::assertIsNotBool(...func_get_args());
51524 }
51525 }
51526 if (!function_exists('PHPUnit\Framework\assertIsNotFloat')) {
51527 /**
51528 * Asserts that a variable is not of type float.
51529 *
51530 * @throws Exception
51531 * @throws ExpectationFailedException
51532 *
51533 * @psalm-assert !float $actual
51534 *
51535 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
51536 *
51537 * @see Assert::assertIsNotFloat
51538 */
51539 function assertIsNotFloat(mixed $actual, string $message = ''): void
51540 {
51541 \PHPUnit\Framework\Assert::assertIsNotFloat(...func_get_args());
51542 }
51543 }
51544 if (!function_exists('PHPUnit\Framework\assertIsNotInt')) {
51545 /**
51546 * Asserts that a variable is not of type int.
51547 *
51548 * @throws Exception
51549 * @throws ExpectationFailedException
51550 *
51551 * @psalm-assert !int $actual
51552 *
51553 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
51554 *
51555 * @see Assert::assertIsNotInt
51556 */
51557 function assertIsNotInt(mixed $actual, string $message = ''): void
51558 {
51559 \PHPUnit\Framework\Assert::assertIsNotInt(...func_get_args());
51560 }
51561 }
51562 if (!function_exists('PHPUnit\Framework\assertIsNotNumeric')) {
51563 /**
51564 * Asserts that a variable is not of type numeric.
51565 *
51566 * @throws Exception
51567 * @throws ExpectationFailedException
51568 *
51569 * @psalm-assert !numeric $actual
51570 *
51571 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
51572 *
51573 * @see Assert::assertIsNotNumeric
51574 */
51575 function assertIsNotNumeric(mixed $actual, string $message = ''): void
51576 {
51577 \PHPUnit\Framework\Assert::assertIsNotNumeric(...func_get_args());
51578 }
51579 }
51580 if (!function_exists('PHPUnit\Framework\assertIsNotObject')) {
51581 /**
51582 * Asserts that a variable is not of type object.
51583 *
51584 * @throws Exception
51585 * @throws ExpectationFailedException
51586 *
51587 * @psalm-assert !object $actual
51588 *
51589 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
51590 *
51591 * @see Assert::assertIsNotObject
51592 */
51593 function assertIsNotObject(mixed $actual, string $message = ''): void
51594 {
51595 \PHPUnit\Framework\Assert::assertIsNotObject(...func_get_args());
51596 }
51597 }
51598 if (!function_exists('PHPUnit\Framework\assertIsNotResource')) {
51599 /**
51600 * Asserts that a variable is not of type resource.
51601 *
51602 * @throws Exception
51603 * @throws ExpectationFailedException
51604 *
51605 * @psalm-assert !resource $actual
51606 *
51607 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
51608 *
51609 * @see Assert::assertIsNotResource
51610 */
51611 function assertIsNotResource(mixed $actual, string $message = ''): void
51612 {
51613 \PHPUnit\Framework\Assert::assertIsNotResource(...func_get_args());
51614 }
51615 }
51616 if (!function_exists('PHPUnit\Framework\assertIsNotClosedResource')) {
51617 /**
51618 * Asserts that a variable is not of type resource.
51619 *
51620 * @throws Exception
51621 * @throws ExpectationFailedException
51622 *
51623 * @psalm-assert !resource $actual
51624 *
51625 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
51626 *
51627 * @see Assert::assertIsNotClosedResource
51628 */
51629 function assertIsNotClosedResource(mixed $actual, string $message = ''): void
51630 {
51631 \PHPUnit\Framework\Assert::assertIsNotClosedResource(...func_get_args());
51632 }
51633 }
51634 if (!function_exists('PHPUnit\Framework\assertIsNotString')) {
51635 /**
51636 * Asserts that a variable is not of type string.
51637 *
51638 * @throws Exception
51639 * @throws ExpectationFailedException
51640 *
51641 * @psalm-assert !string $actual
51642 *
51643 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
51644 *
51645 * @see Assert::assertIsNotString
51646 */
51647 function assertIsNotString(mixed $actual, string $message = ''): void
51648 {
51649 \PHPUnit\Framework\Assert::assertIsNotString(...func_get_args());
51650 }
51651 }
51652 if (!function_exists('PHPUnit\Framework\assertIsNotScalar')) {
51653 /**
51654 * Asserts that a variable is not of type scalar.
51655 *
51656 * @throws Exception
51657 * @throws ExpectationFailedException
51658 *
51659 * @psalm-assert !scalar $actual
51660 *
51661 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
51662 *
51663 * @see Assert::assertIsNotScalar
51664 */
51665 function assertIsNotScalar(mixed $actual, string $message = ''): void
51666 {
51667 \PHPUnit\Framework\Assert::assertIsNotScalar(...func_get_args());
51668 }
51669 }
51670 if (!function_exists('PHPUnit\Framework\assertIsNotCallable')) {
51671 /**
51672 * Asserts that a variable is not of type callable.
51673 *
51674 * @throws Exception
51675 * @throws ExpectationFailedException
51676 *
51677 * @psalm-assert !callable $actual
51678 *
51679 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
51680 *
51681 * @see Assert::assertIsNotCallable
51682 */
51683 function assertIsNotCallable(mixed $actual, string $message = ''): void
51684 {
51685 \PHPUnit\Framework\Assert::assertIsNotCallable(...func_get_args());
51686 }
51687 }
51688 if (!function_exists('PHPUnit\Framework\assertIsNotIterable')) {
51689 /**
51690 * Asserts that a variable is not of type iterable.
51691 *
51692 * @throws Exception
51693 * @throws ExpectationFailedException
51694 *
51695 * @psalm-assert !iterable $actual
51696 *
51697 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
51698 *
51699 * @see Assert::assertIsNotIterable
51700 */
51701 function assertIsNotIterable(mixed $actual, string $message = ''): void
51702 {
51703 \PHPUnit\Framework\Assert::assertIsNotIterable(...func_get_args());
51704 }
51705 }
51706 if (!function_exists('PHPUnit\Framework\assertMatchesRegularExpression')) {
51707 /**
51708 * Asserts that a string matches a given regular expression.
51709 *
51710 * @throws ExpectationFailedException
51711 *
51712 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
51713 *
51714 * @see Assert::assertMatchesRegularExpression
51715 */
51716 function assertMatchesRegularExpression(string $pattern, string $string, string $message = ''): void
51717 {
51718 \PHPUnit\Framework\Assert::assertMatchesRegularExpression(...func_get_args());
51719 }
51720 }
51721 if (!function_exists('PHPUnit\Framework\assertDoesNotMatchRegularExpression')) {
51722 /**
51723 * Asserts that a string does not match a given regular expression.
51724 *
51725 * @throws ExpectationFailedException
51726 *
51727 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
51728 *
51729 * @see Assert::assertDoesNotMatchRegularExpression
51730 */
51731 function assertDoesNotMatchRegularExpression(string $pattern, string $string, string $message = ''): void
51732 {
51733 \PHPUnit\Framework\Assert::assertDoesNotMatchRegularExpression(...func_get_args());
51734 }
51735 }
51736 if (!function_exists('PHPUnit\Framework\assertSameSize')) {
51737 /**
51738 * Assert that the size of two arrays (or `Countable` or `Traversable` objects)
51739 * is the same.
51740 *
51741 * @throws Exception
51742 * @throws ExpectationFailedException
51743 * @throws GeneratorNotSupportedException
51744 *
51745 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
51746 *
51747 * @see Assert::assertSameSize
51748 */
51749 function assertSameSize(Countable|iterable $expected, Countable|iterable $actual, string $message = ''): void
51750 {
51751 \PHPUnit\Framework\Assert::assertSameSize(...func_get_args());
51752 }
51753 }
51754 if (!function_exists('PHPUnit\Framework\assertNotSameSize')) {
51755 /**
51756 * Assert that the size of two arrays (or `Countable` or `Traversable` objects)
51757 * is not the same.
51758 *
51759 * @throws Exception
51760 * @throws ExpectationFailedException
51761 * @throws GeneratorNotSupportedException
51762 *
51763 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
51764 *
51765 * @see Assert::assertNotSameSize
51766 */
51767 function assertNotSameSize(Countable|iterable $expected, Countable|iterable $actual, string $message = ''): void
51768 {
51769 \PHPUnit\Framework\Assert::assertNotSameSize(...func_get_args());
51770 }
51771 }
51772 if (!function_exists('PHPUnit\Framework\assertStringContainsStringIgnoringLineEndings')) {
51773 /**
51774 * @throws ExpectationFailedException
51775 *
51776 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
51777 *
51778 * @see Assert::assertStringContainsStringIgnoringLineEndings
51779 */
51780 function assertStringContainsStringIgnoringLineEndings(string $needle, string $haystack, string $message = ''): void
51781 {
51782 \PHPUnit\Framework\Assert::assertStringContainsStringIgnoringLineEndings(...func_get_args());
51783 }
51784 }
51785 if (!function_exists('PHPUnit\Framework\assertStringEqualsStringIgnoringLineEndings')) {
51786 /**
51787 * Asserts that two strings are equal except for line endings.
51788 *
51789 * @throws ExpectationFailedException
51790 *
51791 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
51792 *
51793 * @see Assert::assertStringEqualsStringIgnoringLineEndings
51794 */
51795 function assertStringEqualsStringIgnoringLineEndings(string $expected, string $actual, string $message = ''): void
51796 {
51797 \PHPUnit\Framework\Assert::assertStringEqualsStringIgnoringLineEndings(...func_get_args());
51798 }
51799 }
51800 if (!function_exists('PHPUnit\Framework\assertFileMatchesFormat')) {
51801 /**
51802 * Asserts that a string matches a given format string.
51803 *
51804 * @throws ExpectationFailedException
51805 *
51806 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
51807 *
51808 * @see Assert::assertFileMatchesFormat
51809 */
51810 function assertFileMatchesFormat(string $format, string $actualFile, string $message = ''): void
51811 {
51812 \PHPUnit\Framework\Assert::assertFileMatchesFormat(...func_get_args());
51813 }
51814 }
51815 if (!function_exists('PHPUnit\Framework\assertFileMatchesFormatFile')) {
51816 /**
51817 * Asserts that a string matches a given format string.
51818 *
51819 * @throws ExpectationFailedException
51820 *
51821 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
51822 *
51823 * @see Assert::assertFileMatchesFormatFile
51824 */
51825 function assertFileMatchesFormatFile(string $formatFile, string $actualFile, string $message = ''): void
51826 {
51827 \PHPUnit\Framework\Assert::assertFileMatchesFormatFile(...func_get_args());
51828 }
51829 }
51830 if (!function_exists('PHPUnit\Framework\assertStringMatchesFormat')) {
51831 /**
51832 * Asserts that a string matches a given format string.
51833 *
51834 * @throws ExpectationFailedException
51835 *
51836 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
51837 *
51838 * @see Assert::assertStringMatchesFormat
51839 */
51840 function assertStringMatchesFormat(string $format, string $string, string $message = ''): void
51841 {
51842 \PHPUnit\Framework\Assert::assertStringMatchesFormat(...func_get_args());
51843 }
51844 }
51845 if (!function_exists('PHPUnit\Framework\assertStringNotMatchesFormat')) {
51846 /**
51847 * Asserts that a string does not match a given format string.
51848 *
51849 * @throws ExpectationFailedException
51850 *
51851 * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5472
51852 *
51853 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
51854 *
51855 * @see Assert::assertStringNotMatchesFormat
51856 */
51857 function assertStringNotMatchesFormat(string $format, string $string, string $message = ''): void
51858 {
51859 \PHPUnit\Framework\Assert::assertStringNotMatchesFormat(...func_get_args());
51860 }
51861 }
51862 if (!function_exists('PHPUnit\Framework\assertStringMatchesFormatFile')) {
51863 /**
51864 * Asserts that a string matches a given format file.
51865 *
51866 * @throws ExpectationFailedException
51867 *
51868 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
51869 *
51870 * @see Assert::assertStringMatchesFormatFile
51871 */
51872 function assertStringMatchesFormatFile(string $formatFile, string $string, string $message = ''): void
51873 {
51874 \PHPUnit\Framework\Assert::assertStringMatchesFormatFile(...func_get_args());
51875 }
51876 }
51877 if (!function_exists('PHPUnit\Framework\assertStringNotMatchesFormatFile')) {
51878 /**
51879 * Asserts that a string does not match a given format string.
51880 *
51881 * @throws ExpectationFailedException
51882 *
51883 * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5472
51884 *
51885 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
51886 *
51887 * @see Assert::assertStringNotMatchesFormatFile
51888 */
51889 function assertStringNotMatchesFormatFile(string $formatFile, string $string, string $message = ''): void
51890 {
51891 \PHPUnit\Framework\Assert::assertStringNotMatchesFormatFile(...func_get_args());
51892 }
51893 }
51894 if (!function_exists('PHPUnit\Framework\assertStringStartsWith')) {
51895 /**
51896 * Asserts that a string starts with a given prefix.
51897 *
51898 * @psalm-param non-empty-string $prefix
51899 *
51900 * @throws ExpectationFailedException
51901 * @throws InvalidArgumentException
51902 *
51903 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
51904 *
51905 * @see Assert::assertStringStartsWith
51906 */
51907 function assertStringStartsWith(string $prefix, string $string, string $message = ''): void
51908 {
51909 \PHPUnit\Framework\Assert::assertStringStartsWith(...func_get_args());
51910 }
51911 }
51912 if (!function_exists('PHPUnit\Framework\assertStringStartsNotWith')) {
51913 /**
51914 * Asserts that a string starts not with a given prefix.
51915 *
51916 * @psalm-param non-empty-string $prefix
51917 *
51918 * @throws ExpectationFailedException
51919 * @throws InvalidArgumentException
51920 *
51921 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
51922 *
51923 * @see Assert::assertStringStartsNotWith
51924 */
51925 function assertStringStartsNotWith(string $prefix, string $string, string $message = ''): void
51926 {
51927 \PHPUnit\Framework\Assert::assertStringStartsNotWith(...func_get_args());
51928 }
51929 }
51930 if (!function_exists('PHPUnit\Framework\assertStringContainsString')) {
51931 /**
51932 * @throws ExpectationFailedException
51933 *
51934 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
51935 *
51936 * @see Assert::assertStringContainsString
51937 */
51938 function assertStringContainsString(string $needle, string $haystack, string $message = ''): void
51939 {
51940 \PHPUnit\Framework\Assert::assertStringContainsString(...func_get_args());
51941 }
51942 }
51943 if (!function_exists('PHPUnit\Framework\assertStringContainsStringIgnoringCase')) {
51944 /**
51945 * @throws ExpectationFailedException
51946 *
51947 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
51948 *
51949 * @see Assert::assertStringContainsStringIgnoringCase
51950 */
51951 function assertStringContainsStringIgnoringCase(string $needle, string $haystack, string $message = ''): void
51952 {
51953 \PHPUnit\Framework\Assert::assertStringContainsStringIgnoringCase(...func_get_args());
51954 }
51955 }
51956 if (!function_exists('PHPUnit\Framework\assertStringNotContainsString')) {
51957 /**
51958 * @throws ExpectationFailedException
51959 *
51960 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
51961 *
51962 * @see Assert::assertStringNotContainsString
51963 */
51964 function assertStringNotContainsString(string $needle, string $haystack, string $message = ''): void
51965 {
51966 \PHPUnit\Framework\Assert::assertStringNotContainsString(...func_get_args());
51967 }
51968 }
51969 if (!function_exists('PHPUnit\Framework\assertStringNotContainsStringIgnoringCase')) {
51970 /**
51971 * @throws ExpectationFailedException
51972 *
51973 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
51974 *
51975 * @see Assert::assertStringNotContainsStringIgnoringCase
51976 */
51977 function assertStringNotContainsStringIgnoringCase(string $needle, string $haystack, string $message = ''): void
51978 {
51979 \PHPUnit\Framework\Assert::assertStringNotContainsStringIgnoringCase(...func_get_args());
51980 }
51981 }
51982 if (!function_exists('PHPUnit\Framework\assertStringEndsWith')) {
51983 /**
51984 * Asserts that a string ends with a given suffix.
51985 *
51986 * @psalm-param non-empty-string $suffix
51987 *
51988 * @throws ExpectationFailedException
51989 * @throws InvalidArgumentException
51990 *
51991 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
51992 *
51993 * @see Assert::assertStringEndsWith
51994 */
51995 function assertStringEndsWith(string $suffix, string $string, string $message = ''): void
51996 {
51997 \PHPUnit\Framework\Assert::assertStringEndsWith(...func_get_args());
51998 }
51999 }
52000 if (!function_exists('PHPUnit\Framework\assertStringEndsNotWith')) {
52001 /**
52002 * Asserts that a string ends not with a given suffix.
52003 *
52004 * @psalm-param non-empty-string $suffix
52005 *
52006 * @throws ExpectationFailedException
52007 * @throws InvalidArgumentException
52008 *
52009 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
52010 *
52011 * @see Assert::assertStringEndsNotWith
52012 */
52013 function assertStringEndsNotWith(string $suffix, string $string, string $message = ''): void
52014 {
52015 \PHPUnit\Framework\Assert::assertStringEndsNotWith(...func_get_args());
52016 }
52017 }
52018 if (!function_exists('PHPUnit\Framework\assertXmlFileEqualsXmlFile')) {
52019 /**
52020 * Asserts that two XML files are equal.
52021 *
52022 * @throws Exception
52023 * @throws ExpectationFailedException
52024 * @throws XmlException
52025 *
52026 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
52027 *
52028 * @see Assert::assertXmlFileEqualsXmlFile
52029 */
52030 function assertXmlFileEqualsXmlFile(string $expectedFile, string $actualFile, string $message = ''): void
52031 {
52032 \PHPUnit\Framework\Assert::assertXmlFileEqualsXmlFile(...func_get_args());
52033 }
52034 }
52035 if (!function_exists('PHPUnit\Framework\assertXmlFileNotEqualsXmlFile')) {
52036 /**
52037 * Asserts that two XML files are not equal.
52038 *
52039 * @throws \PHPUnit\Util\Exception
52040 * @throws ExpectationFailedException
52041 *
52042 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
52043 *
52044 * @see Assert::assertXmlFileNotEqualsXmlFile
52045 */
52046 function assertXmlFileNotEqualsXmlFile(string $expectedFile, string $actualFile, string $message = ''): void
52047 {
52048 \PHPUnit\Framework\Assert::assertXmlFileNotEqualsXmlFile(...func_get_args());
52049 }
52050 }
52051 if (!function_exists('PHPUnit\Framework\assertXmlStringEqualsXmlFile')) {
52052 /**
52053 * Asserts that two XML documents are equal.
52054 *
52055 * @throws ExpectationFailedException
52056 * @throws XmlException
52057 *
52058 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
52059 *
52060 * @see Assert::assertXmlStringEqualsXmlFile
52061 */
52062 function assertXmlStringEqualsXmlFile(string $expectedFile, string $actualXml, string $message = ''): void
52063 {
52064 \PHPUnit\Framework\Assert::assertXmlStringEqualsXmlFile(...func_get_args());
52065 }
52066 }
52067 if (!function_exists('PHPUnit\Framework\assertXmlStringNotEqualsXmlFile')) {
52068 /**
52069 * Asserts that two XML documents are not equal.
52070 *
52071 * @throws ExpectationFailedException
52072 * @throws XmlException
52073 *
52074 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
52075 *
52076 * @see Assert::assertXmlStringNotEqualsXmlFile
52077 */
52078 function assertXmlStringNotEqualsXmlFile(string $expectedFile, string $actualXml, string $message = ''): void
52079 {
52080 \PHPUnit\Framework\Assert::assertXmlStringNotEqualsXmlFile(...func_get_args());
52081 }
52082 }
52083 if (!function_exists('PHPUnit\Framework\assertXmlStringEqualsXmlString')) {
52084 /**
52085 * Asserts that two XML documents are equal.
52086 *
52087 * @throws ExpectationFailedException
52088 * @throws XmlException
52089 *
52090 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
52091 *
52092 * @see Assert::assertXmlStringEqualsXmlString
52093 */
52094 function assertXmlStringEqualsXmlString(string $expectedXml, string $actualXml, string $message = ''): void
52095 {
52096 \PHPUnit\Framework\Assert::assertXmlStringEqualsXmlString(...func_get_args());
52097 }
52098 }
52099 if (!function_exists('PHPUnit\Framework\assertXmlStringNotEqualsXmlString')) {
52100 /**
52101 * Asserts that two XML documents are not equal.
52102 *
52103 * @throws ExpectationFailedException
52104 * @throws XmlException
52105 *
52106 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
52107 *
52108 * @see Assert::assertXmlStringNotEqualsXmlString
52109 */
52110 function assertXmlStringNotEqualsXmlString(string $expectedXml, string $actualXml, string $message = ''): void
52111 {
52112 \PHPUnit\Framework\Assert::assertXmlStringNotEqualsXmlString(...func_get_args());
52113 }
52114 }
52115 if (!function_exists('PHPUnit\Framework\assertThat')) {
52116 /**
52117 * Evaluates a PHPUnit\Framework\Constraint matcher object.
52118 *
52119 * @throws ExpectationFailedException
52120 *
52121 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
52122 *
52123 * @see Assert::assertThat
52124 */
52125 function assertThat(mixed $value, Constraint $constraint, string $message = ''): void
52126 {
52127 \PHPUnit\Framework\Assert::assertThat(...func_get_args());
52128 }
52129 }
52130 if (!function_exists('PHPUnit\Framework\assertJson')) {
52131 /**
52132 * Asserts that a string is a valid JSON string.
52133 *
52134 * @throws ExpectationFailedException
52135 *
52136 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
52137 *
52138 * @see Assert::assertJson
52139 */
52140 function assertJson(string $actual, string $message = ''): void
52141 {
52142 \PHPUnit\Framework\Assert::assertJson(...func_get_args());
52143 }
52144 }
52145 if (!function_exists('PHPUnit\Framework\assertJsonStringEqualsJsonString')) {
52146 /**
52147 * Asserts that two given JSON encoded objects or arrays are equal.
52148 *
52149 * @throws ExpectationFailedException
52150 *
52151 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
52152 *
52153 * @see Assert::assertJsonStringEqualsJsonString
52154 */
52155 function assertJsonStringEqualsJsonString(string $expectedJson, string $actualJson, string $message = ''): void
52156 {
52157 \PHPUnit\Framework\Assert::assertJsonStringEqualsJsonString(...func_get_args());
52158 }
52159 }
52160 if (!function_exists('PHPUnit\Framework\assertJsonStringNotEqualsJsonString')) {
52161 /**
52162 * Asserts that two given JSON encoded objects or arrays are not equal.
52163 *
52164 * @throws ExpectationFailedException
52165 *
52166 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
52167 *
52168 * @see Assert::assertJsonStringNotEqualsJsonString
52169 */
52170 function assertJsonStringNotEqualsJsonString(string $expectedJson, string $actualJson, string $message = ''): void
52171 {
52172 \PHPUnit\Framework\Assert::assertJsonStringNotEqualsJsonString(...func_get_args());
52173 }
52174 }
52175 if (!function_exists('PHPUnit\Framework\assertJsonStringEqualsJsonFile')) {
52176 /**
52177 * Asserts that the generated JSON encoded object and the content of the given file are equal.
52178 *
52179 * @throws ExpectationFailedException
52180 *
52181 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
52182 *
52183 * @see Assert::assertJsonStringEqualsJsonFile
52184 */
52185 function assertJsonStringEqualsJsonFile(string $expectedFile, string $actualJson, string $message = ''): void
52186 {
52187 \PHPUnit\Framework\Assert::assertJsonStringEqualsJsonFile(...func_get_args());
52188 }
52189 }
52190 if (!function_exists('PHPUnit\Framework\assertJsonStringNotEqualsJsonFile')) {
52191 /**
52192 * Asserts that the generated JSON encoded object and the content of the given file are not equal.
52193 *
52194 * @throws ExpectationFailedException
52195 *
52196 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
52197 *
52198 * @see Assert::assertJsonStringNotEqualsJsonFile
52199 */
52200 function assertJsonStringNotEqualsJsonFile(string $expectedFile, string $actualJson, string $message = ''): void
52201 {
52202 \PHPUnit\Framework\Assert::assertJsonStringNotEqualsJsonFile(...func_get_args());
52203 }
52204 }
52205 if (!function_exists('PHPUnit\Framework\assertJsonFileEqualsJsonFile')) {
52206 /**
52207 * Asserts that two JSON files are equal.
52208 *
52209 * @throws ExpectationFailedException
52210 *
52211 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
52212 *
52213 * @see Assert::assertJsonFileEqualsJsonFile
52214 */
52215 function assertJsonFileEqualsJsonFile(string $expectedFile, string $actualFile, string $message = ''): void
52216 {
52217 \PHPUnit\Framework\Assert::assertJsonFileEqualsJsonFile(...func_get_args());
52218 }
52219 }
52220 if (!function_exists('PHPUnit\Framework\assertJsonFileNotEqualsJsonFile')) {
52221 /**
52222 * Asserts that two JSON files are not equal.
52223 *
52224 * @throws ExpectationFailedException
52225 *
52226 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
52227 *
52228 * @see Assert::assertJsonFileNotEqualsJsonFile
52229 */
52230 function assertJsonFileNotEqualsJsonFile(string $expectedFile, string $actualFile, string $message = ''): void
52231 {
52232 \PHPUnit\Framework\Assert::assertJsonFileNotEqualsJsonFile(...func_get_args());
52233 }
52234 }
52235 if (!function_exists('PHPUnit\Framework\logicalAnd')) {
52236 function logicalAnd(mixed ...$constraints): LogicalAnd
52237 {
52238 return \PHPUnit\Framework\Assert::logicalAnd(...func_get_args());
52239 }
52240 }
52241 if (!function_exists('PHPUnit\Framework\logicalOr')) {
52242 function logicalOr(mixed ...$constraints): LogicalOr
52243 {
52244 return \PHPUnit\Framework\Assert::logicalOr(...func_get_args());
52245 }
52246 }
52247 if (!function_exists('PHPUnit\Framework\logicalNot')) {
52248 function logicalNot(Constraint $constraint): LogicalNot
52249 {
52250 return \PHPUnit\Framework\Assert::logicalNot(...func_get_args());
52251 }
52252 }
52253 if (!function_exists('PHPUnit\Framework\logicalXor')) {
52254 function logicalXor(mixed ...$constraints): LogicalXor
52255 {
52256 return \PHPUnit\Framework\Assert::logicalXor(...func_get_args());
52257 }
52258 }
52259 if (!function_exists('PHPUnit\Framework\anything')) {
52260 function anything(): IsAnything
52261 {
52262 return \PHPUnit\Framework\Assert::anything(...func_get_args());
52263 }
52264 }
52265 if (!function_exists('PHPUnit\Framework\isTrue')) {
52266 function isTrue(): IsTrue
52267 {
52268 return \PHPUnit\Framework\Assert::isTrue(...func_get_args());
52269 }
52270 }
52271 if (!function_exists('PHPUnit\Framework\isFalse')) {
52272 function isFalse(): IsFalse
52273 {
52274 return \PHPUnit\Framework\Assert::isFalse(...func_get_args());
52275 }
52276 }
52277 if (!function_exists('PHPUnit\Framework\isJson')) {
52278 function isJson(): IsJson
52279 {
52280 return \PHPUnit\Framework\Assert::isJson(...func_get_args());
52281 }
52282 }
52283 if (!function_exists('PHPUnit\Framework\isNull')) {
52284 function isNull(): IsNull
52285 {
52286 return \PHPUnit\Framework\Assert::isNull(...func_get_args());
52287 }
52288 }
52289 if (!function_exists('PHPUnit\Framework\isFinite')) {
52290 function isFinite(): IsFinite
52291 {
52292 return \PHPUnit\Framework\Assert::isFinite(...func_get_args());
52293 }
52294 }
52295 if (!function_exists('PHPUnit\Framework\isInfinite')) {
52296 function isInfinite(): IsInfinite
52297 {
52298 return \PHPUnit\Framework\Assert::isInfinite(...func_get_args());
52299 }
52300 }
52301 if (!function_exists('PHPUnit\Framework\isNan')) {
52302 function isNan(): IsNan
52303 {
52304 return \PHPUnit\Framework\Assert::isNan(...func_get_args());
52305 }
52306 }
52307 if (!function_exists('PHPUnit\Framework\containsEqual')) {
52308 function containsEqual(mixed $value): TraversableContainsEqual
52309 {
52310 return \PHPUnit\Framework\Assert::containsEqual(...func_get_args());
52311 }
52312 }
52313 if (!function_exists('PHPUnit\Framework\containsIdentical')) {
52314 function containsIdentical(mixed $value): TraversableContainsIdentical
52315 {
52316 return \PHPUnit\Framework\Assert::containsIdentical(...func_get_args());
52317 }
52318 }
52319 if (!function_exists('PHPUnit\Framework\containsOnly')) {
52320 function containsOnly(string $type): TraversableContainsOnly
52321 {
52322 return \PHPUnit\Framework\Assert::containsOnly(...func_get_args());
52323 }
52324 }
52325 if (!function_exists('PHPUnit\Framework\containsOnlyInstancesOf')) {
52326 function containsOnlyInstancesOf(string $className): TraversableContainsOnly
52327 {
52328 return \PHPUnit\Framework\Assert::containsOnlyInstancesOf(...func_get_args());
52329 }
52330 }
52331 if (!function_exists('PHPUnit\Framework\arrayHasKey')) {
52332 function arrayHasKey(mixed $key): ArrayHasKey
52333 {
52334 return \PHPUnit\Framework\Assert::arrayHasKey(...func_get_args());
52335 }
52336 }
52337 if (!function_exists('PHPUnit\Framework\isList')) {
52338 function isList(): IsList
52339 {
52340 return \PHPUnit\Framework\Assert::isList(...func_get_args());
52341 }
52342 }
52343 if (!function_exists('PHPUnit\Framework\equalTo')) {
52344 function equalTo(mixed $value): IsEqual
52345 {
52346 return \PHPUnit\Framework\Assert::equalTo(...func_get_args());
52347 }
52348 }
52349 if (!function_exists('PHPUnit\Framework\equalToCanonicalizing')) {
52350 function equalToCanonicalizing(mixed $value): IsEqualCanonicalizing
52351 {
52352 return \PHPUnit\Framework\Assert::equalToCanonicalizing(...func_get_args());
52353 }
52354 }
52355 if (!function_exists('PHPUnit\Framework\equalToIgnoringCase')) {
52356 function equalToIgnoringCase(mixed $value): IsEqualIgnoringCase
52357 {
52358 return \PHPUnit\Framework\Assert::equalToIgnoringCase(...func_get_args());
52359 }
52360 }
52361 if (!function_exists('PHPUnit\Framework\equalToWithDelta')) {
52362 function equalToWithDelta(mixed $value, float $delta): IsEqualWithDelta
52363 {
52364 return \PHPUnit\Framework\Assert::equalToWithDelta(...func_get_args());
52365 }
52366 }
52367 if (!function_exists('PHPUnit\Framework\isEmpty')) {
52368 function isEmpty(): IsEmpty
52369 {
52370 return \PHPUnit\Framework\Assert::isEmpty(...func_get_args());
52371 }
52372 }
52373 if (!function_exists('PHPUnit\Framework\isWritable')) {
52374 function isWritable(): IsWritable
52375 {
52376 return \PHPUnit\Framework\Assert::isWritable(...func_get_args());
52377 }
52378 }
52379 if (!function_exists('PHPUnit\Framework\isReadable')) {
52380 function isReadable(): IsReadable
52381 {
52382 return \PHPUnit\Framework\Assert::isReadable(...func_get_args());
52383 }
52384 }
52385 if (!function_exists('PHPUnit\Framework\directoryExists')) {
52386 function directoryExists(): DirectoryExists
52387 {
52388 return \PHPUnit\Framework\Assert::directoryExists(...func_get_args());
52389 }
52390 }
52391 if (!function_exists('PHPUnit\Framework\fileExists')) {
52392 function fileExists(): FileExists
52393 {
52394 return \PHPUnit\Framework\Assert::fileExists(...func_get_args());
52395 }
52396 }
52397 if (!function_exists('PHPUnit\Framework\greaterThan')) {
52398 function greaterThan(mixed $value): GreaterThan
52399 {
52400 return \PHPUnit\Framework\Assert::greaterThan(...func_get_args());
52401 }
52402 }
52403 if (!function_exists('PHPUnit\Framework\greaterThanOrEqual')) {
52404 function greaterThanOrEqual(mixed $value): LogicalOr
52405 {
52406 return \PHPUnit\Framework\Assert::greaterThanOrEqual(...func_get_args());
52407 }
52408 }
52409 if (!function_exists('PHPUnit\Framework\identicalTo')) {
52410 function identicalTo(mixed $value): IsIdentical
52411 {
52412 return \PHPUnit\Framework\Assert::identicalTo(...func_get_args());
52413 }
52414 }
52415 if (!function_exists('PHPUnit\Framework\isInstanceOf')) {
52416 function isInstanceOf(string $className): IsInstanceOf
52417 {
52418 return \PHPUnit\Framework\Assert::isInstanceOf(...func_get_args());
52419 }
52420 }
52421 if (!function_exists('PHPUnit\Framework\isType')) {
52422 function isType(string $type): IsType
52423 {
52424 return \PHPUnit\Framework\Assert::isType(...func_get_args());
52425 }
52426 }
52427 if (!function_exists('PHPUnit\Framework\lessThan')) {
52428 function lessThan(mixed $value): LessThan
52429 {
52430 return \PHPUnit\Framework\Assert::lessThan(...func_get_args());
52431 }
52432 }
52433 if (!function_exists('PHPUnit\Framework\lessThanOrEqual')) {
52434 function lessThanOrEqual(mixed $value): LogicalOr
52435 {
52436 return \PHPUnit\Framework\Assert::lessThanOrEqual(...func_get_args());
52437 }
52438 }
52439 if (!function_exists('PHPUnit\Framework\matchesRegularExpression')) {
52440 function matchesRegularExpression(string $pattern): RegularExpression
52441 {
52442 return \PHPUnit\Framework\Assert::matchesRegularExpression(...func_get_args());
52443 }
52444 }
52445 if (!function_exists('PHPUnit\Framework\matches')) {
52446 function matches(string $string): StringMatchesFormatDescription
52447 {
52448 return \PHPUnit\Framework\Assert::matches(...func_get_args());
52449 }
52450 }
52451 if (!function_exists('PHPUnit\Framework\stringStartsWith')) {
52452 function stringStartsWith(string $prefix): StringStartsWith
52453 {
52454 return \PHPUnit\Framework\Assert::stringStartsWith(...func_get_args());
52455 }
52456 }
52457 if (!function_exists('PHPUnit\Framework\stringContains')) {
52458 function stringContains(string $string, bool $case = \true): StringContains
52459 {
52460 return \PHPUnit\Framework\Assert::stringContains(...func_get_args());
52461 }
52462 }
52463 if (!function_exists('PHPUnit\Framework\stringEndsWith')) {
52464 function stringEndsWith(string $suffix): StringEndsWith
52465 {
52466 return \PHPUnit\Framework\Assert::stringEndsWith(...func_get_args());
52467 }
52468 }
52469 if (!function_exists('PHPUnit\Framework\stringEqualsStringIgnoringLineEndings')) {
52470 function stringEqualsStringIgnoringLineEndings(string $string): StringEqualsStringIgnoringLineEndings
52471 {
52472 return \PHPUnit\Framework\Assert::stringEqualsStringIgnoringLineEndings(...func_get_args());
52473 }
52474 }
52475 if (!function_exists('PHPUnit\Framework\countOf')) {
52476 function countOf(int $count): Count
52477 {
52478 return \PHPUnit\Framework\Assert::countOf(...func_get_args());
52479 }
52480 }
52481 if (!function_exists('PHPUnit\Framework\objectEquals')) {
52482 function objectEquals(object $object, string $method = 'equals'): ObjectEquals
52483 {
52484 return \PHPUnit\Framework\Assert::objectEquals(...func_get_args());
52485 }
52486 }
52487 if (!function_exists('PHPUnit\Framework\callback')) {
52488 /**
52489 * @psalm-template CallbackInput of mixed
52490 *
52491 * @psalm-param callable(CallbackInput $callback): bool $callback
52492 *
52493 * @psalm-return Callback<CallbackInput>
52494 */
52495 function callback(callable $callback): Callback
52496 {
52497 return \PHPUnit\Framework\Assert::callback($callback);
52498 }
52499 }
52500 if (!function_exists('PHPUnit\Framework\any')) {
52501 /**
52502 * Returns a matcher that matches when the method is executed
52503 * zero or more times.
52504 */
52505 function any(): AnyInvokedCountMatcher
52506 {
52507 return new AnyInvokedCountMatcher();
52508 }
52509 }
52510 if (!function_exists('PHPUnit\Framework\never')) {
52511 /**
52512 * Returns a matcher that matches when the method is never executed.
52513 */
52514 function never(): InvokedCountMatcher
52515 {
52516 return new InvokedCountMatcher(0);
52517 }
52518 }
52519 if (!function_exists('PHPUnit\Framework\atLeast')) {
52520 /**
52521 * Returns a matcher that matches when the method is executed
52522 * at least N times.
52523 */
52524 function atLeast(int $requiredInvocations): InvokedAtLeastCountMatcher
52525 {
52526 return new InvokedAtLeastCountMatcher($requiredInvocations);
52527 }
52528 }
52529 if (!function_exists('PHPUnit\Framework\atLeastOnce')) {
52530 /**
52531 * Returns a matcher that matches when the method is executed at least once.
52532 */
52533 function atLeastOnce(): InvokedAtLeastOnceMatcher
52534 {
52535 return new InvokedAtLeastOnceMatcher();
52536 }
52537 }
52538 if (!function_exists('PHPUnit\Framework\once')) {
52539 /**
52540 * Returns a matcher that matches when the method is executed exactly once.
52541 */
52542 function once(): InvokedCountMatcher
52543 {
52544 return new InvokedCountMatcher(1);
52545 }
52546 }
52547 if (!function_exists('PHPUnit\Framework\exactly')) {
52548 /**
52549 * Returns a matcher that matches when the method is executed
52550 * exactly $count times.
52551 */
52552 function exactly(int $count): InvokedCountMatcher
52553 {
52554 return new InvokedCountMatcher($count);
52555 }
52556 }
52557 if (!function_exists('PHPUnit\Framework\atMost')) {
52558 /**
52559 * Returns a matcher that matches when the method is executed
52560 * at most N times.
52561 */
52562 function atMost(int $allowedInvocations): InvokedAtMostCountMatcher
52563 {
52564 return new InvokedAtMostCountMatcher($allowedInvocations);
52565 }
52566 }
52567 if (!function_exists('PHPUnit\Framework\returnValue')) {
52568 function returnValue(mixed $value): ReturnStub
52569 {
52570 return new ReturnStub($value);
52571 }
52572 }
52573 if (!function_exists('PHPUnit\Framework\returnValueMap')) {
52574 function returnValueMap(array $valueMap): ReturnValueMapStub
52575 {
52576 return new ReturnValueMapStub($valueMap);
52577 }
52578 }
52579 if (!function_exists('PHPUnit\Framework\returnArgument')) {
52580 function returnArgument(int $argumentIndex): ReturnArgumentStub
52581 {
52582 return new ReturnArgumentStub($argumentIndex);
52583 }
52584 }
52585 if (!function_exists('PHPUnit\Framework\returnCallback')) {
52586 function returnCallback(callable $callback): ReturnCallbackStub
52587 {
52588 return new ReturnCallbackStub($callback);
52589 }
52590 }
52591 if (!function_exists('PHPUnit\Framework\returnSelf')) {
52592 /**
52593 * Returns the current object.
52594 *
52595 * This method is useful when mocking a fluent interface.
52596 */
52597 function returnSelf(): ReturnSelfStub
52598 {
52599 return new ReturnSelfStub();
52600 }
52601 }
52602 if (!function_exists('PHPUnit\Framework\throwException')) {
52603 function throwException(Throwable $exception): ExceptionStub
52604 {
52605 return new ExceptionStub($exception);
52606 }
52607 }
52608 if (!function_exists('PHPUnit\Framework\onConsecutiveCalls')) {
52609 function onConsecutiveCalls(): ConsecutiveCallsStub
52610 {
52611 $arguments = func_get_args();
52612 return new ConsecutiveCallsStub($arguments);
52613 }
52614 }
52615 <?php
52616
52617 declare (strict_types=1);
52618 /*
52619 * This file is part of PHPUnit.
52620 *
52621 * (c) Sebastian Bergmann <sebastian@phpunit.de>
52622 *
52623 * For the full copyright and license information, please view the LICENSE
52624 * file that was distributed with this source code.
52625 */
52626 namespace PHPUnit\Framework\Attributes;
52627
52628 use Attribute;
52629 /**
52630 * @psalm-immutable
52631 *
52632 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
52633 */
52634 #[Attribute(Attribute::TARGET_METHOD)]
52635 final class After
52636 {
52637 }
52638 <?php
52639
52640 declare (strict_types=1);
52641 /*
52642 * This file is part of PHPUnit.
52643 *
52644 * (c) Sebastian Bergmann <sebastian@phpunit.de>
52645 *
52646 * For the full copyright and license information, please view the LICENSE
52647 * file that was distributed with this source code.
52648 */
52649 namespace PHPUnit\Framework\Attributes;
52650
52651 use Attribute;
52652 /**
52653 * @psalm-immutable
52654 *
52655 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
52656 */
52657 #[Attribute(Attribute::TARGET_METHOD)]
52658 final class AfterClass
52659 {
52660 }
52661 <?php
52662
52663 declare (strict_types=1);
52664 /*
52665 * This file is part of PHPUnit.
52666 *
52667 * (c) Sebastian Bergmann <sebastian@phpunit.de>
52668 *
52669 * For the full copyright and license information, please view the LICENSE
52670 * file that was distributed with this source code.
52671 */
52672 namespace PHPUnit\Framework\Attributes;
52673
52674 use Attribute;
52675 /**
52676 * @psalm-immutable
52677 *
52678 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
52679 */
52680 #[Attribute(Attribute::TARGET_CLASS | Attribute::TARGET_METHOD)]
52681 final class BackupGlobals
52682 {
52683 private readonly bool $enabled;
52684 public function __construct(bool $enabled)
52685 {
52686 $this->enabled = $enabled;
52687 }
52688 public function enabled(): bool
52689 {
52690 return $this->enabled;
52691 }
52692 }
52693 <?php
52694
52695 declare (strict_types=1);
52696 /*
52697 * This file is part of PHPUnit.
52698 *
52699 * (c) Sebastian Bergmann <sebastian@phpunit.de>
52700 *
52701 * For the full copyright and license information, please view the LICENSE
52702 * file that was distributed with this source code.
52703 */
52704 namespace PHPUnit\Framework\Attributes;
52705
52706 use Attribute;
52707 /**
52708 * @psalm-immutable
52709 *
52710 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
52711 */
52712 #[Attribute(Attribute::TARGET_CLASS | Attribute::TARGET_METHOD)]
52713 final class BackupStaticProperties
52714 {
52715 private readonly bool $enabled;
52716 public function __construct(bool $enabled)
52717 {
52718 $this->enabled = $enabled;
52719 }
52720 public function enabled(): bool
52721 {
52722 return $this->enabled;
52723 }
52724 }
52725 <?php
52726
52727 declare (strict_types=1);
52728 /*
52729 * This file is part of PHPUnit.
52730 *
52731 * (c) Sebastian Bergmann <sebastian@phpunit.de>
52732 *
52733 * For the full copyright and license information, please view the LICENSE
52734 * file that was distributed with this source code.
52735 */
52736 namespace PHPUnit\Framework\Attributes;
52737
52738 use Attribute;
52739 /**
52740 * @psalm-immutable
52741 *
52742 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
52743 */
52744 #[Attribute(Attribute::TARGET_METHOD)]
52745 final class Before
52746 {
52747 }
52748 <?php
52749
52750 declare (strict_types=1);
52751 /*
52752 * This file is part of PHPUnit.
52753 *
52754 * (c) Sebastian Bergmann <sebastian@phpunit.de>
52755 *
52756 * For the full copyright and license information, please view the LICENSE
52757 * file that was distributed with this source code.
52758 */
52759 namespace PHPUnit\Framework\Attributes;
52760
52761 use Attribute;
52762 /**
52763 * @psalm-immutable
52764 *
52765 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
52766 */
52767 #[Attribute(Attribute::TARGET_METHOD)]
52768 final class BeforeClass
52769 {
52770 }
52771 <?php
52772
52773 declare (strict_types=1);
52774 /*
52775 * This file is part of PHPUnit.
52776 *
52777 * (c) Sebastian Bergmann <sebastian@phpunit.de>
52778 *
52779 * For the full copyright and license information, please view the LICENSE
52780 * file that was distributed with this source code.
52781 */
52782 namespace PHPUnit\Framework\Attributes;
52783
52784 use Attribute;
52785 /**
52786 * @psalm-immutable
52787 *
52788 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
52789 *
52790 * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5236
52791 */
52792 #[Attribute(Attribute::TARGET_CLASS | Attribute::TARGET_METHOD)]
52793 final class CodeCoverageIgnore
52794 {
52795 }
52796 <?php
52797
52798 declare (strict_types=1);
52799 /*
52800 * This file is part of PHPUnit.
52801 *
52802 * (c) Sebastian Bergmann <sebastian@phpunit.de>
52803 *
52804 * For the full copyright and license information, please view the LICENSE
52805 * file that was distributed with this source code.
52806 */
52807 namespace PHPUnit\Framework\Attributes;
52808
52809 use Attribute;
52810 /**
52811 * @psalm-immutable
52812 *
52813 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
52814 */
52815 #[Attribute(Attribute::TARGET_CLASS | Attribute::IS_REPEATABLE)]
52816 final class CoversClass
52817 {
52818 /**
52819 * @psalm-var class-string
52820 */
52821 private readonly string $className;
52822 /**
52823 * @psalm-param class-string $className
52824 */
52825 public function __construct(string $className)
52826 {
52827 $this->className = $className;
52828 }
52829 /**
52830 * @psalm-return class-string
52831 */
52832 public function className(): string
52833 {
52834 return $this->className;
52835 }
52836 }
52837 <?php
52838
52839 declare (strict_types=1);
52840 /*
52841 * This file is part of PHPUnit.
52842 *
52843 * (c) Sebastian Bergmann <sebastian@phpunit.de>
52844 *
52845 * For the full copyright and license information, please view the LICENSE
52846 * file that was distributed with this source code.
52847 */
52848 namespace PHPUnit\Framework\Attributes;
52849
52850 use Attribute;
52851 /**
52852 * @psalm-immutable
52853 *
52854 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
52855 */
52856 #[Attribute(Attribute::TARGET_CLASS | Attribute::IS_REPEATABLE)]
52857 final class CoversFunction
52858 {
52859 /**
52860 * @psalm-var non-empty-string
52861 */
52862 private readonly string $functionName;
52863 /**
52864 * @psalm-param non-empty-string $functionName
52865 */
52866 public function __construct(string $functionName)
52867 {
52868 $this->functionName = $functionName;
52869 }
52870 /**
52871 * @psalm-return non-empty-string
52872 */
52873 public function functionName(): string
52874 {
52875 return $this->functionName;
52876 }
52877 }
52878 <?php
52879
52880 declare (strict_types=1);
52881 /*
52882 * This file is part of PHPUnit.
52883 *
52884 * (c) Sebastian Bergmann <sebastian@phpunit.de>
52885 *
52886 * For the full copyright and license information, please view the LICENSE
52887 * file that was distributed with this source code.
52888 */
52889 namespace PHPUnit\Framework\Attributes;
52890
52891 use Attribute;
52892 /**
52893 * @psalm-immutable
52894 *
52895 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
52896 */
52897 #[Attribute(Attribute::TARGET_CLASS | Attribute::TARGET_METHOD)]
52898 final class CoversNothing
52899 {
52900 }
52901 <?php
52902
52903 declare (strict_types=1);
52904 /*
52905 * This file is part of PHPUnit.
52906 *
52907 * (c) Sebastian Bergmann <sebastian@phpunit.de>
52908 *
52909 * For the full copyright and license information, please view the LICENSE
52910 * file that was distributed with this source code.
52911 */
52912 namespace PHPUnit\Framework\Attributes;
52913
52914 use Attribute;
52915 /**
52916 * @psalm-immutable
52917 *
52918 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
52919 */
52920 #[Attribute(Attribute::TARGET_METHOD | Attribute::IS_REPEATABLE)]
52921 final class DataProvider
52922 {
52923 /**
52924 * @psalm-var non-empty-string
52925 */
52926 private readonly string $methodName;
52927 /**
52928 * @psalm-param non-empty-string $methodName
52929 */
52930 public function __construct(string $methodName)
52931 {
52932 $this->methodName = $methodName;
52933 }
52934 /**
52935 * @psalm-return non-empty-string
52936 */
52937 public function methodName(): string
52938 {
52939 return $this->methodName;
52940 }
52941 }
52942 <?php
52943
52944 declare (strict_types=1);
52945 /*
52946 * This file is part of PHPUnit.
52947 *
52948 * (c) Sebastian Bergmann <sebastian@phpunit.de>
52949 *
52950 * For the full copyright and license information, please view the LICENSE
52951 * file that was distributed with this source code.
52952 */
52953 namespace PHPUnit\Framework\Attributes;
52954
52955 use Attribute;
52956 /**
52957 * @psalm-immutable
52958 *
52959 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
52960 */
52961 #[Attribute(Attribute::TARGET_METHOD | Attribute::IS_REPEATABLE)]
52962 final class DataProviderExternal
52963 {
52964 /**
52965 * @psalm-var class-string
52966 */
52967 private readonly string $className;
52968 /**
52969 * @psalm-var non-empty-string
52970 */
52971 private readonly string $methodName;
52972 /**
52973 * @psalm-param class-string $className
52974 * @psalm-param non-empty-string $methodName
52975 */
52976 public function __construct(string $className, string $methodName)
52977 {
52978 $this->className = $className;
52979 $this->methodName = $methodName;
52980 }
52981 /**
52982 * @psalm-return class-string
52983 */
52984 public function className(): string
52985 {
52986 return $this->className;
52987 }
52988 /**
52989 * @psalm-return non-empty-string
52990 */
52991 public function methodName(): string
52992 {
52993 return $this->methodName;
52994 }
52995 }
52996 <?php
52997
52998 declare (strict_types=1);
52999 /*
53000 * This file is part of PHPUnit.
53001 *
53002 * (c) Sebastian Bergmann <sebastian@phpunit.de>
53003 *
53004 * For the full copyright and license information, please view the LICENSE
53005 * file that was distributed with this source code.
53006 */
53007 namespace PHPUnit\Framework\Attributes;
53008
53009 use Attribute;
53010 /**
53011 * @psalm-immutable
53012 *
53013 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
53014 */
53015 #[Attribute(Attribute::TARGET_METHOD | Attribute::IS_REPEATABLE)]
53016 final class Depends
53017 {
53018 /**
53019 * @psalm-var non-empty-string
53020 */
53021 private readonly string $methodName;
53022 /**
53023 * @psalm-param non-empty-string $methodName
53024 */
53025 public function __construct(string $methodName)
53026 {
53027 $this->methodName = $methodName;
53028 }
53029 /**
53030 * @psalm-return non-empty-string
53031 */
53032 public function methodName(): string
53033 {
53034 return $this->methodName;
53035 }
53036 }
53037 <?php
53038
53039 declare (strict_types=1);
53040 /*
53041 * This file is part of PHPUnit.
53042 *
53043 * (c) Sebastian Bergmann <sebastian@phpunit.de>
53044 *
53045 * For the full copyright and license information, please view the LICENSE
53046 * file that was distributed with this source code.
53047 */
53048 namespace PHPUnit\Framework\Attributes;
53049
53050 use Attribute;
53051 /**
53052 * @psalm-immutable
53053 *
53054 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
53055 */
53056 #[Attribute(Attribute::TARGET_METHOD | Attribute::IS_REPEATABLE)]
53057 final class DependsExternal
53058 {
53059 /**
53060 * @psalm-var class-string
53061 */
53062 private readonly string $className;
53063 /**
53064 * @psalm-var non-empty-string
53065 */
53066 private readonly string $methodName;
53067 /**
53068 * @psalm-param class-string $className
53069 * @psalm-param non-empty-string $methodName
53070 */
53071 public function __construct(string $className, string $methodName)
53072 {
53073 $this->className = $className;
53074 $this->methodName = $methodName;
53075 }
53076 /**
53077 * @psalm-return class-string
53078 */
53079 public function className(): string
53080 {
53081 return $this->className;
53082 }
53083 /**
53084 * @psalm-return non-empty-string
53085 */
53086 public function methodName(): string
53087 {
53088 return $this->methodName;
53089 }
53090 }
53091 <?php
53092
53093 declare (strict_types=1);
53094 /*
53095 * This file is part of PHPUnit.
53096 *
53097 * (c) Sebastian Bergmann <sebastian@phpunit.de>
53098 *
53099 * For the full copyright and license information, please view the LICENSE
53100 * file that was distributed with this source code.
53101 */
53102 namespace PHPUnit\Framework\Attributes;
53103
53104 use Attribute;
53105 /**
53106 * @psalm-immutable
53107 *
53108 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
53109 */
53110 #[Attribute(Attribute::TARGET_METHOD | Attribute::IS_REPEATABLE)]
53111 final class DependsExternalUsingDeepClone
53112 {
53113 /**
53114 * @psalm-var class-string
53115 */
53116 private readonly string $className;
53117 /**
53118 * @psalm-var non-empty-string
53119 */
53120 private readonly string $methodName;
53121 /**
53122 * @psalm-param class-string $className
53123 * @psalm-param non-empty-string $methodName
53124 */
53125 public function __construct(string $className, string $methodName)
53126 {
53127 $this->className = $className;
53128 $this->methodName = $methodName;
53129 }
53130 /**
53131 * @psalm-return class-string
53132 */
53133 public function className(): string
53134 {
53135 return $this->className;
53136 }
53137 /**
53138 * @psalm-return non-empty-string
53139 */
53140 public function methodName(): string
53141 {
53142 return $this->methodName;
53143 }
53144 }
53145 <?php
53146
53147 declare (strict_types=1);
53148 /*
53149 * This file is part of PHPUnit.
53150 *
53151 * (c) Sebastian Bergmann <sebastian@phpunit.de>
53152 *
53153 * For the full copyright and license information, please view the LICENSE
53154 * file that was distributed with this source code.
53155 */
53156 namespace PHPUnit\Framework\Attributes;
53157
53158 use Attribute;
53159 /**
53160 * @psalm-immutable
53161 *
53162 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
53163 */
53164 #[Attribute(Attribute::TARGET_METHOD | Attribute::IS_REPEATABLE)]
53165 final class DependsExternalUsingShallowClone
53166 {
53167 /**
53168 * @psalm-var class-string
53169 */
53170 private readonly string $className;
53171 /**
53172 * @psalm-var non-empty-string
53173 */
53174 private readonly string $methodName;
53175 /**
53176 * @psalm-param class-string $className
53177 * @psalm-param non-empty-string $methodName
53178 */
53179 public function __construct(string $className, string $methodName)
53180 {
53181 $this->className = $className;
53182 $this->methodName = $methodName;
53183 }
53184 /**
53185 * @psalm-return class-string
53186 */
53187 public function className(): string
53188 {
53189 return $this->className;
53190 }
53191 /**
53192 * @psalm-return non-empty-string
53193 */
53194 public function methodName(): string
53195 {
53196 return $this->methodName;
53197 }
53198 }
53199 <?php
53200
53201 declare (strict_types=1);
53202 /*
53203 * This file is part of PHPUnit.
53204 *
53205 * (c) Sebastian Bergmann <sebastian@phpunit.de>
53206 *
53207 * For the full copyright and license information, please view the LICENSE
53208 * file that was distributed with this source code.
53209 */
53210 namespace PHPUnit\Framework\Attributes;
53211
53212 use Attribute;
53213 /**
53214 * @psalm-immutable
53215 *
53216 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
53217 */
53218 #[Attribute(Attribute::TARGET_METHOD | Attribute::IS_REPEATABLE)]
53219 final class DependsOnClass
53220 {
53221 /**
53222 * @psalm-var class-string
53223 */
53224 private readonly string $className;
53225 /**
53226 * @psalm-param class-string $className
53227 */
53228 public function __construct(string $className)
53229 {
53230 $this->className = $className;
53231 }
53232 /**
53233 * @psalm-return class-string
53234 */
53235 public function className(): string
53236 {
53237 return $this->className;
53238 }
53239 }
53240 <?php
53241
53242 declare (strict_types=1);
53243 /*
53244 * This file is part of PHPUnit.
53245 *
53246 * (c) Sebastian Bergmann <sebastian@phpunit.de>
53247 *
53248 * For the full copyright and license information, please view the LICENSE
53249 * file that was distributed with this source code.
53250 */
53251 namespace PHPUnit\Framework\Attributes;
53252
53253 use Attribute;
53254 /**
53255 * @psalm-immutable
53256 *
53257 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
53258 */
53259 #[Attribute(Attribute::TARGET_METHOD | Attribute::IS_REPEATABLE)]
53260 final class DependsOnClassUsingDeepClone
53261 {
53262 /**
53263 * @psalm-var class-string
53264 */
53265 private readonly string $className;
53266 /**
53267 * @psalm-param class-string $className
53268 */
53269 public function __construct(string $className)
53270 {
53271 $this->className = $className;
53272 }
53273 /**
53274 * @psalm-return class-string
53275 */
53276 public function className(): string
53277 {
53278 return $this->className;
53279 }
53280 }
53281 <?php
53282
53283 declare (strict_types=1);
53284 /*
53285 * This file is part of PHPUnit.
53286 *
53287 * (c) Sebastian Bergmann <sebastian@phpunit.de>
53288 *
53289 * For the full copyright and license information, please view the LICENSE
53290 * file that was distributed with this source code.
53291 */
53292 namespace PHPUnit\Framework\Attributes;
53293
53294 use Attribute;
53295 /**
53296 * @psalm-immutable
53297 *
53298 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
53299 */
53300 #[Attribute(Attribute::TARGET_METHOD | Attribute::IS_REPEATABLE)]
53301 final class DependsOnClassUsingShallowClone
53302 {
53303 /**
53304 * @psalm-var class-string
53305 */
53306 private readonly string $className;
53307 /**
53308 * @psalm-param class-string $className
53309 */
53310 public function __construct(string $className)
53311 {
53312 $this->className = $className;
53313 }
53314 /**
53315 * @psalm-return class-string
53316 */
53317 public function className(): string
53318 {
53319 return $this->className;
53320 }
53321 }
53322 <?php
53323
53324 declare (strict_types=1);
53325 /*
53326 * This file is part of PHPUnit.
53327 *
53328 * (c) Sebastian Bergmann <sebastian@phpunit.de>
53329 *
53330 * For the full copyright and license information, please view the LICENSE
53331 * file that was distributed with this source code.
53332 */
53333 namespace PHPUnit\Framework\Attributes;
53334
53335 use Attribute;
53336 /**
53337 * @psalm-immutable
53338 *
53339 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
53340 */
53341 #[Attribute(Attribute::TARGET_METHOD | Attribute::IS_REPEATABLE)]
53342 final class DependsUsingDeepClone
53343 {
53344 /**
53345 * @psalm-var non-empty-string
53346 */
53347 private readonly string $methodName;
53348 /**
53349 * @psalm-param non-empty-string $methodName
53350 */
53351 public function __construct(string $methodName)
53352 {
53353 $this->methodName = $methodName;
53354 }
53355 /**
53356 * @psalm-return non-empty-string
53357 */
53358 public function methodName(): string
53359 {
53360 return $this->methodName;
53361 }
53362 }
53363 <?php
53364
53365 declare (strict_types=1);
53366 /*
53367 * This file is part of PHPUnit.
53368 *
53369 * (c) Sebastian Bergmann <sebastian@phpunit.de>
53370 *
53371 * For the full copyright and license information, please view the LICENSE
53372 * file that was distributed with this source code.
53373 */
53374 namespace PHPUnit\Framework\Attributes;
53375
53376 use Attribute;
53377 /**
53378 * @psalm-immutable
53379 *
53380 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
53381 */
53382 #[Attribute(Attribute::TARGET_METHOD | Attribute::IS_REPEATABLE)]
53383 final class DependsUsingShallowClone
53384 {
53385 /**
53386 * @psalm-var non-empty-string
53387 */
53388 private readonly string $methodName;
53389 /**
53390 * @psalm-param non-empty-string $methodName
53391 */
53392 public function __construct(string $methodName)
53393 {
53394 $this->methodName = $methodName;
53395 }
53396 /**
53397 * @psalm-return non-empty-string
53398 */
53399 public function methodName(): string
53400 {
53401 return $this->methodName;
53402 }
53403 }
53404 <?php
53405
53406 declare (strict_types=1);
53407 /*
53408 * This file is part of PHPUnit.
53409 *
53410 * (c) Sebastian Bergmann <sebastian@phpunit.de>
53411 *
53412 * For the full copyright and license information, please view the LICENSE
53413 * file that was distributed with this source code.
53414 */
53415 namespace PHPUnit\Framework\Attributes;
53416
53417 use Attribute;
53418 /**
53419 * @psalm-immutable
53420 *
53421 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
53422 */
53423 #[Attribute(Attribute::TARGET_CLASS | Attribute::TARGET_METHOD)]
53424 final class DoesNotPerformAssertions
53425 {
53426 }
53427 <?php
53428
53429 declare (strict_types=1);
53430 /*
53431 * This file is part of PHPUnit.
53432 *
53433 * (c) Sebastian Bergmann <sebastian@phpunit.de>
53434 *
53435 * For the full copyright and license information, please view the LICENSE
53436 * file that was distributed with this source code.
53437 */
53438 namespace PHPUnit\Framework\Attributes;
53439
53440 use Attribute;
53441 /**
53442 * @psalm-immutable
53443 *
53444 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
53445 */
53446 #[Attribute(Attribute::TARGET_CLASS | Attribute::TARGET_METHOD | Attribute::IS_REPEATABLE)]
53447 final class ExcludeGlobalVariableFromBackup
53448 {
53449 /**
53450 * @psalm-var non-empty-string
53451 */
53452 private readonly string $globalVariableName;
53453 /**
53454 * @psalm-param non-empty-string $globalVariableName
53455 */
53456 public function __construct(string $globalVariableName)
53457 {
53458 $this->globalVariableName = $globalVariableName;
53459 }
53460 /**
53461 * @psalm-return non-empty-string
53462 */
53463 public function globalVariableName(): string
53464 {
53465 return $this->globalVariableName;
53466 }
53467 }
53468 <?php
53469
53470 declare (strict_types=1);
53471 /*
53472 * This file is part of PHPUnit.
53473 *
53474 * (c) Sebastian Bergmann <sebastian@phpunit.de>
53475 *
53476 * For the full copyright and license information, please view the LICENSE
53477 * file that was distributed with this source code.
53478 */
53479 namespace PHPUnit\Framework\Attributes;
53480
53481 use Attribute;
53482 /**
53483 * @psalm-immutable
53484 *
53485 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
53486 */
53487 #[Attribute(Attribute::TARGET_CLASS | Attribute::TARGET_METHOD | Attribute::IS_REPEATABLE)]
53488 final class ExcludeStaticPropertyFromBackup
53489 {
53490 /**
53491 * @psalm-var class-string
53492 */
53493 private readonly string $className;
53494 /**
53495 * @psalm-var non-empty-string
53496 */
53497 private readonly string $propertyName;
53498 /**
53499 * @psalm-param class-string $className
53500 * @psalm-param non-empty-string $propertyName
53501 */
53502 public function __construct(string $className, string $propertyName)
53503 {
53504 $this->className = $className;
53505 $this->propertyName = $propertyName;
53506 }
53507 /**
53508 * @psalm-return class-string
53509 */
53510 public function className(): string
53511 {
53512 return $this->className;
53513 }
53514 /**
53515 * @psalm-return non-empty-string
53516 */
53517 public function propertyName(): string
53518 {
53519 return $this->propertyName;
53520 }
53521 }
53522 <?php
53523
53524 declare (strict_types=1);
53525 /*
53526 * This file is part of PHPUnit.
53527 *
53528 * (c) Sebastian Bergmann <sebastian@phpunit.de>
53529 *
53530 * For the full copyright and license information, please view the LICENSE
53531 * file that was distributed with this source code.
53532 */
53533 namespace PHPUnit\Framework\Attributes;
53534
53535 use Attribute;
53536 /**
53537 * @psalm-immutable
53538 *
53539 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
53540 */
53541 #[Attribute(Attribute::TARGET_CLASS | Attribute::TARGET_METHOD | Attribute::IS_REPEATABLE)]
53542 final class Group
53543 {
53544 /**
53545 * @psalm-var non-empty-string
53546 */
53547 private readonly string $name;
53548 /**
53549 * @psalm-param non-empty-string $name
53550 */
53551 public function __construct(string $name)
53552 {
53553 $this->name = $name;
53554 }
53555 /**
53556 * @psalm-return non-empty-string
53557 */
53558 public function name(): string
53559 {
53560 return $this->name;
53561 }
53562 }
53563 <?php
53564
53565 declare (strict_types=1);
53566 /*
53567 * This file is part of PHPUnit.
53568 *
53569 * (c) Sebastian Bergmann <sebastian@phpunit.de>
53570 *
53571 * For the full copyright and license information, please view the LICENSE
53572 * file that was distributed with this source code.
53573 */
53574 namespace PHPUnit\Framework\Attributes;
53575
53576 use Attribute;
53577 /**
53578 * @psalm-immutable
53579 *
53580 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
53581 *
53582 * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5513
53583 */
53584 #[Attribute(Attribute::TARGET_CLASS | Attribute::IS_REPEATABLE)]
53585 final class IgnoreClassForCodeCoverage
53586 {
53587 /**
53588 * @psalm-var class-string
53589 */
53590 private readonly string $className;
53591 /**
53592 * @psalm-param class-string $className
53593 */
53594 public function __construct(string $className)
53595 {
53596 $this->className = $className;
53597 }
53598 /**
53599 * @psalm-return class-string
53600 */
53601 public function className(): string
53602 {
53603 return $this->className;
53604 }
53605 }
53606 <?php
53607
53608 declare (strict_types=1);
53609 /*
53610 * This file is part of PHPUnit.
53611 *
53612 * (c) Sebastian Bergmann <sebastian@phpunit.de>
53613 *
53614 * For the full copyright and license information, please view the LICENSE
53615 * file that was distributed with this source code.
53616 */
53617 namespace PHPUnit\Framework\Attributes;
53618
53619 use Attribute;
53620 /**
53621 * @psalm-immutable
53622 *
53623 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
53624 */
53625 #[Attribute(Attribute::TARGET_CLASS | Attribute::TARGET_METHOD)]
53626 final class IgnoreDeprecations
53627 {
53628 }
53629 <?php
53630
53631 declare (strict_types=1);
53632 /*
53633 * This file is part of PHPUnit.
53634 *
53635 * (c) Sebastian Bergmann <sebastian@phpunit.de>
53636 *
53637 * For the full copyright and license information, please view the LICENSE
53638 * file that was distributed with this source code.
53639 */
53640 namespace PHPUnit\Framework\Attributes;
53641
53642 use Attribute;
53643 /**
53644 * @psalm-immutable
53645 *
53646 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
53647 *
53648 * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5513
53649 */
53650 #[Attribute(Attribute::TARGET_CLASS | Attribute::IS_REPEATABLE)]
53651 final class IgnoreFunctionForCodeCoverage
53652 {
53653 /**
53654 * @psalm-var non-empty-string
53655 */
53656 private readonly string $functionName;
53657 /**
53658 * @psalm-param non-empty-string $functionName
53659 */
53660 public function __construct(string $functionName)
53661 {
53662 $this->functionName = $functionName;
53663 }
53664 /**
53665 * @psalm-return non-empty-string
53666 */
53667 public function functionName(): string
53668 {
53669 return $this->functionName;
53670 }
53671 }
53672 <?php
53673
53674 declare (strict_types=1);
53675 /*
53676 * This file is part of PHPUnit.
53677 *
53678 * (c) Sebastian Bergmann <sebastian@phpunit.de>
53679 *
53680 * For the full copyright and license information, please view the LICENSE
53681 * file that was distributed with this source code.
53682 */
53683 namespace PHPUnit\Framework\Attributes;
53684
53685 use Attribute;
53686 /**
53687 * @psalm-immutable
53688 *
53689 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
53690 *
53691 * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5513
53692 */
53693 #[Attribute(Attribute::TARGET_CLASS | Attribute::IS_REPEATABLE)]
53694 final class IgnoreMethodForCodeCoverage
53695 {
53696 /**
53697 * @psalm-var class-string
53698 */
53699 private readonly string $className;
53700 /**
53701 * @psalm-var non-empty-string
53702 */
53703 private readonly string $methodName;
53704 /**
53705 * @psalm-param class-string $className
53706 * @psalm-param non-empty-string $methodName
53707 */
53708 public function __construct(string $className, string $methodName)
53709 {
53710 $this->className = $className;
53711 $this->methodName = $methodName;
53712 }
53713 /**
53714 * @psalm-return class-string
53715 */
53716 public function className(): string
53717 {
53718 return $this->className;
53719 }
53720 /**
53721 * @psalm-return non-empty-string
53722 */
53723 public function methodName(): string
53724 {
53725 return $this->methodName;
53726 }
53727 }
53728 <?php
53729
53730 declare (strict_types=1);
53731 /*
53732 * This file is part of PHPUnit.
53733 *
53734 * (c) Sebastian Bergmann <sebastian@phpunit.de>
53735 *
53736 * For the full copyright and license information, please view the LICENSE
53737 * file that was distributed with this source code.
53738 */
53739 namespace PHPUnit\Framework\Attributes;
53740
53741 use Attribute;
53742 /**
53743 * @psalm-immutable
53744 *
53745 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
53746 */
53747 #[Attribute(Attribute::TARGET_CLASS)]
53748 final class Large
53749 {
53750 }
53751 <?php
53752
53753 declare (strict_types=1);
53754 /*
53755 * This file is part of PHPUnit.
53756 *
53757 * (c) Sebastian Bergmann <sebastian@phpunit.de>
53758 *
53759 * For the full copyright and license information, please view the LICENSE
53760 * file that was distributed with this source code.
53761 */
53762 namespace PHPUnit\Framework\Attributes;
53763
53764 use Attribute;
53765 /**
53766 * @psalm-immutable
53767 *
53768 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
53769 */
53770 #[Attribute(Attribute::TARGET_CLASS)]
53771 final class Medium
53772 {
53773 }
53774 <?php
53775
53776 declare (strict_types=1);
53777 /*
53778 * This file is part of PHPUnit.
53779 *
53780 * (c) Sebastian Bergmann <sebastian@phpunit.de>
53781 *
53782 * For the full copyright and license information, please view the LICENSE
53783 * file that was distributed with this source code.
53784 */
53785 namespace PHPUnit\Framework\Attributes;
53786
53787 use Attribute;
53788 /**
53789 * @psalm-immutable
53790 *
53791 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
53792 */
53793 #[Attribute(Attribute::TARGET_METHOD)]
53794 final class PostCondition
53795 {
53796 }
53797 <?php
53798
53799 declare (strict_types=1);
53800 /*
53801 * This file is part of PHPUnit.
53802 *
53803 * (c) Sebastian Bergmann <sebastian@phpunit.de>
53804 *
53805 * For the full copyright and license information, please view the LICENSE
53806 * file that was distributed with this source code.
53807 */
53808 namespace PHPUnit\Framework\Attributes;
53809
53810 use Attribute;
53811 /**
53812 * @psalm-immutable
53813 *
53814 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
53815 */
53816 #[Attribute(Attribute::TARGET_METHOD)]
53817 final class PreCondition
53818 {
53819 }
53820 <?php
53821
53822 declare (strict_types=1);
53823 /*
53824 * This file is part of PHPUnit.
53825 *
53826 * (c) Sebastian Bergmann <sebastian@phpunit.de>
53827 *
53828 * For the full copyright and license information, please view the LICENSE
53829 * file that was distributed with this source code.
53830 */
53831 namespace PHPUnit\Framework\Attributes;
53832
53833 use Attribute;
53834 /**
53835 * @psalm-immutable
53836 *
53837 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
53838 */
53839 #[Attribute(Attribute::TARGET_CLASS | Attribute::TARGET_METHOD)]
53840 final class PreserveGlobalState
53841 {
53842 private readonly bool $enabled;
53843 public function __construct(bool $enabled)
53844 {
53845 $this->enabled = $enabled;
53846 }
53847 public function enabled(): bool
53848 {
53849 return $this->enabled;
53850 }
53851 }
53852 <?php
53853
53854 declare (strict_types=1);
53855 /*
53856 * This file is part of PHPUnit.
53857 *
53858 * (c) Sebastian Bergmann <sebastian@phpunit.de>
53859 *
53860 * For the full copyright and license information, please view the LICENSE
53861 * file that was distributed with this source code.
53862 */
53863 namespace PHPUnit\Framework\Attributes;
53864
53865 use Attribute;
53866 /**
53867 * @psalm-immutable
53868 *
53869 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
53870 */
53871 #[Attribute(Attribute::TARGET_CLASS | Attribute::TARGET_METHOD | Attribute::IS_REPEATABLE)]
53872 final class RequiresFunction
53873 {
53874 /**
53875 * @psalm-var non-empty-string
53876 */
53877 private readonly string $functionName;
53878 /**
53879 * @psalm-param non-empty-string $functionName
53880 */
53881 public function __construct(string $functionName)
53882 {
53883 $this->functionName = $functionName;
53884 }
53885 /**
53886 * @psalm-return non-empty-string
53887 */
53888 public function functionName(): string
53889 {
53890 return $this->functionName;
53891 }
53892 }
53893 <?php
53894
53895 declare (strict_types=1);
53896 /*
53897 * This file is part of PHPUnit.
53898 *
53899 * (c) Sebastian Bergmann <sebastian@phpunit.de>
53900 *
53901 * For the full copyright and license information, please view the LICENSE
53902 * file that was distributed with this source code.
53903 */
53904 namespace PHPUnit\Framework\Attributes;
53905
53906 use Attribute;
53907 /**
53908 * @psalm-immutable
53909 *
53910 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
53911 */
53912 #[Attribute(Attribute::TARGET_CLASS | Attribute::TARGET_METHOD | Attribute::IS_REPEATABLE)]
53913 final class RequiresMethod
53914 {
53915 /**
53916 * @psalm-var class-string
53917 */
53918 private readonly string $className;
53919 /**
53920 * @psalm-var non-empty-string
53921 */
53922 private readonly string $methodName;
53923 /**
53924 * @psalm-param class-string $className
53925 * @psalm-param non-empty-string $methodName
53926 */
53927 public function __construct(string $className, string $methodName)
53928 {
53929 $this->className = $className;
53930 $this->methodName = $methodName;
53931 }
53932 /**
53933 * @psalm-return class-string
53934 */
53935 public function className(): string
53936 {
53937 return $this->className;
53938 }
53939 /**
53940 * @psalm-return non-empty-string
53941 */
53942 public function methodName(): string
53943 {
53944 return $this->methodName;
53945 }
53946 }
53947 <?php
53948
53949 declare (strict_types=1);
53950 /*
53951 * This file is part of PHPUnit.
53952 *
53953 * (c) Sebastian Bergmann <sebastian@phpunit.de>
53954 *
53955 * For the full copyright and license information, please view the LICENSE
53956 * file that was distributed with this source code.
53957 */
53958 namespace PHPUnit\Framework\Attributes;
53959
53960 use Attribute;
53961 /**
53962 * @psalm-immutable
53963 *
53964 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
53965 */
53966 #[Attribute(Attribute::TARGET_CLASS | Attribute::TARGET_METHOD)]
53967 final class RequiresOperatingSystem
53968 {
53969 /**
53970 * @psalm-var non-empty-string
53971 */
53972 private readonly string $regularExpression;
53973 /**
53974 * @psalm-param non-empty-string $regularExpression
53975 */
53976 public function __construct(string $regularExpression)
53977 {
53978 $this->regularExpression = $regularExpression;
53979 }
53980 /**
53981 * @psalm-return non-empty-string
53982 */
53983 public function regularExpression(): string
53984 {
53985 return $this->regularExpression;
53986 }
53987 }
53988 <?php
53989
53990 declare (strict_types=1);
53991 /*
53992 * This file is part of PHPUnit.
53993 *
53994 * (c) Sebastian Bergmann <sebastian@phpunit.de>
53995 *
53996 * For the full copyright and license information, please view the LICENSE
53997 * file that was distributed with this source code.
53998 */
53999 namespace PHPUnit\Framework\Attributes;
54000
54001 use Attribute;
54002 /**
54003 * @psalm-immutable
54004 *
54005 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
54006 */
54007 #[Attribute(Attribute::TARGET_CLASS | Attribute::TARGET_METHOD)]
54008 final class RequiresOperatingSystemFamily
54009 {
54010 /**
54011 * @psalm-var non-empty-string
54012 */
54013 private readonly string $operatingSystemFamily;
54014 /**
54015 * @psalm-param non-empty-string $operatingSystemFamily
54016 */
54017 public function __construct(string $operatingSystemFamily)
54018 {
54019 $this->operatingSystemFamily = $operatingSystemFamily;
54020 }
54021 /**
54022 * @psalm-return non-empty-string
54023 */
54024 public function operatingSystemFamily(): string
54025 {
54026 return $this->operatingSystemFamily;
54027 }
54028 }
54029 <?php
54030
54031 declare (strict_types=1);
54032 /*
54033 * This file is part of PHPUnit.
54034 *
54035 * (c) Sebastian Bergmann <sebastian@phpunit.de>
54036 *
54037 * For the full copyright and license information, please view the LICENSE
54038 * file that was distributed with this source code.
54039 */
54040 namespace PHPUnit\Framework\Attributes;
54041
54042 use Attribute;
54043 /**
54044 * @psalm-immutable
54045 *
54046 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
54047 */
54048 #[Attribute(Attribute::TARGET_CLASS | Attribute::TARGET_METHOD)]
54049 final class RequiresPhp
54050 {
54051 /**
54052 * @psalm-var non-empty-string
54053 */
54054 private readonly string $versionRequirement;
54055 /**
54056 * @psalm-param non-empty-string $versionRequirement
54057 */
54058 public function __construct(string $versionRequirement)
54059 {
54060 $this->versionRequirement = $versionRequirement;
54061 }
54062 /**
54063 * @psalm-return non-empty-string
54064 */
54065 public function versionRequirement(): string
54066 {
54067 return $this->versionRequirement;
54068 }
54069 }
54070 <?php
54071
54072 declare (strict_types=1);
54073 /*
54074 * This file is part of PHPUnit.
54075 *
54076 * (c) Sebastian Bergmann <sebastian@phpunit.de>
54077 *
54078 * For the full copyright and license information, please view the LICENSE
54079 * file that was distributed with this source code.
54080 */
54081 namespace PHPUnit\Framework\Attributes;
54082
54083 use Attribute;
54084 /**
54085 * @psalm-immutable
54086 *
54087 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
54088 */
54089 #[Attribute(Attribute::TARGET_CLASS | Attribute::TARGET_METHOD | Attribute::IS_REPEATABLE)]
54090 final class RequiresPhpExtension
54091 {
54092 /**
54093 * @psalm-var non-empty-string
54094 */
54095 private readonly string $extension;
54096 /**
54097 * @psalm-var null|non-empty-string
54098 */
54099 private readonly ?string $versionRequirement;
54100 /**
54101 * @psalm-param non-empty-string $extension
54102 * @psalm-param null|non-empty-string $versionRequirement
54103 */
54104 public function __construct(string $extension, ?string $versionRequirement = null)
54105 {
54106 $this->extension = $extension;
54107 $this->versionRequirement = $versionRequirement;
54108 }
54109 /**
54110 * @psalm-return non-empty-string
54111 */
54112 public function extension(): string
54113 {
54114 return $this->extension;
54115 }
54116 /**
54117 * @psalm-return null|non-empty-string
54118 */
54119 public function versionRequirement(): ?string
54120 {
54121 return $this->versionRequirement;
54122 }
54123 }
54124 <?php
54125
54126 declare (strict_types=1);
54127 /*
54128 * This file is part of PHPUnit.
54129 *
54130 * (c) Sebastian Bergmann <sebastian@phpunit.de>
54131 *
54132 * For the full copyright and license information, please view the LICENSE
54133 * file that was distributed with this source code.
54134 */
54135 namespace PHPUnit\Framework\Attributes;
54136
54137 use Attribute;
54138 /**
54139 * @psalm-immutable
54140 *
54141 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
54142 */
54143 #[Attribute(Attribute::TARGET_CLASS | Attribute::TARGET_METHOD)]
54144 final class RequiresPhpunit
54145 {
54146 /**
54147 * @psalm-var non-empty-string
54148 */
54149 private readonly string $versionRequirement;
54150 /**
54151 * @psalm-param non-empty-string $versionRequirement
54152 */
54153 public function __construct(string $versionRequirement)
54154 {
54155 $this->versionRequirement = $versionRequirement;
54156 }
54157 /**
54158 * @psalm-return non-empty-string
54159 */
54160 public function versionRequirement(): string
54161 {
54162 return $this->versionRequirement;
54163 }
54164 }
54165 <?php
54166
54167 declare (strict_types=1);
54168 /*
54169 * This file is part of PHPUnit.
54170 *
54171 * (c) Sebastian Bergmann <sebastian@phpunit.de>
54172 *
54173 * For the full copyright and license information, please view the LICENSE
54174 * file that was distributed with this source code.
54175 */
54176 namespace PHPUnit\Framework\Attributes;
54177
54178 use Attribute;
54179 /**
54180 * @psalm-immutable
54181 *
54182 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
54183 */
54184 #[Attribute(Attribute::TARGET_CLASS | Attribute::TARGET_METHOD | Attribute::IS_REPEATABLE)]
54185 final class RequiresSetting
54186 {
54187 /**
54188 * @psalm-var non-empty-string
54189 */
54190 private readonly string $setting;
54191 /**
54192 * @psalm-var non-empty-string
54193 */
54194 private readonly string $value;
54195 /**
54196 * @psalm-param non-empty-string $setting
54197 * @psalm-param non-empty-string $value
54198 */
54199 public function __construct(string $setting, string $value)
54200 {
54201 $this->setting = $setting;
54202 $this->value = $value;
54203 }
54204 /**
54205 * @psalm-return non-empty-string
54206 */
54207 public function setting(): string
54208 {
54209 return $this->setting;
54210 }
54211 /**
54212 * @psalm-return non-empty-string
54213 */
54214 public function value(): string
54215 {
54216 return $this->value;
54217 }
54218 }
54219 <?php
54220
54221 declare (strict_types=1);
54222 /*
54223 * This file is part of PHPUnit.
54224 *
54225 * (c) Sebastian Bergmann <sebastian@phpunit.de>
54226 *
54227 * For the full copyright and license information, please view the LICENSE
54228 * file that was distributed with this source code.
54229 */
54230 namespace PHPUnit\Framework\Attributes;
54231
54232 use Attribute;
54233 /**
54234 * @psalm-immutable
54235 *
54236 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
54237 */
54238 #[Attribute(Attribute::TARGET_CLASS)]
54239 final class RunClassInSeparateProcess
54240 {
54241 }
54242 <?php
54243
54244 declare (strict_types=1);
54245 /*
54246 * This file is part of PHPUnit.
54247 *
54248 * (c) Sebastian Bergmann <sebastian@phpunit.de>
54249 *
54250 * For the full copyright and license information, please view the LICENSE
54251 * file that was distributed with this source code.
54252 */
54253 namespace PHPUnit\Framework\Attributes;
54254
54255 use Attribute;
54256 /**
54257 * @psalm-immutable
54258 *
54259 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
54260 */
54261 #[Attribute(Attribute::TARGET_METHOD)]
54262 final class RunInSeparateProcess
54263 {
54264 }
54265 <?php
54266
54267 declare (strict_types=1);
54268 /*
54269 * This file is part of PHPUnit.
54270 *
54271 * (c) Sebastian Bergmann <sebastian@phpunit.de>
54272 *
54273 * For the full copyright and license information, please view the LICENSE
54274 * file that was distributed with this source code.
54275 */
54276 namespace PHPUnit\Framework\Attributes;
54277
54278 use Attribute;
54279 /**
54280 * @psalm-immutable
54281 *
54282 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
54283 */
54284 #[Attribute(Attribute::TARGET_CLASS)]
54285 final class RunTestsInSeparateProcesses
54286 {
54287 }
54288 <?php
54289
54290 declare (strict_types=1);
54291 /*
54292 * This file is part of PHPUnit.
54293 *
54294 * (c) Sebastian Bergmann <sebastian@phpunit.de>
54295 *
54296 * For the full copyright and license information, please view the LICENSE
54297 * file that was distributed with this source code.
54298 */
54299 namespace PHPUnit\Framework\Attributes;
54300
54301 use Attribute;
54302 /**
54303 * @psalm-immutable
54304 *
54305 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
54306 */
54307 #[Attribute(Attribute::TARGET_CLASS)]
54308 final class Small
54309 {
54310 }
54311 <?php
54312
54313 declare (strict_types=1);
54314 /*
54315 * This file is part of PHPUnit.
54316 *
54317 * (c) Sebastian Bergmann <sebastian@phpunit.de>
54318 *
54319 * For the full copyright and license information, please view the LICENSE
54320 * file that was distributed with this source code.
54321 */
54322 namespace PHPUnit\Framework\Attributes;
54323
54324 use Attribute;
54325 /**
54326 * @psalm-immutable
54327 *
54328 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
54329 */
54330 #[Attribute(Attribute::TARGET_METHOD)]
54331 final class Test
54332 {
54333 }
54334 <?php
54335
54336 declare (strict_types=1);
54337 /*
54338 * This file is part of PHPUnit.
54339 *
54340 * (c) Sebastian Bergmann <sebastian@phpunit.de>
54341 *
54342 * For the full copyright and license information, please view the LICENSE
54343 * file that was distributed with this source code.
54344 */
54345 namespace PHPUnit\Framework\Attributes;
54346
54347 use Attribute;
54348 /**
54349 * @psalm-immutable
54350 *
54351 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
54352 */
54353 #[Attribute(Attribute::TARGET_CLASS | Attribute::TARGET_METHOD)]
54354 final class TestDox
54355 {
54356 /**
54357 * @psalm-var non-empty-string
54358 */
54359 private readonly string $text;
54360 /**
54361 * @psalm-param non-empty-string $text
54362 */
54363 public function __construct(string $text)
54364 {
54365 $this->text = $text;
54366 }
54367 /**
54368 * @psalm-return non-empty-string
54369 */
54370 public function text(): string
54371 {
54372 return $this->text;
54373 }
54374 }
54375 <?php
54376
54377 declare (strict_types=1);
54378 /*
54379 * This file is part of PHPUnit.
54380 *
54381 * (c) Sebastian Bergmann <sebastian@phpunit.de>
54382 *
54383 * For the full copyright and license information, please view the LICENSE
54384 * file that was distributed with this source code.
54385 */
54386 namespace PHPUnit\Framework\Attributes;
54387
54388 use Attribute;
54389 /**
54390 * @psalm-immutable
54391 *
54392 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
54393 */
54394 #[Attribute(Attribute::TARGET_METHOD | Attribute::IS_REPEATABLE)]
54395 final class TestWith
54396 {
54397 private readonly array $data;
54398 public function __construct(array $data)
54399 {
54400 $this->data = $data;
54401 }
54402 public function data(): array
54403 {
54404 return $this->data;
54405 }
54406 }
54407 <?php
54408
54409 declare (strict_types=1);
54410 /*
54411 * This file is part of PHPUnit.
54412 *
54413 * (c) Sebastian Bergmann <sebastian@phpunit.de>
54414 *
54415 * For the full copyright and license information, please view the LICENSE
54416 * file that was distributed with this source code.
54417 */
54418 namespace PHPUnit\Framework\Attributes;
54419
54420 use Attribute;
54421 /**
54422 * @psalm-immutable
54423 *
54424 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
54425 */
54426 #[Attribute(Attribute::TARGET_METHOD | Attribute::IS_REPEATABLE)]
54427 final class TestWithJson
54428 {
54429 /**
54430 * @psalm-var non-empty-string
54431 */
54432 private readonly string $json;
54433 /**
54434 * @psalm-param non-empty-string $json
54435 */
54436 public function __construct(string $json)
54437 {
54438 $this->json = $json;
54439 }
54440 /**
54441 * @psalm-return non-empty-string
54442 */
54443 public function json(): string
54444 {
54445 return $this->json;
54446 }
54447 }
54448 <?php
54449
54450 declare (strict_types=1);
54451 /*
54452 * This file is part of PHPUnit.
54453 *
54454 * (c) Sebastian Bergmann <sebastian@phpunit.de>
54455 *
54456 * For the full copyright and license information, please view the LICENSE
54457 * file that was distributed with this source code.
54458 */
54459 namespace PHPUnit\Framework\Attributes;
54460
54461 use Attribute;
54462 /**
54463 * @psalm-immutable
54464 *
54465 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
54466 */
54467 #[Attribute(Attribute::TARGET_CLASS | Attribute::TARGET_METHOD | Attribute::IS_REPEATABLE)]
54468 final class Ticket
54469 {
54470 /**
54471 * @psalm-var non-empty-string
54472 */
54473 private readonly string $text;
54474 /**
54475 * @psalm-param non-empty-string $text
54476 */
54477 public function __construct(string $text)
54478 {
54479 $this->text = $text;
54480 }
54481 /**
54482 * @psalm-return non-empty-string
54483 */
54484 public function text(): string
54485 {
54486 return $this->text;
54487 }
54488 }
54489 <?php
54490
54491 declare (strict_types=1);
54492 /*
54493 * This file is part of PHPUnit.
54494 *
54495 * (c) Sebastian Bergmann <sebastian@phpunit.de>
54496 *
54497 * For the full copyright and license information, please view the LICENSE
54498 * file that was distributed with this source code.
54499 */
54500 namespace PHPUnit\Framework\Attributes;
54501
54502 use Attribute;
54503 /**
54504 * @psalm-immutable
54505 *
54506 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
54507 */
54508 #[Attribute(Attribute::TARGET_CLASS | Attribute::IS_REPEATABLE)]
54509 final class UsesClass
54510 {
54511 /**
54512 * @psalm-var class-string
54513 */
54514 private readonly string $className;
54515 /**
54516 * @psalm-param class-string $className
54517 */
54518 public function __construct(string $className)
54519 {
54520 $this->className = $className;
54521 }
54522 /**
54523 * @psalm-return class-string
54524 */
54525 public function className(): string
54526 {
54527 return $this->className;
54528 }
54529 }
54530 <?php
54531
54532 declare (strict_types=1);
54533 /*
54534 * This file is part of PHPUnit.
54535 *
54536 * (c) Sebastian Bergmann <sebastian@phpunit.de>
54537 *
54538 * For the full copyright and license information, please view the LICENSE
54539 * file that was distributed with this source code.
54540 */
54541 namespace PHPUnit\Framework\Attributes;
54542
54543 use Attribute;
54544 /**
54545 * @psalm-immutable
54546 *
54547 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
54548 */
54549 #[Attribute(Attribute::TARGET_CLASS | Attribute::IS_REPEATABLE)]
54550 final class UsesFunction
54551 {
54552 /**
54553 * @psalm-var non-empty-string
54554 */
54555 private readonly string $functionName;
54556 /**
54557 * @psalm-param non-empty-string $functionName
54558 */
54559 public function __construct(string $functionName)
54560 {
54561 $this->functionName = $functionName;
54562 }
54563 /**
54564 * @psalm-return non-empty-string
54565 */
54566 public function functionName(): string
54567 {
54568 return $this->functionName;
54569 }
54570 }
54571 <?php
54572
54573 declare (strict_types=1);
54574 /*
54575 * This file is part of PHPUnit.
54576 *
54577 * (c) Sebastian Bergmann <sebastian@phpunit.de>
54578 *
54579 * For the full copyright and license information, please view the LICENSE
54580 * file that was distributed with this source code.
54581 */
54582 namespace PHPUnit\Framework\Attributes;
54583
54584 use Attribute;
54585 /**
54586 * @psalm-immutable
54587 *
54588 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
54589 */
54590 #[Attribute(Attribute::TARGET_METHOD)]
54591 final class WithoutErrorHandler
54592 {
54593 }
54594 <?php
54595
54596 declare (strict_types=1);
54597 /*
54598 * This file is part of PHPUnit.
54599 *
54600 * (c) Sebastian Bergmann <sebastian@phpunit.de>
54601 *
54602 * For the full copyright and license information, please view the LICENSE
54603 * file that was distributed with this source code.
54604 */
54605 namespace PHPUnit\Framework\Constraint;
54606
54607 /**
54608 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
54609 */
54610 final class IsFalse extends \PHPUnit\Framework\Constraint\Constraint
54611 {
54612 /**
54613 * Returns a string representation of the constraint.
54614 */
54615 public function toString(): string
54616 {
54617 return 'is false';
54618 }
54619 /**
54620 * Evaluates the constraint for parameter $other. Returns true if the
54621 * constraint is met, false otherwise.
54622 */
54623 protected function matches(mixed $other): bool
54624 {
54625 return $other === \false;
54626 }
54627 }
54628 <?php
54629
54630 declare (strict_types=1);
54631 /*
54632 * This file is part of PHPUnit.
54633 *
54634 * (c) Sebastian Bergmann <sebastian@phpunit.de>
54635 *
54636 * For the full copyright and license information, please view the LICENSE
54637 * file that was distributed with this source code.
54638 */
54639 namespace PHPUnit\Framework\Constraint;
54640
54641 /**
54642 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
54643 */
54644 final class IsTrue extends \PHPUnit\Framework\Constraint\Constraint
54645 {
54646 /**
54647 * Returns a string representation of the constraint.
54648 */
54649 public function toString(): string
54650 {
54651 return 'is true';
54652 }
54653 /**
54654 * Evaluates the constraint for parameter $other. Returns true if the
54655 * constraint is met, false otherwise.
54656 */
54657 protected function matches(mixed $other): bool
54658 {
54659 return $other === \true;
54660 }
54661 }
54662 <?php
54663
54664 declare (strict_types=1);
54665 /*
54666 * This file is part of PHPUnit.
54667 *
54668 * (c) Sebastian Bergmann <sebastian@phpunit.de>
54669 *
54670 * For the full copyright and license information, please view the LICENSE
54671 * file that was distributed with this source code.
54672 */
54673 namespace PHPUnit\Framework\Constraint;
54674
54675 use Closure;
54676 use ReflectionFunction;
54677 /**
54678 * @psalm-template CallbackInput of mixed
54679 *
54680 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
54681 */
54682 final class Callback extends \PHPUnit\Framework\Constraint\Constraint
54683 {
54684 /**
54685 * @psalm-var callable(CallbackInput $input): bool
54686 */
54687 private readonly mixed $callback;
54688 /**
54689 * @psalm-param callable(CallbackInput $input): bool $callback
54690 */
54691 public function __construct(callable $callback)
54692 {
54693 $this->callback = $callback;
54694 }
54695 /**
54696 * Returns a string representation of the constraint.
54697 */
54698 public function toString(): string
54699 {
54700 return 'is accepted by specified callback';
54701 }
54702 /**
54703 * @psalm-suppress ArgumentTypeCoercion
54704 */
54705 public function isVariadic(): bool
54706 {
54707 foreach ((new ReflectionFunction(Closure::fromCallable($this->callback)))->getParameters() as $parameter) {
54708 if ($parameter->isVariadic()) {
54709 return \true;
54710 }
54711 }
54712 return \false;
54713 }
54714 /**
54715 * Evaluates the constraint for parameter $value. Returns true if the
54716 * constraint is met, false otherwise.
54717 *
54718 * @psalm-param CallbackInput $other
54719 *
54720 * @psalm-suppress InvalidArgument
54721 */
54722 protected function matches(mixed $other): bool
54723 {
54724 if ($this->isVariadic()) {
54725 return ($this->callback)(...$other);
54726 }
54727 return ($this->callback)($other);
54728 }
54729 }
54730 <?php
54731
54732 declare (strict_types=1);
54733 /*
54734 * This file is part of PHPUnit.
54735 *
54736 * (c) Sebastian Bergmann <sebastian@phpunit.de>
54737 *
54738 * For the full copyright and license information, please view the LICENSE
54739 * file that was distributed with this source code.
54740 */
54741 namespace PHPUnit\Framework\Constraint;
54742
54743 use function count;
54744 use function is_countable;
54745 use function iterator_count;
54746 use function sprintf;
54747 use EmptyIterator;
54748 use Generator;
54749 use Iterator;
54750 use IteratorAggregate;
54751 use PHPUnit\Framework\Exception;
54752 use PHPUnit\Framework\GeneratorNotSupportedException;
54753 use Traversable;
54754 /**
54755 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
54756 */
54757 class Count extends \PHPUnit\Framework\Constraint\Constraint
54758 {
54759 private readonly int $expectedCount;
54760 public function __construct(int $expected)
54761 {
54762 $this->expectedCount = $expected;
54763 }
54764 public function toString(): string
54765 {
54766 return sprintf('count matches %d', $this->expectedCount);
54767 }
54768 /**
54769 * Evaluates the constraint for parameter $other. Returns true if the
54770 * constraint is met, false otherwise.
54771 *
54772 * @throws Exception
54773 */
54774 protected function matches(mixed $other): bool
54775 {
54776 return $this->expectedCount === $this->getCountOf($other);
54777 }
54778 /**
54779 * @throws Exception
54780 */
54781 protected function getCountOf(mixed $other): ?int
54782 {
54783 if (is_countable($other)) {
54784 return count($other);
54785 }
54786 if ($other instanceof EmptyIterator) {
54787 return 0;
54788 }
54789 if ($other instanceof Traversable) {
54790 while ($other instanceof IteratorAggregate) {
54791 try {
54792 $other = $other->getIterator();
54793 } catch (\Exception $e) {
54794 throw new Exception($e->getMessage(), $e->getCode(), $e);
54795 }
54796 }
54797 $iterator = $other;
54798 if ($iterator instanceof Generator) {
54799 throw new GeneratorNotSupportedException();
54800 }
54801 if (!$iterator instanceof Iterator) {
54802 return iterator_count($iterator);
54803 }
54804 $key = $iterator->key();
54805 $count = iterator_count($iterator);
54806 // Manually rewind $iterator to previous key, since iterator_count
54807 // moves pointer.
54808 if ($key !== null) {
54809 $iterator->rewind();
54810 while ($iterator->valid() && $key !== $iterator->key()) {
54811 $iterator->next();
54812 }
54813 }
54814 return $count;
54815 }
54816 return null;
54817 }
54818 /**
54819 * Returns the description of the failure.
54820 *
54821 * The beginning of failure messages is "Failed asserting that" in most
54822 * cases. This method should return the second part of that sentence.
54823 *
54824 * @throws Exception
54825 */
54826 protected function failureDescription(mixed $other): string
54827 {
54828 return sprintf('actual size %d matches expected size %d', (int) $this->getCountOf($other), $this->expectedCount);
54829 }
54830 }
54831 <?php
54832
54833 declare (strict_types=1);
54834 /*
54835 * This file is part of PHPUnit.
54836 *
54837 * (c) Sebastian Bergmann <sebastian@phpunit.de>
54838 *
54839 * For the full copyright and license information, please view the LICENSE
54840 * file that was distributed with this source code.
54841 */
54842 namespace PHPUnit\Framework\Constraint;
54843
54844 use PHPUnit\Util\Exporter;
54845 /**
54846 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
54847 */
54848 final class GreaterThan extends \PHPUnit\Framework\Constraint\Constraint
54849 {
54850 private readonly mixed $value;
54851 public function __construct(mixed $value)
54852 {
54853 $this->value = $value;
54854 }
54855 /**
54856 * Returns a string representation of the constraint.
54857 */
54858 public function toString(bool $exportObjects = \false): string
54859 {
54860 return 'is greater than ' . Exporter::export($this->value, $exportObjects);
54861 }
54862 /**
54863 * Evaluates the constraint for parameter $other. Returns true if the
54864 * constraint is met, false otherwise.
54865 */
54866 protected function matches(mixed $other): bool
54867 {
54868 return $this->value < $other;
54869 }
54870 }
54871 <?php
54872
54873 declare (strict_types=1);
54874 /*
54875 * This file is part of PHPUnit.
54876 *
54877 * (c) Sebastian Bergmann <sebastian@phpunit.de>
54878 *
54879 * For the full copyright and license information, please view the LICENSE
54880 * file that was distributed with this source code.
54881 */
54882 namespace PHPUnit\Framework\Constraint;
54883
54884 use function count;
54885 use function gettype;
54886 use function sprintf;
54887 use function str_starts_with;
54888 use Countable;
54889 use EmptyIterator;
54890 /**
54891 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
54892 */
54893 final class IsEmpty extends \PHPUnit\Framework\Constraint\Constraint
54894 {
54895 /**
54896 * Returns a string representation of the constraint.
54897 */
54898 public function toString(): string
54899 {
54900 return 'is empty';
54901 }
54902 /**
54903 * Evaluates the constraint for parameter $other. Returns true if the
54904 * constraint is met, false otherwise.
54905 */
54906 protected function matches(mixed $other): bool
54907 {
54908 if ($other instanceof EmptyIterator) {
54909 return \true;
54910 }
54911 if ($other instanceof Countable) {
54912 return count($other) === 0;
54913 }
54914 return empty($other);
54915 }
54916 /**
54917 * Returns the description of the failure.
54918 *
54919 * The beginning of failure messages is "Failed asserting that" in most
54920 * cases. This method should return the second part of that sentence.
54921 */
54922 protected function failureDescription(mixed $other): string
54923 {
54924 $type = gettype($other);
54925 return sprintf('%s %s %s', str_starts_with($type, 'a') || str_starts_with($type, 'o') ? 'an' : 'a', $type, $this->toString(\true));
54926 }
54927 }
54928 <?php
54929
54930 declare (strict_types=1);
54931 /*
54932 * This file is part of PHPUnit.
54933 *
54934 * (c) Sebastian Bergmann <sebastian@phpunit.de>
54935 *
54936 * For the full copyright and license information, please view the LICENSE
54937 * file that was distributed with this source code.
54938 */
54939 namespace PHPUnit\Framework\Constraint;
54940
54941 use PHPUnit\Util\Exporter;
54942 /**
54943 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
54944 */
54945 final class LessThan extends \PHPUnit\Framework\Constraint\Constraint
54946 {
54947 private readonly mixed $value;
54948 public function __construct(mixed $value)
54949 {
54950 $this->value = $value;
54951 }
54952 /**
54953 * Returns a string representation of the constraint.
54954 */
54955 public function toString(bool $exportObjects = \false): string
54956 {
54957 return 'is less than ' . Exporter::export($this->value, $exportObjects);
54958 }
54959 /**
54960 * Evaluates the constraint for parameter $other. Returns true if the
54961 * constraint is met, false otherwise.
54962 */
54963 protected function matches(mixed $other): bool
54964 {
54965 return $this->value > $other;
54966 }
54967 }
54968 <?php
54969
54970 declare (strict_types=1);
54971 /*
54972 * This file is part of PHPUnit.
54973 *
54974 * (c) Sebastian Bergmann <sebastian@phpunit.de>
54975 *
54976 * For the full copyright and license information, please view the LICENSE
54977 * file that was distributed with this source code.
54978 */
54979 namespace PHPUnit\Framework\Constraint;
54980
54981 use Countable;
54982 use PHPUnit\Framework\Exception;
54983 /**
54984 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
54985 */
54986 final class SameSize extends \PHPUnit\Framework\Constraint\Count
54987 {
54988 /**
54989 * @psalm-param Countable|iterable $expected
54990 *
54991 * @throws Exception
54992 */
54993 public function __construct($expected)
54994 {
54995 parent::__construct((int) $this->getCountOf($expected));
54996 }
54997 }
54998 <?php
54999
55000 declare (strict_types=1);
55001 /*
55002 * This file is part of PHPUnit.
55003 *
55004 * (c) Sebastian Bergmann <sebastian@phpunit.de>
55005 *
55006 * For the full copyright and license information, please view the LICENSE
55007 * file that was distributed with this source code.
55008 */
55009 namespace PHPUnit\Framework\Constraint;
55010
55011 use function gettype;
55012 use function sprintf;
55013 use function strtolower;
55014 use Countable;
55015 use PHPUnit\Framework\ExpectationFailedException;
55016 use PHPUnit\Framework\SelfDescribing;
55017 use PHPUnit\Util\Exporter;
55018 use PHPUnitPHAR\SebastianBergmann\Comparator\ComparisonFailure;
55019 /**
55020 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
55021 */
55022 abstract class Constraint implements Countable, SelfDescribing
55023 {
55024 /**
55025 * Evaluates the constraint for parameter $other.
55026 *
55027 * If $returnResult is set to false (the default), an exception is thrown
55028 * in case of a failure. null is returned otherwise.
55029 *
55030 * If $returnResult is true, the result of the evaluation is returned as
55031 * a boolean value instead: true in case of success, false in case of a
55032 * failure.
55033 *
55034 * @throws ExpectationFailedException
55035 */
55036 public function evaluate(mixed $other, string $description = '', bool $returnResult = \false): ?bool
55037 {
55038 $success = \false;
55039 if ($this->matches($other)) {
55040 $success = \true;
55041 }
55042 if ($returnResult) {
55043 return $success;
55044 }
55045 if (!$success) {
55046 $this->fail($other, $description);
55047 }
55048 return null;
55049 }
55050 /**
55051 * Counts the number of constraint elements.
55052 */
55053 public function count(): int
55054 {
55055 return 1;
55056 }
55057 /**
55058 * @deprecated
55059 */
55060 protected function exporter(): \PHPUnitPHAR\SebastianBergmann\Exporter\Exporter
55061 {
55062 return new \PHPUnitPHAR\SebastianBergmann\Exporter\Exporter();
55063 }
55064 /**
55065 * Evaluates the constraint for parameter $other. Returns true if the
55066 * constraint is met, false otherwise.
55067 *
55068 * This method can be overridden to implement the evaluation algorithm.
55069 */
55070 protected function matches(mixed $other): bool
55071 {
55072 return \false;
55073 }
55074 /**
55075 * Throws an exception for the given compared value and test description.
55076 *
55077 * @throws ExpectationFailedException
55078 */
55079 protected function fail(mixed $other, string $description, ?ComparisonFailure $comparisonFailure = null): never
55080 {
55081 $failureDescription = sprintf('Failed asserting that %s.', $this->failureDescription($other));
55082 $additionalFailureDescription = $this->additionalFailureDescription($other);
55083 if ($additionalFailureDescription) {
55084 $failureDescription .= "\n" . $additionalFailureDescription;
55085 }
55086 if (!empty($description)) {
55087 $failureDescription = $description . "\n" . $failureDescription;
55088 }
55089 throw new ExpectationFailedException($failureDescription, $comparisonFailure);
55090 }
55091 /**
55092 * Return additional failure description where needed.
55093 *
55094 * The function can be overridden to provide additional failure
55095 * information like a diff
55096 */
55097 protected function additionalFailureDescription(mixed $other): string
55098 {
55099 return '';
55100 }
55101 /**
55102 * Returns the description of the failure.
55103 *
55104 * The beginning of failure messages is "Failed asserting that" in most
55105 * cases. This method should return the second part of that sentence.
55106 *
55107 * To provide additional failure information additionalFailureDescription
55108 * can be used.
55109 */
55110 protected function failureDescription(mixed $other): string
55111 {
55112 return Exporter::export($other, \true) . ' ' . $this->toString(\true);
55113 }
55114 /**
55115 * Returns a custom string representation of the constraint object when it
55116 * appears in context of an $operator expression.
55117 *
55118 * The purpose of this method is to provide meaningful descriptive string
55119 * in context of operators such as LogicalNot. Native PHPUnit constraints
55120 * are supported out of the box by LogicalNot, but externally developed
55121 * ones had no way to provide correct strings in this context.
55122 *
55123 * The method shall return empty string, when it does not handle
55124 * customization by itself.
55125 */
55126 protected function toStringInContext(\PHPUnit\Framework\Constraint\Operator $operator, mixed $role): string
55127 {
55128 return '';
55129 }
55130 /**
55131 * Returns the description of the failure when this constraint appears in
55132 * context of an $operator expression.
55133 *
55134 * The purpose of this method is to provide meaningful failure description
55135 * in context of operators such as LogicalNot. Native PHPUnit constraints
55136 * are supported out of the box by LogicalNot, but externally developed
55137 * ones had no way to provide correct messages in this context.
55138 *
55139 * The method shall return empty string, when it does not handle
55140 * customization by itself.
55141 */
55142 protected function failureDescriptionInContext(\PHPUnit\Framework\Constraint\Operator $operator, mixed $role, mixed $other): string
55143 {
55144 $string = $this->toStringInContext($operator, $role);
55145 if ($string === '') {
55146 return '';
55147 }
55148 return Exporter::export($other, \true) . ' ' . $string;
55149 }
55150 /**
55151 * Reduces the sub-expression starting at $this by skipping degenerate
55152 * sub-expression and returns first descendant constraint that starts
55153 * a non-reducible sub-expression.
55154 *
55155 * Returns $this for terminal constraints and for operators that start
55156 * non-reducible sub-expression, or the nearest descendant of $this that
55157 * starts a non-reducible sub-expression.
55158 *
55159 * A constraint expression may be modelled as a tree with non-terminal
55160 * nodes (operators) and terminal nodes. For example:
55161 *
55162 * LogicalOr (operator, non-terminal)
55163 * + LogicalAnd (operator, non-terminal)
55164 * | + IsType('int') (terminal)
55165 * | + GreaterThan(10) (terminal)
55166 * + LogicalNot (operator, non-terminal)
55167 * + IsType('array') (terminal)
55168 *
55169 * A degenerate sub-expression is a part of the tree, that effectively does
55170 * not contribute to the evaluation of the expression it appears in. An example
55171 * of degenerate sub-expression is a BinaryOperator constructed with single
55172 * operand or nested BinaryOperators, each with single operand. An
55173 * expression involving a degenerate sub-expression is equivalent to a
55174 * reduced expression with the degenerate sub-expression removed, for example
55175 *
55176 * LogicalAnd (operator)
55177 * + LogicalOr (degenerate operator)
55178 * | + LogicalAnd (degenerate operator)
55179 * | + IsType('int') (terminal)
55180 * + GreaterThan(10) (terminal)
55181 *
55182 * is equivalent to
55183 *
55184 * LogicalAnd (operator)
55185 * + IsType('int') (terminal)
55186 * + GreaterThan(10) (terminal)
55187 *
55188 * because the subexpression
55189 *
55190 * + LogicalOr
55191 * + LogicalAnd
55192 * + -
55193 *
55194 * is degenerate. Calling reduce() on the LogicalOr object above, as well
55195 * as on LogicalAnd, shall return the IsType('int') instance.
55196 *
55197 * Other specific reductions can be implemented, for example cascade of
55198 * LogicalNot operators
55199 *
55200 * + LogicalNot
55201 * + LogicalNot
55202 * +LogicalNot
55203 * + IsTrue
55204 *
55205 * can be reduced to
55206 *
55207 * LogicalNot
55208 * + IsTrue
55209 */
55210 protected function reduce(): self
55211 {
55212 return $this;
55213 }
55214 /**
55215 * @psalm-return non-empty-string
55216 */
55217 protected function valueToTypeStringFragment(mixed $value): string
55218 {
55219 $type = strtolower(gettype($value));
55220 if ($type === 'double') {
55221 $type = 'float';
55222 }
55223 if ($type === 'resource (closed)') {
55224 $type = 'closed resource';
55225 }
55226 return match ($type) {
55227 'array', 'integer', 'object' => 'an ' . $type . ' ',
55228 'boolean', 'closed resource', 'float', 'resource', 'string' => 'a ' . $type . ' ',
55229 'null' => 'null ',
55230 default => 'a value of ' . $type . ' ',
55231 };
55232 }
55233 }
55234 <?php
55235
55236 declare (strict_types=1);
55237 /*
55238 * This file is part of PHPUnit.
55239 *
55240 * (c) Sebastian Bergmann <sebastian@phpunit.de>
55241 *
55242 * For the full copyright and license information, please view the LICENSE
55243 * file that was distributed with this source code.
55244 */
55245 namespace PHPUnit\Framework\Constraint;
55246
55247 use function is_string;
55248 use function sprintf;
55249 use function str_contains;
55250 use function trim;
55251 use PHPUnit\Framework\ExpectationFailedException;
55252 use PHPUnit\Util\Exporter;
55253 use PHPUnitPHAR\SebastianBergmann\Comparator\ComparisonFailure;
55254 use PHPUnitPHAR\SebastianBergmann\Comparator\Factory as ComparatorFactory;
55255 /**
55256 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
55257 */
55258 final class IsEqual extends \PHPUnit\Framework\Constraint\Constraint
55259 {
55260 private readonly mixed $value;
55261 private readonly float $delta;
55262 private readonly bool $canonicalize;
55263 private readonly bool $ignoreCase;
55264 public function __construct(mixed $value, float $delta = 0.0, bool $canonicalize = \false, bool $ignoreCase = \false)
55265 {
55266 $this->value = $value;
55267 $this->delta = $delta;
55268 $this->canonicalize = $canonicalize;
55269 $this->ignoreCase = $ignoreCase;
55270 }
55271 /**
55272 * Evaluates the constraint for parameter $other.
55273 *
55274 * If $returnResult is set to false (the default), an exception is thrown
55275 * in case of a failure. null is returned otherwise.
55276 *
55277 * If $returnResult is true, the result of the evaluation is returned as
55278 * a boolean value instead: true in case of success, false in case of a
55279 * failure.
55280 *
55281 * @throws ExpectationFailedException
55282 */
55283 public function evaluate(mixed $other, string $description = '', bool $returnResult = \false): ?bool
55284 {
55285 // If $this->value and $other are identical, they are also equal.
55286 // This is the most common path and will allow us to skip
55287 // initialization of all the comparators.
55288 if ($this->value === $other) {
55289 return \true;
55290 }
55291 $comparatorFactory = ComparatorFactory::getInstance();
55292 try {
55293 $comparator = $comparatorFactory->getComparatorFor($this->value, $other);
55294 $comparator->assertEquals($this->value, $other, $this->delta, $this->canonicalize, $this->ignoreCase);
55295 } catch (ComparisonFailure $f) {
55296 if ($returnResult) {
55297 return \false;
55298 }
55299 throw new ExpectationFailedException(trim($description . "\n" . $f->getMessage()), $f);
55300 }
55301 return \true;
55302 }
55303 /**
55304 * Returns a string representation of the constraint.
55305 */
55306 public function toString(bool $exportObjects = \false): string
55307 {
55308 $delta = '';
55309 if (is_string($this->value)) {
55310 if (str_contains($this->value, "\n")) {
55311 return 'is equal to <text>';
55312 }
55313 return sprintf("is equal to '%s'", $this->value);
55314 }
55315 if ($this->delta != 0) {
55316 $delta = sprintf(' with delta <%F>', $this->delta);
55317 }
55318 return sprintf('is equal to %s%s', Exporter::export($this->value, $exportObjects), $delta);
55319 }
55320 }
55321 <?php
55322
55323 declare (strict_types=1);
55324 /*
55325 * This file is part of PHPUnit.
55326 *
55327 * (c) Sebastian Bergmann <sebastian@phpunit.de>
55328 *
55329 * For the full copyright and license information, please view the LICENSE
55330 * file that was distributed with this source code.
55331 */
55332 namespace PHPUnit\Framework\Constraint;
55333
55334 use function is_string;
55335 use function sprintf;
55336 use function str_contains;
55337 use function trim;
55338 use PHPUnit\Framework\ExpectationFailedException;
55339 use PHPUnit\Util\Exporter;
55340 use PHPUnitPHAR\SebastianBergmann\Comparator\ComparisonFailure;
55341 use PHPUnitPHAR\SebastianBergmann\Comparator\Factory as ComparatorFactory;
55342 /**
55343 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
55344 */
55345 final class IsEqualCanonicalizing extends \PHPUnit\Framework\Constraint\Constraint
55346 {
55347 private readonly mixed $value;
55348 public function __construct(mixed $value)
55349 {
55350 $this->value = $value;
55351 }
55352 /**
55353 * Evaluates the constraint for parameter $other.
55354 *
55355 * If $returnResult is set to false (the default), an exception is thrown
55356 * in case of a failure. null is returned otherwise.
55357 *
55358 * If $returnResult is true, the result of the evaluation is returned as
55359 * a boolean value instead: true in case of success, false in case of a
55360 * failure.
55361 *
55362 * @throws ExpectationFailedException
55363 */
55364 public function evaluate(mixed $other, string $description = '', bool $returnResult = \false): ?bool
55365 {
55366 // If $this->value and $other are identical, they are also equal.
55367 // This is the most common path and will allow us to skip
55368 // initialization of all the comparators.
55369 if ($this->value === $other) {
55370 return \true;
55371 }
55372 $comparatorFactory = ComparatorFactory::getInstance();
55373 try {
55374 $comparator = $comparatorFactory->getComparatorFor($this->value, $other);
55375 $comparator->assertEquals($this->value, $other, 0.0, \true);
55376 } catch (ComparisonFailure $f) {
55377 if ($returnResult) {
55378 return \false;
55379 }
55380 throw new ExpectationFailedException(trim($description . "\n" . $f->getMessage()), $f);
55381 }
55382 return \true;
55383 }
55384 /**
55385 * Returns a string representation of the constraint.
55386 */
55387 public function toString(bool $exportObjects = \false): string
55388 {
55389 if (is_string($this->value)) {
55390 if (str_contains($this->value, "\n")) {
55391 return 'is equal to <text>';
55392 }
55393 return sprintf("is equal to '%s'", $this->value);
55394 }
55395 return sprintf('is equal to %s', Exporter::export($this->value, $exportObjects));
55396 }
55397 }
55398 <?php
55399
55400 declare (strict_types=1);
55401 /*
55402 * This file is part of PHPUnit.
55403 *
55404 * (c) Sebastian Bergmann <sebastian@phpunit.de>
55405 *
55406 * For the full copyright and license information, please view the LICENSE
55407 * file that was distributed with this source code.
55408 */
55409 namespace PHPUnit\Framework\Constraint;
55410
55411 use function is_string;
55412 use function sprintf;
55413 use function str_contains;
55414 use function trim;
55415 use PHPUnit\Framework\ExpectationFailedException;
55416 use PHPUnit\Util\Exporter;
55417 use PHPUnitPHAR\SebastianBergmann\Comparator\ComparisonFailure;
55418 use PHPUnitPHAR\SebastianBergmann\Comparator\Factory as ComparatorFactory;
55419 /**
55420 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
55421 */
55422 final class IsEqualIgnoringCase extends \PHPUnit\Framework\Constraint\Constraint
55423 {
55424 private readonly mixed $value;
55425 public function __construct(mixed $value)
55426 {
55427 $this->value = $value;
55428 }
55429 /**
55430 * Evaluates the constraint for parameter $other.
55431 *
55432 * If $returnResult is set to false (the default), an exception is thrown
55433 * in case of a failure. null is returned otherwise.
55434 *
55435 * If $returnResult is true, the result of the evaluation is returned as
55436 * a boolean value instead: true in case of success, false in case of a
55437 * failure.
55438 *
55439 * @throws ExpectationFailedException
55440 */
55441 public function evaluate(mixed $other, string $description = '', bool $returnResult = \false): ?bool
55442 {
55443 // If $this->value and $other are identical, they are also equal.
55444 // This is the most common path and will allow us to skip
55445 // initialization of all the comparators.
55446 if ($this->value === $other) {
55447 return \true;
55448 }
55449 $comparatorFactory = ComparatorFactory::getInstance();
55450 try {
55451 $comparator = $comparatorFactory->getComparatorFor($this->value, $other);
55452 $comparator->assertEquals($this->value, $other, 0.0, \false, \true);
55453 } catch (ComparisonFailure $f) {
55454 if ($returnResult) {
55455 return \false;
55456 }
55457 throw new ExpectationFailedException(trim($description . "\n" . $f->getMessage()), $f);
55458 }
55459 return \true;
55460 }
55461 /**
55462 * Returns a string representation of the constraint.
55463 */
55464 public function toString(bool $exportObjects = \false): string
55465 {
55466 if (is_string($this->value)) {
55467 if (str_contains($this->value, "\n")) {
55468 return 'is equal to <text>';
55469 }
55470 return sprintf("is equal to '%s'", $this->value);
55471 }
55472 return sprintf('is equal to %s', Exporter::export($this->value, $exportObjects));
55473 }
55474 }
55475 <?php
55476
55477 declare (strict_types=1);
55478 /*
55479 * This file is part of PHPUnit.
55480 *
55481 * (c) Sebastian Bergmann <sebastian@phpunit.de>
55482 *
55483 * For the full copyright and license information, please view the LICENSE
55484 * file that was distributed with this source code.
55485 */
55486 namespace PHPUnit\Framework\Constraint;
55487
55488 use function sprintf;
55489 use function trim;
55490 use PHPUnit\Framework\ExpectationFailedException;
55491 use PHPUnit\Util\Exporter;
55492 use PHPUnitPHAR\SebastianBergmann\Comparator\ComparisonFailure;
55493 use PHPUnitPHAR\SebastianBergmann\Comparator\Factory as ComparatorFactory;
55494 /**
55495 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
55496 */
55497 final class IsEqualWithDelta extends \PHPUnit\Framework\Constraint\Constraint
55498 {
55499 private readonly mixed $value;
55500 private readonly float $delta;
55501 public function __construct(mixed $value, float $delta)
55502 {
55503 $this->value = $value;
55504 $this->delta = $delta;
55505 }
55506 /**
55507 * Evaluates the constraint for parameter $other.
55508 *
55509 * If $returnResult is set to false (the default), an exception is thrown
55510 * in case of a failure. null is returned otherwise.
55511 *
55512 * If $returnResult is true, the result of the evaluation is returned as
55513 * a boolean value instead: true in case of success, false in case of a
55514 * failure.
55515 *
55516 * @throws ExpectationFailedException
55517 */
55518 public function evaluate(mixed $other, string $description = '', bool $returnResult = \false): ?bool
55519 {
55520 // If $this->value and $other are identical, they are also equal.
55521 // This is the most common path and will allow us to skip
55522 // initialization of all the comparators.
55523 if ($this->value === $other) {
55524 return \true;
55525 }
55526 $comparatorFactory = ComparatorFactory::getInstance();
55527 try {
55528 $comparator = $comparatorFactory->getComparatorFor($this->value, $other);
55529 $comparator->assertEquals($this->value, $other, $this->delta);
55530 } catch (ComparisonFailure $f) {
55531 if ($returnResult) {
55532 return \false;
55533 }
55534 throw new ExpectationFailedException(trim($description . "\n" . $f->getMessage()), $f);
55535 }
55536 return \true;
55537 }
55538 /**
55539 * Returns a string representation of the constraint.
55540 */
55541 public function toString(bool $exportObjects = \false): string
55542 {
55543 return sprintf('is equal to %s with delta <%F>', Exporter::export($this->value, $exportObjects), $this->delta);
55544 }
55545 }
55546 <?php
55547
55548 declare (strict_types=1);
55549 /*
55550 * This file is part of PHPUnit.
55551 *
55552 * (c) Sebastian Bergmann <sebastian@phpunit.de>
55553 *
55554 * For the full copyright and license information, please view the LICENSE
55555 * file that was distributed with this source code.
55556 */
55557 namespace PHPUnit\Framework\Constraint;
55558
55559 use function sprintf;
55560 use PHPUnit\Util\Filter;
55561 use Throwable;
55562 /**
55563 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
55564 *
55565 * @internal This class is not covered by the backward compatibility promise for PHPUnit
55566 */
55567 final class Exception extends \PHPUnit\Framework\Constraint\Constraint
55568 {
55569 private readonly string $className;
55570 public function __construct(string $className)
55571 {
55572 $this->className = $className;
55573 }
55574 /**
55575 * Returns a string representation of the constraint.
55576 */
55577 public function toString(): string
55578 {
55579 return sprintf('exception of type "%s"', $this->className);
55580 }
55581 /**
55582 * Evaluates the constraint for parameter $other. Returns true if the
55583 * constraint is met, false otherwise.
55584 */
55585 protected function matches(mixed $other): bool
55586 {
55587 return $other instanceof $this->className;
55588 }
55589 /**
55590 * Returns the description of the failure.
55591 *
55592 * The beginning of failure messages is "Failed asserting that" in most
55593 * cases. This method should return the second part of that sentence.
55594 *
55595 * @throws \PHPUnit\Framework\Exception
55596 */
55597 protected function failureDescription(mixed $other): string
55598 {
55599 if ($other === null) {
55600 return sprintf('exception of type "%s" is thrown', $this->className);
55601 }
55602 $message = '';
55603 if ($other instanceof Throwable) {
55604 $message = '. Message was: "' . $other->getMessage() . '" at' . "\n" . Filter::getFilteredStacktrace($other);
55605 }
55606 return sprintf('exception of type "%s" matches expected exception "%s"%s', $other::class, $this->className, $message);
55607 }
55608 }
55609 <?php
55610
55611 declare (strict_types=1);
55612 /*
55613 * This file is part of PHPUnit.
55614 *
55615 * (c) Sebastian Bergmann <sebastian@phpunit.de>
55616 *
55617 * For the full copyright and license information, please view the LICENSE
55618 * file that was distributed with this source code.
55619 */
55620 namespace PHPUnit\Framework\Constraint;
55621
55622 use function sprintf;
55623 use PHPUnit\Util\Exporter;
55624 /**
55625 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
55626 *
55627 * @internal This class is not covered by the backward compatibility promise for PHPUnit
55628 */
55629 final class ExceptionCode extends \PHPUnit\Framework\Constraint\Constraint
55630 {
55631 private readonly int|string $expectedCode;
55632 public function __construct(int|string $expected)
55633 {
55634 $this->expectedCode = $expected;
55635 }
55636 public function toString(): string
55637 {
55638 return 'exception code is ' . $this->expectedCode;
55639 }
55640 /**
55641 * Evaluates the constraint for parameter $other. Returns true if the
55642 * constraint is met, false otherwise.
55643 */
55644 protected function matches(mixed $other): bool
55645 {
55646 return (string) $other === (string) $this->expectedCode;
55647 }
55648 /**
55649 * Returns the description of the failure.
55650 *
55651 * The beginning of failure messages is "Failed asserting that" in most
55652 * cases. This method should return the second part of that sentence.
55653 */
55654 protected function failureDescription(mixed $other): string
55655 {
55656 return sprintf('%s is equal to expected exception code %s', Exporter::export($other, \true), Exporter::export($this->expectedCode, \true));
55657 }
55658 }
55659 <?php
55660
55661 declare (strict_types=1);
55662 /*
55663 * This file is part of PHPUnit.
55664 *
55665 * (c) Sebastian Bergmann <sebastian@phpunit.de>
55666 *
55667 * For the full copyright and license information, please view the LICENSE
55668 * file that was distributed with this source code.
55669 */
55670 namespace PHPUnit\Framework\Constraint;
55671
55672 use function sprintf;
55673 use function str_contains;
55674 use PHPUnit\Util\Exporter;
55675 /**
55676 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
55677 *
55678 * @internal This class is not covered by the backward compatibility promise for PHPUnit
55679 */
55680 final class ExceptionMessageIsOrContains extends \PHPUnit\Framework\Constraint\Constraint
55681 {
55682 private readonly string $expectedMessage;
55683 public function __construct(string $expectedMessage)
55684 {
55685 $this->expectedMessage = $expectedMessage;
55686 }
55687 public function toString(): string
55688 {
55689 if ($this->expectedMessage === '') {
55690 return 'exception message is empty';
55691 }
55692 return 'exception message contains ' . Exporter::export($this->expectedMessage);
55693 }
55694 protected function matches(mixed $other): bool
55695 {
55696 if ($this->expectedMessage === '') {
55697 return $other === '';
55698 }
55699 return str_contains((string) $other, $this->expectedMessage);
55700 }
55701 /**
55702 * Returns the description of the failure.
55703 *
55704 * The beginning of failure messages is "Failed asserting that" in most
55705 * cases. This method should return the second part of that sentence.
55706 */
55707 protected function failureDescription(mixed $other): string
55708 {
55709 if ($this->expectedMessage === '') {
55710 return sprintf("exception message is empty but is '%s'", $other);
55711 }
55712 return sprintf("exception message '%s' contains '%s'", $other, $this->expectedMessage);
55713 }
55714 }
55715 <?php
55716
55717 declare (strict_types=1);
55718 /*
55719 * This file is part of PHPUnit.
55720 *
55721 * (c) Sebastian Bergmann <sebastian@phpunit.de>
55722 *
55723 * For the full copyright and license information, please view the LICENSE
55724 * file that was distributed with this source code.
55725 */
55726 namespace PHPUnit\Framework\Constraint;
55727
55728 use function preg_match;
55729 use function sprintf;
55730 use Exception;
55731 use PHPUnit\Util\Exporter;
55732 /**
55733 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
55734 *
55735 * @internal This class is not covered by the backward compatibility promise for PHPUnit
55736 */
55737 final class ExceptionMessageMatchesRegularExpression extends \PHPUnit\Framework\Constraint\Constraint
55738 {
55739 private readonly string $regularExpression;
55740 public function __construct(string $regularExpression)
55741 {
55742 $this->regularExpression = $regularExpression;
55743 }
55744 public function toString(): string
55745 {
55746 return 'exception message matches ' . Exporter::export($this->regularExpression);
55747 }
55748 /**
55749 * Evaluates the constraint for parameter $other. Returns true if the
55750 * constraint is met, false otherwise.
55751 *
55752 * @throws \PHPUnit\Framework\Exception
55753 * @throws Exception
55754 */
55755 protected function matches(mixed $other): bool
55756 {
55757 $match = @preg_match($this->regularExpression, (string) $other);
55758 if ($match === \false) {
55759 throw new \PHPUnit\Framework\Exception(sprintf('Invalid expected exception message regular expression given: %s', $this->regularExpression));
55760 }
55761 return $match === 1;
55762 }
55763 /**
55764 * Returns the description of the failure.
55765 *
55766 * The beginning of failure messages is "Failed asserting that" in most
55767 * cases. This method should return the second part of that sentence.
55768 */
55769 protected function failureDescription(mixed $other): string
55770 {
55771 return sprintf("exception message '%s' matches '%s'", $other, $this->regularExpression);
55772 }
55773 }
55774 <?php
55775
55776 declare (strict_types=1);
55777 /*
55778 * This file is part of PHPUnit.
55779 *
55780 * (c) Sebastian Bergmann <sebastian@phpunit.de>
55781 *
55782 * For the full copyright and license information, please view the LICENSE
55783 * file that was distributed with this source code.
55784 */
55785 namespace PHPUnit\Framework\Constraint;
55786
55787 use function is_dir;
55788 use function sprintf;
55789 /**
55790 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
55791 */
55792 final class DirectoryExists extends \PHPUnit\Framework\Constraint\Constraint
55793 {
55794 /**
55795 * Returns a string representation of the constraint.
55796 */
55797 public function toString(): string
55798 {
55799 return 'directory exists';
55800 }
55801 /**
55802 * Evaluates the constraint for parameter $other. Returns true if the
55803 * constraint is met, false otherwise.
55804 */
55805 protected function matches(mixed $other): bool
55806 {
55807 return is_dir($other);
55808 }
55809 /**
55810 * Returns the description of the failure.
55811 *
55812 * The beginning of failure messages is "Failed asserting that" in most
55813 * cases. This method should return the second part of that sentence.
55814 */
55815 protected function failureDescription(mixed $other): string
55816 {
55817 return sprintf('directory "%s" exists', $other);
55818 }
55819 }
55820 <?php
55821
55822 declare (strict_types=1);
55823 /*
55824 * This file is part of PHPUnit.
55825 *
55826 * (c) Sebastian Bergmann <sebastian@phpunit.de>
55827 *
55828 * For the full copyright and license information, please view the LICENSE
55829 * file that was distributed with this source code.
55830 */
55831 namespace PHPUnit\Framework\Constraint;
55832
55833 use function file_exists;
55834 use function sprintf;
55835 /**
55836 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
55837 */
55838 final class FileExists extends \PHPUnit\Framework\Constraint\Constraint
55839 {
55840 /**
55841 * Returns a string representation of the constraint.
55842 */
55843 public function toString(): string
55844 {
55845 return 'file exists';
55846 }
55847 /**
55848 * Evaluates the constraint for parameter $other. Returns true if the
55849 * constraint is met, false otherwise.
55850 */
55851 protected function matches(mixed $other): bool
55852 {
55853 return file_exists($other);
55854 }
55855 /**
55856 * Returns the description of the failure.
55857 *
55858 * The beginning of failure messages is "Failed asserting that" in most
55859 * cases. This method should return the second part of that sentence.
55860 */
55861 protected function failureDescription(mixed $other): string
55862 {
55863 return sprintf('file "%s" exists', $other);
55864 }
55865 }
55866 <?php
55867
55868 declare (strict_types=1);
55869 /*
55870 * This file is part of PHPUnit.
55871 *
55872 * (c) Sebastian Bergmann <sebastian@phpunit.de>
55873 *
55874 * For the full copyright and license information, please view the LICENSE
55875 * file that was distributed with this source code.
55876 */
55877 namespace PHPUnit\Framework\Constraint;
55878
55879 use function is_readable;
55880 use function sprintf;
55881 /**
55882 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
55883 */
55884 final class IsReadable extends \PHPUnit\Framework\Constraint\Constraint
55885 {
55886 /**
55887 * Returns a string representation of the constraint.
55888 */
55889 public function toString(): string
55890 {
55891 return 'is readable';
55892 }
55893 /**
55894 * Evaluates the constraint for parameter $other. Returns true if the
55895 * constraint is met, false otherwise.
55896 */
55897 protected function matches(mixed $other): bool
55898 {
55899 return is_readable($other);
55900 }
55901 /**
55902 * Returns the description of the failure.
55903 *
55904 * The beginning of failure messages is "Failed asserting that" in most
55905 * cases. This method should return the second part of that sentence.
55906 */
55907 protected function failureDescription(mixed $other): string
55908 {
55909 return sprintf('"%s" is readable', $other);
55910 }
55911 }
55912 <?php
55913
55914 declare (strict_types=1);
55915 /*
55916 * This file is part of PHPUnit.
55917 *
55918 * (c) Sebastian Bergmann <sebastian@phpunit.de>
55919 *
55920 * For the full copyright and license information, please view the LICENSE
55921 * file that was distributed with this source code.
55922 */
55923 namespace PHPUnit\Framework\Constraint;
55924
55925 use function is_writable;
55926 use function sprintf;
55927 /**
55928 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
55929 */
55930 final class IsWritable extends \PHPUnit\Framework\Constraint\Constraint
55931 {
55932 /**
55933 * Returns a string representation of the constraint.
55934 */
55935 public function toString(): string
55936 {
55937 return 'is writable';
55938 }
55939 /**
55940 * Evaluates the constraint for parameter $other. Returns true if the
55941 * constraint is met, false otherwise.
55942 */
55943 protected function matches(mixed $other): bool
55944 {
55945 return is_writable($other);
55946 }
55947 /**
55948 * Returns the description of the failure.
55949 *
55950 * The beginning of failure messages is "Failed asserting that" in most
55951 * cases. This method should return the second part of that sentence.
55952 */
55953 protected function failureDescription(mixed $other): string
55954 {
55955 return sprintf('"%s" is writable', $other);
55956 }
55957 }
55958 <?php
55959
55960 declare (strict_types=1);
55961 /*
55962 * This file is part of PHPUnit.
55963 *
55964 * (c) Sebastian Bergmann <sebastian@phpunit.de>
55965 *
55966 * For the full copyright and license information, please view the LICENSE
55967 * file that was distributed with this source code.
55968 */
55969 namespace PHPUnit\Framework\Constraint;
55970
55971 use PHPUnit\Framework\ExpectationFailedException;
55972 /**
55973 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
55974 */
55975 final class IsAnything extends \PHPUnit\Framework\Constraint\Constraint
55976 {
55977 /**
55978 * Evaluates the constraint for parameter $other.
55979 *
55980 * If $returnResult is set to false (the default), an exception is thrown
55981 * in case of a failure. null is returned otherwise.
55982 *
55983 * If $returnResult is true, the result of the evaluation is returned as
55984 * a boolean value instead: true in case of success, false in case of a
55985 * failure.
55986 *
55987 * @throws ExpectationFailedException
55988 */
55989 public function evaluate(mixed $other, string $description = '', bool $returnResult = \false): ?bool
55990 {
55991 return $returnResult ? \true : null;
55992 }
55993 /**
55994 * Returns a string representation of the constraint.
55995 */
55996 public function toString(): string
55997 {
55998 return 'is anything';
55999 }
56000 /**
56001 * Counts the number of constraint elements.
56002 */
56003 public function count(): int
56004 {
56005 return 0;
56006 }
56007 }
56008 <?php
56009
56010 declare (strict_types=1);
56011 /*
56012 * This file is part of PHPUnit.
56013 *
56014 * (c) Sebastian Bergmann <sebastian@phpunit.de>
56015 *
56016 * For the full copyright and license information, please view the LICENSE
56017 * file that was distributed with this source code.
56018 */
56019 namespace PHPUnit\Framework\Constraint;
56020
56021 use function explode;
56022 use function gettype;
56023 use function is_array;
56024 use function is_object;
56025 use function is_string;
56026 use function sprintf;
56027 use PHPUnit\Framework\ExpectationFailedException;
56028 use PHPUnit\Util\Exporter;
56029 use PHPUnitPHAR\SebastianBergmann\Comparator\ComparisonFailure;
56030 use UnitEnum;
56031 /**
56032 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
56033 */
56034 final class IsIdentical extends \PHPUnit\Framework\Constraint\Constraint
56035 {
56036 private readonly mixed $value;
56037 public function __construct(mixed $value)
56038 {
56039 $this->value = $value;
56040 }
56041 /**
56042 * Evaluates the constraint for parameter $other.
56043 *
56044 * If $returnResult is set to false (the default), an exception is thrown
56045 * in case of a failure. null is returned otherwise.
56046 *
56047 * If $returnResult is true, the result of the evaluation is returned as
56048 * a boolean value instead: true in case of success, false in case of a
56049 * failure.
56050 *
56051 * @throws ExpectationFailedException
56052 */
56053 public function evaluate(mixed $other, string $description = '', bool $returnResult = \false): ?bool
56054 {
56055 $success = $this->value === $other;
56056 if ($returnResult) {
56057 return $success;
56058 }
56059 if (!$success) {
56060 $f = null;
56061 // if both values are strings, make sure a diff is generated
56062 if (is_string($this->value) && is_string($other)) {
56063 $f = new ComparisonFailure($this->value, $other, sprintf("'%s'", $this->value), sprintf("'%s'", $other));
56064 }
56065 // if both values are array or enums, make sure a diff is generated
56066 if (is_array($this->value) && is_array($other) || $this->value instanceof UnitEnum && $other instanceof UnitEnum) {
56067 $f = new ComparisonFailure($this->value, $other, Exporter::export($this->value, \true), Exporter::export($other, \true));
56068 }
56069 $this->fail($other, $description, $f);
56070 }
56071 return null;
56072 }
56073 /**
56074 * Returns a string representation of the constraint.
56075 */
56076 public function toString(bool $exportObjects = \false): string
56077 {
56078 if (is_object($this->value)) {
56079 return 'is identical to an object of class "' . $this->value::class . '"';
56080 }
56081 return 'is identical to ' . Exporter::export($this->value, $exportObjects);
56082 }
56083 /**
56084 * Returns the description of the failure.
56085 *
56086 * The beginning of failure messages is "Failed asserting that" in most
56087 * cases. This method should return the second part of that sentence.
56088 */
56089 protected function failureDescription(mixed $other): string
56090 {
56091 if (is_object($this->value) && is_object($other)) {
56092 return 'two variables reference the same object';
56093 }
56094 if (explode(' ', gettype($this->value), 2)[0] === 'resource' && explode(' ', gettype($other), 2)[0] === 'resource') {
56095 return 'two variables reference the same resource';
56096 }
56097 if (is_string($this->value) && is_string($other)) {
56098 return 'two strings are identical';
56099 }
56100 if (is_array($this->value) && is_array($other)) {
56101 return 'two arrays are identical';
56102 }
56103 return parent::failureDescription($other);
56104 }
56105 }
56106 <?php
56107
56108 declare (strict_types=1);
56109 /*
56110 * This file is part of PHPUnit.
56111 *
56112 * (c) Sebastian Bergmann <sebastian@phpunit.de>
56113 *
56114 * For the full copyright and license information, please view the LICENSE
56115 * file that was distributed with this source code.
56116 */
56117 namespace PHPUnit\Framework\Constraint;
56118
56119 use function json_decode;
56120 use function sprintf;
56121 use PHPUnit\Framework\ExpectationFailedException;
56122 use PHPUnit\Util\InvalidJsonException;
56123 use PHPUnit\Util\Json;
56124 use PHPUnitPHAR\SebastianBergmann\Comparator\ComparisonFailure;
56125 /**
56126 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
56127 */
56128 final class JsonMatches extends \PHPUnit\Framework\Constraint\Constraint
56129 {
56130 private readonly string $value;
56131 public function __construct(string $value)
56132 {
56133 $this->value = $value;
56134 }
56135 /**
56136 * Returns a string representation of the object.
56137 */
56138 public function toString(): string
56139 {
56140 return sprintf('matches JSON string "%s"', $this->value);
56141 }
56142 /**
56143 * Evaluates the constraint for parameter $other. Returns true if the
56144 * constraint is met, false otherwise.
56145 *
56146 * This method can be overridden to implement the evaluation algorithm.
56147 */
56148 protected function matches(mixed $other): bool
56149 {
56150 [$error, $recodedOther] = Json::canonicalize($other);
56151 if ($error) {
56152 return \false;
56153 }
56154 [$error, $recodedValue] = Json::canonicalize($this->value);
56155 if ($error) {
56156 return \false;
56157 }
56158 return $recodedOther == $recodedValue;
56159 }
56160 /**
56161 * Throws an exception for the given compared value and test description.
56162 *
56163 * @throws ExpectationFailedException
56164 * @throws InvalidJsonException
56165 */
56166 protected function fail(mixed $other, string $description, ?ComparisonFailure $comparisonFailure = null): never
56167 {
56168 if ($comparisonFailure === null) {
56169 [$error, $recodedOther] = Json::canonicalize($other);
56170 if ($error) {
56171 parent::fail($other, $description);
56172 }
56173 [$error, $recodedValue] = Json::canonicalize($this->value);
56174 if ($error) {
56175 parent::fail($other, $description);
56176 }
56177 $comparisonFailure = new ComparisonFailure(json_decode($this->value), json_decode($other), Json::prettify($recodedValue), Json::prettify($recodedOther), 'Failed asserting that two json values are equal.');
56178 }
56179 parent::fail($other, $description, $comparisonFailure);
56180 }
56181 }
56182 <?php
56183
56184 declare (strict_types=1);
56185 /*
56186 * This file is part of PHPUnit.
56187 *
56188 * (c) Sebastian Bergmann <sebastian@phpunit.de>
56189 *
56190 * For the full copyright and license information, please view the LICENSE
56191 * file that was distributed with this source code.
56192 */
56193 namespace PHPUnit\Framework\Constraint;
56194
56195 use function is_finite;
56196 /**
56197 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
56198 */
56199 final class IsFinite extends \PHPUnit\Framework\Constraint\Constraint
56200 {
56201 /**
56202 * Returns a string representation of the constraint.
56203 */
56204 public function toString(): string
56205 {
56206 return 'is finite';
56207 }
56208 /**
56209 * Evaluates the constraint for parameter $other. Returns true if the
56210 * constraint is met, false otherwise.
56211 */
56212 protected function matches(mixed $other): bool
56213 {
56214 return is_finite($other);
56215 }
56216 }
56217 <?php
56218
56219 declare (strict_types=1);
56220 /*
56221 * This file is part of PHPUnit.
56222 *
56223 * (c) Sebastian Bergmann <sebastian@phpunit.de>
56224 *
56225 * For the full copyright and license information, please view the LICENSE
56226 * file that was distributed with this source code.
56227 */
56228 namespace PHPUnit\Framework\Constraint;
56229
56230 use function is_infinite;
56231 /**
56232 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
56233 */
56234 final class IsInfinite extends \PHPUnit\Framework\Constraint\Constraint
56235 {
56236 /**
56237 * Returns a string representation of the constraint.
56238 */
56239 public function toString(): string
56240 {
56241 return 'is infinite';
56242 }
56243 /**
56244 * Evaluates the constraint for parameter $other. Returns true if the
56245 * constraint is met, false otherwise.
56246 */
56247 protected function matches(mixed $other): bool
56248 {
56249 return is_infinite($other);
56250 }
56251 }
56252 <?php
56253
56254 declare (strict_types=1);
56255 /*
56256 * This file is part of PHPUnit.
56257 *
56258 * (c) Sebastian Bergmann <sebastian@phpunit.de>
56259 *
56260 * For the full copyright and license information, please view the LICENSE
56261 * file that was distributed with this source code.
56262 */
56263 namespace PHPUnit\Framework\Constraint;
56264
56265 use function is_nan;
56266 /**
56267 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
56268 */
56269 final class IsNan extends \PHPUnit\Framework\Constraint\Constraint
56270 {
56271 /**
56272 * Returns a string representation of the constraint.
56273 */
56274 public function toString(): string
56275 {
56276 return 'is nan';
56277 }
56278 /**
56279 * Evaluates the constraint for parameter $other. Returns true if the
56280 * constraint is met, false otherwise.
56281 */
56282 protected function matches(mixed $other): bool
56283 {
56284 return is_nan($other);
56285 }
56286 }
56287 <?php
56288
56289 declare (strict_types=1);
56290 /*
56291 * This file is part of PHPUnit.
56292 *
56293 * (c) Sebastian Bergmann <sebastian@phpunit.de>
56294 *
56295 * For the full copyright and license information, please view the LICENSE
56296 * file that was distributed with this source code.
56297 */
56298 namespace PHPUnit\Framework\Constraint;
56299
56300 use function is_object;
56301 use PHPUnit\Framework\ActualValueIsNotAnObjectException;
56302 use PHPUnit\Framework\ComparisonMethodDoesNotAcceptParameterTypeException;
56303 use PHPUnit\Framework\ComparisonMethodDoesNotDeclareBoolReturnTypeException;
56304 use PHPUnit\Framework\ComparisonMethodDoesNotDeclareExactlyOneParameterException;
56305 use PHPUnit\Framework\ComparisonMethodDoesNotDeclareParameterTypeException;
56306 use PHPUnit\Framework\ComparisonMethodDoesNotExistException;
56307 use ReflectionNamedType;
56308 use ReflectionObject;
56309 /**
56310 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
56311 */
56312 final class ObjectEquals extends \PHPUnit\Framework\Constraint\Constraint
56313 {
56314 private readonly object $expected;
56315 private readonly string $method;
56316 public function __construct(object $object, string $method = 'equals')
56317 {
56318 $this->expected = $object;
56319 $this->method = $method;
56320 }
56321 public function toString(): string
56322 {
56323 return 'two objects are equal';
56324 }
56325 /**
56326 * @throws ActualValueIsNotAnObjectException
56327 * @throws ComparisonMethodDoesNotAcceptParameterTypeException
56328 * @throws ComparisonMethodDoesNotDeclareBoolReturnTypeException
56329 * @throws ComparisonMethodDoesNotDeclareExactlyOneParameterException
56330 * @throws ComparisonMethodDoesNotDeclareParameterTypeException
56331 * @throws ComparisonMethodDoesNotExistException
56332 */
56333 protected function matches(mixed $other): bool
56334 {
56335 if (!is_object($other)) {
56336 throw new ActualValueIsNotAnObjectException();
56337 }
56338 $object = new ReflectionObject($other);
56339 if (!$object->hasMethod($this->method)) {
56340 throw new ComparisonMethodDoesNotExistException($other::class, $this->method);
56341 }
56342 $method = $object->getMethod($this->method);
56343 if (!$method->hasReturnType()) {
56344 throw new ComparisonMethodDoesNotDeclareBoolReturnTypeException($other::class, $this->method);
56345 }
56346 $returnType = $method->getReturnType();
56347 if (!$returnType instanceof ReflectionNamedType) {
56348 throw new ComparisonMethodDoesNotDeclareBoolReturnTypeException($other::class, $this->method);
56349 }
56350 if ($returnType->allowsNull()) {
56351 throw new ComparisonMethodDoesNotDeclareBoolReturnTypeException($other::class, $this->method);
56352 }
56353 if ($returnType->getName() !== 'bool') {
56354 throw new ComparisonMethodDoesNotDeclareBoolReturnTypeException($other::class, $this->method);
56355 }
56356 if ($method->getNumberOfParameters() !== 1 || $method->getNumberOfRequiredParameters() !== 1) {
56357 throw new ComparisonMethodDoesNotDeclareExactlyOneParameterException($other::class, $this->method);
56358 }
56359 $parameter = $method->getParameters()[0];
56360 if (!$parameter->hasType()) {
56361 throw new ComparisonMethodDoesNotDeclareParameterTypeException($other::class, $this->method);
56362 }
56363 $type = $parameter->getType();
56364 if (!$type instanceof ReflectionNamedType) {
56365 throw new ComparisonMethodDoesNotDeclareParameterTypeException($other::class, $this->method);
56366 }
56367 $typeName = $type->getName();
56368 if ($typeName === 'self') {
56369 $typeName = $other::class;
56370 }
56371 if (!$this->expected instanceof $typeName) {
56372 throw new ComparisonMethodDoesNotAcceptParameterTypeException($other::class, $this->method, $this->expected::class);
56373 }
56374 return $other->{$this->method}($this->expected);
56375 }
56376 protected function failureDescription(mixed $other): string
56377 {
56378 return $this->toString(\true);
56379 }
56380 }
56381 <?php
56382
56383 declare (strict_types=1);
56384 /*
56385 * This file is part of PHPUnit.
56386 *
56387 * (c) Sebastian Bergmann <sebastian@phpunit.de>
56388 *
56389 * For the full copyright and license information, please view the LICENSE
56390 * file that was distributed with this source code.
56391 */
56392 namespace PHPUnit\Framework\Constraint;
56393
56394 use function gettype;
56395 use function is_object;
56396 use function sprintf;
56397 use ReflectionObject;
56398 /**
56399 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
56400 */
56401 final class ObjectHasProperty extends \PHPUnit\Framework\Constraint\Constraint
56402 {
56403 private readonly string $propertyName;
56404 public function __construct(string $propertyName)
56405 {
56406 $this->propertyName = $propertyName;
56407 }
56408 /**
56409 * Returns a string representation of the constraint.
56410 */
56411 public function toString(): string
56412 {
56413 return sprintf('has property "%s"', $this->propertyName);
56414 }
56415 /**
56416 * Evaluates the constraint for parameter $other. Returns true if the
56417 * constraint is met, false otherwise.
56418 *
56419 * @param mixed $other value or object to evaluate
56420 */
56421 protected function matches(mixed $other): bool
56422 {
56423 if (!is_object($other)) {
56424 return \false;
56425 }
56426 return (new ReflectionObject($other))->hasProperty($this->propertyName);
56427 }
56428 /**
56429 * Returns the description of the failure.
56430 *
56431 * The beginning of failure messages is "Failed asserting that" in most
56432 * cases. This method should return the second part of that sentence.
56433 *
56434 * @param mixed $other evaluated value or object
56435 */
56436 protected function failureDescription(mixed $other): string
56437 {
56438 if (is_object($other)) {
56439 return sprintf('object of class "%s" %s', $other::class, $this->toString(\true));
56440 }
56441 return sprintf('"%s" (%s) %s', $other, gettype($other), $this->toString(\true));
56442 }
56443 }
56444 <?php
56445
56446 declare (strict_types=1);
56447 /*
56448 * This file is part of PHPUnit.
56449 *
56450 * (c) Sebastian Bergmann <sebastian@phpunit.de>
56451 *
56452 * For the full copyright and license information, please view the LICENSE
56453 * file that was distributed with this source code.
56454 */
56455 namespace PHPUnit\Framework\Constraint;
56456
56457 use function array_map;
56458 use function count;
56459 /**
56460 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
56461 */
56462 abstract class BinaryOperator extends \PHPUnit\Framework\Constraint\Operator
56463 {
56464 /**
56465 * @psalm-var list<Constraint>
56466 */
56467 private readonly array $constraints;
56468 protected function __construct(mixed ...$constraints)
56469 {
56470 $this->constraints = array_map(fn($constraint): \PHPUnit\Framework\Constraint\Constraint => $this->checkConstraint($constraint), $constraints);
56471 }
56472 /**
56473 * Returns the number of operands (constraints).
56474 */
56475 final public function arity(): int
56476 {
56477 return count($this->constraints);
56478 }
56479 /**
56480 * Returns a string representation of the constraint.
56481 */
56482 public function toString(): string
56483 {
56484 $reduced = $this->reduce();
56485 if ($reduced !== $this) {
56486 return $reduced->toString();
56487 }
56488 $text = '';
56489 foreach ($this->constraints as $key => $constraint) {
56490 $constraint = $constraint->reduce();
56491 $text .= $this->constraintToString($constraint, $key);
56492 }
56493 return $text;
56494 }
56495 /**
56496 * Counts the number of constraint elements.
56497 */
56498 public function count(): int
56499 {
56500 $count = 0;
56501 foreach ($this->constraints as $constraint) {
56502 $count += count($constraint);
56503 }
56504 return $count;
56505 }
56506 /**
56507 * @psalm-return list<Constraint>
56508 */
56509 final protected function constraints(): array
56510 {
56511 return $this->constraints;
56512 }
56513 /**
56514 * Returns true if the $constraint needs to be wrapped with braces.
56515 */
56516 final protected function constraintNeedsParentheses(\PHPUnit\Framework\Constraint\Constraint $constraint): bool
56517 {
56518 return $this->arity() > 1 && parent::constraintNeedsParentheses($constraint);
56519 }
56520 /**
56521 * Reduces the sub-expression starting at $this by skipping degenerate
56522 * sub-expression and returns first descendant constraint that starts
56523 * a non-reducible sub-expression.
56524 *
56525 * See Constraint::reduce() for more.
56526 */
56527 protected function reduce(): \PHPUnit\Framework\Constraint\Constraint
56528 {
56529 if ($this->arity() === 1 && $this->constraints[0] instanceof \PHPUnit\Framework\Constraint\Operator) {
56530 return $this->constraints[0]->reduce();
56531 }
56532 return parent::reduce();
56533 }
56534 /**
56535 * Returns string representation of given operand in context of this operator.
56536 */
56537 private function constraintToString(\PHPUnit\Framework\Constraint\Constraint $constraint, int $position): string
56538 {
56539 $prefix = '';
56540 if ($position > 0) {
56541 $prefix = ' ' . $this->operator() . ' ';
56542 }
56543 if ($this->constraintNeedsParentheses($constraint)) {
56544 return $prefix . '( ' . $constraint->toString() . ' )';
56545 }
56546 $string = $constraint->toStringInContext($this, $position);
56547 if ($string === '') {
56548 $string = $constraint->toString();
56549 }
56550 return $prefix . $string;
56551 }
56552 }
56553 <?php
56554
56555 declare (strict_types=1);
56556 /*
56557 * This file is part of PHPUnit.
56558 *
56559 * (c) Sebastian Bergmann <sebastian@phpunit.de>
56560 *
56561 * For the full copyright and license information, please view the LICENSE
56562 * file that was distributed with this source code.
56563 */
56564 namespace PHPUnit\Framework\Constraint;
56565
56566 /**
56567 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
56568 */
56569 final class LogicalAnd extends \PHPUnit\Framework\Constraint\BinaryOperator
56570 {
56571 public static function fromConstraints(mixed ...$constraints): self
56572 {
56573 return new self(...$constraints);
56574 }
56575 /**
56576 * Returns the name of this operator.
56577 */
56578 public function operator(): string
56579 {
56580 return 'and';
56581 }
56582 /**
56583 * Returns this operator's precedence.
56584 *
56585 * @see https://www.php.net/manual/en/language.operators.precedence.php
56586 */
56587 public function precedence(): int
56588 {
56589 return 22;
56590 }
56591 /**
56592 * Evaluates the constraint for parameter $other. Returns true if the
56593 * constraint is met, false otherwise.
56594 */
56595 protected function matches(mixed $other): bool
56596 {
56597 foreach ($this->constraints() as $constraint) {
56598 if (!$constraint->evaluate($other, '', \true)) {
56599 return \false;
56600 }
56601 }
56602 return [] !== $this->constraints();
56603 }
56604 }
56605 <?php
56606
56607 declare (strict_types=1);
56608 /*
56609 * This file is part of PHPUnit.
56610 *
56611 * (c) Sebastian Bergmann <sebastian@phpunit.de>
56612 *
56613 * For the full copyright and license information, please view the LICENSE
56614 * file that was distributed with this source code.
56615 */
56616 namespace PHPUnit\Framework\Constraint;
56617
56618 use function array_map;
56619 use function count;
56620 use function preg_match;
56621 use function preg_quote;
56622 use function preg_replace;
56623 use PHPUnit\Framework\ExpectationFailedException;
56624 /**
56625 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
56626 */
56627 final class LogicalNot extends \PHPUnit\Framework\Constraint\UnaryOperator
56628 {
56629 public static function negate(string $string): string
56630 {
56631 $positives = ['contains ', 'exists', 'has ', 'is ', 'are ', 'matches ', 'starts with ', 'ends with ', 'reference ', 'not not '];
56632 $negatives = ['does not contain ', 'does not exist', 'does not have ', 'is not ', 'are not ', 'does not match ', 'starts not with ', 'ends not with ', 'don\'t reference ', 'not '];
56633 preg_match('/(\'[\w\W]*\')([\w\W]*)("[\w\W]*")/i', $string, $matches);
56634 if (count($matches) === 0) {
56635 preg_match('/(\'[\w\W]*\')([\w\W]*)(\'[\w\W]*\')/i', $string, $matches);
56636 }
56637 $positives = array_map(static fn(string $s) => '/\b' . preg_quote($s, '/') . '/', $positives);
56638 if (count($matches) > 0) {
56639 $nonInput = $matches[2];
56640 $negatedString = preg_replace('/' . preg_quote($nonInput, '/') . '/', preg_replace($positives, $negatives, $nonInput), $string);
56641 } else {
56642 $negatedString = preg_replace($positives, $negatives, $string);
56643 }
56644 return $negatedString;
56645 }
56646 /**
56647 * Returns the name of this operator.
56648 */
56649 public function operator(): string
56650 {
56651 return 'not';
56652 }
56653 /**
56654 * Returns this operator's precedence.
56655 *
56656 * @see https://www.php.net/manual/en/language.operators.precedence.php
56657 */
56658 public function precedence(): int
56659 {
56660 return 5;
56661 }
56662 /**
56663 * Evaluates the constraint for parameter $other. Returns true if the
56664 * constraint is met, false otherwise.
56665 *
56666 * @throws ExpectationFailedException
56667 */
56668 protected function matches(mixed $other): bool
56669 {
56670 return !$this->constraint()->evaluate($other, '', \true);
56671 }
56672 /**
56673 * Applies additional transformation to strings returned by toString() or
56674 * failureDescription().
56675 */
56676 protected function transformString(string $string): string
56677 {
56678 return self::negate($string);
56679 }
56680 /**
56681 * Reduces the sub-expression starting at $this by skipping degenerate
56682 * sub-expression and returns first descendant constraint that starts
56683 * a non-reducible sub-expression.
56684 *
56685 * See Constraint::reduce() for more.
56686 */
56687 protected function reduce(): \PHPUnit\Framework\Constraint\Constraint
56688 {
56689 $constraint = $this->constraint();
56690 if ($constraint instanceof self) {
56691 return $constraint->constraint()->reduce();
56692 }
56693 return parent::reduce();
56694 }
56695 }
56696 <?php
56697
56698 declare (strict_types=1);
56699 /*
56700 * This file is part of PHPUnit.
56701 *
56702 * (c) Sebastian Bergmann <sebastian@phpunit.de>
56703 *
56704 * For the full copyright and license information, please view the LICENSE
56705 * file that was distributed with this source code.
56706 */
56707 namespace PHPUnit\Framework\Constraint;
56708
56709 /**
56710 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
56711 */
56712 final class LogicalOr extends \PHPUnit\Framework\Constraint\BinaryOperator
56713 {
56714 public static function fromConstraints(mixed ...$constraints): self
56715 {
56716 return new self(...$constraints);
56717 }
56718 /**
56719 * Returns the name of this operator.
56720 */
56721 public function operator(): string
56722 {
56723 return 'or';
56724 }
56725 /**
56726 * Returns this operator's precedence.
56727 *
56728 * @see https://www.php.net/manual/en/language.operators.precedence.php
56729 */
56730 public function precedence(): int
56731 {
56732 return 24;
56733 }
56734 /**
56735 * Evaluates the constraint for parameter $other. Returns true if the
56736 * constraint is met, false otherwise.
56737 */
56738 public function matches(mixed $other): bool
56739 {
56740 foreach ($this->constraints() as $constraint) {
56741 if ($constraint->evaluate($other, '', \true)) {
56742 return \true;
56743 }
56744 }
56745 return \false;
56746 }
56747 }
56748 <?php
56749
56750 declare (strict_types=1);
56751 /*
56752 * This file is part of PHPUnit.
56753 *
56754 * (c) Sebastian Bergmann <sebastian@phpunit.de>
56755 *
56756 * For the full copyright and license information, please view the LICENSE
56757 * file that was distributed with this source code.
56758 */
56759 namespace PHPUnit\Framework\Constraint;
56760
56761 use function array_reduce;
56762 use function array_shift;
56763 use PHPUnit\Framework\ExpectationFailedException;
56764 /**
56765 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
56766 */
56767 final class LogicalXor extends \PHPUnit\Framework\Constraint\BinaryOperator
56768 {
56769 public static function fromConstraints(mixed ...$constraints): self
56770 {
56771 return new self(...$constraints);
56772 }
56773 /**
56774 * Returns the name of this operator.
56775 */
56776 public function operator(): string
56777 {
56778 return 'xor';
56779 }
56780 /**
56781 * Returns this operator's precedence.
56782 *
56783 * @see https://www.php.net/manual/en/language.operators.precedence.php.
56784 */
56785 public function precedence(): int
56786 {
56787 return 23;
56788 }
56789 /**
56790 * Evaluates the constraint for parameter $other. Returns true if the
56791 * constraint is met, false otherwise.
56792 *
56793 * @throws ExpectationFailedException
56794 */
56795 public function matches(mixed $other): bool
56796 {
56797 $constraints = $this->constraints();
56798 $initial = array_shift($constraints);
56799 if ($initial === null) {
56800 return \false;
56801 }
56802 return array_reduce($constraints, static fn(bool $matches, \PHPUnit\Framework\Constraint\Constraint $constraint): bool => $matches xor $constraint->evaluate($other, '', \true), $initial->evaluate($other, '', \true));
56803 }
56804 }
56805 <?php
56806
56807 declare (strict_types=1);
56808 /*
56809 * This file is part of PHPUnit.
56810 *
56811 * (c) Sebastian Bergmann <sebastian@phpunit.de>
56812 *
56813 * For the full copyright and license information, please view the LICENSE
56814 * file that was distributed with this source code.
56815 */
56816 namespace PHPUnit\Framework\Constraint;
56817
56818 /**
56819 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
56820 */
56821 abstract class Operator extends \PHPUnit\Framework\Constraint\Constraint
56822 {
56823 /**
56824 * Returns the name of this operator.
56825 */
56826 abstract public function operator(): string;
56827 /**
56828 * Returns this operator's precedence.
56829 *
56830 * @see https://www.php.net/manual/en/language.operators.precedence.php
56831 */
56832 abstract public function precedence(): int;
56833 /**
56834 * Returns the number of operands.
56835 */
56836 abstract public function arity(): int;
56837 /**
56838 * Validates $constraint argument.
56839 */
56840 protected function checkConstraint(mixed $constraint): \PHPUnit\Framework\Constraint\Constraint
56841 {
56842 if (!$constraint instanceof \PHPUnit\Framework\Constraint\Constraint) {
56843 return new \PHPUnit\Framework\Constraint\IsEqual($constraint);
56844 }
56845 return $constraint;
56846 }
56847 /**
56848 * Returns true if the $constraint needs to be wrapped with braces.
56849 */
56850 protected function constraintNeedsParentheses(\PHPUnit\Framework\Constraint\Constraint $constraint): bool
56851 {
56852 return $constraint instanceof self && $constraint->arity() > 1 && $this->precedence() <= $constraint->precedence();
56853 }
56854 }
56855 <?php
56856
56857 declare (strict_types=1);
56858 /*
56859 * This file is part of PHPUnit.
56860 *
56861 * (c) Sebastian Bergmann <sebastian@phpunit.de>
56862 *
56863 * For the full copyright and license information, please view the LICENSE
56864 * file that was distributed with this source code.
56865 */
56866 namespace PHPUnit\Framework\Constraint;
56867
56868 use function count;
56869 /**
56870 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
56871 */
56872 abstract class UnaryOperator extends \PHPUnit\Framework\Constraint\Operator
56873 {
56874 private readonly \PHPUnit\Framework\Constraint\Constraint $constraint;
56875 public function __construct(mixed $constraint)
56876 {
56877 $this->constraint = $this->checkConstraint($constraint);
56878 }
56879 /**
56880 * Returns the number of operands (constraints).
56881 */
56882 public function arity(): int
56883 {
56884 return 1;
56885 }
56886 /**
56887 * Returns a string representation of the constraint.
56888 */
56889 public function toString(): string
56890 {
56891 $reduced = $this->reduce();
56892 if ($reduced !== $this) {
56893 return $reduced->toString();
56894 }
56895 $constraint = $this->constraint->reduce();
56896 if ($this->constraintNeedsParentheses($constraint)) {
56897 return $this->operator() . '( ' . $constraint->toString() . ' )';
56898 }
56899 $string = $constraint->toStringInContext($this, 0);
56900 if ($string === '') {
56901 return $this->transformString($constraint->toString());
56902 }
56903 return $string;
56904 }
56905 /**
56906 * Counts the number of constraint elements.
56907 */
56908 public function count(): int
56909 {
56910 return count($this->constraint);
56911 }
56912 /**
56913 * Returns the description of the failure.
56914 *
56915 * The beginning of failure messages is "Failed asserting that" in most
56916 * cases. This method should return the second part of that sentence.
56917 */
56918 protected function failureDescription(mixed $other): string
56919 {
56920 $reduced = $this->reduce();
56921 if ($reduced !== $this) {
56922 return $reduced->failureDescription($other);
56923 }
56924 $constraint = $this->constraint->reduce();
56925 if ($this->constraintNeedsParentheses($constraint)) {
56926 return $this->operator() . '( ' . $constraint->failureDescription($other) . ' )';
56927 }
56928 $string = $constraint->failureDescriptionInContext($this, 0, $other);
56929 if ($string === '') {
56930 return $this->transformString($constraint->failureDescription($other));
56931 }
56932 return $string;
56933 }
56934 /**
56935 * Transforms string returned by the member constraint's toString() or
56936 * failureDescription() such that it reflects constraint's participation in
56937 * this expression.
56938 *
56939 * The method may be overwritten in a subclass to apply default
56940 * transformation in case the operand constraint does not provide its own
56941 * custom strings via toStringInContext() or failureDescriptionInContext().
56942 */
56943 protected function transformString(string $string): string
56944 {
56945 return $string;
56946 }
56947 /**
56948 * Provides access to $this->constraint for subclasses.
56949 */
56950 final protected function constraint(): \PHPUnit\Framework\Constraint\Constraint
56951 {
56952 return $this->constraint;
56953 }
56954 /**
56955 * Returns true if the $constraint needs to be wrapped with parentheses.
56956 */
56957 protected function constraintNeedsParentheses(\PHPUnit\Framework\Constraint\Constraint $constraint): bool
56958 {
56959 $constraint = $constraint->reduce();
56960 return $constraint instanceof self || parent::constraintNeedsParentheses($constraint);
56961 }
56962 }
56963 <?php
56964
56965 declare (strict_types=1);
56966 /*
56967 * This file is part of PHPUnit.
56968 *
56969 * (c) Sebastian Bergmann <sebastian@phpunit.de>
56970 *
56971 * For the full copyright and license information, please view the LICENSE
56972 * file that was distributed with this source code.
56973 */
56974 namespace PHPUnit\Framework\Constraint;
56975
56976 use const JSON_ERROR_CTRL_CHAR;
56977 use const JSON_ERROR_DEPTH;
56978 use const JSON_ERROR_NONE;
56979 use const JSON_ERROR_STATE_MISMATCH;
56980 use const JSON_ERROR_SYNTAX;
56981 use const JSON_ERROR_UTF8;
56982 use function is_string;
56983 use function json_decode;
56984 use function json_last_error;
56985 use function sprintf;
56986 /**
56987 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
56988 */
56989 final class IsJson extends \PHPUnit\Framework\Constraint\Constraint
56990 {
56991 /**
56992 * Returns a string representation of the constraint.
56993 */
56994 public function toString(): string
56995 {
56996 return 'is valid JSON';
56997 }
56998 /**
56999 * Evaluates the constraint for parameter $other. Returns true if the
57000 * constraint is met, false otherwise.
57001 */
57002 protected function matches(mixed $other): bool
57003 {
57004 if (!is_string($other) || $other === '') {
57005 return \false;
57006 }
57007 json_decode($other);
57008 if (json_last_error()) {
57009 return \false;
57010 }
57011 return \true;
57012 }
57013 /**
57014 * Returns the description of the failure.
57015 *
57016 * The beginning of failure messages is "Failed asserting that" in most
57017 * cases. This method should return the second part of that sentence.
57018 */
57019 protected function failureDescription(mixed $other): string
57020 {
57021 if (!is_string($other)) {
57022 return $this->valueToTypeStringFragment($other) . 'is valid JSON';
57023 }
57024 if ($other === '') {
57025 return 'an empty string is valid JSON';
57026 }
57027 return sprintf('a string is valid JSON (%s)', $this->determineJsonError($other));
57028 }
57029 private function determineJsonError(string $json): string
57030 {
57031 json_decode($json);
57032 return match (json_last_error()) {
57033 JSON_ERROR_NONE => '',
57034 JSON_ERROR_DEPTH => 'Maximum stack depth exceeded',
57035 JSON_ERROR_STATE_MISMATCH => 'Underflow or the modes mismatch',
57036 JSON_ERROR_CTRL_CHAR => 'Unexpected control character found',
57037 JSON_ERROR_SYNTAX => 'Syntax error, malformed JSON',
57038 JSON_ERROR_UTF8 => 'Malformed UTF-8 characters, possibly incorrectly encoded',
57039 default => 'Unknown error',
57040 };
57041 }
57042 }
57043 <?php
57044
57045 declare (strict_types=1);
57046 /*
57047 * This file is part of PHPUnit.
57048 *
57049 * (c) Sebastian Bergmann <sebastian@phpunit.de>
57050 *
57051 * For the full copyright and license information, please view the LICENSE
57052 * file that was distributed with this source code.
57053 */
57054 namespace PHPUnit\Framework\Constraint;
57055
57056 use function preg_match;
57057 use function sprintf;
57058 /**
57059 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
57060 */
57061 final class RegularExpression extends \PHPUnit\Framework\Constraint\Constraint
57062 {
57063 private readonly string $pattern;
57064 public function __construct(string $pattern)
57065 {
57066 $this->pattern = $pattern;
57067 }
57068 /**
57069 * Returns a string representation of the constraint.
57070 */
57071 public function toString(): string
57072 {
57073 return sprintf('matches PCRE pattern "%s"', $this->pattern);
57074 }
57075 /**
57076 * Evaluates the constraint for parameter $other. Returns true if the
57077 * constraint is met, false otherwise.
57078 */
57079 protected function matches(mixed $other): bool
57080 {
57081 return preg_match($this->pattern, $other) > 0;
57082 }
57083 }
57084 <?php
57085
57086 declare (strict_types=1);
57087 /*
57088 * This file is part of PHPUnit.
57089 *
57090 * (c) Sebastian Bergmann <sebastian@phpunit.de>
57091 *
57092 * For the full copyright and license information, please view the LICENSE
57093 * file that was distributed with this source code.
57094 */
57095 namespace PHPUnit\Framework\Constraint;
57096
57097 use function is_string;
57098 use function mb_detect_encoding;
57099 use function mb_stripos;
57100 use function mb_strtolower;
57101 use function sprintf;
57102 use function str_contains;
57103 use function strlen;
57104 use function strtr;
57105 use PHPUnit\Util\Exporter;
57106 /**
57107 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
57108 */
57109 final class StringContains extends \PHPUnit\Framework\Constraint\Constraint
57110 {
57111 private readonly string $needle;
57112 private readonly bool $ignoreCase;
57113 private readonly bool $ignoreLineEndings;
57114 public function __construct(string $needle, bool $ignoreCase = \false, bool $ignoreLineEndings = \false)
57115 {
57116 if ($ignoreLineEndings) {
57117 $needle = $this->normalizeLineEndings($needle);
57118 }
57119 $this->needle = $needle;
57120 $this->ignoreCase = $ignoreCase;
57121 $this->ignoreLineEndings = $ignoreLineEndings;
57122 }
57123 /**
57124 * Returns a string representation of the constraint.
57125 */
57126 public function toString(): string
57127 {
57128 $needle = $this->needle;
57129 if ($this->ignoreCase) {
57130 $needle = mb_strtolower($this->needle, 'UTF-8');
57131 }
57132 return sprintf('contains "%s" [%s](length: %s)', $needle, $this->getDetectedEncoding($needle), strlen($needle));
57133 }
57134 public function failureDescription(mixed $other): string
57135 {
57136 $stringifiedHaystack = Exporter::export($other, \true);
57137 $haystackEncoding = $this->getDetectedEncoding($other);
57138 $haystackLength = $this->getHaystackLength($other);
57139 $haystackInformation = sprintf('%s [%s](length: %s) ', $stringifiedHaystack, $haystackEncoding, $haystackLength);
57140 $needleInformation = $this->toString(\true);
57141 return $haystackInformation . $needleInformation;
57142 }
57143 /**
57144 * Evaluates the constraint for parameter $other. Returns true if the
57145 * constraint is met, false otherwise.
57146 */
57147 protected function matches(mixed $other): bool
57148 {
57149 $haystack = $other;
57150 if ('' === $this->needle) {
57151 return \true;
57152 }
57153 if (!is_string($haystack)) {
57154 return \false;
57155 }
57156 if ($this->ignoreLineEndings) {
57157 $haystack = $this->normalizeLineEndings($haystack);
57158 }
57159 if ($this->ignoreCase) {
57160 /*
57161 * We must use the multibyte-safe version, so we can accurately compare non-latin uppercase characters with
57162 * their lowercase equivalents.
57163 */
57164 return mb_stripos($haystack, $this->needle, 0, 'UTF-8') !== \false;
57165 }
57166 /*
57167 * Use the non-multibyte safe functions to see if the string is contained in $other.
57168 *
57169 * This function is very fast, and we don't care about the character position in the string.
57170 *
57171 * Additionally, we want this method to be binary safe, so we can check if some binary data is in other binary
57172 * data.
57173 */
57174 return str_contains($haystack, $this->needle);
57175 }
57176 private function getDetectedEncoding(mixed $other): string
57177 {
57178 if ($this->ignoreCase) {
57179 return 'Encoding ignored';
57180 }
57181 if (!is_string($other)) {
57182 return 'Encoding detection failed';
57183 }
57184 $detectedEncoding = mb_detect_encoding($other, null, \true);
57185 if ($detectedEncoding === \false) {
57186 return 'Encoding detection failed';
57187 }
57188 return $detectedEncoding;
57189 }
57190 private function getHaystackLength(mixed $haystack): int
57191 {
57192 if (!is_string($haystack)) {
57193 return 0;
57194 }
57195 if ($this->ignoreLineEndings) {
57196 $haystack = $this->normalizeLineEndings($haystack);
57197 }
57198 return strlen($haystack);
57199 }
57200 private function normalizeLineEndings(string $string): string
57201 {
57202 return strtr($string, ["\r\n" => "\n", "\r" => "\n"]);
57203 }
57204 }
57205 <?php
57206
57207 declare (strict_types=1);
57208 /*
57209 * This file is part of PHPUnit.
57210 *
57211 * (c) Sebastian Bergmann <sebastian@phpunit.de>
57212 *
57213 * For the full copyright and license information, please view the LICENSE
57214 * file that was distributed with this source code.
57215 */
57216 namespace PHPUnit\Framework\Constraint;
57217
57218 use function str_ends_with;
57219 use PHPUnit\Framework\EmptyStringException;
57220 /**
57221 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
57222 */
57223 final class StringEndsWith extends \PHPUnit\Framework\Constraint\Constraint
57224 {
57225 private readonly string $suffix;
57226 /**
57227 * @throws EmptyStringException
57228 */
57229 public function __construct(string $suffix)
57230 {
57231 if ($suffix === '') {
57232 throw new EmptyStringException();
57233 }
57234 $this->suffix = $suffix;
57235 }
57236 /**
57237 * Returns a string representation of the constraint.
57238 */
57239 public function toString(): string
57240 {
57241 return 'ends with "' . $this->suffix . '"';
57242 }
57243 /**
57244 * Evaluates the constraint for parameter $other. Returns true if the
57245 * constraint is met, false otherwise.
57246 */
57247 protected function matches(mixed $other): bool
57248 {
57249 return str_ends_with((string) $other, $this->suffix);
57250 }
57251 }
57252 <?php
57253
57254 declare (strict_types=1);
57255 /*
57256 * This file is part of PHPUnit.
57257 *
57258 * (c) Sebastian Bergmann <sebastian@phpunit.de>
57259 *
57260 * For the full copyright and license information, please view the LICENSE
57261 * file that was distributed with this source code.
57262 */
57263 namespace PHPUnit\Framework\Constraint;
57264
57265 use function sprintf;
57266 use function strtr;
57267 /**
57268 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
57269 */
57270 final class StringEqualsStringIgnoringLineEndings extends \PHPUnit\Framework\Constraint\Constraint
57271 {
57272 private readonly string $string;
57273 public function __construct(string $string)
57274 {
57275 $this->string = $this->normalizeLineEndings($string);
57276 }
57277 /**
57278 * Returns a string representation of the constraint.
57279 */
57280 public function toString(): string
57281 {
57282 return sprintf('is equal to "%s" ignoring line endings', $this->string);
57283 }
57284 /**
57285 * Evaluates the constraint for parameter $other. Returns true if the
57286 * constraint is met, false otherwise.
57287 */
57288 protected function matches(mixed $other): bool
57289 {
57290 return $this->string === $this->normalizeLineEndings((string) $other);
57291 }
57292 private function normalizeLineEndings(string $string): string
57293 {
57294 return strtr($string, ["\r\n" => "\n", "\r" => "\n"]);
57295 }
57296 }
57297 <?php
57298
57299 declare (strict_types=1);
57300 /*
57301 * This file is part of PHPUnit.
57302 *
57303 * (c) Sebastian Bergmann <sebastian@phpunit.de>
57304 *
57305 * For the full copyright and license information, please view the LICENSE
57306 * file that was distributed with this source code.
57307 */
57308 namespace PHPUnit\Framework\Constraint;
57309
57310 use const DIRECTORY_SEPARATOR;
57311 use const PHP_EOL;
57312 use function explode;
57313 use function implode;
57314 use function preg_match;
57315 use function preg_quote;
57316 use function preg_replace;
57317 use function strtr;
57318 use PHPUnitPHAR\SebastianBergmann\Diff\Differ;
57319 use PHPUnitPHAR\SebastianBergmann\Diff\Output\UnifiedDiffOutputBuilder;
57320 /**
57321 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
57322 */
57323 final class StringMatchesFormatDescription extends \PHPUnit\Framework\Constraint\Constraint
57324 {
57325 private readonly string $formatDescription;
57326 public function __construct(string $formatDescription)
57327 {
57328 $this->formatDescription = $formatDescription;
57329 }
57330 public function toString(): string
57331 {
57332 return 'matches format description:' . PHP_EOL . $this->formatDescription;
57333 }
57334 /**
57335 * Evaluates the constraint for parameter $other. Returns true if the
57336 * constraint is met, false otherwise.
57337 */
57338 protected function matches(mixed $other): bool
57339 {
57340 $other = $this->convertNewlines($other);
57341 $matches = preg_match($this->regularExpressionForFormatDescription($this->convertNewlines($this->formatDescription)), $other);
57342 return $matches > 0;
57343 }
57344 protected function failureDescription(mixed $other): string
57345 {
57346 return 'string matches format description';
57347 }
57348 protected function additionalFailureDescription(mixed $other): string
57349 {
57350 $from = explode("\n", $this->formatDescription);
57351 $to = explode("\n", $this->convertNewlines($other));
57352 foreach ($from as $index => $line) {
57353 if (isset($to[$index]) && $line !== $to[$index]) {
57354 $line = $this->regularExpressionForFormatDescription($line);
57355 if (preg_match($line, $to[$index]) > 0) {
57356 $from[$index] = $to[$index];
57357 }
57358 }
57359 }
57360 $from = implode("\n", $from);
57361 $to = implode("\n", $to);
57362 return $this->differ()->diff($from, $to);
57363 }
57364 private function regularExpressionForFormatDescription(string $string): string
57365 {
57366 $string = strtr(preg_quote($string, '/'), ['%%' => '%', '%e' => preg_quote(DIRECTORY_SEPARATOR, '/'), '%s' => '[^\r\n]+', '%S' => '[^\r\n]*', '%a' => '.+?', '%A' => '.*?', '%w' => '\s*', '%i' => '[+-]?\d+', '%d' => '\d+', '%x' => '[0-9a-fA-F]+', '%f' => '[+-]?(?:\d+|(?=\.\d))(?:\.\d+)?(?:[Ee][+-]?\d+)?', '%c' => '.', '%0' => '\x00']);
57367 return '/^' . $string . '$/s';
57368 }
57369 private function convertNewlines(string $text): string
57370 {
57371 return preg_replace('/\r\n/', "\n", $text);
57372 }
57373 private function differ(): Differ
57374 {
57375 return new Differ(new UnifiedDiffOutputBuilder("--- Expected\n+++ Actual\n"));
57376 }
57377 }
57378 <?php
57379
57380 declare (strict_types=1);
57381 /*
57382 * This file is part of PHPUnit.
57383 *
57384 * (c) Sebastian Bergmann <sebastian@phpunit.de>
57385 *
57386 * For the full copyright and license information, please view the LICENSE
57387 * file that was distributed with this source code.
57388 */
57389 namespace PHPUnit\Framework\Constraint;
57390
57391 use function str_starts_with;
57392 use PHPUnit\Framework\EmptyStringException;
57393 /**
57394 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
57395 */
57396 final class StringStartsWith extends \PHPUnit\Framework\Constraint\Constraint
57397 {
57398 private readonly string $prefix;
57399 /**
57400 * @throws EmptyStringException
57401 */
57402 public function __construct(string $prefix)
57403 {
57404 if ($prefix === '') {
57405 throw new EmptyStringException();
57406 }
57407 $this->prefix = $prefix;
57408 }
57409 /**
57410 * Returns a string representation of the constraint.
57411 */
57412 public function toString(): string
57413 {
57414 return 'starts with "' . $this->prefix . '"';
57415 }
57416 /**
57417 * Evaluates the constraint for parameter $other. Returns true if the
57418 * constraint is met, false otherwise.
57419 */
57420 protected function matches(mixed $other): bool
57421 {
57422 return str_starts_with((string) $other, $this->prefix);
57423 }
57424 }
57425 <?php
57426
57427 declare (strict_types=1);
57428 /*
57429 * This file is part of PHPUnit.
57430 *
57431 * (c) Sebastian Bergmann <sebastian@phpunit.de>
57432 *
57433 * For the full copyright and license information, please view the LICENSE
57434 * file that was distributed with this source code.
57435 */
57436 namespace PHPUnit\Framework\Constraint;
57437
57438 use function array_key_exists;
57439 use function is_array;
57440 use ArrayAccess;
57441 use PHPUnit\Util\Exporter;
57442 /**
57443 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
57444 */
57445 final class ArrayHasKey extends \PHPUnit\Framework\Constraint\Constraint
57446 {
57447 private readonly mixed $key;
57448 public function __construct(mixed $key)
57449 {
57450 $this->key = $key;
57451 }
57452 /**
57453 * Returns a string representation of the constraint.
57454 */
57455 public function toString(): string
57456 {
57457 return 'has the key ' . Exporter::export($this->key);
57458 }
57459 /**
57460 * Evaluates the constraint for parameter $other. Returns true if the
57461 * constraint is met, false otherwise.
57462 */
57463 protected function matches(mixed $other): bool
57464 {
57465 if (is_array($other)) {
57466 return array_key_exists($this->key, $other);
57467 }
57468 if ($other instanceof ArrayAccess) {
57469 return $other->offsetExists($this->key);
57470 }
57471 return \false;
57472 }
57473 /**
57474 * Returns the description of the failure.
57475 *
57476 * The beginning of failure messages is "Failed asserting that" in most
57477 * cases. This method should return the second part of that sentence.
57478 */
57479 protected function failureDescription(mixed $other): string
57480 {
57481 return 'an array ' . $this->toString(\true);
57482 }
57483 }
57484 <?php
57485
57486 declare (strict_types=1);
57487 /*
57488 * This file is part of PHPUnit.
57489 *
57490 * (c) Sebastian Bergmann <sebastian@phpunit.de>
57491 *
57492 * For the full copyright and license information, please view the LICENSE
57493 * file that was distributed with this source code.
57494 */
57495 namespace PHPUnit\Framework\Constraint;
57496
57497 use function array_is_list;
57498 use function is_array;
57499 /**
57500 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
57501 */
57502 final class IsList extends \PHPUnit\Framework\Constraint\Constraint
57503 {
57504 /**
57505 * Returns a string representation of the constraint.
57506 */
57507 public function toString(): string
57508 {
57509 return 'is a list';
57510 }
57511 /**
57512 * Evaluates the constraint for parameter $other. Returns true if the
57513 * constraint is met, false otherwise.
57514 */
57515 protected function matches(mixed $other): bool
57516 {
57517 if (!is_array($other)) {
57518 return \false;
57519 }
57520 return array_is_list($other);
57521 }
57522 /**
57523 * Returns the description of the failure.
57524 *
57525 * The beginning of failure messages is "Failed asserting that" in most
57526 * cases. This method should return the second part of that sentence.
57527 */
57528 protected function failureDescription(mixed $other): string
57529 {
57530 return $this->valueToTypeStringFragment($other) . $this->toString(\true);
57531 }
57532 }
57533 <?php
57534
57535 declare (strict_types=1);
57536 /*
57537 * This file is part of PHPUnit.
57538 *
57539 * (c) Sebastian Bergmann <sebastian@phpunit.de>
57540 *
57541 * For the full copyright and license information, please view the LICENSE
57542 * file that was distributed with this source code.
57543 */
57544 namespace PHPUnit\Framework\Constraint;
57545
57546 use function is_array;
57547 use function sprintf;
57548 use PHPUnit\Util\Exporter;
57549 /**
57550 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
57551 */
57552 abstract class TraversableContains extends \PHPUnit\Framework\Constraint\Constraint
57553 {
57554 private readonly mixed $value;
57555 public function __construct(mixed $value)
57556 {
57557 $this->value = $value;
57558 }
57559 /**
57560 * Returns a string representation of the constraint.
57561 */
57562 public function toString(bool $exportObjects = \false): string
57563 {
57564 return 'contains ' . Exporter::export($this->value, $exportObjects);
57565 }
57566 /**
57567 * Returns the description of the failure.
57568 *
57569 * The beginning of failure messages is "Failed asserting that" in most
57570 * cases. This method should return the second part of that sentence.
57571 */
57572 protected function failureDescription(mixed $other): string
57573 {
57574 return sprintf('%s %s', is_array($other) ? 'an array' : 'a traversable', $this->toString(\true));
57575 }
57576 protected function value(): mixed
57577 {
57578 return $this->value;
57579 }
57580 }
57581 <?php
57582
57583 declare (strict_types=1);
57584 /*
57585 * This file is part of PHPUnit.
57586 *
57587 * (c) Sebastian Bergmann <sebastian@phpunit.de>
57588 *
57589 * For the full copyright and license information, please view the LICENSE
57590 * file that was distributed with this source code.
57591 */
57592 namespace PHPUnit\Framework\Constraint;
57593
57594 use SplObjectStorage;
57595 /**
57596 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
57597 */
57598 final class TraversableContainsEqual extends \PHPUnit\Framework\Constraint\TraversableContains
57599 {
57600 /**
57601 * Evaluates the constraint for parameter $other. Returns true if the
57602 * constraint is met, false otherwise.
57603 */
57604 protected function matches(mixed $other): bool
57605 {
57606 if ($other instanceof SplObjectStorage) {
57607 return $other->offsetExists($this->value());
57608 }
57609 foreach ($other as $element) {
57610 /* @noinspection TypeUnsafeComparisonInspection */
57611 if ($this->value() == $element) {
57612 return \true;
57613 }
57614 }
57615 return \false;
57616 }
57617 }
57618 <?php
57619
57620 declare (strict_types=1);
57621 /*
57622 * This file is part of PHPUnit.
57623 *
57624 * (c) Sebastian Bergmann <sebastian@phpunit.de>
57625 *
57626 * For the full copyright and license information, please view the LICENSE
57627 * file that was distributed with this source code.
57628 */
57629 namespace PHPUnit\Framework\Constraint;
57630
57631 use SplObjectStorage;
57632 /**
57633 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
57634 */
57635 final class TraversableContainsIdentical extends \PHPUnit\Framework\Constraint\TraversableContains
57636 {
57637 /**
57638 * Evaluates the constraint for parameter $other. Returns true if the
57639 * constraint is met, false otherwise.
57640 */
57641 protected function matches(mixed $other): bool
57642 {
57643 if ($other instanceof SplObjectStorage) {
57644 return $other->offsetExists($this->value());
57645 }
57646 foreach ($other as $element) {
57647 if ($this->value() === $element) {
57648 return \true;
57649 }
57650 }
57651 return \false;
57652 }
57653 }
57654 <?php
57655
57656 declare (strict_types=1);
57657 /*
57658 * This file is part of PHPUnit.
57659 *
57660 * (c) Sebastian Bergmann <sebastian@phpunit.de>
57661 *
57662 * For the full copyright and license information, please view the LICENSE
57663 * file that was distributed with this source code.
57664 */
57665 namespace PHPUnit\Framework\Constraint;
57666
57667 use PHPUnit\Framework\Exception;
57668 use PHPUnit\Framework\ExpectationFailedException;
57669 /**
57670 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
57671 */
57672 final class TraversableContainsOnly extends \PHPUnit\Framework\Constraint\Constraint
57673 {
57674 private \PHPUnit\Framework\Constraint\Constraint $constraint;
57675 private readonly string $type;
57676 /**
57677 * @throws Exception
57678 */
57679 public function __construct(string $type, bool $isNativeType = \true)
57680 {
57681 if ($isNativeType) {
57682 $this->constraint = new \PHPUnit\Framework\Constraint\IsType($type);
57683 } else {
57684 $this->constraint = new \PHPUnit\Framework\Constraint\IsInstanceOf($type);
57685 }
57686 $this->type = $type;
57687 }
57688 /**
57689 * Evaluates the constraint for parameter $other.
57690 *
57691 * If $returnResult is set to false (the default), an exception is thrown
57692 * in case of a failure. null is returned otherwise.
57693 *
57694 * If $returnResult is true, the result of the evaluation is returned as
57695 * a boolean value instead: true in case of success, false in case of a
57696 * failure.
57697 *
57698 * @throws ExpectationFailedException
57699 */
57700 public function evaluate(mixed $other, string $description = '', bool $returnResult = \false): bool
57701 {
57702 $success = \true;
57703 foreach ($other as $item) {
57704 if (!$this->constraint->evaluate($item, '', \true)) {
57705 $success = \false;
57706 break;
57707 }
57708 }
57709 if (!$success && !$returnResult) {
57710 $this->fail($other, $description);
57711 }
57712 return $success;
57713 }
57714 /**
57715 * Returns a string representation of the constraint.
57716 */
57717 public function toString(): string
57718 {
57719 return 'contains only values of type "' . $this->type . '"';
57720 }
57721 }
57722 <?php
57723
57724 declare (strict_types=1);
57725 /*
57726 * This file is part of PHPUnit.
57727 *
57728 * (c) Sebastian Bergmann <sebastian@phpunit.de>
57729 *
57730 * For the full copyright and license information, please view the LICENSE
57731 * file that was distributed with this source code.
57732 */
57733 namespace PHPUnit\Framework\Constraint;
57734
57735 use function class_exists;
57736 use function interface_exists;
57737 use function sprintf;
57738 use PHPUnit\Framework\UnknownClassOrInterfaceException;
57739 /**
57740 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
57741 */
57742 final class IsInstanceOf extends \PHPUnit\Framework\Constraint\Constraint
57743 {
57744 /**
57745 * @psalm-var class-string
57746 */
57747 private readonly string $name;
57748 /**
57749 * @psalm-var 'class'|'interface'
57750 */
57751 private readonly string $type;
57752 /**
57753 * @throws UnknownClassOrInterfaceException
57754 */
57755 public function __construct(string $name)
57756 {
57757 if (class_exists($name)) {
57758 $this->type = 'class';
57759 } elseif (interface_exists($name)) {
57760 $this->type = 'interface';
57761 } else {
57762 throw new UnknownClassOrInterfaceException($name);
57763 }
57764 $this->name = $name;
57765 }
57766 /**
57767 * Returns a string representation of the constraint.
57768 */
57769 public function toString(): string
57770 {
57771 return sprintf('is an instance of %s %s', $this->type, $this->name);
57772 }
57773 /**
57774 * Evaluates the constraint for parameter $other. Returns true if the
57775 * constraint is met, false otherwise.
57776 */
57777 protected function matches(mixed $other): bool
57778 {
57779 return $other instanceof $this->name;
57780 }
57781 /**
57782 * Returns the description of the failure.
57783 *
57784 * The beginning of failure messages is "Failed asserting that" in most
57785 * cases. This method should return the second part of that sentence.
57786 */
57787 protected function failureDescription(mixed $other): string
57788 {
57789 return $this->valueToTypeStringFragment($other) . $this->toString(\true);
57790 }
57791 }
57792 <?php
57793
57794 declare (strict_types=1);
57795 /*
57796 * This file is part of PHPUnit.
57797 *
57798 * (c) Sebastian Bergmann <sebastian@phpunit.de>
57799 *
57800 * For the full copyright and license information, please view the LICENSE
57801 * file that was distributed with this source code.
57802 */
57803 namespace PHPUnit\Framework\Constraint;
57804
57805 /**
57806 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
57807 */
57808 final class IsNull extends \PHPUnit\Framework\Constraint\Constraint
57809 {
57810 /**
57811 * Returns a string representation of the constraint.
57812 */
57813 public function toString(): string
57814 {
57815 return 'is null';
57816 }
57817 /**
57818 * Evaluates the constraint for parameter $other. Returns true if the
57819 * constraint is met, false otherwise.
57820 */
57821 protected function matches(mixed $other): bool
57822 {
57823 return $other === null;
57824 }
57825 }
57826 <?php
57827
57828 declare (strict_types=1);
57829 /*
57830 * This file is part of PHPUnit.
57831 *
57832 * (c) Sebastian Bergmann <sebastian@phpunit.de>
57833 *
57834 * For the full copyright and license information, please view the LICENSE
57835 * file that was distributed with this source code.
57836 */
57837 namespace PHPUnit\Framework\Constraint;
57838
57839 use function gettype;
57840 use function is_array;
57841 use function is_bool;
57842 use function is_callable;
57843 use function is_float;
57844 use function is_int;
57845 use function is_iterable;
57846 use function is_numeric;
57847 use function is_object;
57848 use function is_scalar;
57849 use function is_string;
57850 use function sprintf;
57851 use PHPUnit\Framework\UnknownTypeException;
57852 /**
57853 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
57854 */
57855 final class IsType extends \PHPUnit\Framework\Constraint\Constraint
57856 {
57857 /**
57858 * @var string
57859 */
57860 public const TYPE_ARRAY = 'array';
57861 /**
57862 * @var string
57863 */
57864 public const TYPE_BOOL = 'bool';
57865 /**
57866 * @var string
57867 */
57868 public const TYPE_FLOAT = 'float';
57869 /**
57870 * @var string
57871 */
57872 public const TYPE_INT = 'int';
57873 /**
57874 * @var string
57875 */
57876 public const TYPE_NULL = 'null';
57877 /**
57878 * @var string
57879 */
57880 public const TYPE_NUMERIC = 'numeric';
57881 /**
57882 * @var string
57883 */
57884 public const TYPE_OBJECT = 'object';
57885 /**
57886 * @var string
57887 */
57888 public const TYPE_RESOURCE = 'resource';
57889 /**
57890 * @var string
57891 */
57892 public const TYPE_CLOSED_RESOURCE = 'resource (closed)';
57893 /**
57894 * @var string
57895 */
57896 public const TYPE_STRING = 'string';
57897 /**
57898 * @var string
57899 */
57900 public const TYPE_SCALAR = 'scalar';
57901 /**
57902 * @var string
57903 */
57904 public const TYPE_CALLABLE = 'callable';
57905 /**
57906 * @var string
57907 */
57908 public const TYPE_ITERABLE = 'iterable';
57909 /**
57910 * @psalm-var array<string,bool>
57911 */
57912 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];
57913 /**
57914 * @psalm-var 'array'|'boolean'|'bool'|'double'|'float'|'integer'|'int'|'null'|'numeric'|'object'|'real'|'resource'|'resource (closed)'|'string'|'scalar'|'callable'|'iterable'
57915 */
57916 private readonly string $type;
57917 /**
57918 * @psalm-param 'array'|'boolean'|'bool'|'double'|'float'|'integer'|'int'|'null'|'numeric'|'object'|'real'|'resource'|'resource (closed)'|'string'|'scalar'|'callable'|'iterable' $type
57919 *
57920 * @throws UnknownTypeException
57921 */
57922 public function __construct(string $type)
57923 {
57924 if (!isset(self::KNOWN_TYPES[$type])) {
57925 throw new UnknownTypeException($type);
57926 }
57927 $this->type = $type;
57928 }
57929 /**
57930 * Returns a string representation of the constraint.
57931 */
57932 public function toString(): string
57933 {
57934 return sprintf('is of type %s', $this->type);
57935 }
57936 /**
57937 * Evaluates the constraint for parameter $other. Returns true if the
57938 * constraint is met, false otherwise.
57939 */
57940 protected function matches(mixed $other): bool
57941 {
57942 switch ($this->type) {
57943 case 'numeric':
57944 return is_numeric($other);
57945 case 'integer':
57946 case 'int':
57947 return is_int($other);
57948 case 'double':
57949 case 'float':
57950 case 'real':
57951 return is_float($other);
57952 case 'string':
57953 return is_string($other);
57954 case 'boolean':
57955 case 'bool':
57956 return is_bool($other);
57957 case 'null':
57958 return null === $other;
57959 case 'array':
57960 return is_array($other);
57961 case 'object':
57962 return is_object($other);
57963 case 'resource':
57964 $type = gettype($other);
57965 return $type === 'resource' || $type === 'resource (closed)';
57966 case 'resource (closed)':
57967 return gettype($other) === 'resource (closed)';
57968 case 'scalar':
57969 return is_scalar($other);
57970 case 'callable':
57971 return is_callable($other);
57972 case 'iterable':
57973 return is_iterable($other);
57974 default:
57975 return \false;
57976 }
57977 }
57978 }
57979 <?php
57980
57981 declare (strict_types=1);
57982 /*
57983 * This file is part of PHPUnit.
57984 *
57985 * (c) Sebastian Bergmann <sebastian@phpunit.de>
57986 *
57987 * For the full copyright and license information, please view the LICENSE
57988 * file that was distributed with this source code.
57989 */
57990 namespace PHPUnit\Framework;
57991
57992 use function explode;
57993 use PHPUnit\Framework\TestSize\TestSize;
57994 use PHPUnit\Metadata\Api\Groups;
57995 /**
57996 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
57997 *
57998 * @internal This class is not covered by the backward compatibility promise for PHPUnit
57999 */
58000 final class DataProviderTestSuite extends \PHPUnit\Framework\TestSuite
58001 {
58002 /**
58003 * @psalm-var list<ExecutionOrderDependency>
58004 */
58005 private array $dependencies = [];
58006 private ?array $providedTests = null;
58007 /**
58008 * @psalm-param list<ExecutionOrderDependency> $dependencies
58009 */
58010 public function setDependencies(array $dependencies): void
58011 {
58012 $this->dependencies = $dependencies;
58013 foreach ($this->tests() as $test) {
58014 if (!$test instanceof \PHPUnit\Framework\TestCase) {
58015 continue;
58016 }
58017 $test->setDependencies($dependencies);
58018 }
58019 }
58020 /**
58021 * @psalm-return list<ExecutionOrderDependency>
58022 */
58023 public function provides(): array
58024 {
58025 if ($this->providedTests === null) {
58026 $this->providedTests = [new \PHPUnit\Framework\ExecutionOrderDependency($this->name())];
58027 }
58028 return $this->providedTests;
58029 }
58030 /**
58031 * @psalm-return list<ExecutionOrderDependency>
58032 */
58033 public function requires(): array
58034 {
58035 // A DataProviderTestSuite does not have to traverse its child tests
58036 // as these are inherited and cannot reference dataProvider rows directly
58037 return $this->dependencies;
58038 }
58039 /**
58040 * Returns the size of each test created using the data provider(s).
58041 */
58042 public function size(): TestSize
58043 {
58044 [$className, $methodName] = explode('::', $this->name());
58045 return (new Groups())->size($className, $methodName);
58046 }
58047 }
58048 <?php
58049
58050 declare (strict_types=1);
58051 /*
58052 * This file is part of PHPUnit.
58053 *
58054 * (c) Sebastian Bergmann <sebastian@phpunit.de>
58055 *
58056 * For the full copyright and license information, please view the LICENSE
58057 * file that was distributed with this source code.
58058 */
58059 namespace PHPUnit\Framework;
58060
58061 /**
58062 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
58063 *
58064 * @internal This class is not covered by the backward compatibility promise for PHPUnit
58065 */
58066 class AssertionFailedError extends \PHPUnit\Framework\Exception implements \PHPUnit\Framework\SelfDescribing
58067 {
58068 /**
58069 * Wrapper for getMessage() which is declared as final.
58070 */
58071 public function toString(): string
58072 {
58073 return $this->getMessage();
58074 }
58075 }
58076 <?php
58077
58078 declare (strict_types=1);
58079 /*
58080 * This file is part of PHPUnit.
58081 *
58082 * (c) Sebastian Bergmann <sebastian@phpunit.de>
58083 *
58084 * For the full copyright and license information, please view the LICENSE
58085 * file that was distributed with this source code.
58086 */
58087 namespace PHPUnit\Framework;
58088
58089 /**
58090 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
58091 *
58092 * @internal This class is not covered by the backward compatibility promise for PHPUnit
58093 */
58094 class CodeCoverageException extends \PHPUnit\Framework\Exception
58095 {
58096 }
58097 <?php
58098
58099 declare (strict_types=1);
58100 /*
58101 * This file is part of PHPUnit.
58102 *
58103 * (c) Sebastian Bergmann <sebastian@phpunit.de>
58104 *
58105 * For the full copyright and license information, please view the LICENSE
58106 * file that was distributed with this source code.
58107 */
58108 namespace PHPUnit\Framework;
58109
58110 /**
58111 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
58112 *
58113 * @internal This class is not covered by the backward compatibility promise for PHPUnit
58114 */
58115 final class EmptyStringException extends \PHPUnit\Framework\InvalidArgumentException
58116 {
58117 }
58118 <?php
58119
58120 declare (strict_types=1);
58121 /*
58122 * This file is part of PHPUnit.
58123 *
58124 * (c) Sebastian Bergmann <sebastian@phpunit.de>
58125 *
58126 * For the full copyright and license information, please view the LICENSE
58127 * file that was distributed with this source code.
58128 */
58129 namespace PHPUnit\Framework;
58130
58131 use function array_keys;
58132 use function get_object_vars;
58133 use function is_int;
58134 use function sprintf;
58135 use RuntimeException;
58136 use Throwable;
58137 /**
58138 * Base class for all PHPUnit Framework exceptions.
58139 *
58140 * Ensures that exceptions thrown during a test run do not leave stray
58141 * references behind.
58142 *
58143 * Every Exception contains a stack trace. Each stack frame contains the 'args'
58144 * of the called function. The function arguments can contain references to
58145 * instantiated objects. The references prevent the objects from being
58146 * destructed (until test results are eventually printed), so memory cannot be
58147 * freed up.
58148 *
58149 * With enabled process isolation, test results are serialized in the child
58150 * process and unserialized in the parent process. The stack trace of Exceptions
58151 * may contain objects that cannot be serialized or unserialized (e.g., PDO
58152 * connections). Unserializing user-space objects from the child process into
58153 * the parent would break the intended encapsulation of process isolation.
58154 *
58155 * @see http://fabien.potencier.org/article/9/php-serialization-stack-traces-and-exceptions
58156 *
58157 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
58158 *
58159 * @internal This class is not covered by the backward compatibility promise for PHPUnit
58160 */
58161 class Exception extends RuntimeException implements \PHPUnit\Exception
58162 {
58163 protected array $serializableTrace;
58164 public function __construct(string $message = '', int|string $code = 0, ?Throwable $previous = null)
58165 {
58166 /**
58167 * @see https://github.com/sebastianbergmann/phpunit/issues/5965
58168 */
58169 if (!is_int($code)) {
58170 $message .= sprintf(' (exception code: %s)', $code);
58171 $code = 0;
58172 }
58173 parent::__construct($message, $code, $previous);
58174 $this->serializableTrace = $this->getTrace();
58175 foreach (array_keys($this->serializableTrace) as $key) {
58176 unset($this->serializableTrace[$key]['args']);
58177 }
58178 }
58179 public function __serialize(): array
58180 {
58181 return get_object_vars($this);
58182 }
58183 /**
58184 * Returns the serializable trace (without 'args').
58185 */
58186 public function getSerializableTrace(): array
58187 {
58188 return $this->serializableTrace;
58189 }
58190 }
58191 <?php
58192
58193 declare (strict_types=1);
58194 /*
58195 * This file is part of PHPUnit.
58196 *
58197 * (c) Sebastian Bergmann <sebastian@phpunit.de>
58198 *
58199 * For the full copyright and license information, please view the LICENSE
58200 * file that was distributed with this source code.
58201 */
58202 namespace PHPUnit\Framework;
58203
58204 use Exception;
58205 use PHPUnitPHAR\SebastianBergmann\Comparator\ComparisonFailure;
58206 /**
58207 * Exception for expectations which failed their check.
58208 *
58209 * The exception contains the error message and optionally a
58210 * SebastianBergmann\Comparator\ComparisonFailure which is used to
58211 * generate diff output of the failed expectations.
58212 *
58213 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
58214 */
58215 final class ExpectationFailedException extends \PHPUnit\Framework\AssertionFailedError
58216 {
58217 protected ?ComparisonFailure $comparisonFailure = null;
58218 public function __construct(string $message, ?ComparisonFailure $comparisonFailure = null, ?Exception $previous = null)
58219 {
58220 $this->comparisonFailure = $comparisonFailure;
58221 parent::__construct($message, 0, $previous);
58222 }
58223 public function getComparisonFailure(): ?ComparisonFailure
58224 {
58225 return $this->comparisonFailure;
58226 }
58227 }
58228 <?php
58229
58230 declare (strict_types=1);
58231 /*
58232 * This file is part of PHPUnit.
58233 *
58234 * (c) Sebastian Bergmann <sebastian@phpunit.de>
58235 *
58236 * For the full copyright and license information, please view the LICENSE
58237 * file that was distributed with this source code.
58238 */
58239 namespace PHPUnit\Framework;
58240
58241 use function sprintf;
58242 /**
58243 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
58244 *
58245 * @internal This class is not covered by the backward compatibility promise for PHPUnit
58246 */
58247 final class GeneratorNotSupportedException extends \PHPUnit\Framework\InvalidArgumentException
58248 {
58249 public static function fromParameterName(string $parameterName): self
58250 {
58251 return new self(sprintf('Passing an argument of type Generator for the %s parameter is not supported', $parameterName));
58252 }
58253 }
58254 <?php
58255
58256 declare (strict_types=1);
58257 /*
58258 * This file is part of PHPUnit.
58259 *
58260 * (c) Sebastian Bergmann <sebastian@phpunit.de>
58261 *
58262 * For the full copyright and license information, please view the LICENSE
58263 * file that was distributed with this source code.
58264 */
58265 namespace PHPUnit\Framework;
58266
58267 use Throwable;
58268 /**
58269 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
58270 *
58271 * @internal This interface is not covered by the backward compatibility promise for PHPUnit
58272 */
58273 interface IncompleteTest extends Throwable
58274 {
58275 }
58276 <?php
58277
58278 declare (strict_types=1);
58279 /*
58280 * This file is part of PHPUnit.
58281 *
58282 * (c) Sebastian Bergmann <sebastian@phpunit.de>
58283 *
58284 * For the full copyright and license information, please view the LICENSE
58285 * file that was distributed with this source code.
58286 */
58287 namespace PHPUnit\Framework;
58288
58289 /**
58290 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
58291 *
58292 * @internal This class is not covered by the backward compatibility promise for PHPUnit
58293 */
58294 final class IncompleteTestError extends \PHPUnit\Framework\AssertionFailedError implements \PHPUnit\Framework\IncompleteTest
58295 {
58296 }
58297 <?php
58298
58299 declare (strict_types=1);
58300 /*
58301 * This file is part of PHPUnit.
58302 *
58303 * (c) Sebastian Bergmann <sebastian@phpunit.de>
58304 *
58305 * For the full copyright and license information, please view the LICENSE
58306 * file that was distributed with this source code.
58307 */
58308 namespace PHPUnit\Framework;
58309
58310 /**
58311 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
58312 *
58313 * @internal This class is not covered by the backward compatibility promise for PHPUnit
58314 */
58315 abstract class InvalidArgumentException extends \PHPUnit\Framework\Exception
58316 {
58317 }
58318 <?php
58319
58320 declare (strict_types=1);
58321 /*
58322 * This file is part of PHPUnit.
58323 *
58324 * (c) Sebastian Bergmann <sebastian@phpunit.de>
58325 *
58326 * For the full copyright and license information, please view the LICENSE
58327 * file that was distributed with this source code.
58328 */
58329 namespace PHPUnit\Framework;
58330
58331 /**
58332 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
58333 *
58334 * @internal This class is not covered by the backward compatibility promise for PHPUnit
58335 */
58336 final class InvalidCoversTargetException extends \PHPUnit\Framework\CodeCoverageException
58337 {
58338 }
58339 <?php
58340
58341 declare (strict_types=1);
58342 /*
58343 * This file is part of PHPUnit.
58344 *
58345 * (c) Sebastian Bergmann <sebastian@phpunit.de>
58346 *
58347 * For the full copyright and license information, please view the LICENSE
58348 * file that was distributed with this source code.
58349 */
58350 namespace PHPUnit\Framework;
58351
58352 /**
58353 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
58354 *
58355 * @internal This class is not covered by the backward compatibility promise for PHPUnit
58356 */
58357 final class InvalidDataProviderException extends \PHPUnit\Framework\Exception
58358 {
58359 }
58360 <?php
58361
58362 declare (strict_types=1);
58363 /*
58364 * This file is part of PHPUnit.
58365 *
58366 * (c) Sebastian Bergmann <sebastian@phpunit.de>
58367 *
58368 * For the full copyright and license information, please view the LICENSE
58369 * file that was distributed with this source code.
58370 */
58371 namespace PHPUnit\Framework;
58372
58373 /**
58374 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
58375 *
58376 * @internal This class is not covered by the backward compatibility promise for PHPUnit
58377 */
58378 final class InvalidDependencyException extends \PHPUnit\Framework\AssertionFailedError implements \PHPUnit\Framework\SkippedTest
58379 {
58380 }
58381 <?php
58382
58383 declare (strict_types=1);
58384 /*
58385 * This file is part of PHPUnit.
58386 *
58387 * (c) Sebastian Bergmann <sebastian@phpunit.de>
58388 *
58389 * For the full copyright and license information, please view the LICENSE
58390 * file that was distributed with this source code.
58391 */
58392 namespace PHPUnit\Framework;
58393
58394 /**
58395 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
58396 *
58397 * @internal This class is not covered by the backward compatibility promise for PHPUnit
58398 */
58399 final class NoChildTestSuiteException extends \PHPUnit\Framework\Exception
58400 {
58401 }
58402 <?php
58403
58404 declare (strict_types=1);
58405 /*
58406 * This file is part of PHPUnit.
58407 *
58408 * (c) Sebastian Bergmann <sebastian@phpunit.de>
58409 *
58410 * For the full copyright and license information, please view the LICENSE
58411 * file that was distributed with this source code.
58412 */
58413 namespace PHPUnit\Framework;
58414
58415 /**
58416 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
58417 *
58418 * @internal This class is not covered by the backward compatibility promise for PHPUnit
58419 */
58420 final class ActualValueIsNotAnObjectException extends \PHPUnit\Framework\Exception
58421 {
58422 public function __construct()
58423 {
58424 parent::__construct('Actual value is not an object');
58425 }
58426 }
58427 <?php
58428
58429 declare (strict_types=1);
58430 /*
58431 * This file is part of PHPUnit.
58432 *
58433 * (c) Sebastian Bergmann <sebastian@phpunit.de>
58434 *
58435 * For the full copyright and license information, please view the LICENSE
58436 * file that was distributed with this source code.
58437 */
58438 namespace PHPUnit\Framework;
58439
58440 use function sprintf;
58441 /**
58442 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
58443 *
58444 * @internal This class is not covered by the backward compatibility promise for PHPUnit
58445 */
58446 final class ComparisonMethodDoesNotAcceptParameterTypeException extends \PHPUnit\Framework\Exception
58447 {
58448 public function __construct(string $className, string $methodName, string $type)
58449 {
58450 parent::__construct(sprintf('%s is not an accepted argument type for comparison method %s::%s().', $type, $className, $methodName));
58451 }
58452 }
58453 <?php
58454
58455 declare (strict_types=1);
58456 /*
58457 * This file is part of PHPUnit.
58458 *
58459 * (c) Sebastian Bergmann <sebastian@phpunit.de>
58460 *
58461 * For the full copyright and license information, please view the LICENSE
58462 * file that was distributed with this source code.
58463 */
58464 namespace PHPUnit\Framework;
58465
58466 use function sprintf;
58467 /**
58468 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
58469 *
58470 * @internal This class is not covered by the backward compatibility promise for PHPUnit
58471 */
58472 final class ComparisonMethodDoesNotDeclareBoolReturnTypeException extends \PHPUnit\Framework\Exception
58473 {
58474 public function __construct(string $className, string $methodName)
58475 {
58476 parent::__construct(sprintf('Comparison method %s::%s() does not declare bool return type.', $className, $methodName));
58477 }
58478 }
58479 <?php
58480
58481 declare (strict_types=1);
58482 /*
58483 * This file is part of PHPUnit.
58484 *
58485 * (c) Sebastian Bergmann <sebastian@phpunit.de>
58486 *
58487 * For the full copyright and license information, please view the LICENSE
58488 * file that was distributed with this source code.
58489 */
58490 namespace PHPUnit\Framework;
58491
58492 use function sprintf;
58493 /**
58494 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
58495 *
58496 * @internal This class is not covered by the backward compatibility promise for PHPUnit
58497 */
58498 final class ComparisonMethodDoesNotDeclareExactlyOneParameterException extends \PHPUnit\Framework\Exception
58499 {
58500 public function __construct(string $className, string $methodName)
58501 {
58502 parent::__construct(sprintf('Comparison method %s::%s() does not declare exactly one parameter.', $className, $methodName));
58503 }
58504 }
58505 <?php
58506
58507 declare (strict_types=1);
58508 /*
58509 * This file is part of PHPUnit.
58510 *
58511 * (c) Sebastian Bergmann <sebastian@phpunit.de>
58512 *
58513 * For the full copyright and license information, please view the LICENSE
58514 * file that was distributed with this source code.
58515 */
58516 namespace PHPUnit\Framework;
58517
58518 use function sprintf;
58519 /**
58520 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
58521 *
58522 * @internal This class is not covered by the backward compatibility promise for PHPUnit
58523 */
58524 final class ComparisonMethodDoesNotDeclareParameterTypeException extends \PHPUnit\Framework\Exception
58525 {
58526 public function __construct(string $className, string $methodName)
58527 {
58528 parent::__construct(sprintf('Parameter of comparison method %s::%s() does not have a declared type.', $className, $methodName));
58529 }
58530 }
58531 <?php
58532
58533 declare (strict_types=1);
58534 /*
58535 * This file is part of PHPUnit.
58536 *
58537 * (c) Sebastian Bergmann <sebastian@phpunit.de>
58538 *
58539 * For the full copyright and license information, please view the LICENSE
58540 * file that was distributed with this source code.
58541 */
58542 namespace PHPUnit\Framework;
58543
58544 use function sprintf;
58545 /**
58546 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
58547 *
58548 * @internal This class is not covered by the backward compatibility promise for PHPUnit
58549 */
58550 final class ComparisonMethodDoesNotExistException extends \PHPUnit\Framework\Exception
58551 {
58552 public function __construct(string $className, string $methodName)
58553 {
58554 parent::__construct(sprintf('Comparison method %s::%s() does not exist.', $className, $methodName));
58555 }
58556 }
58557 <?php
58558
58559 declare (strict_types=1);
58560 /*
58561 * This file is part of PHPUnit.
58562 *
58563 * (c) Sebastian Bergmann <sebastian@phpunit.de>
58564 *
58565 * For the full copyright and license information, please view the LICENSE
58566 * file that was distributed with this source code.
58567 */
58568 namespace PHPUnit\Framework;
58569
58570 /**
58571 * @psalm-immutable
58572 *
58573 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
58574 *
58575 * @internal This class is not covered by the backward compatibility promise for PHPUnit
58576 */
58577 final class PhptAssertionFailedError extends \PHPUnit\Framework\AssertionFailedError
58578 {
58579 private readonly string $syntheticFile;
58580 private readonly int $syntheticLine;
58581 private readonly array $syntheticTrace;
58582 private readonly string $diff;
58583 public function __construct(string $message, int $code, string $file, int $line, array $trace, string $diff)
58584 {
58585 parent::__construct($message, $code);
58586 $this->syntheticFile = $file;
58587 $this->syntheticLine = $line;
58588 $this->syntheticTrace = $trace;
58589 $this->diff = $diff;
58590 }
58591 public function syntheticFile(): string
58592 {
58593 return $this->syntheticFile;
58594 }
58595 public function syntheticLine(): int
58596 {
58597 return $this->syntheticLine;
58598 }
58599 public function syntheticTrace(): array
58600 {
58601 return $this->syntheticTrace;
58602 }
58603 public function diff(): string
58604 {
58605 return $this->diff;
58606 }
58607 }
58608 <?php
58609
58610 declare (strict_types=1);
58611 /*
58612 * This file is part of PHPUnit.
58613 *
58614 * (c) Sebastian Bergmann <sebastian@phpunit.de>
58615 *
58616 * For the full copyright and license information, please view the LICENSE
58617 * file that was distributed with this source code.
58618 */
58619 namespace PHPUnit\Framework;
58620
58621 /**
58622 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
58623 *
58624 * @internal This class is not covered by the backward compatibility promise for PHPUnit
58625 */
58626 final class ProcessIsolationException extends \PHPUnit\Framework\Exception
58627 {
58628 }
58629 <?php
58630
58631 declare (strict_types=1);
58632 /*
58633 * This file is part of PHPUnit.
58634 *
58635 * (c) Sebastian Bergmann <sebastian@phpunit.de>
58636 *
58637 * For the full copyright and license information, please view the LICENSE
58638 * file that was distributed with this source code.
58639 */
58640 namespace PHPUnit\Framework;
58641
58642 use Throwable;
58643 /**
58644 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
58645 *
58646 * @internal This interface is not covered by the backward compatibility promise for PHPUnit
58647 */
58648 interface SkippedTest extends Throwable
58649 {
58650 }
58651 <?php
58652
58653 declare (strict_types=1);
58654 /*
58655 * This file is part of PHPUnit.
58656 *
58657 * (c) Sebastian Bergmann <sebastian@phpunit.de>
58658 *
58659 * For the full copyright and license information, please view the LICENSE
58660 * file that was distributed with this source code.
58661 */
58662 namespace PHPUnit\Framework;
58663
58664 /**
58665 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
58666 *
58667 * @internal This class is not covered by the backward compatibility promise for PHPUnit
58668 */
58669 final class SkippedTestSuiteError extends \PHPUnit\Framework\AssertionFailedError implements \PHPUnit\Framework\SkippedTest
58670 {
58671 }
58672 <?php
58673
58674 declare (strict_types=1);
58675 /*
58676 * This file is part of PHPUnit.
58677 *
58678 * (c) Sebastian Bergmann <sebastian@phpunit.de>
58679 *
58680 * For the full copyright and license information, please view the LICENSE
58681 * file that was distributed with this source code.
58682 */
58683 namespace PHPUnit\Framework;
58684
58685 /**
58686 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
58687 *
58688 * @internal This class is not covered by the backward compatibility promise for PHPUnit
58689 */
58690 final class SkippedWithMessageException extends \PHPUnit\Framework\AssertionFailedError implements \PHPUnit\Framework\SkippedTest
58691 {
58692 }
58693 <?php
58694
58695 declare (strict_types=1);
58696 /*
58697 * This file is part of PHPUnit.
58698 *
58699 * (c) Sebastian Bergmann <sebastian@phpunit.de>
58700 *
58701 * For the full copyright and license information, please view the LICENSE
58702 * file that was distributed with this source code.
58703 */
58704 namespace PHPUnit\Framework;
58705
58706 use function sprintf;
58707 /**
58708 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
58709 *
58710 * @internal This class is not covered by the backward compatibility promise for PHPUnit
58711 */
58712 final class UnknownClassOrInterfaceException extends \PHPUnit\Framework\InvalidArgumentException
58713 {
58714 public function __construct(string $name)
58715 {
58716 parent::__construct(sprintf('Class or interface "%s" does not exist', $name));
58717 }
58718 }
58719 <?php
58720
58721 declare (strict_types=1);
58722 /*
58723 * This file is part of PHPUnit.
58724 *
58725 * (c) Sebastian Bergmann <sebastian@phpunit.de>
58726 *
58727 * For the full copyright and license information, please view the LICENSE
58728 * file that was distributed with this source code.
58729 */
58730 namespace PHPUnit\Framework;
58731
58732 use function sprintf;
58733 /**
58734 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
58735 *
58736 * @internal This class is not covered by the backward compatibility promise for PHPUnit
58737 */
58738 final class UnknownTypeException extends \PHPUnit\Framework\InvalidArgumentException
58739 {
58740 public function __construct(string $name)
58741 {
58742 parent::__construct(sprintf('Type "%s" is not known', $name));
58743 }
58744 }
58745 <?php
58746
58747 declare (strict_types=1);
58748 /*
58749 * This file is part of PHPUnit.
58750 *
58751 * (c) Sebastian Bergmann <sebastian@phpunit.de>
58752 *
58753 * For the full copyright and license information, please view the LICENSE
58754 * file that was distributed with this source code.
58755 */
58756 namespace PHPUnit\Framework;
58757
58758 use function array_filter;
58759 use function array_map;
58760 use function array_values;
58761 use function explode;
58762 use function in_array;
58763 use function str_contains;
58764 use PHPUnit\Metadata\DependsOnClass;
58765 use PHPUnit\Metadata\DependsOnMethod;
58766 use Stringable;
58767 /**
58768 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
58769 *
58770 * @internal This class is not covered by the backward compatibility promise for PHPUnit
58771 */
58772 final class ExecutionOrderDependency implements Stringable
58773 {
58774 private string $className = '';
58775 private string $methodName = '';
58776 private readonly bool $shallowClone;
58777 private readonly bool $deepClone;
58778 public static function invalid(): self
58779 {
58780 return new self('', '', \false, \false);
58781 }
58782 public static function forClass(DependsOnClass $metadata): self
58783 {
58784 return new self($metadata->className(), 'class', $metadata->deepClone(), $metadata->shallowClone());
58785 }
58786 public static function forMethod(DependsOnMethod $metadata): self
58787 {
58788 return new self($metadata->className(), $metadata->methodName(), $metadata->deepClone(), $metadata->shallowClone());
58789 }
58790 /**
58791 * @psalm-param list<ExecutionOrderDependency> $dependencies
58792 *
58793 * @psalm-return list<ExecutionOrderDependency>
58794 */
58795 public static function filterInvalid(array $dependencies): array
58796 {
58797 return array_values(array_filter($dependencies, static fn(self $d) => $d->isValid()));
58798 }
58799 /**
58800 * @psalm-param list<ExecutionOrderDependency> $existing
58801 * @psalm-param list<ExecutionOrderDependency> $additional
58802 *
58803 * @psalm-return list<ExecutionOrderDependency>
58804 */
58805 public static function mergeUnique(array $existing, array $additional): array
58806 {
58807 $existingTargets = array_map(static fn($dependency) => $dependency->getTarget(), $existing);
58808 foreach ($additional as $dependency) {
58809 $additionalTarget = $dependency->getTarget();
58810 if (in_array($additionalTarget, $existingTargets, \true)) {
58811 continue;
58812 }
58813 $existingTargets[] = $additionalTarget;
58814 $existing[] = $dependency;
58815 }
58816 return $existing;
58817 }
58818 /**
58819 * @psalm-param list<ExecutionOrderDependency> $left
58820 * @psalm-param list<ExecutionOrderDependency> $right
58821 *
58822 * @psalm-return list<ExecutionOrderDependency>
58823 */
58824 public static function diff(array $left, array $right): array
58825 {
58826 if ($right === []) {
58827 return $left;
58828 }
58829 if ($left === []) {
58830 return [];
58831 }
58832 $diff = [];
58833 $rightTargets = array_map(static fn($dependency) => $dependency->getTarget(), $right);
58834 foreach ($left as $dependency) {
58835 if (in_array($dependency->getTarget(), $rightTargets, \true)) {
58836 continue;
58837 }
58838 $diff[] = $dependency;
58839 }
58840 return $diff;
58841 }
58842 public function __construct(string $classOrCallableName, ?string $methodName = null, bool $deepClone = \false, bool $shallowClone = \false)
58843 {
58844 $this->deepClone = $deepClone;
58845 $this->shallowClone = $shallowClone;
58846 if ($classOrCallableName === '') {
58847 return;
58848 }
58849 if (str_contains($classOrCallableName, '::')) {
58850 [$this->className, $this->methodName] = explode('::', $classOrCallableName);
58851 } else {
58852 $this->className = $classOrCallableName;
58853 $this->methodName = !empty($methodName) ? $methodName : 'class';
58854 }
58855 }
58856 public function __toString(): string
58857 {
58858 return $this->getTarget();
58859 }
58860 public function isValid(): bool
58861 {
58862 // Invalid dependencies can be declared and are skipped by the runner
58863 return $this->className !== '' && $this->methodName !== '';
58864 }
58865 public function shallowClone(): bool
58866 {
58867 return $this->shallowClone;
58868 }
58869 public function deepClone(): bool
58870 {
58871 return $this->deepClone;
58872 }
58873 public function targetIsClass(): bool
58874 {
58875 return $this->methodName === 'class';
58876 }
58877 public function getTarget(): string
58878 {
58879 return $this->isValid() ? $this->className . '::' . $this->methodName : '';
58880 }
58881 public function getTargetClassName(): string
58882 {
58883 return $this->className;
58884 }
58885 }
58886 <?php
58887
58888 declare (strict_types=1);
58889 /*
58890 * This file is part of PHPUnit.
58891 *
58892 * (c) Sebastian Bergmann <sebastian@phpunit.de>
58893 *
58894 * For the full copyright and license information, please view the LICENSE
58895 * file that was distributed with this source code.
58896 */
58897 namespace PHPUnit\Framework\MockObject;
58898
58899 use PHPUnitPHAR\SebastianBergmann\Type\Type;
58900 /**
58901 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
58902 *
58903 * @internal This class is not covered by the backward compatibility promise for PHPUnit
58904 */
58905 final class ConfigurableMethod
58906 {
58907 /**
58908 * @psalm-var non-empty-string
58909 */
58910 private readonly string $name;
58911 /**
58912 * @psalm-var array<int, mixed>
58913 */
58914 private readonly array $defaultParameterValues;
58915 /**
58916 * @psalm-var non-negative-int
58917 */
58918 private readonly int $numberOfParameters;
58919 private readonly Type $returnType;
58920 /**
58921 * @psalm-param non-empty-string $name
58922 * @psalm-param array<int, mixed> $defaultParameterValues
58923 * @psalm-param non-negative-int $numberOfParameters
58924 */
58925 public function __construct(string $name, array $defaultParameterValues, int $numberOfParameters, Type $returnType)
58926 {
58927 $this->name = $name;
58928 $this->defaultParameterValues = $defaultParameterValues;
58929 $this->numberOfParameters = $numberOfParameters;
58930 $this->returnType = $returnType;
58931 }
58932 /**
58933 * @psalm-return non-empty-string
58934 */
58935 public function name(): string
58936 {
58937 return $this->name;
58938 }
58939 /**
58940 * @psalm-return array<int, mixed>
58941 */
58942 public function defaultParameterValues(): array
58943 {
58944 return $this->defaultParameterValues;
58945 }
58946 /**
58947 * @psalm-return non-negative-int
58948 */
58949 public function numberOfParameters(): int
58950 {
58951 return $this->numberOfParameters;
58952 }
58953 public function mayReturn(mixed $value): bool
58954 {
58955 return $this->returnType->isAssignable(Type::fromValue($value, \false));
58956 }
58957 public function returnTypeDeclaration(): string
58958 {
58959 return $this->returnType->asString();
58960 }
58961 }
58962 <?php
58963
58964 declare (strict_types=1);
58965 /*
58966 * This file is part of PHPUnit.
58967 *
58968 * (c) Sebastian Bergmann <sebastian@phpunit.de>
58969 *
58970 * For the full copyright and license information, please view the LICENSE
58971 * file that was distributed with this source code.
58972 */
58973 namespace PHPUnit\Framework\MockObject;
58974
58975 /**
58976 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
58977 *
58978 * @internal This class is not covered by the backward compatibility promise for PHPUnit
58979 */
58980 final class BadMethodCallException extends \BadMethodCallException implements \PHPUnit\Framework\MockObject\Exception
58981 {
58982 }
58983 <?php
58984
58985 declare (strict_types=1);
58986 /*
58987 * This file is part of PHPUnit.
58988 *
58989 * (c) Sebastian Bergmann <sebastian@phpunit.de>
58990 *
58991 * For the full copyright and license information, please view the LICENSE
58992 * file that was distributed with this source code.
58993 */
58994 namespace PHPUnit\Framework\MockObject;
58995
58996 use function sprintf;
58997 /**
58998 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
58999 *
59000 * @internal This class is not covered by the backward compatibility promise for PHPUnit
59001 */
59002 final class CannotUseOnlyMethodsException extends \PHPUnit\Framework\Exception implements \PHPUnit\Framework\MockObject\Exception
59003 {
59004 public function __construct(string $type, string $methodName)
59005 {
59006 parent::__construct(sprintf('Trying to configure method "%s" with onlyMethods(), but it does not exist in class "%s"', $methodName, $type));
59007 }
59008 }
59009 <?php
59010
59011 declare (strict_types=1);
59012 /*
59013 * This file is part of PHPUnit.
59014 *
59015 * (c) Sebastian Bergmann <sebastian@phpunit.de>
59016 *
59017 * For the full copyright and license information, please view the LICENSE
59018 * file that was distributed with this source code.
59019 */
59020 namespace PHPUnit\Framework\MockObject;
59021
59022 /**
59023 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
59024 *
59025 * @internal This interface is not covered by the backward compatibility promise for PHPUnit
59026 */
59027 interface Exception extends \PHPUnit\Exception
59028 {
59029 }
59030 <?php
59031
59032 declare (strict_types=1);
59033 /*
59034 * This file is part of PHPUnit.
59035 *
59036 * (c) Sebastian Bergmann <sebastian@phpunit.de>
59037 *
59038 * For the full copyright and license information, please view the LICENSE
59039 * file that was distributed with this source code.
59040 */
59041 namespace PHPUnit\Framework\MockObject;
59042
59043 use function get_debug_type;
59044 use function sprintf;
59045 /**
59046 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
59047 *
59048 * @internal This class is not covered by the backward compatibility promise for PHPUnit
59049 */
59050 final class IncompatibleReturnValueException extends \PHPUnit\Framework\Exception implements \PHPUnit\Framework\MockObject\Exception
59051 {
59052 public function __construct(\PHPUnit\Framework\MockObject\ConfigurableMethod $method, mixed $value)
59053 {
59054 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()));
59055 }
59056 }
59057 <?php
59058
59059 declare (strict_types=1);
59060 /*
59061 * This file is part of PHPUnit.
59062 *
59063 * (c) Sebastian Bergmann <sebastian@phpunit.de>
59064 *
59065 * For the full copyright and license information, please view the LICENSE
59066 * file that was distributed with this source code.
59067 */
59068 namespace PHPUnit\Framework\MockObject;
59069
59070 use function sprintf;
59071 /**
59072 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
59073 *
59074 * @internal This class is not covered by the backward compatibility promise for PHPUnit
59075 */
59076 final class MatchBuilderNotFoundException extends \PHPUnit\Framework\Exception implements \PHPUnit\Framework\MockObject\Exception
59077 {
59078 public function __construct(string $id)
59079 {
59080 parent::__construct(sprintf('No builder found for match builder identification <%s>', $id));
59081 }
59082 }
59083 <?php
59084
59085 declare (strict_types=1);
59086 /*
59087 * This file is part of PHPUnit.
59088 *
59089 * (c) Sebastian Bergmann <sebastian@phpunit.de>
59090 *
59091 * For the full copyright and license information, please view the LICENSE
59092 * file that was distributed with this source code.
59093 */
59094 namespace PHPUnit\Framework\MockObject;
59095
59096 use function sprintf;
59097 /**
59098 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
59099 *
59100 * @internal This class is not covered by the backward compatibility promise for PHPUnit
59101 */
59102 final class MatcherAlreadyRegisteredException extends \PHPUnit\Framework\Exception implements \PHPUnit\Framework\MockObject\Exception
59103 {
59104 public function __construct(string $id)
59105 {
59106 parent::__construct(sprintf('Matcher with id <%s> is already registered', $id));
59107 }
59108 }
59109 <?php
59110
59111 declare (strict_types=1);
59112 /*
59113 * This file is part of PHPUnit.
59114 *
59115 * (c) Sebastian Bergmann <sebastian@phpunit.de>
59116 *
59117 * For the full copyright and license information, please view the LICENSE
59118 * file that was distributed with this source code.
59119 */
59120 namespace PHPUnit\Framework\MockObject;
59121
59122 use function sprintf;
59123 /**
59124 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
59125 *
59126 * @internal This class is not covered by the backward compatibility promise for PHPUnit
59127 */
59128 final class MethodCannotBeConfiguredException extends \PHPUnit\Framework\Exception implements \PHPUnit\Framework\MockObject\Exception
59129 {
59130 public function __construct(string $method)
59131 {
59132 parent::__construct(sprintf('Trying to configure method "%s" which cannot be configured because it does not exist, has not been specified, is final, or is static', $method));
59133 }
59134 }
59135 <?php
59136
59137 declare (strict_types=1);
59138 /*
59139 * This file is part of PHPUnit.
59140 *
59141 * (c) Sebastian Bergmann <sebastian@phpunit.de>
59142 *
59143 * For the full copyright and license information, please view the LICENSE
59144 * file that was distributed with this source code.
59145 */
59146 namespace PHPUnit\Framework\MockObject;
59147
59148 /**
59149 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
59150 *
59151 * @internal This class is not covered by the backward compatibility promise for PHPUnit
59152 */
59153 final class MethodNameAlreadyConfiguredException extends \PHPUnit\Framework\Exception implements \PHPUnit\Framework\MockObject\Exception
59154 {
59155 public function __construct()
59156 {
59157 parent::__construct('Method name is already configured');
59158 }
59159 }
59160 <?php
59161
59162 declare (strict_types=1);
59163 /*
59164 * This file is part of PHPUnit.
59165 *
59166 * (c) Sebastian Bergmann <sebastian@phpunit.de>
59167 *
59168 * For the full copyright and license information, please view the LICENSE
59169 * file that was distributed with this source code.
59170 */
59171 namespace PHPUnit\Framework\MockObject;
59172
59173 /**
59174 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
59175 *
59176 * @internal This class is not covered by the backward compatibility promise for PHPUnit
59177 */
59178 final class MethodNameNotConfiguredException extends \PHPUnit\Framework\Exception implements \PHPUnit\Framework\MockObject\Exception
59179 {
59180 public function __construct()
59181 {
59182 parent::__construct('Method name is not configured');
59183 }
59184 }
59185 <?php
59186
59187 declare (strict_types=1);
59188 /*
59189 * This file is part of PHPUnit.
59190 *
59191 * (c) Sebastian Bergmann <sebastian@phpunit.de>
59192 *
59193 * For the full copyright and license information, please view the LICENSE
59194 * file that was distributed with this source code.
59195 */
59196 namespace PHPUnit\Framework\MockObject;
59197
59198 /**
59199 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
59200 *
59201 * @internal This class is not covered by the backward compatibility promise for PHPUnit
59202 */
59203 final class MethodParametersAlreadyConfiguredException extends \PHPUnit\Framework\Exception implements \PHPUnit\Framework\MockObject\Exception
59204 {
59205 public function __construct()
59206 {
59207 parent::__construct('Method parameters already configured');
59208 }
59209 }
59210 <?php
59211
59212 declare (strict_types=1);
59213 /*
59214 * This file is part of PHPUnit.
59215 *
59216 * (c) Sebastian Bergmann <sebastian@phpunit.de>
59217 *
59218 * For the full copyright and license information, please view the LICENSE
59219 * file that was distributed with this source code.
59220 */
59221 namespace PHPUnit\Framework\MockObject;
59222
59223 use function sprintf;
59224 use RuntimeException;
59225 /**
59226 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
59227 */
59228 final class NeverReturningMethodException extends RuntimeException implements \PHPUnit\Framework\MockObject\Exception
59229 {
59230 /**
59231 * @psalm-param class-string $className
59232 * @psalm-param non-empty-string $methodName
59233 */
59234 public function __construct(string $className, string $methodName)
59235 {
59236 parent::__construct(sprintf('Method %s::%s() is declared to never return', $className, $methodName));
59237 }
59238 }
59239 <?php
59240
59241 declare (strict_types=1);
59242 /*
59243 * This file is part of PHPUnit.
59244 *
59245 * (c) Sebastian Bergmann <sebastian@phpunit.de>
59246 *
59247 * For the full copyright and license information, please view the LICENSE
59248 * file that was distributed with this source code.
59249 */
59250 namespace PHPUnit\Framework\MockObject;
59251
59252 use function sprintf;
59253 /**
59254 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
59255 *
59256 * @internal This class is not covered by the backward compatibility promise for PHPUnit
59257 */
59258 final class NoMoreReturnValuesConfiguredException extends \PHPUnit\Framework\Exception implements \PHPUnit\Framework\MockObject\Exception
59259 {
59260 public function __construct(\PHPUnit\Framework\MockObject\Invocation $invocation, int $numberOfConfiguredReturnValues)
59261 {
59262 parent::__construct(sprintf('Only %d return values have been configured for %s::%s()', $numberOfConfiguredReturnValues, $invocation->className(), $invocation->methodName()));
59263 }
59264 }
59265 <?php
59266
59267 declare (strict_types=1);
59268 /*
59269 * This file is part of PHPUnit.
59270 *
59271 * (c) Sebastian Bergmann <sebastian@phpunit.de>
59272 *
59273 * For the full copyright and license information, please view the LICENSE
59274 * file that was distributed with this source code.
59275 */
59276 namespace PHPUnit\Framework\MockObject;
59277
59278 use function sprintf;
59279 /**
59280 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
59281 *
59282 * @internal This class is not covered by the backward compatibility promise for PHPUnit
59283 */
59284 final class ReturnValueNotConfiguredException extends \PHPUnit\Framework\Exception implements \PHPUnit\Framework\MockObject\Exception
59285 {
59286 public function __construct(\PHPUnit\Framework\MockObject\Invocation $invocation)
59287 {
59288 parent::__construct(sprintf('No return value is configured for %s::%s() and return value generation is disabled', $invocation->className(), $invocation->methodName()));
59289 }
59290 }
59291 <?php
59292
59293 declare (strict_types=1);
59294 /*
59295 * This file is part of PHPUnit.
59296 *
59297 * (c) Sebastian Bergmann <sebastian@phpunit.de>
59298 *
59299 * For the full copyright and license information, please view the LICENSE
59300 * file that was distributed with this source code.
59301 */
59302 namespace PHPUnit\Framework\MockObject;
59303
59304 /**
59305 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
59306 *
59307 * @internal This class is not covered by the backward compatibility promise for PHPUnit
59308 */
59309 final class RuntimeException extends \RuntimeException implements \PHPUnit\Framework\MockObject\Exception
59310 {
59311 }
59312 <?php
59313
59314 declare (strict_types=1);
59315 /*
59316 * This file is part of PHPUnit.
59317 *
59318 * (c) Sebastian Bergmann <sebastian@phpunit.de>
59319 *
59320 * For the full copyright and license information, please view the LICENSE
59321 * file that was distributed with this source code.
59322 */
59323 namespace PHPUnit\Framework\MockObject\Generator;
59324
59325 use function sprintf;
59326 /**
59327 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
59328 *
59329 * @internal This class is not covered by the backward compatibility promise for PHPUnit
59330 */
59331 final class CannotUseAddMethodsException extends \PHPUnit\Framework\Exception implements \PHPUnit\Framework\MockObject\Generator\Exception
59332 {
59333 public function __construct(string $type, string $methodName)
59334 {
59335 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));
59336 }
59337 }
59338 <?php
59339
59340 declare (strict_types=1);
59341 /*
59342 * This file is part of PHPUnit.
59343 *
59344 * (c) Sebastian Bergmann <sebastian@phpunit.de>
59345 *
59346 * For the full copyright and license information, please view the LICENSE
59347 * file that was distributed with this source code.
59348 */
59349 namespace PHPUnit\Framework\MockObject\Generator;
59350
59351 use function sprintf;
59352 /**
59353 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
59354 *
59355 * @internal This class is not covered by the backward compatibility promise for PHPUnit
59356 */
59357 final class ClassIsEnumerationException extends \PHPUnit\Framework\Exception implements \PHPUnit\Framework\MockObject\Generator\Exception
59358 {
59359 public function __construct(string $className)
59360 {
59361 parent::__construct(sprintf('Class "%s" is an enumeration and cannot be doubled', $className));
59362 }
59363 }
59364 <?php
59365
59366 declare (strict_types=1);
59367 /*
59368 * This file is part of PHPUnit.
59369 *
59370 * (c) Sebastian Bergmann <sebastian@phpunit.de>
59371 *
59372 * For the full copyright and license information, please view the LICENSE
59373 * file that was distributed with this source code.
59374 */
59375 namespace PHPUnit\Framework\MockObject\Generator;
59376
59377 use function sprintf;
59378 /**
59379 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
59380 *
59381 * @internal This class is not covered by the backward compatibility promise for PHPUnit
59382 */
59383 final class ClassIsFinalException extends \PHPUnit\Framework\Exception implements \PHPUnit\Framework\MockObject\Generator\Exception
59384 {
59385 public function __construct(string $className)
59386 {
59387 parent::__construct(sprintf('Class "%s" is declared "final" and cannot be doubled', $className));
59388 }
59389 }
59390 <?php
59391
59392 declare (strict_types=1);
59393 /*
59394 * This file is part of PHPUnit.
59395 *
59396 * (c) Sebastian Bergmann <sebastian@phpunit.de>
59397 *
59398 * For the full copyright and license information, please view the LICENSE
59399 * file that was distributed with this source code.
59400 */
59401 namespace PHPUnit\Framework\MockObject\Generator;
59402
59403 use function sprintf;
59404 /**
59405 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
59406 *
59407 * @internal This class is not covered by the backward compatibility promise for PHPUnit
59408 */
59409 final class ClassIsReadonlyException extends \PHPUnit\Framework\Exception implements \PHPUnit\Framework\MockObject\Generator\Exception
59410 {
59411 public function __construct(string $className)
59412 {
59413 parent::__construct(sprintf('Class "%s" is declared "readonly" and cannot be doubled', $className));
59414 }
59415 }
59416 <?php
59417
59418 declare (strict_types=1);
59419 /*
59420 * This file is part of PHPUnit.
59421 *
59422 * (c) Sebastian Bergmann <sebastian@phpunit.de>
59423 *
59424 * For the full copyright and license information, please view the LICENSE
59425 * file that was distributed with this source code.
59426 */
59427 namespace PHPUnit\Framework\MockObject\Generator;
59428
59429 use function array_diff_assoc;
59430 use function array_unique;
59431 use function implode;
59432 use function sprintf;
59433 /**
59434 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
59435 *
59436 * @internal This class is not covered by the backward compatibility promise for PHPUnit
59437 */
59438 final class DuplicateMethodException extends \PHPUnit\Framework\Exception implements \PHPUnit\Framework\MockObject\Generator\Exception
59439 {
59440 /**
59441 * @psalm-param list<string> $methods
59442 */
59443 public function __construct(array $methods)
59444 {
59445 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))))));
59446 }
59447 }
59448 <?php
59449
59450 declare (strict_types=1);
59451 /*
59452 * This file is part of PHPUnit.
59453 *
59454 * (c) Sebastian Bergmann <sebastian@phpunit.de>
59455 *
59456 * For the full copyright and license information, please view the LICENSE
59457 * file that was distributed with this source code.
59458 */
59459 namespace PHPUnit\Framework\MockObject\Generator;
59460
59461 use PHPUnit\Framework\MockObject\Exception as BaseException;
59462 /**
59463 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
59464 *
59465 * @internal This interface is not covered by the backward compatibility promise for PHPUnit
59466 */
59467 interface Exception extends BaseException
59468 {
59469 }
59470 <?php
59471
59472 declare (strict_types=1);
59473 /*
59474 * This file is part of PHPUnit.
59475 *
59476 * (c) Sebastian Bergmann <sebastian@phpunit.de>
59477 *
59478 * For the full copyright and license information, please view the LICENSE
59479 * file that was distributed with this source code.
59480 */
59481 namespace PHPUnit\Framework\MockObject\Generator;
59482
59483 use function sprintf;
59484 /**
59485 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
59486 *
59487 * @internal This class is not covered by the backward compatibility promise for PHPUnit
59488 */
59489 final class InvalidMethodNameException extends \PHPUnit\Framework\Exception implements \PHPUnit\Framework\MockObject\Generator\Exception
59490 {
59491 public function __construct(string $method)
59492 {
59493 parent::__construct(sprintf('Cannot double method with invalid name "%s"', $method));
59494 }
59495 }
59496 <?php
59497
59498 declare (strict_types=1);
59499 /*
59500 * This file is part of PHPUnit.
59501 *
59502 * (c) Sebastian Bergmann <sebastian@phpunit.de>
59503 *
59504 * For the full copyright and license information, please view the LICENSE
59505 * file that was distributed with this source code.
59506 */
59507 namespace PHPUnit\Framework\MockObject\Generator;
59508
59509 use function sprintf;
59510 /**
59511 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
59512 *
59513 * @internal This class is not covered by the backward compatibility promise for PHPUnit
59514 */
59515 final class NameAlreadyInUseException extends \PHPUnit\Framework\Exception implements \PHPUnit\Framework\MockObject\Generator\Exception
59516 {
59517 /**
59518 * @psalm-param class-string|trait-string $name
59519 */
59520 public function __construct(string $name)
59521 {
59522 parent::__construct(sprintf('The name "%s" is already in use', $name));
59523 }
59524 }
59525 <?php
59526
59527 declare (strict_types=1);
59528 /*
59529 * This file is part of PHPUnit.
59530 *
59531 * (c) Sebastian Bergmann <sebastian@phpunit.de>
59532 *
59533 * For the full copyright and license information, please view the LICENSE
59534 * file that was distributed with this source code.
59535 */
59536 namespace PHPUnit\Framework\MockObject\Generator;
59537
59538 /**
59539 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
59540 *
59541 * @internal This class is not covered by the backward compatibility promise for PHPUnit
59542 */
59543 final class OriginalConstructorInvocationRequiredException extends \PHPUnit\Framework\Exception implements \PHPUnit\Framework\MockObject\Generator\Exception
59544 {
59545 public function __construct()
59546 {
59547 parent::__construct('Proxying to original methods requires invoking the original constructor');
59548 }
59549 }
59550 <?php
59551
59552 declare (strict_types=1);
59553 /*
59554 * This file is part of PHPUnit.
59555 *
59556 * (c) Sebastian Bergmann <sebastian@phpunit.de>
59557 *
59558 * For the full copyright and license information, please view the LICENSE
59559 * file that was distributed with this source code.
59560 */
59561 namespace PHPUnit\Framework\MockObject\Generator;
59562
59563 /**
59564 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
59565 *
59566 * @internal This class is not covered by the backward compatibility promise for PHPUnit
59567 */
59568 final class ReflectionException extends \PHPUnit\Framework\Exception implements \PHPUnit\Framework\MockObject\Generator\Exception
59569 {
59570 }
59571 <?php
59572
59573 declare (strict_types=1);
59574 /*
59575 * This file is part of PHPUnit.
59576 *
59577 * (c) Sebastian Bergmann <sebastian@phpunit.de>
59578 *
59579 * For the full copyright and license information, please view the LICENSE
59580 * file that was distributed with this source code.
59581 */
59582 namespace PHPUnit\Framework\MockObject\Generator;
59583
59584 /**
59585 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
59586 *
59587 * @internal This class is not covered by the backward compatibility promise for PHPUnit
59588 */
59589 final class RuntimeException extends \PHPUnit\Framework\Exception implements \PHPUnit\Framework\MockObject\Generator\Exception
59590 {
59591 }
59592 <?php
59593
59594 declare (strict_types=1);
59595 /*
59596 * This file is part of PHPUnit.
59597 *
59598 * (c) Sebastian Bergmann <sebastian@phpunit.de>
59599 *
59600 * For the full copyright and license information, please view the LICENSE
59601 * file that was distributed with this source code.
59602 */
59603 namespace PHPUnit\Framework\MockObject\Generator;
59604
59605 /**
59606 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
59607 *
59608 * @internal This class is not covered by the backward compatibility promise for PHPUnit
59609 */
59610 final class SoapExtensionNotAvailableException extends \PHPUnit\Framework\Exception implements \PHPUnit\Framework\MockObject\Generator\Exception
59611 {
59612 public function __construct()
59613 {
59614 parent::__construct('The SOAP extension is required to generate a test double from WSDL');
59615 }
59616 }
59617 <?php
59618
59619 declare (strict_types=1);
59620 /*
59621 * This file is part of PHPUnit.
59622 *
59623 * (c) Sebastian Bergmann <sebastian@phpunit.de>
59624 *
59625 * For the full copyright and license information, please view the LICENSE
59626 * file that was distributed with this source code.
59627 */
59628 namespace PHPUnit\Framework\MockObject\Generator;
59629
59630 use function sprintf;
59631 /**
59632 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
59633 *
59634 * @internal This class is not covered by the backward compatibility promise for PHPUnit
59635 */
59636 final class UnknownClassException extends \PHPUnit\Framework\Exception implements \PHPUnit\Framework\MockObject\Generator\Exception
59637 {
59638 public function __construct(string $className)
59639 {
59640 parent::__construct(sprintf('Class "%s" does not exist', $className));
59641 }
59642 }
59643 <?php
59644
59645 declare (strict_types=1);
59646 /*
59647 * This file is part of PHPUnit.
59648 *
59649 * (c) Sebastian Bergmann <sebastian@phpunit.de>
59650 *
59651 * For the full copyright and license information, please view the LICENSE
59652 * file that was distributed with this source code.
59653 */
59654 namespace PHPUnit\Framework\MockObject\Generator;
59655
59656 use function sprintf;
59657 /**
59658 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
59659 *
59660 * @internal This class is not covered by the backward compatibility promise for PHPUnit
59661 *
59662 * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5243
59663 */
59664 final class UnknownTraitException extends \PHPUnit\Framework\Exception implements \PHPUnit\Framework\MockObject\Generator\Exception
59665 {
59666 public function __construct(string $traitName)
59667 {
59668 parent::__construct(sprintf('Trait "%s" does not exist', $traitName));
59669 }
59670 }
59671 <?php
59672
59673 declare (strict_types=1);
59674 /*
59675 * This file is part of PHPUnit.
59676 *
59677 * (c) Sebastian Bergmann <sebastian@phpunit.de>
59678 *
59679 * For the full copyright and license information, please view the LICENSE
59680 * file that was distributed with this source code.
59681 */
59682 namespace PHPUnit\Framework\MockObject\Generator;
59683
59684 use function sprintf;
59685 /**
59686 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
59687 *
59688 * @internal This class is not covered by the backward compatibility promise for PHPUnit
59689 */
59690 final class UnknownTypeException extends \PHPUnit\Framework\Exception implements \PHPUnit\Framework\MockObject\Generator\Exception
59691 {
59692 public function __construct(string $type)
59693 {
59694 parent::__construct(sprintf('Class or interface "%s" does not exist', $type));
59695 }
59696 }
59697 <?php
59698
59699 declare (strict_types=1);
59700 /*
59701 * This file is part of PHPUnit.
59702 *
59703 * (c) Sebastian Bergmann <sebastian@phpunit.de>
59704 *
59705 * For the full copyright and license information, please view the LICENSE
59706 * file that was distributed with this source code.
59707 */
59708 namespace PHPUnit\Framework\MockObject\Generator;
59709
59710 use const PHP_EOL;
59711 use const PHP_VERSION;
59712 use const PREG_OFFSET_CAPTURE;
59713 use const WSDL_CACHE_NONE;
59714 use function array_merge;
59715 use function array_pop;
59716 use function array_unique;
59717 use function assert;
59718 use function class_exists;
59719 use function count;
59720 use function explode;
59721 use function extension_loaded;
59722 use function implode;
59723 use function in_array;
59724 use function interface_exists;
59725 use function is_array;
59726 use function is_object;
59727 use function md5;
59728 use function method_exists;
59729 use function mt_rand;
59730 use function preg_match;
59731 use function preg_match_all;
59732 use function range;
59733 use function serialize;
59734 use function sort;
59735 use function sprintf;
59736 use function str_contains;
59737 use function str_replace;
59738 use function strlen;
59739 use function strpos;
59740 use function substr;
59741 use function trait_exists;
59742 use function version_compare;
59743 use Exception;
59744 use Iterator;
59745 use IteratorAggregate;
59746 use PHPUnit\Framework\InvalidArgumentException;
59747 use PHPUnit\Framework\MockObject\ConfigurableMethod;
59748 use PHPUnit\Framework\MockObject\DoubledCloneMethod;
59749 use PHPUnit\Framework\MockObject\Method;
59750 use PHPUnit\Framework\MockObject\MockObject;
59751 use PHPUnit\Framework\MockObject\MockObjectApi;
59752 use PHPUnit\Framework\MockObject\MockObjectInternal;
59753 use PHPUnit\Framework\MockObject\ProxiedCloneMethod;
59754 use PHPUnit\Framework\MockObject\Stub;
59755 use PHPUnit\Framework\MockObject\StubApi;
59756 use PHPUnit\Framework\MockObject\StubInternal;
59757 use ReflectionClass;
59758 use ReflectionMethod;
59759 use SoapClient;
59760 use SoapFault;
59761 use Throwable;
59762 use Traversable;
59763 /**
59764 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
59765 *
59766 * @internal This class is not covered by the backward compatibility promise for PHPUnit
59767 */
59768 final class Generator
59769 {
59770 use \PHPUnit\Framework\MockObject\Generator\TemplateLoader;
59771 /**
59772 * @var array<non-empty-string, true>
59773 */
59774 private static $excludedMethodNames = [];
59775 /**
59776 * @psalm-var array<non-empty-string, MockClass>
59777 */
59778 private static array $cache = [];
59779 /**
59780 * Returns a test double for the specified class.
59781 *
59782 * @throws ClassIsEnumerationException
59783 * @throws ClassIsFinalException
59784 * @throws ClassIsReadonlyException
59785 * @throws DuplicateMethodException
59786 * @throws InvalidMethodNameException
59787 * @throws NameAlreadyInUseException
59788 * @throws OriginalConstructorInvocationRequiredException
59789 * @throws ReflectionException
59790 * @throws RuntimeException
59791 * @throws UnknownTypeException
59792 */
59793 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
59794 {
59795 if ($type === Traversable::class) {
59796 $type = Iterator::class;
59797 }
59798 if (!$allowMockingUnknownTypes) {
59799 $this->ensureKnownType($type, $callAutoload);
59800 }
59801 $this->ensureValidMethods($methods);
59802 $this->ensureNameForTestDoubleClassIsAvailable($mockClassName);
59803 if (!$callOriginalConstructor && $callOriginalMethods) {
59804 throw new \PHPUnit\Framework\MockObject\Generator\OriginalConstructorInvocationRequiredException();
59805 }
59806 $mock = $this->generate($type, $mockObject, $methods, $mockClassName, $callOriginalClone, $callAutoload, $cloneArguments, $callOriginalMethods);
59807 $object = $this->getObject($mock, $type, $callOriginalConstructor, $arguments, $callOriginalMethods, $proxyTarget, $returnValueGeneration);
59808 assert($object instanceof $type);
59809 if ($mockObject) {
59810 assert($object instanceof MockObject);
59811 } else {
59812 assert($object instanceof Stub);
59813 }
59814 return $object;
59815 }
59816 /**
59817 * @psalm-param list<class-string> $interfaces
59818 *
59819 * @throws RuntimeException
59820 * @throws UnknownTypeException
59821 */
59822 public function testDoubleForInterfaceIntersection(array $interfaces, bool $mockObject, bool $callAutoload = \true): MockObject|Stub
59823 {
59824 if (count($interfaces) < 2) {
59825 throw new \PHPUnit\Framework\MockObject\Generator\RuntimeException('At least two interfaces must be specified');
59826 }
59827 foreach ($interfaces as $interface) {
59828 if (!interface_exists($interface, $callAutoload)) {
59829 throw new \PHPUnit\Framework\MockObject\Generator\UnknownTypeException($interface);
59830 }
59831 }
59832 sort($interfaces);
59833 $methods = [];
59834 foreach ($interfaces as $interface) {
59835 $methods = array_merge($methods, $this->namesOfMethodsIn($interface));
59836 }
59837 if (count(array_unique($methods)) < count($methods)) {
59838 throw new \PHPUnit\Framework\MockObject\Generator\RuntimeException('Interfaces must not declare the same method');
59839 }
59840 $unqualifiedNames = [];
59841 foreach ($interfaces as $interface) {
59842 $parts = explode('\\', $interface);
59843 $unqualifiedNames[] = array_pop($parts);
59844 }
59845 sort($unqualifiedNames);
59846 do {
59847 $intersectionName = sprintf('Intersection_%s_%s', implode('_', $unqualifiedNames), substr(md5((string) mt_rand()), 0, 8));
59848 } while (interface_exists($intersectionName, \false));
59849 $template = $this->loadTemplate('intersection.tpl');
59850 $template->setVar(['intersection' => $intersectionName, 'interfaces' => implode(', ', $interfaces)]);
59851 eval($template->render());
59852 return $this->testDouble($intersectionName, $mockObject);
59853 }
59854 /**
59855 * Returns a mock object for the specified abstract class with all abstract
59856 * methods of the class mocked.
59857 *
59858 * Concrete methods to mock can be specified with the $mockedMethods parameter.
59859 *
59860 * @throws ClassIsEnumerationException
59861 * @throws ClassIsFinalException
59862 * @throws ClassIsReadonlyException
59863 * @throws DuplicateMethodException
59864 * @throws InvalidArgumentException
59865 * @throws InvalidMethodNameException
59866 * @throws NameAlreadyInUseException
59867 * @throws OriginalConstructorInvocationRequiredException
59868 * @throws ReflectionException
59869 * @throws RuntimeException
59870 * @throws UnknownClassException
59871 * @throws UnknownTypeException
59872 *
59873 * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5241
59874 */
59875 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
59876 {
59877 if (class_exists($originalClassName, $callAutoload) || interface_exists($originalClassName, $callAutoload)) {
59878 $reflector = $this->reflectClass($originalClassName);
59879 $methods = $mockedMethods;
59880 foreach ($reflector->getMethods() as $method) {
59881 if ($method->isAbstract() && !in_array($method->getName(), $methods ?? [], \true)) {
59882 $methods[] = $method->getName();
59883 }
59884 }
59885 if (empty($methods)) {
59886 $methods = null;
59887 }
59888 $mockObject = $this->testDouble($originalClassName, \true, $methods, $arguments, $mockClassName, $callOriginalConstructor, $callOriginalClone, $callAutoload, $cloneArguments);
59889 assert($mockObject instanceof $originalClassName);
59890 assert($mockObject instanceof MockObject);
59891 return $mockObject;
59892 }
59893 throw new \PHPUnit\Framework\MockObject\Generator\UnknownClassException($originalClassName);
59894 }
59895 /**
59896 * Returns a mock object for the specified trait with all abstract methods
59897 * of the trait mocked. Concrete methods to mock can be specified with the
59898 * `$mockedMethods` parameter.
59899 *
59900 * @psalm-param trait-string $traitName
59901 *
59902 * @throws ClassIsEnumerationException
59903 * @throws ClassIsFinalException
59904 * @throws ClassIsReadonlyException
59905 * @throws DuplicateMethodException
59906 * @throws InvalidArgumentException
59907 * @throws InvalidMethodNameException
59908 * @throws NameAlreadyInUseException
59909 * @throws OriginalConstructorInvocationRequiredException
59910 * @throws ReflectionException
59911 * @throws RuntimeException
59912 * @throws UnknownClassException
59913 * @throws UnknownTraitException
59914 * @throws UnknownTypeException
59915 *
59916 * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5243
59917 */
59918 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
59919 {
59920 if (!trait_exists($traitName, $callAutoload)) {
59921 throw new \PHPUnit\Framework\MockObject\Generator\UnknownTraitException($traitName);
59922 }
59923 $className = $this->generateClassName($traitName, '', 'Trait_');
59924 $classTemplate = $this->loadTemplate('trait_class.tpl');
59925 $classTemplate->setVar(['prologue' => 'abstract ', 'class_name' => $className['className'], 'trait_name' => $traitName]);
59926 $mockTrait = new \PHPUnit\Framework\MockObject\Generator\MockTrait($classTemplate->render(), $className['className']);
59927 $mockTrait->generate();
59928 return $this->mockObjectForAbstractClass($className['className'], $arguments, $mockClassName, $callOriginalConstructor, $callOriginalClone, $callAutoload, $mockedMethods, $cloneArguments);
59929 }
59930 /**
59931 * Returns an object for the specified trait.
59932 *
59933 * @psalm-param trait-string $traitName
59934 *
59935 * @throws ReflectionException
59936 * @throws RuntimeException
59937 * @throws UnknownTraitException
59938 *
59939 * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5244
59940 */
59941 public function objectForTrait(string $traitName, string $traitClassName = '', bool $callAutoload = \true, bool $callOriginalConstructor = \false, array $arguments = []): object
59942 {
59943 if (!trait_exists($traitName, $callAutoload)) {
59944 throw new \PHPUnit\Framework\MockObject\Generator\UnknownTraitException($traitName);
59945 }
59946 $className = $this->generateClassName($traitName, $traitClassName, 'Trait_');
59947 $classTemplate = $this->loadTemplate('trait_class.tpl');
59948 $classTemplate->setVar(['prologue' => '', 'class_name' => $className['className'], 'trait_name' => $traitName]);
59949 return $this->getObject(new \PHPUnit\Framework\MockObject\Generator\MockTrait($classTemplate->render(), $className['className']), '', $callOriginalConstructor, $arguments);
59950 }
59951 /**
59952 * @throws ClassIsEnumerationException
59953 * @throws ClassIsFinalException
59954 * @throws ClassIsReadonlyException
59955 * @throws ReflectionException
59956 * @throws RuntimeException
59957 *
59958 * @todo This method is only public because it is used to test generated code in PHPT tests
59959 *
59960 * @see https://github.com/sebastianbergmann/phpunit/issues/5476
59961 */
59962 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
59963 {
59964 if ($mockClassName !== '') {
59965 return $this->generateCodeForTestDoubleClass($type, $mockObject, $methods, $mockClassName, $callOriginalClone, $callAutoload, $cloneArguments, $callOriginalMethods);
59966 }
59967 $key = md5($type . ($mockObject ? 'MockObject' : 'TestStub') . serialize($methods) . serialize($callOriginalClone) . serialize($cloneArguments) . serialize($callOriginalMethods));
59968 if (!isset(self::$cache[$key])) {
59969 self::$cache[$key] = $this->generateCodeForTestDoubleClass($type, $mockObject, $methods, $mockClassName, $callOriginalClone, $callAutoload, $cloneArguments, $callOriginalMethods);
59970 }
59971 return self::$cache[$key];
59972 }
59973 /**
59974 * @throws RuntimeException
59975 * @throws SoapExtensionNotAvailableException
59976 *
59977 * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5242
59978 */
59979 public function generateClassFromWsdl(string $wsdlFile, string $className, array $methods = [], array $options = []): string
59980 {
59981 if (!extension_loaded('soap')) {
59982 throw new \PHPUnit\Framework\MockObject\Generator\SoapExtensionNotAvailableException();
59983 }
59984 $options['cache_wsdl'] = WSDL_CACHE_NONE;
59985 try {
59986 $client = new SoapClient($wsdlFile, $options);
59987 $_methods = array_unique($client->__getFunctions());
59988 unset($client);
59989 } catch (SoapFault $e) {
59990 throw new \PHPUnit\Framework\MockObject\Generator\RuntimeException($e->getMessage(), $e->getCode(), $e);
59991 }
59992 sort($_methods);
59993 $methodTemplate = $this->loadTemplate('wsdl_method.tpl');
59994 $methodsBuffer = '';
59995 foreach ($_methods as $method) {
59996 preg_match_all('/[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*\(/', $method, $matches, PREG_OFFSET_CAPTURE);
59997 $lastFunction = array_pop($matches[0]);
59998 $nameStart = $lastFunction[1];
59999 $nameEnd = $nameStart + strlen($lastFunction[0]) - 1;
60000 $name = str_replace('(', '', $lastFunction[0]);
60001 if (empty($methods) || in_array($name, $methods, \true)) {
60002 $arguments = explode(',', str_replace(')', '', substr($method, $nameEnd + 1)));
60003 foreach (range(0, count($arguments) - 1) as $i) {
60004 $parameterStart = strpos($arguments[$i], '$');
60005 if (!$parameterStart) {
60006 continue;
60007 }
60008 $arguments[$i] = substr($arguments[$i], $parameterStart);
60009 }
60010 $methodTemplate->setVar(['method_name' => $name, 'arguments' => implode(', ', $arguments)]);
60011 $methodsBuffer .= $methodTemplate->render();
60012 }
60013 }
60014 $optionsBuffer = '[';
60015 foreach ($options as $key => $value) {
60016 $optionsBuffer .= $key . ' => ' . $value;
60017 }
60018 $optionsBuffer .= ']';
60019 $classTemplate = $this->loadTemplate('wsdl_class.tpl');
60020 $namespace = '';
60021 if (str_contains($className, '\\')) {
60022 $parts = explode('\\', $className);
60023 $className = array_pop($parts);
60024 $namespace = 'namespace ' . implode('\\', $parts) . ';' . "\n\n";
60025 }
60026 $classTemplate->setVar(['namespace' => $namespace, 'class_name' => $className, 'wsdl' => $wsdlFile, 'options' => $optionsBuffer, 'methods' => $methodsBuffer]);
60027 return $classTemplate->render();
60028 }
60029 /**
60030 * @throws ReflectionException
60031 *
60032 * @psalm-return list<MockMethod>
60033 */
60034 public function mockClassMethods(string $className, bool $callOriginalMethods, bool $cloneArguments): array
60035 {
60036 $class = $this->reflectClass($className);
60037 $methods = [];
60038 foreach ($class->getMethods() as $method) {
60039 if (($method->isPublic() || $method->isAbstract()) && $this->canMethodBeDoubled($method)) {
60040 $methods[] = \PHPUnit\Framework\MockObject\Generator\MockMethod::fromReflection($method, $callOriginalMethods, $cloneArguments);
60041 }
60042 }
60043 return $methods;
60044 }
60045 /**
60046 * @psalm-param class-string $interfaceName
60047 *
60048 * @throws ReflectionException
60049 *
60050 * @psalm-return list<ReflectionMethod>
60051 */
60052 private function userDefinedInterfaceMethods(string $interfaceName): array
60053 {
60054 $interface = $this->reflectClass($interfaceName);
60055 $methods = [];
60056 foreach ($interface->getMethods() as $method) {
60057 if (!$method->isUserDefined()) {
60058 continue;
60059 }
60060 $methods[] = $method;
60061 }
60062 return $methods;
60063 }
60064 /**
60065 * @throws ReflectionException
60066 * @throws RuntimeException
60067 */
60068 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
60069 {
60070 $className = $mockClass->generate();
60071 $object = $this->instantiate($className, $callOriginalConstructor, $arguments);
60072 if ($callOriginalMethods) {
60073 $this->instantiateProxyTarget($proxyTarget, $object, $type, $arguments);
60074 }
60075 if ($object instanceof StubInternal) {
60076 $object->__phpunit_setReturnValueGeneration($returnValueGeneration);
60077 }
60078 return $object;
60079 }
60080 /**
60081 * @throws ClassIsEnumerationException
60082 * @throws ClassIsFinalException
60083 * @throws ClassIsReadonlyException
60084 * @throws ReflectionException
60085 * @throws RuntimeException
60086 */
60087 private function generateCodeForTestDoubleClass(string $type, bool $mockObject, ?array $explicitMethods, string $mockClassName, bool $callOriginalClone, bool $callAutoload, bool $cloneArguments, bool $callOriginalMethods): \PHPUnit\Framework\MockObject\Generator\MockClass
60088 {
60089 $classTemplate = $this->loadTemplate('test_double_class.tpl');
60090 $additionalInterfaces = [];
60091 $doubledCloneMethod = \false;
60092 $proxiedCloneMethod = \false;
60093 $isClass = \false;
60094 $isInterface = \false;
60095 $class = null;
60096 $mockMethods = new \PHPUnit\Framework\MockObject\Generator\MockMethodSet();
60097 $testDoubleClassPrefix = $mockObject ? 'MockObject_' : 'TestStub_';
60098 $_mockClassName = $this->generateClassName($type, $mockClassName, $testDoubleClassPrefix);
60099 if (class_exists($_mockClassName['fullClassName'], $callAutoload)) {
60100 $isClass = \true;
60101 } elseif (interface_exists($_mockClassName['fullClassName'], $callAutoload)) {
60102 $isInterface = \true;
60103 }
60104 if (!$isClass && !$isInterface) {
60105 $prologue = 'class ' . $_mockClassName['originalClassName'] . "\n{\n}\n\n";
60106 if (!empty($_mockClassName['namespaceName'])) {
60107 $prologue = 'namespace ' . $_mockClassName['namespaceName'] . " {\n\n" . $prologue . "}\n\n" . "namespace {\n\n";
60108 $epilogue = "\n\n}";
60109 }
60110 $doubledCloneMethod = \true;
60111 } else {
60112 $class = $this->reflectClass($_mockClassName['fullClassName']);
60113 if ($class->isEnum()) {
60114 throw new \PHPUnit\Framework\MockObject\Generator\ClassIsEnumerationException($_mockClassName['fullClassName']);
60115 }
60116 if ($class->isFinal()) {
60117 throw new \PHPUnit\Framework\MockObject\Generator\ClassIsFinalException($_mockClassName['fullClassName']);
60118 }
60119 if (method_exists($class, 'isReadOnly') && $class->isReadOnly()) {
60120 throw new \PHPUnit\Framework\MockObject\Generator\ClassIsReadonlyException($_mockClassName['fullClassName']);
60121 }
60122 // @see https://github.com/sebastianbergmann/phpunit/issues/2995
60123 if ($isInterface && $class->implementsInterface(Throwable::class)) {
60124 $actualClassName = Exception::class;
60125 $additionalInterfaces[] = $class->getName();
60126 $isInterface = \false;
60127 $class = $this->reflectClass($actualClassName);
60128 foreach ($this->userDefinedInterfaceMethods($_mockClassName['fullClassName']) as $method) {
60129 $methodName = $method->getName();
60130 if ($class->hasMethod($methodName)) {
60131 $classMethod = $class->getMethod($methodName);
60132 if (!$this->canMethodBeDoubled($classMethod)) {
60133 continue;
60134 }
60135 }
60136 $mockMethods->addMethods(\PHPUnit\Framework\MockObject\Generator\MockMethod::fromReflection($method, $callOriginalMethods, $cloneArguments));
60137 }
60138 $_mockClassName = $this->generateClassName($actualClassName, $_mockClassName['className'], $testDoubleClassPrefix);
60139 }
60140 // @see https://github.com/sebastianbergmann/phpunit-mock-objects/issues/103
60141 if ($isInterface && $class->implementsInterface(Traversable::class) && !$class->implementsInterface(Iterator::class) && !$class->implementsInterface(IteratorAggregate::class)) {
60142 $additionalInterfaces[] = Iterator::class;
60143 $mockMethods->addMethods(...$this->mockClassMethods(Iterator::class, $callOriginalMethods, $cloneArguments));
60144 }
60145 if ($class->hasMethod('__clone')) {
60146 $cloneMethod = $class->getMethod('__clone');
60147 if (!$cloneMethod->isFinal()) {
60148 if ($callOriginalClone && !$isInterface) {
60149 $proxiedCloneMethod = \true;
60150 } else {
60151 $doubledCloneMethod = \true;
60152 }
60153 }
60154 } else {
60155 $doubledCloneMethod = \true;
60156 }
60157 }
60158 if ($isClass && $explicitMethods === []) {
60159 $mockMethods->addMethods(...$this->mockClassMethods($_mockClassName['fullClassName'], $callOriginalMethods, $cloneArguments));
60160 }
60161 if ($isInterface && ($explicitMethods === [] || $explicitMethods === null)) {
60162 $mockMethods->addMethods(...$this->interfaceMethods($_mockClassName['fullClassName'], $cloneArguments));
60163 }
60164 if (is_array($explicitMethods)) {
60165 foreach ($explicitMethods as $methodName) {
60166 if ($class !== null && $class->hasMethod($methodName)) {
60167 $method = $class->getMethod($methodName);
60168 if ($this->canMethodBeDoubled($method)) {
60169 $mockMethods->addMethods(\PHPUnit\Framework\MockObject\Generator\MockMethod::fromReflection($method, $callOriginalMethods, $cloneArguments));
60170 }
60171 } else {
60172 $mockMethods->addMethods(\PHPUnit\Framework\MockObject\Generator\MockMethod::fromName($_mockClassName['fullClassName'], $methodName, $cloneArguments));
60173 }
60174 }
60175 }
60176 $mockedMethods = '';
60177 $configurable = [];
60178 foreach ($mockMethods->asArray() as $mockMethod) {
60179 $mockedMethods .= $mockMethod->generateCode();
60180 $configurable[] = new ConfigurableMethod($mockMethod->methodName(), $mockMethod->defaultParameterValues(), $mockMethod->numberOfParameters(), $mockMethod->returnType());
60181 }
60182 /** @psalm-var trait-string[] $traits */
60183 $traits = [StubApi::class];
60184 if ($mockObject) {
60185 $traits[] = MockObjectApi::class;
60186 }
60187 if (!$mockMethods->hasMethod('method') && (!isset($class) || !$class->hasMethod('method'))) {
60188 $traits[] = Method::class;
60189 }
60190 if ($doubledCloneMethod) {
60191 $traits[] = DoubledCloneMethod::class;
60192 }
60193 if ($proxiedCloneMethod) {
60194 $traits[] = ProxiedCloneMethod::class;
60195 }
60196 $useStatements = '';
60197 foreach ($traits as $trait) {
60198 $useStatements .= sprintf(' use %s;' . PHP_EOL, $trait);
60199 }
60200 unset($traits);
60201 $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]);
60202 return new \PHPUnit\Framework\MockObject\Generator\MockClass($classTemplate->render(), $_mockClassName['className'], $configurable);
60203 }
60204 private function generateClassName(string $type, string $className, string $prefix): array
60205 {
60206 if ($type[0] === '\\') {
60207 $type = substr($type, 1);
60208 }
60209 $classNameParts = explode('\\', $type);
60210 if (count($classNameParts) > 1) {
60211 $type = array_pop($classNameParts);
60212 $namespaceName = implode('\\', $classNameParts);
60213 $fullClassName = $namespaceName . '\\' . $type;
60214 } else {
60215 $namespaceName = '';
60216 $fullClassName = $type;
60217 }
60218 if ($className === '') {
60219 do {
60220 $className = $prefix . $type . '_' . substr(md5((string) mt_rand()), 0, 8);
60221 } while (class_exists($className, \false));
60222 }
60223 return ['className' => $className, 'originalClassName' => $type, 'fullClassName' => $fullClassName, 'namespaceName' => $namespaceName];
60224 }
60225 private function generateTestDoubleClassDeclaration(bool $mockObject, array $mockClassName, bool $isInterface, array $additionalInterfaces = []): string
60226 {
60227 if ($mockObject) {
60228 $additionalInterfaces[] = MockObjectInternal::class;
60229 } else {
60230 $additionalInterfaces[] = StubInternal::class;
60231 }
60232 $buffer = 'class ';
60233 $interfaces = implode(', ', $additionalInterfaces);
60234 if ($isInterface) {
60235 $buffer .= sprintf('%s implements %s', $mockClassName['className'], $interfaces);
60236 if (!in_array($mockClassName['originalClassName'], $additionalInterfaces, \true)) {
60237 $buffer .= ', ';
60238 if (!empty($mockClassName['namespaceName'])) {
60239 $buffer .= $mockClassName['namespaceName'] . '\\';
60240 }
60241 $buffer .= $mockClassName['originalClassName'];
60242 }
60243 } else {
60244 $buffer .= sprintf('%s extends %s%s implements %s', $mockClassName['className'], !empty($mockClassName['namespaceName']) ? $mockClassName['namespaceName'] . '\\' : '', $mockClassName['originalClassName'], $interfaces);
60245 }
60246 return $buffer;
60247 }
60248 private function canMethodBeDoubled(ReflectionMethod $method): bool
60249 {
60250 if ($method->isConstructor()) {
60251 return \false;
60252 }
60253 if ($method->isDestructor()) {
60254 return \false;
60255 }
60256 if ($method->isFinal()) {
60257 return \false;
60258 }
60259 if ($method->isPrivate()) {
60260 return \false;
60261 }
60262 return !$this->isMethodNameExcluded($method->getName());
60263 }
60264 private function isMethodNameExcluded(string $name): bool
60265 {
60266 if (self::$excludedMethodNames === []) {
60267 self::$excludedMethodNames = ['__CLASS__' => \true, '__DIR__' => \true, '__FILE__' => \true, '__FUNCTION__' => \true, '__LINE__' => \true, '__METHOD__' => \true, '__NAMESPACE__' => \true, '__TRAIT__' => \true, '__clone' => \true, '__halt_compiler' => \true];
60268 if (version_compare(PHP_VERSION, '8.5', '>=')) {
60269 self::$excludedMethodNames['__sleep'] = \true;
60270 self::$excludedMethodNames['__wakeup'] = \true;
60271 }
60272 }
60273 return isset(self::$excludedMethodNames[$name]);
60274 }
60275 /**
60276 * @throws UnknownTypeException
60277 */
60278 private function ensureKnownType(string $type, bool $callAutoload): void
60279 {
60280 if (!class_exists($type, $callAutoload) && !interface_exists($type, $callAutoload)) {
60281 throw new \PHPUnit\Framework\MockObject\Generator\UnknownTypeException($type);
60282 }
60283 }
60284 /**
60285 * @throws DuplicateMethodException
60286 * @throws InvalidMethodNameException
60287 */
60288 private function ensureValidMethods(?array $methods): void
60289 {
60290 if ($methods === null) {
60291 return;
60292 }
60293 foreach ($methods as $method) {
60294 if (!preg_match('~[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*~', (string) $method)) {
60295 throw new \PHPUnit\Framework\MockObject\Generator\InvalidMethodNameException((string) $method);
60296 }
60297 }
60298 if ($methods !== array_unique($methods)) {
60299 throw new \PHPUnit\Framework\MockObject\Generator\DuplicateMethodException($methods);
60300 }
60301 }
60302 /**
60303 * @throws NameAlreadyInUseException
60304 * @throws ReflectionException
60305 */
60306 private function ensureNameForTestDoubleClassIsAvailable(string $className): void
60307 {
60308 if ($className === '') {
60309 return;
60310 }
60311 if (class_exists($className, \false) || interface_exists($className, \false) || trait_exists($className, \false)) {
60312 throw new \PHPUnit\Framework\MockObject\Generator\NameAlreadyInUseException($className);
60313 }
60314 }
60315 /**
60316 * @psalm-param class-string $className
60317 *
60318 * @throws ReflectionException
60319 */
60320 private function instantiate(string $className, bool $callOriginalConstructor, array $arguments): object
60321 {
60322 if ($callOriginalConstructor) {
60323 if (count($arguments) === 0) {
60324 return new $className();
60325 }
60326 try {
60327 return (new ReflectionClass($className))->newInstanceArgs($arguments);
60328 // @codeCoverageIgnoreStart
60329 } catch (\ReflectionException $e) {
60330 throw new \PHPUnit\Framework\MockObject\Generator\ReflectionException($e->getMessage(), $e->getCode(), $e);
60331 }
60332 // @codeCoverageIgnoreEnd
60333 }
60334 try {
60335 return (new ReflectionClass($className))->newInstanceWithoutConstructor();
60336 // @codeCoverageIgnoreStart
60337 } catch (\ReflectionException $e) {
60338 throw new \PHPUnit\Framework\MockObject\Generator\ReflectionException($e->getMessage(), $e->getCode(), $e);
60339 // @codeCoverageIgnoreEnd
60340 }
60341 }
60342 /**
60343 * @psalm-param class-string $type
60344 *
60345 * @throws ReflectionException
60346 */
60347 private function instantiateProxyTarget(?object $proxyTarget, object $object, string $type, array $arguments): void
60348 {
60349 if (!is_object($proxyTarget)) {
60350 assert(class_exists($type));
60351 if (count($arguments) === 0) {
60352 $proxyTarget = new $type();
60353 } else {
60354 $class = new ReflectionClass($type);
60355 try {
60356 $proxyTarget = $class->newInstanceArgs($arguments);
60357 // @codeCoverageIgnoreStart
60358 } catch (\ReflectionException $e) {
60359 throw new \PHPUnit\Framework\MockObject\Generator\ReflectionException($e->getMessage(), $e->getCode(), $e);
60360 }
60361 // @codeCoverageIgnoreEnd
60362 }
60363 }
60364 $object->__phpunit_setOriginalObject($proxyTarget);
60365 }
60366 /**
60367 * @psalm-param class-string $className
60368 *
60369 * @throws ReflectionException
60370 */
60371 private function reflectClass(string $className): ReflectionClass
60372 {
60373 try {
60374 $class = new ReflectionClass($className);
60375 // @codeCoverageIgnoreStart
60376 } catch (\ReflectionException $e) {
60377 throw new \PHPUnit\Framework\MockObject\Generator\ReflectionException($e->getMessage(), $e->getCode(), $e);
60378 }
60379 // @codeCoverageIgnoreEnd
60380 return $class;
60381 }
60382 /**
60383 * @psalm-param class-string $classOrInterfaceName
60384 *
60385 * @throws ReflectionException
60386 *
60387 * @psalm-return list<string>
60388 */
60389 private function namesOfMethodsIn(string $classOrInterfaceName): array
60390 {
60391 $class = $this->reflectClass($classOrInterfaceName);
60392 $methods = [];
60393 foreach ($class->getMethods() as $method) {
60394 if ($method->isPublic() || $method->isAbstract()) {
60395 $methods[] = $method->getName();
60396 }
60397 }
60398 return $methods;
60399 }
60400 /**
60401 * @psalm-param class-string $interfaceName
60402 *
60403 * @throws ReflectionException
60404 *
60405 * @psalm-return list<MockMethod>
60406 */
60407 private function interfaceMethods(string $interfaceName, bool $cloneArguments): array
60408 {
60409 $class = $this->reflectClass($interfaceName);
60410 $methods = [];
60411 foreach ($class->getMethods() as $method) {
60412 $methods[] = \PHPUnit\Framework\MockObject\Generator\MockMethod::fromReflection($method, \false, $cloneArguments);
60413 }
60414 return $methods;
60415 }
60416 }
60417 <?php
60418
60419 declare (strict_types=1);
60420 /*
60421 * This file is part of PHPUnit.
60422 *
60423 * (c) Sebastian Bergmann <sebastian@phpunit.de>
60424 *
60425 * For the full copyright and license information, please view the LICENSE
60426 * file that was distributed with this source code.
60427 */
60428 namespace PHPUnit\Framework\MockObject\Generator;
60429
60430 use function call_user_func;
60431 use function class_exists;
60432 use PHPUnit\Framework\MockObject\ConfigurableMethod;
60433 /**
60434 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
60435 *
60436 * @internal This class is not covered by the backward compatibility promise for PHPUnit
60437 */
60438 final class MockClass implements \PHPUnit\Framework\MockObject\Generator\MockType
60439 {
60440 private readonly string $classCode;
60441 /**
60442 * @psalm-var class-string
60443 */
60444 private readonly string $mockName;
60445 /**
60446 * @psalm-var list<ConfigurableMethod>
60447 */
60448 private readonly array $configurableMethods;
60449 /**
60450 * @psalm-param class-string $mockName
60451 * @psalm-param list<ConfigurableMethod> $configurableMethods
60452 */
60453 public function __construct(string $classCode, string $mockName, array $configurableMethods)
60454 {
60455 $this->classCode = $classCode;
60456 $this->mockName = $mockName;
60457 $this->configurableMethods = $configurableMethods;
60458 }
60459 /**
60460 * @psalm-return class-string
60461 */
60462 public function generate(): string
60463 {
60464 if (!class_exists($this->mockName, \false)) {
60465 eval($this->classCode);
60466 call_user_func([$this->mockName, '__phpunit_initConfigurableMethods'], ...$this->configurableMethods);
60467 }
60468 return $this->mockName;
60469 }
60470 public function classCode(): string
60471 {
60472 return $this->classCode;
60473 }
60474 }
60475 <?php
60476
60477 declare (strict_types=1);
60478 /*
60479 * This file is part of PHPUnit.
60480 *
60481 * (c) Sebastian Bergmann <sebastian@phpunit.de>
60482 *
60483 * For the full copyright and license information, please view the LICENSE
60484 * file that was distributed with this source code.
60485 */
60486 namespace PHPUnit\Framework\MockObject\Generator;
60487
60488 use function count;
60489 use function explode;
60490 use function implode;
60491 use function is_object;
60492 use function is_string;
60493 use function preg_match;
60494 use function preg_replace;
60495 use function sprintf;
60496 use function str_contains;
60497 use function strlen;
60498 use function strpos;
60499 use function substr;
60500 use function substr_count;
60501 use function trim;
60502 use function var_export;
60503 use ReflectionMethod;
60504 use ReflectionParameter;
60505 use PHPUnitPHAR\SebastianBergmann\Type\ReflectionMapper;
60506 use PHPUnitPHAR\SebastianBergmann\Type\Type;
60507 use PHPUnitPHAR\SebastianBergmann\Type\UnknownType;
60508 /**
60509 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
60510 *
60511 * @internal This class is not covered by the backward compatibility promise for PHPUnit
60512 */
60513 final class MockMethod
60514 {
60515 use \PHPUnit\Framework\MockObject\Generator\TemplateLoader;
60516 /**
60517 * @psalm-var class-string
60518 */
60519 private readonly string $className;
60520 /**
60521 * @psalm-var non-empty-string
60522 */
60523 private readonly string $methodName;
60524 private readonly bool $cloneArguments;
60525 private readonly string $modifier;
60526 private readonly string $argumentsForDeclaration;
60527 private readonly string $argumentsForCall;
60528 private readonly Type $returnType;
60529 private readonly string $reference;
60530 private readonly bool $callOriginalMethod;
60531 private readonly bool $static;
60532 private readonly ?string $deprecation;
60533 /**
60534 * @psalm-var array<int, mixed>
60535 */
60536 private readonly array $defaultParameterValues;
60537 /**
60538 * @psalm-var non-negative-int
60539 */
60540 private readonly int $numberOfParameters;
60541 /**
60542 * @throws ReflectionException
60543 * @throws RuntimeException
60544 */
60545 public static function fromReflection(ReflectionMethod $method, bool $callOriginalMethod, bool $cloneArguments): self
60546 {
60547 if ($method->isPrivate()) {
60548 $modifier = 'private';
60549 } elseif ($method->isProtected()) {
60550 $modifier = 'protected';
60551 } else {
60552 $modifier = 'public';
60553 }
60554 if ($method->isStatic()) {
60555 $modifier .= ' static';
60556 }
60557 if ($method->returnsReference()) {
60558 $reference = '&';
60559 } else {
60560 $reference = '';
60561 }
60562 $docComment = $method->getDocComment();
60563 if (is_string($docComment) && preg_match('#\*[ \t]*+@deprecated[ \t]*+(.*?)\r?+\n[ \t]*+\*(?:[ \t]*+@|/$)#s', $docComment, $deprecation)) {
60564 $deprecation = trim(preg_replace('#[ \t]*\r?\n[ \t]*+\*[ \t]*+#', ' ', $deprecation[1]));
60565 } else {
60566 $deprecation = null;
60567 }
60568 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);
60569 }
60570 /**
60571 * @param class-string $className
60572 * @param non-empty-string $methodName
60573 */
60574 public static function fromName(string $className, string $methodName, bool $cloneArguments): self
60575 {
60576 return new self($className, $methodName, $cloneArguments, 'public', '', '', [], 0, new UnknownType(), '', \false, \false, null);
60577 }
60578 /**
60579 * @psalm-param class-string $className
60580 * @psalm-param non-empty-string $methodName
60581 * @psalm-param array<int, mixed> $defaultParameterValues
60582 * @psalm-param non-negative-int $numberOfParameters
60583 */
60584 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)
60585 {
60586 $this->className = $className;
60587 $this->methodName = $methodName;
60588 $this->cloneArguments = $cloneArguments;
60589 $this->modifier = $modifier;
60590 $this->argumentsForDeclaration = $argumentsForDeclaration;
60591 $this->argumentsForCall = $argumentsForCall;
60592 $this->defaultParameterValues = $defaultParameterValues;
60593 $this->numberOfParameters = $numberOfParameters;
60594 $this->returnType = $returnType;
60595 $this->reference = $reference;
60596 $this->callOriginalMethod = $callOriginalMethod;
60597 $this->static = $static;
60598 $this->deprecation = $deprecation;
60599 }
60600 /**
60601 * @psalm-return non-empty-string
60602 */
60603 public function methodName(): string
60604 {
60605 return $this->methodName;
60606 }
60607 /**
60608 * @throws RuntimeException
60609 */
60610 public function generateCode(): string
60611 {
60612 if ($this->static) {
60613 $templateFile = 'doubled_static_method.tpl';
60614 } else {
60615 $templateFile = sprintf('%s_method.tpl', $this->callOriginalMethod ? 'proxied' : 'doubled');
60616 }
60617 $deprecation = $this->deprecation;
60618 $returnResult = '';
60619 if (!$this->returnType->isNever() && !$this->returnType->isVoid()) {
60620 $returnResult = <<<'EOT'
60621
60622
60623 return $__phpunit_result;
60624 EOT;
60625 }
60626 if (null !== $this->deprecation) {
60627 $deprecation = "The {$this->className}::{$this->methodName} method is deprecated ({$this->deprecation}).";
60628 $deprecationTemplate = $this->loadTemplate('deprecation.tpl');
60629 $deprecationTemplate->setVar(['deprecation' => var_export($deprecation, \true)]);
60630 $deprecation = $deprecationTemplate->render();
60631 }
60632 $template = $this->loadTemplate($templateFile);
60633 $argumentsCount = 0;
60634 if (str_contains($this->argumentsForCall, '...')) {
60635 $argumentsCount = null;
60636 } elseif (!empty($this->argumentsForCall)) {
60637 $argumentsCount = substr_count($this->argumentsForCall, ',') + 1;
60638 }
60639 $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' => $argumentsCount, '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]);
60640 return $template->render();
60641 }
60642 public function returnType(): Type
60643 {
60644 return $this->returnType;
60645 }
60646 /**
60647 * @psalm-return array<int, mixed>
60648 */
60649 public function defaultParameterValues(): array
60650 {
60651 return $this->defaultParameterValues;
60652 }
60653 /**
60654 * @psalm-return non-negative-int
60655 */
60656 public function numberOfParameters(): int
60657 {
60658 return $this->numberOfParameters;
60659 }
60660 /**
60661 * Returns the parameters of a function or method.
60662 *
60663 * @throws RuntimeException
60664 */
60665 private static function methodParametersForDeclaration(ReflectionMethod $method): string
60666 {
60667 $parameters = [];
60668 $types = (new ReflectionMapper())->fromParameterTypes($method);
60669 foreach ($method->getParameters() as $i => $parameter) {
60670 $name = '$' . $parameter->getName();
60671 /* Note: PHP extensions may use empty names for reference arguments
60672 * or "..." for methods taking a variable number of arguments.
60673 */
60674 if ($name === '$' || $name === '$...') {
60675 $name = '$arg' . $i;
60676 }
60677 $default = '';
60678 $reference = '';
60679 $typeDeclaration = '';
60680 if (!$types[$i]->type()->isUnknown()) {
60681 $typeDeclaration = $types[$i]->type()->asString() . ' ';
60682 }
60683 if ($parameter->isPassedByReference()) {
60684 $reference = '&';
60685 }
60686 if ($parameter->isVariadic()) {
60687 $name = '...' . $name;
60688 } elseif ($parameter->isDefaultValueAvailable()) {
60689 $default = ' = ' . self::exportDefaultValue($parameter);
60690 } elseif ($parameter->isOptional()) {
60691 $default = ' = null';
60692 }
60693 $parameters[] = $typeDeclaration . $reference . $name . $default;
60694 }
60695 return implode(', ', $parameters);
60696 }
60697 /**
60698 * Returns the parameters of a function or method.
60699 *
60700 * @throws ReflectionException
60701 */
60702 private static function methodParametersForCall(ReflectionMethod $method): string
60703 {
60704 $parameters = [];
60705 foreach ($method->getParameters() as $i => $parameter) {
60706 $name = '$' . $parameter->getName();
60707 /* Note: PHP extensions may use empty names for reference arguments
60708 * or "..." for methods taking a variable number of arguments.
60709 */
60710 if ($name === '$' || $name === '$...') {
60711 $name = '$arg' . $i;
60712 }
60713 if ($parameter->isVariadic()) {
60714 continue;
60715 }
60716 if ($parameter->isPassedByReference()) {
60717 $parameters[] = '&' . $name;
60718 } else {
60719 $parameters[] = $name;
60720 }
60721 }
60722 return implode(', ', $parameters);
60723 }
60724 /**
60725 * @throws ReflectionException
60726 */
60727 private static function exportDefaultValue(ReflectionParameter $parameter): string
60728 {
60729 try {
60730 $defaultValue = $parameter->getDefaultValue();
60731 if (!is_object($defaultValue)) {
60732 return var_export($defaultValue, \true);
60733 }
60734 $parameterAsString = $parameter->__toString();
60735 return explode(' = ', substr(substr($parameterAsString, strpos($parameterAsString, '<optional> ') + strlen('<optional> ')), 0, -2))[1];
60736 // @codeCoverageIgnoreStart
60737 } catch (\ReflectionException $e) {
60738 throw new \PHPUnit\Framework\MockObject\Generator\ReflectionException($e->getMessage(), $e->getCode(), $e);
60739 }
60740 // @codeCoverageIgnoreEnd
60741 }
60742 /**
60743 * @psalm-return array<int, mixed>
60744 */
60745 private static function methodParametersDefaultValues(ReflectionMethod $method): array
60746 {
60747 $result = [];
60748 foreach ($method->getParameters() as $i => $parameter) {
60749 if (!$parameter->isDefaultValueAvailable()) {
60750 continue;
60751 }
60752 $result[$i] = $parameter->getDefaultValue();
60753 }
60754 return $result;
60755 }
60756 }
60757 <?php
60758
60759 declare (strict_types=1);
60760 /*
60761 * This file is part of PHPUnit.
60762 *
60763 * (c) Sebastian Bergmann <sebastian@phpunit.de>
60764 *
60765 * For the full copyright and license information, please view the LICENSE
60766 * file that was distributed with this source code.
60767 */
60768 namespace PHPUnit\Framework\MockObject\Generator;
60769
60770 use function array_key_exists;
60771 use function array_values;
60772 use function strtolower;
60773 /**
60774 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
60775 *
60776 * @internal This class is not covered by the backward compatibility promise for PHPUnit
60777 */
60778 final class MockMethodSet
60779 {
60780 /**
60781 * @psalm-var array<string,MockMethod>
60782 */
60783 private array $methods = [];
60784 public function addMethods(\PHPUnit\Framework\MockObject\Generator\MockMethod ...$methods): void
60785 {
60786 foreach ($methods as $method) {
60787 $this->methods[strtolower($method->methodName())] = $method;
60788 }
60789 }
60790 /**
60791 * @psalm-return list<MockMethod>
60792 */
60793 public function asArray(): array
60794 {
60795 return array_values($this->methods);
60796 }
60797 public function hasMethod(string $methodName): bool
60798 {
60799 return array_key_exists(strtolower($methodName), $this->methods);
60800 }
60801 }
60802 <?php
60803
60804 declare (strict_types=1);
60805 /*
60806 * This file is part of PHPUnit.
60807 *
60808 * (c) Sebastian Bergmann <sebastian@phpunit.de>
60809 *
60810 * For the full copyright and license information, please view the LICENSE
60811 * file that was distributed with this source code.
60812 */
60813 namespace PHPUnit\Framework\MockObject\Generator;
60814
60815 use function class_exists;
60816 /**
60817 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
60818 *
60819 * @internal This class is not covered by the backward compatibility promise for PHPUnit
60820 *
60821 * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5243
60822 */
60823 final class MockTrait implements \PHPUnit\Framework\MockObject\Generator\MockType
60824 {
60825 private readonly string $classCode;
60826 /**
60827 * @psalm-var class-string
60828 */
60829 private readonly string $mockName;
60830 /**
60831 * @psalm-param class-string $mockName
60832 */
60833 public function __construct(string $classCode, string $mockName)
60834 {
60835 $this->classCode = $classCode;
60836 $this->mockName = $mockName;
60837 }
60838 /**
60839 * @psalm-return class-string
60840 */
60841 public function generate(): string
60842 {
60843 if (!class_exists($this->mockName, \false)) {
60844 eval($this->classCode);
60845 }
60846 return $this->mockName;
60847 }
60848 }
60849 <?php
60850
60851 declare (strict_types=1);
60852 /*
60853 * This file is part of PHPUnit.
60854 *
60855 * (c) Sebastian Bergmann <sebastian@phpunit.de>
60856 *
60857 * For the full copyright and license information, please view the LICENSE
60858 * file that was distributed with this source code.
60859 */
60860 namespace PHPUnit\Framework\MockObject\Generator;
60861
60862 /**
60863 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
60864 *
60865 * @internal This interface is not covered by the backward compatibility promise for PHPUnit
60866 */
60867 interface MockType
60868 {
60869 /**
60870 * @psalm-return class-string
60871 */
60872 public function generate(): string;
60873 }
60874 <?php
60875
60876 declare (strict_types=1);
60877 /*
60878 * This file is part of PHPUnit.
60879 *
60880 * (c) Sebastian Bergmann <sebastian@phpunit.de>
60881 *
60882 * For the full copyright and license information, please view the LICENSE
60883 * file that was distributed with this source code.
60884 */
60885 namespace PHPUnit\Framework\MockObject\Generator;
60886
60887 use PHPUnitPHAR\SebastianBergmann\Template\Template;
60888 /**
60889 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
60890 *
60891 * @internal This trait is not covered by the backward compatibility promise for PHPUnit
60892 */
60893 trait TemplateLoader
60894 {
60895 /**
60896 * @psalm-var array<string,Template>
60897 */
60898 private static array $templates = [];
60899 /**
60900 * @psalm-suppress MissingThrowsDocblock
60901 */
60902 private function loadTemplate(string $template): Template
60903 {
60904 $filename = __DIR__ . '/templates/' . $template;
60905 if (!isset(self::$templates[$filename])) {
60906 self::$templates[$filename] = new Template($filename);
60907 }
60908 return self::$templates[$filename];
60909 }
60910 }
60911
60912 @trigger_error({deprecation}, E_USER_DEPRECATED);
60913
60914 {modifier} function {reference}{method_name}({arguments_decl}){return_declaration}
60915 {{deprecation}
60916 $__phpunit_definedVariables = get_defined_vars();
60917 $__phpunit_namedVariadicParameters = [];
60918
60919 foreach ($__phpunit_definedVariables as $__phpunit_definedVariableName => $__phpunit_definedVariableValue) {
60920 if ((new ReflectionParameter([__CLASS__, __FUNCTION__], $__phpunit_definedVariableName))->isVariadic()) {
60921 foreach ($__phpunit_definedVariableValue as $__phpunit_key => $__phpunit_namedValue) {
60922 if (is_string($__phpunit_key)) {
60923 $__phpunit_namedVariadicParameters[$__phpunit_key] = $__phpunit_namedValue;
60924 }
60925 }
60926 }
60927 }
60928
60929 $__phpunit_arguments = [{arguments_call}];
60930 $__phpunit_count = func_num_args();
60931
60932 if ({arguments_count} !== null && $__phpunit_count > {arguments_count}) {
60933 $__phpunit_arguments_tmp = func_get_args();
60934
60935 for ($__phpunit_i = {arguments_count}; $__phpunit_i < $__phpunit_count; $__phpunit_i++) {
60936 $__phpunit_arguments[] = $__phpunit_arguments_tmp[$__phpunit_i];
60937 }
60938 }
60939
60940 $__phpunit_arguments = array_merge($__phpunit_arguments, $__phpunit_namedVariadicParameters);
60941
60942 $__phpunit_result = $this->__phpunit_getInvocationHandler()->invoke(
60943 new \PHPUnit\Framework\MockObject\Invocation(
60944 '{class_name}', '{method_name}', $__phpunit_arguments, '{return_type}', $this, {clone_arguments}
60945 )
60946 );{return_result}
60947 }
60948
60949 {modifier} function {reference}{method_name}({arguments_decl}){return_declaration}
60950 {
60951 throw new \PHPUnit\Framework\MockObject\BadMethodCallException('Static method "{method_name}" cannot be invoked on mock object');
60952 }
60953 declare(strict_types=1);
60954
60955 interface {intersection} extends {interfaces}
60956 {
60957 }
60958
60959 {modifier} function {reference}{method_name}({arguments_decl}){return_declaration}
60960 {
60961 $__phpunit_definedVariables = get_defined_vars();
60962 $__phpunit_namedVariadicParameters = [];
60963
60964 foreach ($__phpunit_definedVariables as $__phpunit_definedVariableName => $__phpunit_definedVariableValue) {
60965 if ((new ReflectionParameter([__CLASS__, __FUNCTION__], $__phpunit_definedVariableName))->isVariadic()) {
60966 foreach ($__phpunit_definedVariableValue as $__phpunit_key => $__phpunit_namedValue) {
60967 if (is_string($__phpunit_key)) {
60968 $__phpunit_namedVariadicParameters[$__phpunit_key] = $__phpunit_namedValue;
60969 }
60970 }
60971 }
60972 }
60973
60974 $__phpunit_arguments = [{arguments_call}];
60975 $__phpunit_count = func_num_args();
60976
60977 if ($__phpunit_count > {arguments_count}) {
60978 $__phpunit_arguments_tmp = func_get_args();
60979
60980 for ($__phpunit_i = {arguments_count}; $__phpunit_i < $__phpunit_count; $__phpunit_i++) {
60981 $__phpunit_arguments[] = $__phpunit_arguments_tmp[$__phpunit_i];
60982 }
60983 }
60984
60985 $__phpunit_arguments = array_merge($__phpunit_arguments, $__phpunit_namedVariadicParameters);
60986
60987 $this->__phpunit_getInvocationHandler()->invoke(
60988 new \PHPUnit\Framework\MockObject\Invocation(
60989 '{class_name}', '{method_name}', $__phpunit_arguments, '{return_type}', $this, {clone_arguments}, true
60990 )
60991 );
60992
60993 $__phpunit_result = call_user_func_array([$this->__phpunit_originalObject, "{method_name}"], $__phpunit_arguments);{return_result}
60994 }
60995 declare(strict_types=1);
60996
60997 {prologue}{class_declaration}
60998 {
60999 {use_statements}{mocked_methods}}{epilogue}
61000 declare(strict_types=1);
61001
61002 {prologue}class {class_name}
61003 {
61004 use {trait_name};
61005 }
61006 declare(strict_types=1);
61007
61008 {namespace}class {class_name} extends \SoapClient
61009 {
61010 public function __construct($wsdl, array $options)
61011 {
61012 parent::__construct('{wsdl}', $options);
61013 }
61014 {methods}}
61015
61016 public function {method_name}({arguments})
61017 {
61018 }
61019 <?php
61020
61021 declare (strict_types=1);
61022 /*
61023 * This file is part of PHPUnit.
61024 *
61025 * (c) Sebastian Bergmann <sebastian@phpunit.de>
61026 *
61027 * For the full copyright and license information, please view the LICENSE
61028 * file that was distributed with this source code.
61029 */
61030 namespace PHPUnit\Framework\MockObject;
61031
61032 use function array_merge;
61033 use function assert;
61034 use function trait_exists;
61035 use PHPUnit\Framework\Exception;
61036 use PHPUnit\Framework\InvalidArgumentException;
61037 use PHPUnit\Framework\MockObject\Generator\CannotUseAddMethodsException;
61038 use PHPUnit\Framework\MockObject\Generator\ClassIsEnumerationException;
61039 use PHPUnit\Framework\MockObject\Generator\ClassIsFinalException;
61040 use PHPUnit\Framework\MockObject\Generator\ClassIsReadonlyException;
61041 use PHPUnit\Framework\MockObject\Generator\DuplicateMethodException;
61042 use PHPUnit\Framework\MockObject\Generator\Generator;
61043 use PHPUnit\Framework\MockObject\Generator\InvalidMethodNameException;
61044 use PHPUnit\Framework\MockObject\Generator\NameAlreadyInUseException;
61045 use PHPUnit\Framework\MockObject\Generator\OriginalConstructorInvocationRequiredException;
61046 use PHPUnit\Framework\MockObject\Generator\ReflectionException;
61047 use PHPUnit\Framework\MockObject\Generator\RuntimeException;
61048 use PHPUnit\Framework\MockObject\Generator\UnknownTypeException;
61049 use PHPUnit\Framework\TestCase;
61050 use ReflectionClass;
61051 /**
61052 * @psalm-template MockedType
61053 *
61054 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
61055 */
61056 final class MockBuilder
61057 {
61058 private readonly TestCase $testCase;
61059 /**
61060 * @psalm-var class-string|trait-string
61061 */
61062 private readonly string $type;
61063 /**
61064 * @psalm-var list<non-empty-string>
61065 */
61066 private array $methods = [];
61067 private bool $emptyMethodsArray = \false;
61068 /**
61069 * @psalm-var ?class-string
61070 */
61071 private ?string $mockClassName = null;
61072 private array $constructorArgs = [];
61073 private bool $originalConstructor = \true;
61074 private bool $originalClone = \true;
61075 private bool $autoload = \true;
61076 private bool $cloneArguments = \false;
61077 private bool $callOriginalMethods = \false;
61078 private ?object $proxyTarget = null;
61079 private bool $allowMockingUnknownTypes = \true;
61080 private bool $returnValueGeneration = \true;
61081 private readonly Generator $generator;
61082 /**
61083 * @psalm-param class-string|trait-string $type
61084 */
61085 public function __construct(TestCase $testCase, string $type)
61086 {
61087 $this->testCase = $testCase;
61088 $this->type = $type;
61089 $this->generator = new Generator();
61090 }
61091 /**
61092 * Creates a mock object using a fluent interface.
61093 *
61094 * @throws ClassIsEnumerationException
61095 * @throws ClassIsFinalException
61096 * @throws ClassIsReadonlyException
61097 * @throws DuplicateMethodException
61098 * @throws InvalidArgumentException
61099 * @throws InvalidMethodNameException
61100 * @throws NameAlreadyInUseException
61101 * @throws OriginalConstructorInvocationRequiredException
61102 * @throws ReflectionException
61103 * @throws RuntimeException
61104 * @throws UnknownTypeException
61105 *
61106 * @psalm-return MockObject&MockedType
61107 */
61108 public function getMock(): \PHPUnit\Framework\MockObject\MockObject
61109 {
61110 $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);
61111 assert($object instanceof $this->type);
61112 assert($object instanceof \PHPUnit\Framework\MockObject\MockObject);
61113 $this->testCase->registerMockObject($object);
61114 return $object;
61115 }
61116 /**
61117 * Creates a mock object for an abstract class using a fluent interface.
61118 *
61119 * @throws Exception
61120 * @throws ReflectionException
61121 * @throws RuntimeException
61122 *
61123 * @psalm-return MockObject&MockedType
61124 *
61125 * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5305
61126 */
61127 public function getMockForAbstractClass(): \PHPUnit\Framework\MockObject\MockObject
61128 {
61129 $object = $this->generator->mockObjectForAbstractClass($this->type, $this->constructorArgs, $this->mockClassName ?? '', $this->originalConstructor, $this->originalClone, $this->autoload, $this->methods, $this->cloneArguments);
61130 assert($object instanceof \PHPUnit\Framework\MockObject\MockObject);
61131 $this->testCase->registerMockObject($object);
61132 return $object;
61133 }
61134 /**
61135 * Creates a mock object for a trait using a fluent interface.
61136 *
61137 * @throws Exception
61138 * @throws ReflectionException
61139 * @throws RuntimeException
61140 *
61141 * @psalm-return MockObject&MockedType
61142 *
61143 * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5306
61144 */
61145 public function getMockForTrait(): \PHPUnit\Framework\MockObject\MockObject
61146 {
61147 assert(trait_exists($this->type));
61148 $object = $this->generator->mockObjectForTrait($this->type, $this->constructorArgs, $this->mockClassName ?? '', $this->originalConstructor, $this->originalClone, $this->autoload, $this->methods, $this->cloneArguments);
61149 assert($object instanceof \PHPUnit\Framework\MockObject\MockObject);
61150 $this->testCase->registerMockObject($object);
61151 return $object;
61152 }
61153 /**
61154 * Specifies the subset of methods to mock, requiring each to exist in the class.
61155 *
61156 * @psalm-param list<non-empty-string> $methods
61157 *
61158 * @throws CannotUseOnlyMethodsException
61159 * @throws ReflectionException
61160 *
61161 * @return $this
61162 */
61163 public function onlyMethods(array $methods): self
61164 {
61165 if (empty($methods)) {
61166 $this->emptyMethodsArray = \true;
61167 return $this;
61168 }
61169 try {
61170 $reflector = new ReflectionClass($this->type);
61171 // @codeCoverageIgnoreStart
61172 } catch (\ReflectionException $e) {
61173 throw new ReflectionException($e->getMessage(), $e->getCode(), $e);
61174 // @codeCoverageIgnoreEnd
61175 }
61176 foreach ($methods as $method) {
61177 if (!$reflector->hasMethod($method)) {
61178 throw new \PHPUnit\Framework\MockObject\CannotUseOnlyMethodsException($this->type, $method);
61179 }
61180 }
61181 $this->methods = array_merge($this->methods, $methods);
61182 return $this;
61183 }
61184 /**
61185 * Specifies methods that don't exist in the class which you want to mock.
61186 *
61187 * @psalm-param list<non-empty-string> $methods
61188 *
61189 * @throws CannotUseAddMethodsException
61190 * @throws ReflectionException
61191 * @throws RuntimeException
61192 *
61193 * @return $this
61194 *
61195 * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5320
61196 */
61197 public function addMethods(array $methods): self
61198 {
61199 if (empty($methods)) {
61200 $this->emptyMethodsArray = \true;
61201 return $this;
61202 }
61203 try {
61204 $reflector = new ReflectionClass($this->type);
61205 // @codeCoverageIgnoreStart
61206 } catch (\ReflectionException $e) {
61207 throw new ReflectionException($e->getMessage(), $e->getCode(), $e);
61208 // @codeCoverageIgnoreEnd
61209 }
61210 foreach ($methods as $method) {
61211 if ($reflector->hasMethod($method)) {
61212 throw new CannotUseAddMethodsException($this->type, $method);
61213 }
61214 }
61215 $this->methods = array_merge($this->methods, $methods);
61216 return $this;
61217 }
61218 /**
61219 * Specifies the arguments for the constructor.
61220 *
61221 * @return $this
61222 */
61223 public function setConstructorArgs(array $arguments): self
61224 {
61225 $this->constructorArgs = $arguments;
61226 return $this;
61227 }
61228 /**
61229 * Specifies the name for the mock class.
61230 *
61231 * @psalm-param class-string $name
61232 *
61233 * @return $this
61234 */
61235 public function setMockClassName(string $name): self
61236 {
61237 $this->mockClassName = $name;
61238 return $this;
61239 }
61240 /**
61241 * Disables the invocation of the original constructor.
61242 *
61243 * @return $this
61244 */
61245 public function disableOriginalConstructor(): self
61246 {
61247 $this->originalConstructor = \false;
61248 return $this;
61249 }
61250 /**
61251 * Enables the invocation of the original constructor.
61252 *
61253 * @return $this
61254 */
61255 public function enableOriginalConstructor(): self
61256 {
61257 $this->originalConstructor = \true;
61258 return $this;
61259 }
61260 /**
61261 * Disables the invocation of the original clone constructor.
61262 *
61263 * @return $this
61264 */
61265 public function disableOriginalClone(): self
61266 {
61267 $this->originalClone = \false;
61268 return $this;
61269 }
61270 /**
61271 * Enables the invocation of the original clone constructor.
61272 *
61273 * @return $this
61274 */
61275 public function enableOriginalClone(): self
61276 {
61277 $this->originalClone = \true;
61278 return $this;
61279 }
61280 /**
61281 * Disables the use of class autoloading while creating the mock object.
61282 *
61283 * @return $this
61284 *
61285 * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5309
61286 *
61287 * @codeCoverageIgnore
61288 */
61289 public function disableAutoload(): self
61290 {
61291 $this->autoload = \false;
61292 return $this;
61293 }
61294 /**
61295 * Enables the use of class autoloading while creating the mock object.
61296 *
61297 * @return $this
61298 *
61299 * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5309
61300 */
61301 public function enableAutoload(): self
61302 {
61303 $this->autoload = \true;
61304 return $this;
61305 }
61306 /**
61307 * Disables the cloning of arguments passed to mocked methods.
61308 *
61309 * @return $this
61310 *
61311 * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5315
61312 */
61313 public function disableArgumentCloning(): self
61314 {
61315 $this->cloneArguments = \false;
61316 return $this;
61317 }
61318 /**
61319 * Enables the cloning of arguments passed to mocked methods.
61320 *
61321 * @return $this
61322 *
61323 * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5315
61324 */
61325 public function enableArgumentCloning(): self
61326 {
61327 $this->cloneArguments = \true;
61328 return $this;
61329 }
61330 /**
61331 * Enables the invocation of the original methods.
61332 *
61333 * @return $this
61334 *
61335 * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5307
61336 *
61337 * @codeCoverageIgnore
61338 */
61339 public function enableProxyingToOriginalMethods(): self
61340 {
61341 $this->callOriginalMethods = \true;
61342 return $this;
61343 }
61344 /**
61345 * Disables the invocation of the original methods.
61346 *
61347 * @return $this
61348 *
61349 * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5307
61350 */
61351 public function disableProxyingToOriginalMethods(): self
61352 {
61353 $this->callOriginalMethods = \false;
61354 $this->proxyTarget = null;
61355 return $this;
61356 }
61357 /**
61358 * Sets the proxy target.
61359 *
61360 * @return $this
61361 *
61362 * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5307
61363 *
61364 * @codeCoverageIgnore
61365 */
61366 public function setProxyTarget(object $object): self
61367 {
61368 $this->proxyTarget = $object;
61369 return $this;
61370 }
61371 /**
61372 * @return $this
61373 *
61374 * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5308
61375 */
61376 public function allowMockingUnknownTypes(): self
61377 {
61378 $this->allowMockingUnknownTypes = \true;
61379 return $this;
61380 }
61381 /**
61382 * @return $this
61383 *
61384 * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5308
61385 */
61386 public function disallowMockingUnknownTypes(): self
61387 {
61388 $this->allowMockingUnknownTypes = \false;
61389 return $this;
61390 }
61391 /**
61392 * @return $this
61393 */
61394 public function enableAutoReturnValueGeneration(): self
61395 {
61396 $this->returnValueGeneration = \true;
61397 return $this;
61398 }
61399 /**
61400 * @return $this
61401 */
61402 public function disableAutoReturnValueGeneration(): self
61403 {
61404 $this->returnValueGeneration = \false;
61405 return $this;
61406 }
61407 }
61408 <?php
61409
61410 declare (strict_types=1);
61411 /*
61412 * This file is part of PHPUnit.
61413 *
61414 * (c) Sebastian Bergmann <sebastian@phpunit.de>
61415 *
61416 * For the full copyright and license information, please view the LICENSE
61417 * file that was distributed with this source code.
61418 */
61419 namespace PHPUnit\Framework\MockObject;
61420
61421 /**
61422 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
61423 *
61424 * @internal This trait is not covered by the backward compatibility promise for PHPUnit
61425 */
61426 trait DoubledCloneMethod
61427 {
61428 public function __clone(): void
61429 {
61430 $this->__phpunit_invocationMocker = clone $this->__phpunit_getInvocationHandler();
61431 }
61432 }
61433 <?php
61434
61435 declare (strict_types=1);
61436 /*
61437 * This file is part of PHPUnit.
61438 *
61439 * (c) Sebastian Bergmann <sebastian@phpunit.de>
61440 *
61441 * For the full copyright and license information, please view the LICENSE
61442 * file that was distributed with this source code.
61443 */
61444 namespace PHPUnit\Framework\MockObject;
61445
61446 use function call_user_func_array;
61447 use function func_get_args;
61448 use PHPUnit\Framework\MockObject\Builder\InvocationMocker;
61449 use PHPUnit\Framework\MockObject\Rule\AnyInvokedCount;
61450 /**
61451 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
61452 *
61453 * @internal This trait is not covered by the backward compatibility promise for PHPUnit
61454 */
61455 trait Method
61456 {
61457 public function method(): InvocationMocker
61458 {
61459 $expects = $this->expects(new AnyInvokedCount());
61460 return call_user_func_array([$expects, 'method'], func_get_args());
61461 }
61462 }
61463 <?php
61464
61465 declare (strict_types=1);
61466 /*
61467 * This file is part of PHPUnit.
61468 *
61469 * (c) Sebastian Bergmann <sebastian@phpunit.de>
61470 *
61471 * For the full copyright and license information, please view the LICENSE
61472 * file that was distributed with this source code.
61473 */
61474 namespace PHPUnit\Framework\MockObject;
61475
61476 use PHPUnit\Framework\MockObject\Builder\InvocationMocker as InvocationMockerBuilder;
61477 use PHPUnit\Framework\MockObject\Rule\InvocationOrder;
61478 /**
61479 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
61480 *
61481 * @internal This trait is not covered by the backward compatibility promise for PHPUnit
61482 */
61483 trait MockObjectApi
61484 {
61485 private object $__phpunit_originalObject;
61486 /** @noinspection MagicMethodsValidityInspection */
61487 public function __phpunit_hasMatchers(): bool
61488 {
61489 return $this->__phpunit_getInvocationHandler()->hasMatchers();
61490 }
61491 /** @noinspection MagicMethodsValidityInspection */
61492 public function __phpunit_setOriginalObject(object $originalObject): void
61493 {
61494 $this->__phpunit_originalObject = $originalObject;
61495 }
61496 /** @noinspection MagicMethodsValidityInspection */
61497 public function __phpunit_verify(bool $unsetInvocationMocker = \true): void
61498 {
61499 $this->__phpunit_getInvocationHandler()->verify();
61500 if ($unsetInvocationMocker) {
61501 $this->__phpunit_unsetInvocationMocker();
61502 }
61503 }
61504 abstract public function __phpunit_getInvocationHandler(): \PHPUnit\Framework\MockObject\InvocationHandler;
61505 abstract public function __phpunit_unsetInvocationMocker(): void;
61506 public function expects(InvocationOrder $matcher): InvocationMockerBuilder
61507 {
61508 return $this->__phpunit_getInvocationHandler()->expects($matcher);
61509 }
61510 }
61511 <?php
61512
61513 declare (strict_types=1);
61514 /*
61515 * This file is part of PHPUnit.
61516 *
61517 * (c) Sebastian Bergmann <sebastian@phpunit.de>
61518 *
61519 * For the full copyright and license information, please view the LICENSE
61520 * file that was distributed with this source code.
61521 */
61522 namespace PHPUnit\Framework\MockObject;
61523
61524 /**
61525 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
61526 *
61527 * @internal This trait is not covered by the backward compatibility promise for PHPUnit
61528 */
61529 trait ProxiedCloneMethod
61530 {
61531 public function __clone(): void
61532 {
61533 $this->__phpunit_invocationMocker = clone $this->__phpunit_getInvocationHandler();
61534 parent::__clone();
61535 }
61536 }
61537 <?php
61538
61539 declare (strict_types=1);
61540 /*
61541 * This file is part of PHPUnit.
61542 *
61543 * (c) Sebastian Bergmann <sebastian@phpunit.de>
61544 *
61545 * For the full copyright and license information, please view the LICENSE
61546 * file that was distributed with this source code.
61547 */
61548 namespace PHPUnit\Framework\MockObject;
61549
61550 /**
61551 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
61552 *
61553 * @internal This trait is not covered by the backward compatibility promise for PHPUnit
61554 */
61555 trait StubApi
61556 {
61557 /**
61558 * @psalm-var list<ConfigurableMethod>
61559 */
61560 private static array $__phpunit_configurableMethods;
61561 private bool $__phpunit_returnValueGeneration = \true;
61562 private ?\PHPUnit\Framework\MockObject\InvocationHandler $__phpunit_invocationMocker = null;
61563 /** @noinspection MagicMethodsValidityInspection */
61564 public static function __phpunit_initConfigurableMethods(\PHPUnit\Framework\MockObject\ConfigurableMethod ...$configurableMethods): void
61565 {
61566 static::$__phpunit_configurableMethods = $configurableMethods;
61567 }
61568 /** @noinspection MagicMethodsValidityInspection */
61569 public function __phpunit_setReturnValueGeneration(bool $returnValueGeneration): void
61570 {
61571 $this->__phpunit_returnValueGeneration = $returnValueGeneration;
61572 }
61573 /** @noinspection MagicMethodsValidityInspection */
61574 public function __phpunit_getInvocationHandler(): \PHPUnit\Framework\MockObject\InvocationHandler
61575 {
61576 if ($this->__phpunit_invocationMocker === null) {
61577 $this->__phpunit_invocationMocker = new \PHPUnit\Framework\MockObject\InvocationHandler(static::$__phpunit_configurableMethods, $this->__phpunit_returnValueGeneration);
61578 }
61579 return $this->__phpunit_invocationMocker;
61580 }
61581 /** @noinspection MagicMethodsValidityInspection */
61582 public function __phpunit_unsetInvocationMocker(): void
61583 {
61584 $this->__phpunit_invocationMocker = null;
61585 }
61586 }
61587 <?php
61588
61589 declare (strict_types=1);
61590 /*
61591 * This file is part of PHPUnit.
61592 *
61593 * (c) Sebastian Bergmann <sebastian@phpunit.de>
61594 *
61595 * For the full copyright and license information, please view the LICENSE
61596 * file that was distributed with this source code.
61597 */
61598 namespace PHPUnit\Framework\MockObject\Builder;
61599
61600 /**
61601 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
61602 *
61603 * @internal This interface is not covered by the backward compatibility promise for PHPUnit
61604 */
61605 interface Identity
61606 {
61607 /**
61608 * Sets the identification of the expectation to $id.
61609 *
61610 * @note The identifier is unique per mock object.
61611 */
61612 public function id(string $id): self;
61613 }
61614 <?php
61615
61616 declare (strict_types=1);
61617 /*
61618 * This file is part of PHPUnit.
61619 *
61620 * (c) Sebastian Bergmann <sebastian@phpunit.de>
61621 *
61622 * For the full copyright and license information, please view the LICENSE
61623 * file that was distributed with this source code.
61624 */
61625 namespace PHPUnit\Framework\MockObject\Builder;
61626
61627 use function array_flip;
61628 use function array_key_exists;
61629 use function array_map;
61630 use function array_merge;
61631 use function array_pop;
61632 use function assert;
61633 use function count;
61634 use function is_string;
61635 use function range;
61636 use function strtolower;
61637 use PHPUnit\Framework\Constraint\Constraint;
61638 use PHPUnit\Framework\InvalidArgumentException;
61639 use PHPUnit\Framework\MockObject\ConfigurableMethod;
61640 use PHPUnit\Framework\MockObject\IncompatibleReturnValueException;
61641 use PHPUnit\Framework\MockObject\InvocationHandler;
61642 use PHPUnit\Framework\MockObject\Matcher;
61643 use PHPUnit\Framework\MockObject\MatcherAlreadyRegisteredException;
61644 use PHPUnit\Framework\MockObject\MethodCannotBeConfiguredException;
61645 use PHPUnit\Framework\MockObject\MethodNameAlreadyConfiguredException;
61646 use PHPUnit\Framework\MockObject\MethodNameNotConfiguredException;
61647 use PHPUnit\Framework\MockObject\MethodParametersAlreadyConfiguredException;
61648 use PHPUnit\Framework\MockObject\Rule;
61649 use PHPUnit\Framework\MockObject\Stub\ConsecutiveCalls;
61650 use PHPUnit\Framework\MockObject\Stub\Exception;
61651 use PHPUnit\Framework\MockObject\Stub\ReturnArgument;
61652 use PHPUnit\Framework\MockObject\Stub\ReturnCallback;
61653 use PHPUnit\Framework\MockObject\Stub\ReturnReference;
61654 use PHPUnit\Framework\MockObject\Stub\ReturnSelf;
61655 use PHPUnit\Framework\MockObject\Stub\ReturnStub;
61656 use PHPUnit\Framework\MockObject\Stub\ReturnValueMap;
61657 use PHPUnit\Framework\MockObject\Stub\Stub;
61658 use Throwable;
61659 /**
61660 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
61661 */
61662 final class InvocationMocker implements \PHPUnit\Framework\MockObject\Builder\InvocationStubber, \PHPUnit\Framework\MockObject\Builder\MethodNameMatch
61663 {
61664 private readonly InvocationHandler $invocationHandler;
61665 private readonly Matcher $matcher;
61666 /**
61667 * @psalm-var list<ConfigurableMethod>
61668 */
61669 private readonly array $configurableMethods;
61670 /**
61671 * @psalm-var ?array<string, int>
61672 */
61673 private ?array $configurableMethodNames = null;
61674 public function __construct(InvocationHandler $handler, Matcher $matcher, ConfigurableMethod ...$configurableMethods)
61675 {
61676 $this->invocationHandler = $handler;
61677 $this->matcher = $matcher;
61678 $this->configurableMethods = $configurableMethods;
61679 }
61680 /**
61681 * @throws MatcherAlreadyRegisteredException
61682 *
61683 * @return $this
61684 */
61685 public function id(string $id): self
61686 {
61687 $this->invocationHandler->registerMatcher($id, $this->matcher);
61688 return $this;
61689 }
61690 /**
61691 * @return $this
61692 */
61693 public function will(Stub $stub): \PHPUnit\Framework\MockObject\Builder\Identity
61694 {
61695 $this->matcher->setStub($stub);
61696 return $this;
61697 }
61698 /**
61699 * @throws IncompatibleReturnValueException
61700 */
61701 public function willReturn(mixed $value, mixed ...$nextValues): self
61702 {
61703 if (count($nextValues) === 0) {
61704 $this->ensureTypeOfReturnValues([$value]);
61705 $stub = $value instanceof Stub ? $value : new ReturnStub($value);
61706 return $this->will($stub);
61707 }
61708 $values = array_merge([$value], $nextValues);
61709 $this->ensureTypeOfReturnValues($values);
61710 $stub = new ConsecutiveCalls($values);
61711 return $this->will($stub);
61712 }
61713 public function willReturnReference(mixed &$reference): self
61714 {
61715 $stub = new ReturnReference($reference);
61716 return $this->will($stub);
61717 }
61718 public function willReturnMap(array $valueMap): self
61719 {
61720 $method = $this->configuredMethod();
61721 assert($method instanceof ConfigurableMethod);
61722 $numberOfParameters = $method->numberOfParameters();
61723 $defaultValues = $method->defaultParameterValues();
61724 $hasDefaultValues = !empty($defaultValues);
61725 $_valueMap = [];
61726 foreach ($valueMap as $mapping) {
61727 $numberOfConfiguredParameters = count($mapping) - 1;
61728 if ($numberOfConfiguredParameters === $numberOfParameters || !$hasDefaultValues) {
61729 $_valueMap[] = $mapping;
61730 continue;
61731 }
61732 $_mapping = [];
61733 $returnValue = array_pop($mapping);
61734 foreach (range(0, $numberOfParameters - 1) as $i) {
61735 if (isset($mapping[$i])) {
61736 $_mapping[] = $mapping[$i];
61737 continue;
61738 }
61739 if (isset($defaultValues[$i])) {
61740 $_mapping[] = $defaultValues[$i];
61741 }
61742 }
61743 $_mapping[] = $returnValue;
61744 $_valueMap[] = $_mapping;
61745 }
61746 $stub = new ReturnValueMap($_valueMap);
61747 return $this->will($stub);
61748 }
61749 public function willReturnArgument(int $argumentIndex): self
61750 {
61751 $stub = new ReturnArgument($argumentIndex);
61752 return $this->will($stub);
61753 }
61754 public function willReturnCallback(callable $callback): self
61755 {
61756 $stub = new ReturnCallback($callback);
61757 return $this->will($stub);
61758 }
61759 public function willReturnSelf(): self
61760 {
61761 $stub = new ReturnSelf();
61762 return $this->will($stub);
61763 }
61764 public function willReturnOnConsecutiveCalls(mixed ...$values): self
61765 {
61766 $stub = new ConsecutiveCalls($values);
61767 return $this->will($stub);
61768 }
61769 public function willThrowException(Throwable $exception): self
61770 {
61771 $stub = new Exception($exception);
61772 return $this->will($stub);
61773 }
61774 /**
61775 * @return $this
61776 */
61777 public function after(string $id): self
61778 {
61779 $this->matcher->setAfterMatchBuilderId($id);
61780 return $this;
61781 }
61782 /**
61783 * @throws \PHPUnit\Framework\Exception
61784 * @throws MethodNameNotConfiguredException
61785 * @throws MethodParametersAlreadyConfiguredException
61786 *
61787 * @return $this
61788 */
61789 public function with(mixed ...$arguments): self
61790 {
61791 $this->ensureParametersCanBeConfigured();
61792 $this->matcher->setParametersRule(new Rule\Parameters($arguments));
61793 return $this;
61794 }
61795 /**
61796 * @throws MethodNameNotConfiguredException
61797 * @throws MethodParametersAlreadyConfiguredException
61798 *
61799 * @return $this
61800 */
61801 public function withAnyParameters(): self
61802 {
61803 $this->ensureParametersCanBeConfigured();
61804 $this->matcher->setParametersRule(new Rule\AnyParameters());
61805 return $this;
61806 }
61807 /**
61808 * @throws InvalidArgumentException
61809 * @throws MethodCannotBeConfiguredException
61810 * @throws MethodNameAlreadyConfiguredException
61811 *
61812 * @return $this
61813 */
61814 public function method(Constraint|string $constraint): self
61815 {
61816 if ($this->matcher->hasMethodNameRule()) {
61817 throw new MethodNameAlreadyConfiguredException();
61818 }
61819 if (is_string($constraint)) {
61820 $this->configurableMethodNames ??= array_flip(array_map(static fn(ConfigurableMethod $configurable) => strtolower($configurable->name()), $this->configurableMethods));
61821 if (!array_key_exists(strtolower($constraint), $this->configurableMethodNames)) {
61822 throw new MethodCannotBeConfiguredException($constraint);
61823 }
61824 }
61825 $this->matcher->setMethodNameRule(new Rule\MethodName($constraint));
61826 return $this;
61827 }
61828 /**
61829 * @throws MethodNameNotConfiguredException
61830 * @throws MethodParametersAlreadyConfiguredException
61831 */
61832 private function ensureParametersCanBeConfigured(): void
61833 {
61834 if (!$this->matcher->hasMethodNameRule()) {
61835 throw new MethodNameNotConfiguredException();
61836 }
61837 if ($this->matcher->hasParametersRule()) {
61838 throw new MethodParametersAlreadyConfiguredException();
61839 }
61840 }
61841 private function configuredMethod(): ?ConfigurableMethod
61842 {
61843 $configuredMethod = null;
61844 foreach ($this->configurableMethods as $configurableMethod) {
61845 if ($this->matcher->methodNameRule()->matchesName($configurableMethod->name())) {
61846 if ($configuredMethod !== null) {
61847 return null;
61848 }
61849 $configuredMethod = $configurableMethod;
61850 }
61851 }
61852 return $configuredMethod;
61853 }
61854 /**
61855 * @throws IncompatibleReturnValueException
61856 */
61857 private function ensureTypeOfReturnValues(array $values): void
61858 {
61859 $configuredMethod = $this->configuredMethod();
61860 if ($configuredMethod === null) {
61861 return;
61862 }
61863 foreach ($values as $value) {
61864 if (!$configuredMethod->mayReturn($value)) {
61865 throw new IncompatibleReturnValueException($configuredMethod, $value);
61866 }
61867 }
61868 }
61869 }
61870 <?php
61871
61872 declare (strict_types=1);
61873 /*
61874 * This file is part of PHPUnit.
61875 *
61876 * (c) Sebastian Bergmann <sebastian@phpunit.de>
61877 *
61878 * For the full copyright and license information, please view the LICENSE
61879 * file that was distributed with this source code.
61880 */
61881 namespace PHPUnit\Framework\MockObject\Builder;
61882
61883 use PHPUnit\Framework\MockObject\Stub\Stub;
61884 use Throwable;
61885 /**
61886 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
61887 */
61888 interface InvocationStubber
61889 {
61890 public function will(Stub $stub): \PHPUnit\Framework\MockObject\Builder\Identity;
61891 public function willReturn(mixed $value, mixed ...$nextValues): self;
61892 public function willReturnReference(mixed &$reference): self;
61893 /**
61894 * @psalm-param array<int, array<int, mixed>> $valueMap
61895 */
61896 public function willReturnMap(array $valueMap): self;
61897 public function willReturnArgument(int $argumentIndex): self;
61898 public function willReturnCallback(callable $callback): self;
61899 public function willReturnSelf(): self;
61900 public function willReturnOnConsecutiveCalls(mixed ...$values): self;
61901 public function willThrowException(Throwable $exception): self;
61902 }
61903 <?php
61904
61905 declare (strict_types=1);
61906 /*
61907 * This file is part of PHPUnit.
61908 *
61909 * (c) Sebastian Bergmann <sebastian@phpunit.de>
61910 *
61911 * For the full copyright and license information, please view the LICENSE
61912 * file that was distributed with this source code.
61913 */
61914 namespace PHPUnit\Framework\MockObject\Builder;
61915
61916 use PHPUnit\Framework\Constraint\Constraint;
61917 /**
61918 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
61919 *
61920 * @internal This interface is not covered by the backward compatibility promise for PHPUnit
61921 */
61922 interface MethodNameMatch extends \PHPUnit\Framework\MockObject\Builder\ParametersMatch
61923 {
61924 /**
61925 * Adds a new method name match and returns the parameter match object for
61926 * further matching possibilities.
61927 */
61928 public function method(Constraint|string $constraint): self;
61929 }
61930 <?php
61931
61932 declare (strict_types=1);
61933 /*
61934 * This file is part of PHPUnit.
61935 *
61936 * (c) Sebastian Bergmann <sebastian@phpunit.de>
61937 *
61938 * For the full copyright and license information, please view the LICENSE
61939 * file that was distributed with this source code.
61940 */
61941 namespace PHPUnit\Framework\MockObject\Builder;
61942
61943 /**
61944 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
61945 *
61946 * @internal This interface is not covered by the backward compatibility promise for PHPUnit
61947 */
61948 interface ParametersMatch extends \PHPUnit\Framework\MockObject\Builder\Stub
61949 {
61950 /**
61951 * Defines the expectation which must occur before the current is valid.
61952 */
61953 public function after(string $id): \PHPUnit\Framework\MockObject\Builder\Stub;
61954 /**
61955 * Sets the parameters to match for, each parameter to this function will
61956 * be part of match. To perform specific matches or constraints create a
61957 * new PHPUnit\Framework\Constraint\Constraint and use it for the parameter.
61958 * If the parameter value is not a constraint it will use the
61959 * PHPUnit\Framework\Constraint\IsEqual for the value.
61960 *
61961 * Some examples:
61962 * <code>
61963 * // match first parameter with value 2
61964 * $b->with(2);
61965 * // match first parameter with value 'smock' and second identical to 42
61966 * $b->with('smock', new PHPUnit\Framework\Constraint\IsEqual(42));
61967 * </code>
61968 */
61969 public function with(mixed ...$arguments): self;
61970 /**
61971 * Sets a rule which allows any kind of parameters.
61972 *
61973 * Some examples:
61974 * <code>
61975 * // match any number of parameters
61976 * $b->withAnyParameters();
61977 * </code>
61978 */
61979 public function withAnyParameters(): self;
61980 }
61981 <?php
61982
61983 declare (strict_types=1);
61984 /*
61985 * This file is part of PHPUnit.
61986 *
61987 * (c) Sebastian Bergmann <sebastian@phpunit.de>
61988 *
61989 * For the full copyright and license information, please view the LICENSE
61990 * file that was distributed with this source code.
61991 */
61992 namespace PHPUnit\Framework\MockObject\Builder;
61993
61994 use PHPUnit\Framework\MockObject\Stub\Stub as BaseStub;
61995 /**
61996 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
61997 *
61998 * @internal This interface is not covered by the backward compatibility promise for PHPUnit
61999 */
62000 interface Stub extends \PHPUnit\Framework\MockObject\Builder\Identity
62001 {
62002 /**
62003 * Stubs the matching method with the stub object $stub. Any invocations of
62004 * the matched method will now be handled by the stub instead.
62005 */
62006 public function will(BaseStub $stub): \PHPUnit\Framework\MockObject\Builder\Identity;
62007 }
62008 <?php
62009
62010 declare (strict_types=1);
62011 /*
62012 * This file is part of PHPUnit.
62013 *
62014 * (c) Sebastian Bergmann <sebastian@phpunit.de>
62015 *
62016 * For the full copyright and license information, please view the LICENSE
62017 * file that was distributed with this source code.
62018 */
62019 namespace PHPUnit\Framework\MockObject;
62020
62021 use PHPUnit\Framework\MockObject\Builder\InvocationMocker;
62022 use PHPUnit\Framework\MockObject\Rule\InvocationOrder;
62023 /**
62024 * @method InvocationMocker method($constraint)
62025 *
62026 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
62027 */
62028 interface MockObject extends \PHPUnit\Framework\MockObject\Stub
62029 {
62030 public function expects(InvocationOrder $invocationRule): InvocationMocker;
62031 }
62032 <?php
62033
62034 declare (strict_types=1);
62035 /*
62036 * This file is part of PHPUnit.
62037 *
62038 * (c) Sebastian Bergmann <sebastian@phpunit.de>
62039 *
62040 * For the full copyright and license information, please view the LICENSE
62041 * file that was distributed with this source code.
62042 */
62043 namespace PHPUnit\Framework\MockObject;
62044
62045 /**
62046 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
62047 *
62048 * @internal This interface is not covered by the backward compatibility promise for PHPUnit
62049 */
62050 interface MockObjectInternal extends \PHPUnit\Framework\MockObject\MockObject, \PHPUnit\Framework\MockObject\StubInternal
62051 {
62052 public function __phpunit_hasMatchers(): bool;
62053 public function __phpunit_setOriginalObject(object $originalObject): void;
62054 public function __phpunit_verify(bool $unsetInvocationMocker = \true): void;
62055 }
62056 <?php
62057
62058 declare (strict_types=1);
62059 /*
62060 * This file is part of PHPUnit.
62061 *
62062 * (c) Sebastian Bergmann <sebastian@phpunit.de>
62063 *
62064 * For the full copyright and license information, please view the LICENSE
62065 * file that was distributed with this source code.
62066 */
62067 namespace PHPUnit\Framework\MockObject;
62068
62069 use PHPUnit\Framework\MockObject\Builder\InvocationStubber;
62070 /**
62071 * @method InvocationStubber method($constraint)
62072 *
62073 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
62074 */
62075 interface Stub
62076 {
62077 }
62078 <?php
62079
62080 declare (strict_types=1);
62081 /*
62082 * This file is part of PHPUnit.
62083 *
62084 * (c) Sebastian Bergmann <sebastian@phpunit.de>
62085 *
62086 * For the full copyright and license information, please view the LICENSE
62087 * file that was distributed with this source code.
62088 */
62089 namespace PHPUnit\Framework\MockObject;
62090
62091 /**
62092 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
62093 *
62094 * @internal This interface is not covered by the backward compatibility promise for PHPUnit
62095 */
62096 interface StubInternal extends \PHPUnit\Framework\MockObject\Stub
62097 {
62098 public static function __phpunit_initConfigurableMethods(\PHPUnit\Framework\MockObject\ConfigurableMethod ...$configurableMethods): void;
62099 public function __phpunit_getInvocationHandler(): \PHPUnit\Framework\MockObject\InvocationHandler;
62100 public function __phpunit_setReturnValueGeneration(bool $returnValueGeneration): void;
62101 public function __phpunit_unsetInvocationMocker(): void;
62102 }
62103 <?php
62104
62105 declare (strict_types=1);
62106 /*
62107 * This file is part of PHPUnit.
62108 *
62109 * (c) Sebastian Bergmann <sebastian@phpunit.de>
62110 *
62111 * For the full copyright and license information, please view the LICENSE
62112 * file that was distributed with this source code.
62113 */
62114 namespace PHPUnit\Framework\MockObject;
62115
62116 use function array_map;
62117 use function implode;
62118 use function is_object;
62119 use function sprintf;
62120 use function str_starts_with;
62121 use function strtolower;
62122 use function substr;
62123 use PHPUnit\Framework\SelfDescribing;
62124 use PHPUnit\Util\Cloner;
62125 use PHPUnitPHAR\SebastianBergmann\Exporter\Exporter;
62126 /**
62127 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
62128 *
62129 * @internal This class is not covered by the backward compatibility promise for PHPUnit
62130 */
62131 final class Invocation implements SelfDescribing
62132 {
62133 /**
62134 * @psalm-var class-string
62135 */
62136 private readonly string $className;
62137 /**
62138 * @psalm-var non-empty-string
62139 */
62140 private readonly string $methodName;
62141 private readonly array $parameters;
62142 private readonly string $returnType;
62143 private readonly bool $isReturnTypeNullable;
62144 private readonly bool $proxiedCall;
62145 private readonly \PHPUnit\Framework\MockObject\MockObjectInternal|\PHPUnit\Framework\MockObject\StubInternal $object;
62146 /**
62147 * @psalm-param class-string $className
62148 * @psalm-param non-empty-string $methodName
62149 */
62150 public function __construct(string $className, string $methodName, array $parameters, string $returnType, \PHPUnit\Framework\MockObject\MockObjectInternal|\PHPUnit\Framework\MockObject\StubInternal $object, bool $cloneObjects = \false, bool $proxiedCall = \false)
62151 {
62152 $this->className = $className;
62153 $this->methodName = $methodName;
62154 $this->object = $object;
62155 $this->proxiedCall = $proxiedCall;
62156 if (strtolower($methodName) === '__tostring') {
62157 $returnType = 'string';
62158 }
62159 if (str_starts_with($returnType, '?')) {
62160 $returnType = substr($returnType, 1);
62161 $this->isReturnTypeNullable = \true;
62162 } else {
62163 $this->isReturnTypeNullable = \false;
62164 }
62165 $this->returnType = $returnType;
62166 if (!$cloneObjects) {
62167 $this->parameters = $parameters;
62168 return;
62169 }
62170 foreach ($parameters as $key => $value) {
62171 if (is_object($value)) {
62172 $parameters[$key] = Cloner::clone($value);
62173 }
62174 }
62175 $this->parameters = $parameters;
62176 }
62177 /**
62178 * @psalm-return class-string
62179 */
62180 public function className(): string
62181 {
62182 return $this->className;
62183 }
62184 /**
62185 * @psalm-return non-empty-string
62186 */
62187 public function methodName(): string
62188 {
62189 return $this->methodName;
62190 }
62191 public function parameters(): array
62192 {
62193 return $this->parameters;
62194 }
62195 /**
62196 * @throws Exception
62197 */
62198 public function generateReturnValue(): mixed
62199 {
62200 if ($this->returnType === 'never') {
62201 throw new \PHPUnit\Framework\MockObject\NeverReturningMethodException($this->className, $this->methodName);
62202 }
62203 if ($this->isReturnTypeNullable || $this->proxiedCall) {
62204 return null;
62205 }
62206 return (new \PHPUnit\Framework\MockObject\ReturnValueGenerator())->generate($this->className, $this->methodName, $this->object::class, $this->returnType);
62207 }
62208 public function toString(): string
62209 {
62210 $exporter = new Exporter();
62211 return sprintf('%s::%s(%s)%s', $this->className, $this->methodName, implode(', ', array_map([$exporter, 'shortenedExport'], $this->parameters)), $this->returnType ? sprintf(': %s', $this->returnType) : '');
62212 }
62213 public function object(): \PHPUnit\Framework\MockObject\MockObjectInternal|\PHPUnit\Framework\MockObject\StubInternal
62214 {
62215 return $this->object;
62216 }
62217 }
62218 <?php
62219
62220 declare (strict_types=1);
62221 /*
62222 * This file is part of PHPUnit.
62223 *
62224 * (c) Sebastian Bergmann <sebastian@phpunit.de>
62225 *
62226 * For the full copyright and license information, please view the LICENSE
62227 * file that was distributed with this source code.
62228 */
62229 namespace PHPUnit\Framework\MockObject;
62230
62231 use function strtolower;
62232 use Exception;
62233 use PHPUnit\Framework\MockObject\Builder\InvocationMocker;
62234 use PHPUnit\Framework\MockObject\Rule\InvocationOrder;
62235 use Throwable;
62236 /**
62237 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
62238 *
62239 * @internal This class is not covered by the backward compatibility promise for PHPUnit
62240 */
62241 final class InvocationHandler
62242 {
62243 /**
62244 * @psalm-var list<Matcher>
62245 */
62246 private array $matchers = [];
62247 /**
62248 * @psalm-var array<string,Matcher>
62249 */
62250 private array $matcherMap = [];
62251 /**
62252 * @psalm-var list<ConfigurableMethod>
62253 */
62254 private readonly array $configurableMethods;
62255 private readonly bool $returnValueGeneration;
62256 /**
62257 * @psalm-param list<ConfigurableMethod> $configurableMethods
62258 */
62259 public function __construct(array $configurableMethods, bool $returnValueGeneration)
62260 {
62261 $this->configurableMethods = $configurableMethods;
62262 $this->returnValueGeneration = $returnValueGeneration;
62263 }
62264 public function hasMatchers(): bool
62265 {
62266 foreach ($this->matchers as $matcher) {
62267 if ($matcher->hasMatchers()) {
62268 return \true;
62269 }
62270 }
62271 return \false;
62272 }
62273 /**
62274 * Looks up the match builder with identification $id and returns it.
62275 */
62276 public function lookupMatcher(string $id): ?\PHPUnit\Framework\MockObject\Matcher
62277 {
62278 return $this->matcherMap[$id] ?? null;
62279 }
62280 /**
62281 * Registers a matcher with the identification $id. The matcher can later be
62282 * looked up using lookupMatcher() to figure out if it has been invoked.
62283 *
62284 * @throws MatcherAlreadyRegisteredException
62285 */
62286 public function registerMatcher(string $id, \PHPUnit\Framework\MockObject\Matcher $matcher): void
62287 {
62288 if (isset($this->matcherMap[$id])) {
62289 throw new \PHPUnit\Framework\MockObject\MatcherAlreadyRegisteredException($id);
62290 }
62291 $this->matcherMap[$id] = $matcher;
62292 }
62293 public function expects(InvocationOrder $rule): InvocationMocker
62294 {
62295 $matcher = new \PHPUnit\Framework\MockObject\Matcher($rule);
62296 $this->addMatcher($matcher);
62297 return new InvocationMocker($this, $matcher, ...$this->configurableMethods);
62298 }
62299 /**
62300 * @throws \PHPUnit\Framework\MockObject\Exception
62301 * @throws Exception
62302 */
62303 public function invoke(\PHPUnit\Framework\MockObject\Invocation $invocation): mixed
62304 {
62305 $exception = null;
62306 $hasReturnValue = \false;
62307 $returnValue = null;
62308 foreach ($this->matchers as $match) {
62309 try {
62310 if ($match->matches($invocation)) {
62311 $value = $match->invoked($invocation);
62312 if (!$hasReturnValue) {
62313 $returnValue = $value;
62314 $hasReturnValue = \true;
62315 }
62316 }
62317 } catch (Exception $e) {
62318 $exception = $e;
62319 }
62320 }
62321 if ($exception !== null) {
62322 throw $exception;
62323 }
62324 if ($hasReturnValue) {
62325 return $returnValue;
62326 }
62327 if (!$this->returnValueGeneration) {
62328 if (strtolower($invocation->methodName()) === '__tostring') {
62329 return '';
62330 }
62331 throw new \PHPUnit\Framework\MockObject\ReturnValueNotConfiguredException($invocation);
62332 }
62333 return $invocation->generateReturnValue();
62334 }
62335 /**
62336 * @throws Throwable
62337 */
62338 public function verify(): void
62339 {
62340 foreach ($this->matchers as $matcher) {
62341 $matcher->verify();
62342 }
62343 }
62344 private function addMatcher(\PHPUnit\Framework\MockObject\Matcher $matcher): void
62345 {
62346 $this->matchers[] = $matcher;
62347 }
62348 }
62349 <?php
62350
62351 declare (strict_types=1);
62352 /*
62353 * This file is part of PHPUnit.
62354 *
62355 * (c) Sebastian Bergmann <sebastian@phpunit.de>
62356 *
62357 * For the full copyright and license information, please view the LICENSE
62358 * file that was distributed with this source code.
62359 */
62360 namespace PHPUnit\Framework\MockObject;
62361
62362 use function sprintf;
62363 use PHPUnit\Framework\ExpectationFailedException;
62364 use PHPUnit\Framework\MockObject\Rule\AnyInvokedCount;
62365 use PHPUnit\Framework\MockObject\Rule\AnyParameters;
62366 use PHPUnit\Framework\MockObject\Rule\InvocationOrder;
62367 use PHPUnit\Framework\MockObject\Rule\InvokedAtMostCount;
62368 use PHPUnit\Framework\MockObject\Rule\InvokedCount;
62369 use PHPUnit\Framework\MockObject\Rule\MethodName;
62370 use PHPUnit\Framework\MockObject\Rule\ParametersRule;
62371 use PHPUnit\Framework\MockObject\Stub\Stub;
62372 use PHPUnit\Util\ThrowableToStringMapper;
62373 /**
62374 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
62375 *
62376 * @internal This class is not covered by the backward compatibility promise for PHPUnit
62377 */
62378 final class Matcher
62379 {
62380 private readonly InvocationOrder $invocationRule;
62381 private ?string $afterMatchBuilderId = null;
62382 private ?MethodName $methodNameRule = null;
62383 private ?ParametersRule $parametersRule = null;
62384 private ?Stub $stub = null;
62385 public function __construct(InvocationOrder $rule)
62386 {
62387 $this->invocationRule = $rule;
62388 }
62389 public function hasMatchers(): bool
62390 {
62391 return !$this->invocationRule instanceof AnyInvokedCount;
62392 }
62393 public function hasMethodNameRule(): bool
62394 {
62395 return $this->methodNameRule !== null;
62396 }
62397 public function methodNameRule(): MethodName
62398 {
62399 return $this->methodNameRule;
62400 }
62401 public function setMethodNameRule(MethodName $rule): void
62402 {
62403 $this->methodNameRule = $rule;
62404 }
62405 public function hasParametersRule(): bool
62406 {
62407 return $this->parametersRule !== null;
62408 }
62409 public function setParametersRule(ParametersRule $rule): void
62410 {
62411 $this->parametersRule = $rule;
62412 }
62413 public function setStub(Stub $stub): void
62414 {
62415 $this->stub = $stub;
62416 }
62417 public function setAfterMatchBuilderId(string $id): void
62418 {
62419 $this->afterMatchBuilderId = $id;
62420 }
62421 /**
62422 * @throws Exception
62423 * @throws ExpectationFailedException
62424 * @throws MatchBuilderNotFoundException
62425 * @throws MethodNameNotConfiguredException
62426 * @throws RuntimeException
62427 */
62428 public function invoked(\PHPUnit\Framework\MockObject\Invocation $invocation): mixed
62429 {
62430 if ($this->methodNameRule === null) {
62431 throw new \PHPUnit\Framework\MockObject\MethodNameNotConfiguredException();
62432 }
62433 if ($this->afterMatchBuilderId !== null) {
62434 $matcher = $invocation->object()->__phpunit_getInvocationHandler()->lookupMatcher($this->afterMatchBuilderId);
62435 if (!$matcher) {
62436 throw new \PHPUnit\Framework\MockObject\MatchBuilderNotFoundException($this->afterMatchBuilderId);
62437 }
62438 }
62439 $this->invocationRule->invoked($invocation);
62440 try {
62441 $this->parametersRule?->apply($invocation);
62442 } catch (ExpectationFailedException $e) {
62443 throw new ExpectationFailedException(sprintf("Expectation failed for %s when %s\n%s", $this->methodNameRule->toString(), $this->invocationRule->toString(), $e->getMessage()), $e->getComparisonFailure());
62444 }
62445 if ($this->stub) {
62446 return $this->stub->invoke($invocation);
62447 }
62448 return $invocation->generateReturnValue();
62449 }
62450 /**
62451 * @throws ExpectationFailedException
62452 * @throws MatchBuilderNotFoundException
62453 * @throws MethodNameNotConfiguredException
62454 * @throws RuntimeException
62455 */
62456 public function matches(\PHPUnit\Framework\MockObject\Invocation $invocation): bool
62457 {
62458 if ($this->afterMatchBuilderId !== null) {
62459 $matcher = $invocation->object()->__phpunit_getInvocationHandler()->lookupMatcher($this->afterMatchBuilderId);
62460 if (!$matcher) {
62461 throw new \PHPUnit\Framework\MockObject\MatchBuilderNotFoundException($this->afterMatchBuilderId);
62462 }
62463 if (!$matcher->invocationRule->hasBeenInvoked()) {
62464 return \false;
62465 }
62466 }
62467 if ($this->methodNameRule === null) {
62468 throw new \PHPUnit\Framework\MockObject\MethodNameNotConfiguredException();
62469 }
62470 if (!$this->invocationRule->matches($invocation)) {
62471 return \false;
62472 }
62473 try {
62474 if (!$this->methodNameRule->matches($invocation)) {
62475 return \false;
62476 }
62477 } catch (ExpectationFailedException $e) {
62478 throw new ExpectationFailedException(sprintf("Expectation failed for %s when %s\n%s", $this->methodNameRule->toString(), $this->invocationRule->toString(), $e->getMessage()), $e->getComparisonFailure());
62479 }
62480 return \true;
62481 }
62482 /**
62483 * @throws ExpectationFailedException
62484 * @throws MethodNameNotConfiguredException
62485 */
62486 public function verify(): void
62487 {
62488 if ($this->methodNameRule === null) {
62489 throw new \PHPUnit\Framework\MockObject\MethodNameNotConfiguredException();
62490 }
62491 try {
62492 $this->invocationRule->verify();
62493 if ($this->parametersRule === null) {
62494 $this->parametersRule = new AnyParameters();
62495 }
62496 $invocationIsAny = $this->invocationRule instanceof AnyInvokedCount;
62497 $invocationIsNever = $this->invocationRule instanceof InvokedCount && $this->invocationRule->isNever();
62498 $invocationIsAtMost = $this->invocationRule instanceof InvokedAtMostCount;
62499 if (!$invocationIsAny && !$invocationIsNever && !$invocationIsAtMost) {
62500 $this->parametersRule->verify();
62501 }
62502 } catch (ExpectationFailedException $e) {
62503 throw new ExpectationFailedException(sprintf("Expectation failed for %s when %s.\n%s", $this->methodNameRule->toString(), $this->invocationRule->toString(), ThrowableToStringMapper::map($e)));
62504 }
62505 }
62506 }
62507 <?php
62508
62509 declare (strict_types=1);
62510 /*
62511 * This file is part of PHPUnit.
62512 *
62513 * (c) Sebastian Bergmann <sebastian@phpunit.de>
62514 *
62515 * For the full copyright and license information, please view the LICENSE
62516 * file that was distributed with this source code.
62517 */
62518 namespace PHPUnit\Framework\MockObject;
62519
62520 use function sprintf;
62521 use function strtolower;
62522 use PHPUnit\Framework\Constraint\Constraint;
62523 /**
62524 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
62525 *
62526 * @internal This class is not covered by the backward compatibility promise for PHPUnit
62527 */
62528 final class MethodNameConstraint extends Constraint
62529 {
62530 private readonly string $methodName;
62531 public function __construct(string $methodName)
62532 {
62533 $this->methodName = $methodName;
62534 }
62535 public function toString(): string
62536 {
62537 return sprintf('is "%s"', $this->methodName);
62538 }
62539 protected function matches(mixed $other): bool
62540 {
62541 return strtolower($this->methodName) === strtolower((string) $other);
62542 }
62543 }
62544 <?php
62545
62546 declare (strict_types=1);
62547 /*
62548 * This file is part of PHPUnit.
62549 *
62550 * (c) Sebastian Bergmann <sebastian@phpunit.de>
62551 *
62552 * For the full copyright and license information, please view the LICENSE
62553 * file that was distributed with this source code.
62554 */
62555 namespace PHPUnit\Framework\MockObject;
62556
62557 use function array_keys;
62558 use function array_map;
62559 use function explode;
62560 use function in_array;
62561 use function interface_exists;
62562 use function sprintf;
62563 use function str_contains;
62564 use function str_ends_with;
62565 use function str_starts_with;
62566 use function substr;
62567 use PHPUnit\Framework\MockObject\Generator\Generator;
62568 use ReflectionClass;
62569 use stdClass;
62570 use Throwable;
62571 /**
62572 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
62573 *
62574 * @internal This class is not covered by the backward compatibility promise for PHPUnit
62575 */
62576 final class ReturnValueGenerator
62577 {
62578 /**
62579 * @psalm-param class-string $className
62580 * @psalm-param non-empty-string $methodName
62581 * @psalm-param class-string $stubClassName
62582 *
62583 * @throws Exception
62584 */
62585 public function generate(string $className, string $methodName, string $stubClassName, string $returnType): mixed
62586 {
62587 $intersection = \false;
62588 $union = \false;
62589 if (str_contains($returnType, '|')) {
62590 $types = explode('|', $returnType);
62591 $union = \true;
62592 foreach (array_keys($types) as $key) {
62593 if (str_starts_with($types[$key], '(') && str_ends_with($types[$key], ')')) {
62594 $types[$key] = substr($types[$key], 1, -1);
62595 }
62596 }
62597 } elseif (str_contains($returnType, '&')) {
62598 $types = explode('&', $returnType);
62599 $intersection = \true;
62600 } else {
62601 $types = [$returnType];
62602 }
62603 if (!$intersection) {
62604 $lowerTypes = array_map('strtolower', $types);
62605 if (in_array('', $lowerTypes, \true) || in_array('null', $lowerTypes, \true) || in_array('mixed', $lowerTypes, \true) || in_array('void', $lowerTypes, \true)) {
62606 return null;
62607 }
62608 if (in_array('true', $lowerTypes, \true)) {
62609 return \true;
62610 }
62611 if (in_array('false', $lowerTypes, \true) || in_array('bool', $lowerTypes, \true)) {
62612 return \false;
62613 }
62614 if (in_array('float', $lowerTypes, \true)) {
62615 return 0.0;
62616 }
62617 if (in_array('int', $lowerTypes, \true)) {
62618 return 0;
62619 }
62620 if (in_array('string', $lowerTypes, \true)) {
62621 return '';
62622 }
62623 if (in_array('array', $lowerTypes, \true)) {
62624 return [];
62625 }
62626 if (in_array('static', $lowerTypes, \true)) {
62627 return $this->newInstanceOf($stubClassName, $className, $methodName);
62628 }
62629 if (in_array('object', $lowerTypes, \true)) {
62630 return new stdClass();
62631 }
62632 if (in_array('callable', $lowerTypes, \true) || in_array('closure', $lowerTypes, \true)) {
62633 return static function (): void {
62634 };
62635 }
62636 if (in_array('traversable', $lowerTypes, \true) || in_array('generator', $lowerTypes, \true) || in_array('iterable', $lowerTypes, \true)) {
62637 $generator = static function (): \Generator {
62638 yield from [];
62639 };
62640 return $generator();
62641 }
62642 if (!$union) {
62643 return $this->testDoubleFor($returnType, $className, $methodName);
62644 }
62645 }
62646 if ($union) {
62647 foreach ($types as $type) {
62648 if (str_contains($type, '&')) {
62649 $_types = explode('&', $type);
62650 if ($this->onlyInterfaces($_types)) {
62651 return $this->testDoubleForIntersectionOfInterfaces($_types, $className, $methodName);
62652 }
62653 }
62654 }
62655 }
62656 if ($intersection && $this->onlyInterfaces($types)) {
62657 return $this->testDoubleForIntersectionOfInterfaces($types, $className, $methodName);
62658 }
62659 $reason = '';
62660 if ($union) {
62661 $reason = ' because the declared return type is a union';
62662 } elseif ($intersection) {
62663 $reason = ' because the declared return type is an intersection';
62664 }
62665 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));
62666 }
62667 /**
62668 * @psalm-param non-empty-list<string> $types
62669 */
62670 private function onlyInterfaces(array $types): bool
62671 {
62672 foreach ($types as $type) {
62673 if (!interface_exists($type)) {
62674 return \false;
62675 }
62676 }
62677 return \true;
62678 }
62679 /**
62680 * @psalm-param class-string $stubClassName
62681 * @psalm-param class-string $className
62682 * @psalm-param non-empty-string $methodName
62683 *
62684 * @throws RuntimeException
62685 */
62686 private function newInstanceOf(string $stubClassName, string $className, string $methodName): \PHPUnit\Framework\MockObject\Stub
62687 {
62688 try {
62689 return (new ReflectionClass($stubClassName))->newInstanceWithoutConstructor();
62690 // @codeCoverageIgnoreStart
62691 } catch (Throwable $t) {
62692 throw new \PHPUnit\Framework\MockObject\RuntimeException(sprintf('Return value for %s::%s() cannot be generated: %s', $className, $methodName, $t->getMessage()));
62693 // @codeCoverageIgnoreEnd
62694 }
62695 }
62696 /**
62697 * @psalm-param class-string $type
62698 * @psalm-param class-string $className
62699 * @psalm-param non-empty-string $methodName
62700 *
62701 * @throws RuntimeException
62702 */
62703 private function testDoubleFor(string $type, string $className, string $methodName): \PHPUnit\Framework\MockObject\Stub
62704 {
62705 try {
62706 return (new Generator())->testDouble($type, \false, [], [], '', \false);
62707 // @codeCoverageIgnoreStart
62708 } catch (Throwable $t) {
62709 throw new \PHPUnit\Framework\MockObject\RuntimeException(sprintf('Return value for %s::%s() cannot be generated: %s', $className, $methodName, $t->getMessage()));
62710 // @codeCoverageIgnoreEnd
62711 }
62712 }
62713 /**
62714 * @psalm-param non-empty-list<string> $types
62715 * @psalm-param class-string $className
62716 * @psalm-param non-empty-string $methodName
62717 *
62718 * @throws RuntimeException
62719 */
62720 private function testDoubleForIntersectionOfInterfaces(array $types, string $className, string $methodName): \PHPUnit\Framework\MockObject\Stub
62721 {
62722 try {
62723 return (new Generator())->testDoubleForInterfaceIntersection($types, \false);
62724 // @codeCoverageIgnoreStart
62725 } catch (Throwable $t) {
62726 throw new \PHPUnit\Framework\MockObject\RuntimeException(sprintf('Return value for %s::%s() cannot be generated: %s', $className, $methodName, $t->getMessage()));
62727 // @codeCoverageIgnoreEnd
62728 }
62729 }
62730 }
62731 <?php
62732
62733 declare (strict_types=1);
62734 /*
62735 * This file is part of PHPUnit.
62736 *
62737 * (c) Sebastian Bergmann <sebastian@phpunit.de>
62738 *
62739 * For the full copyright and license information, please view the LICENSE
62740 * file that was distributed with this source code.
62741 */
62742 namespace PHPUnit\Framework\MockObject\Rule;
62743
62744 use PHPUnit\Framework\MockObject\Invocation as BaseInvocation;
62745 /**
62746 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
62747 *
62748 * @internal This class is not covered by the backward compatibility promise for PHPUnit
62749 */
62750 final class AnyInvokedCount extends \PHPUnit\Framework\MockObject\Rule\InvocationOrder
62751 {
62752 public function toString(): string
62753 {
62754 return 'invoked zero or more times';
62755 }
62756 public function verify(): void
62757 {
62758 }
62759 public function matches(BaseInvocation $invocation): bool
62760 {
62761 return \true;
62762 }
62763 }
62764 <?php
62765
62766 declare (strict_types=1);
62767 /*
62768 * This file is part of PHPUnit.
62769 *
62770 * (c) Sebastian Bergmann <sebastian@phpunit.de>
62771 *
62772 * For the full copyright and license information, please view the LICENSE
62773 * file that was distributed with this source code.
62774 */
62775 namespace PHPUnit\Framework\MockObject\Rule;
62776
62777 use PHPUnit\Framework\MockObject\Invocation as BaseInvocation;
62778 /**
62779 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
62780 *
62781 * @internal This class is not covered by the backward compatibility promise for PHPUnit
62782 */
62783 final class AnyParameters implements \PHPUnit\Framework\MockObject\Rule\ParametersRule
62784 {
62785 public function apply(BaseInvocation $invocation): void
62786 {
62787 }
62788 public function verify(): void
62789 {
62790 }
62791 }
62792 <?php
62793
62794 declare (strict_types=1);
62795 /*
62796 * This file is part of PHPUnit.
62797 *
62798 * (c) Sebastian Bergmann <sebastian@phpunit.de>
62799 *
62800 * For the full copyright and license information, please view the LICENSE
62801 * file that was distributed with this source code.
62802 */
62803 namespace PHPUnit\Framework\MockObject\Rule;
62804
62805 use function count;
62806 use PHPUnit\Framework\MockObject\Invocation as BaseInvocation;
62807 use PHPUnit\Framework\SelfDescribing;
62808 /**
62809 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
62810 *
62811 * @internal This class is not covered by the backward compatibility promise for PHPUnit
62812 */
62813 abstract class InvocationOrder implements SelfDescribing
62814 {
62815 /**
62816 * @psalm-var list<BaseInvocation>
62817 */
62818 private array $invocations = [];
62819 public function numberOfInvocations(): int
62820 {
62821 return count($this->invocations);
62822 }
62823 public function hasBeenInvoked(): bool
62824 {
62825 return count($this->invocations) > 0;
62826 }
62827 final public function invoked(BaseInvocation $invocation): void
62828 {
62829 $this->invocations[] = $invocation;
62830 $this->invokedDo($invocation);
62831 }
62832 abstract public function matches(BaseInvocation $invocation): bool;
62833 abstract public function verify(): void;
62834 protected function invokedDo(BaseInvocation $invocation): void
62835 {
62836 }
62837 }
62838 <?php
62839
62840 declare (strict_types=1);
62841 /*
62842 * This file is part of PHPUnit.
62843 *
62844 * (c) Sebastian Bergmann <sebastian@phpunit.de>
62845 *
62846 * For the full copyright and license information, please view the LICENSE
62847 * file that was distributed with this source code.
62848 */
62849 namespace PHPUnit\Framework\MockObject\Rule;
62850
62851 use function sprintf;
62852 use PHPUnit\Framework\ExpectationFailedException;
62853 use PHPUnit\Framework\MockObject\Invocation as BaseInvocation;
62854 /**
62855 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
62856 *
62857 * @internal This class is not covered by the backward compatibility promise for PHPUnit
62858 */
62859 final class InvokedAtLeastCount extends \PHPUnit\Framework\MockObject\Rule\InvocationOrder
62860 {
62861 private readonly int $requiredInvocations;
62862 public function __construct(int $requiredInvocations)
62863 {
62864 $this->requiredInvocations = $requiredInvocations;
62865 }
62866 public function toString(): string
62867 {
62868 return sprintf('invoked at least %d time%s', $this->requiredInvocations, $this->requiredInvocations !== 1 ? 's' : '');
62869 }
62870 /**
62871 * Verifies that the current expectation is valid. If everything is OK the
62872 * code should just return, if not it must throw an exception.
62873 *
62874 * @throws ExpectationFailedException
62875 */
62876 public function verify(): void
62877 {
62878 $actualInvocations = $this->numberOfInvocations();
62879 if ($actualInvocations < $this->requiredInvocations) {
62880 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' : ''));
62881 }
62882 }
62883 public function matches(BaseInvocation $invocation): bool
62884 {
62885 return \true;
62886 }
62887 }
62888 <?php
62889
62890 declare (strict_types=1);
62891 /*
62892 * This file is part of PHPUnit.
62893 *
62894 * (c) Sebastian Bergmann <sebastian@phpunit.de>
62895 *
62896 * For the full copyright and license information, please view the LICENSE
62897 * file that was distributed with this source code.
62898 */
62899 namespace PHPUnit\Framework\MockObject\Rule;
62900
62901 use PHPUnit\Framework\ExpectationFailedException;
62902 use PHPUnit\Framework\MockObject\Invocation as BaseInvocation;
62903 /**
62904 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
62905 *
62906 * @internal This class is not covered by the backward compatibility promise for PHPUnit
62907 */
62908 final class InvokedAtLeastOnce extends \PHPUnit\Framework\MockObject\Rule\InvocationOrder
62909 {
62910 public function toString(): string
62911 {
62912 return 'invoked at least once';
62913 }
62914 /**
62915 * Verifies that the current expectation is valid. If everything is OK the
62916 * code should just return, if not it must throw an exception.
62917 *
62918 * @throws ExpectationFailedException
62919 */
62920 public function verify(): void
62921 {
62922 $count = $this->numberOfInvocations();
62923 if ($count < 1) {
62924 throw new ExpectationFailedException('Expected invocation at least once but it never occurred.');
62925 }
62926 }
62927 public function matches(BaseInvocation $invocation): bool
62928 {
62929 return \true;
62930 }
62931 }
62932 <?php
62933
62934 declare (strict_types=1);
62935 /*
62936 * This file is part of PHPUnit.
62937 *
62938 * (c) Sebastian Bergmann <sebastian@phpunit.de>
62939 *
62940 * For the full copyright and license information, please view the LICENSE
62941 * file that was distributed with this source code.
62942 */
62943 namespace PHPUnit\Framework\MockObject\Rule;
62944
62945 use function sprintf;
62946 use PHPUnit\Framework\ExpectationFailedException;
62947 use PHPUnit\Framework\MockObject\Invocation as BaseInvocation;
62948 /**
62949 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
62950 *
62951 * @internal This class is not covered by the backward compatibility promise for PHPUnit
62952 */
62953 final class InvokedAtMostCount extends \PHPUnit\Framework\MockObject\Rule\InvocationOrder
62954 {
62955 private readonly int $allowedInvocations;
62956 public function __construct(int $allowedInvocations)
62957 {
62958 $this->allowedInvocations = $allowedInvocations;
62959 }
62960 public function toString(): string
62961 {
62962 return sprintf('invoked at most %d time%s', $this->allowedInvocations, $this->allowedInvocations !== 1 ? 's' : '');
62963 }
62964 /**
62965 * Verifies that the current expectation is valid. If everything is OK the
62966 * code should just return, if not it must throw an exception.
62967 *
62968 * @throws ExpectationFailedException
62969 */
62970 public function verify(): void
62971 {
62972 $actualInvocations = $this->numberOfInvocations();
62973 if ($actualInvocations > $this->allowedInvocations) {
62974 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' : ''));
62975 }
62976 }
62977 public function matches(BaseInvocation $invocation): bool
62978 {
62979 return \true;
62980 }
62981 }
62982 <?php
62983
62984 declare (strict_types=1);
62985 /*
62986 * This file is part of PHPUnit.
62987 *
62988 * (c) Sebastian Bergmann <sebastian@phpunit.de>
62989 *
62990 * For the full copyright and license information, please view the LICENSE
62991 * file that was distributed with this source code.
62992 */
62993 namespace PHPUnit\Framework\MockObject\Rule;
62994
62995 use function sprintf;
62996 use PHPUnit\Framework\ExpectationFailedException;
62997 use PHPUnit\Framework\MockObject\Invocation as BaseInvocation;
62998 /**
62999 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
63000 *
63001 * @internal This class is not covered by the backward compatibility promise for PHPUnit
63002 */
63003 final class InvokedCount extends \PHPUnit\Framework\MockObject\Rule\InvocationOrder
63004 {
63005 private readonly int $expectedCount;
63006 public function __construct(int $expectedCount)
63007 {
63008 $this->expectedCount = $expectedCount;
63009 }
63010 public function isNever(): bool
63011 {
63012 return $this->expectedCount === 0;
63013 }
63014 public function toString(): string
63015 {
63016 return sprintf('invoked %d time%s', $this->expectedCount, $this->expectedCount !== 1 ? 's' : '');
63017 }
63018 public function matches(BaseInvocation $invocation): bool
63019 {
63020 return \true;
63021 }
63022 /**
63023 * Verifies that the current expectation is valid. If everything is OK the
63024 * code should just return, if not it must throw an exception.
63025 *
63026 * @throws ExpectationFailedException
63027 */
63028 public function verify(): void
63029 {
63030 $actualCount = $this->numberOfInvocations();
63031 if ($actualCount !== $this->expectedCount) {
63032 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' : ''));
63033 }
63034 }
63035 /**
63036 * @throws ExpectationFailedException
63037 */
63038 protected function invokedDo(BaseInvocation $invocation): void
63039 {
63040 $count = $this->numberOfInvocations();
63041 if ($count > $this->expectedCount) {
63042 $message = $invocation->toString() . ' ';
63043 $message .= match ($this->expectedCount) {
63044 0 => 'was not expected to be called.',
63045 1 => 'was not expected to be called more than once.',
63046 default => sprintf('was not expected to be called more than %d times.', $this->expectedCount),
63047 };
63048 throw new ExpectationFailedException($message);
63049 }
63050 }
63051 }
63052 <?php
63053
63054 declare (strict_types=1);
63055 /*
63056 * This file is part of PHPUnit.
63057 *
63058 * (c) Sebastian Bergmann <sebastian@phpunit.de>
63059 *
63060 * For the full copyright and license information, please view the LICENSE
63061 * file that was distributed with this source code.
63062 */
63063 namespace PHPUnit\Framework\MockObject\Rule;
63064
63065 use function is_string;
63066 use PHPUnit\Framework\Constraint\Constraint;
63067 use PHPUnit\Framework\ExpectationFailedException;
63068 use PHPUnit\Framework\InvalidArgumentException;
63069 use PHPUnit\Framework\MockObject\Invocation as BaseInvocation;
63070 use PHPUnit\Framework\MockObject\MethodNameConstraint;
63071 /**
63072 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
63073 *
63074 * @internal This class is not covered by the backward compatibility promise for PHPUnit
63075 */
63076 final class MethodName
63077 {
63078 private readonly Constraint $constraint;
63079 /**
63080 * @throws InvalidArgumentException
63081 */
63082 public function __construct(Constraint|string $constraint)
63083 {
63084 if (is_string($constraint)) {
63085 $constraint = new MethodNameConstraint($constraint);
63086 }
63087 $this->constraint = $constraint;
63088 }
63089 public function toString(): string
63090 {
63091 return 'method name ' . $this->constraint->toString();
63092 }
63093 /**
63094 * @throws ExpectationFailedException
63095 */
63096 public function matches(BaseInvocation $invocation): bool
63097 {
63098 return $this->matchesName($invocation->methodName());
63099 }
63100 /**
63101 * @throws ExpectationFailedException
63102 */
63103 public function matchesName(string $methodName): bool
63104 {
63105 return (bool) $this->constraint->evaluate($methodName, '', \true);
63106 }
63107 }
63108 <?php
63109
63110 declare (strict_types=1);
63111 /*
63112 * This file is part of PHPUnit.
63113 *
63114 * (c) Sebastian Bergmann <sebastian@phpunit.de>
63115 *
63116 * For the full copyright and license information, please view the LICENSE
63117 * file that was distributed with this source code.
63118 */
63119 namespace PHPUnit\Framework\MockObject\Rule;
63120
63121 use function count;
63122 use function sprintf;
63123 use Exception;
63124 use PHPUnit\Framework\Constraint\Callback;
63125 use PHPUnit\Framework\Constraint\Constraint;
63126 use PHPUnit\Framework\Constraint\IsAnything;
63127 use PHPUnit\Framework\Constraint\IsEqual;
63128 use PHPUnit\Framework\ExpectationFailedException;
63129 use PHPUnit\Framework\MockObject\Invocation as BaseInvocation;
63130 /**
63131 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
63132 *
63133 * @internal This class is not covered by the backward compatibility promise for PHPUnit
63134 */
63135 final class Parameters implements \PHPUnit\Framework\MockObject\Rule\ParametersRule
63136 {
63137 /**
63138 * @psalm-var list<Constraint>
63139 */
63140 private array $parameters = [];
63141 private ?BaseInvocation $invocation = null;
63142 private null|bool|ExpectationFailedException $parameterVerificationResult;
63143 /**
63144 * @throws \PHPUnit\Framework\Exception
63145 */
63146 public function __construct(array $parameters)
63147 {
63148 foreach ($parameters as $parameter) {
63149 if (!$parameter instanceof Constraint) {
63150 $parameter = new IsEqual($parameter);
63151 }
63152 $this->parameters[] = $parameter;
63153 }
63154 }
63155 /**
63156 * @throws Exception
63157 */
63158 public function apply(BaseInvocation $invocation): void
63159 {
63160 $this->invocation = $invocation;
63161 $this->parameterVerificationResult = null;
63162 try {
63163 $this->parameterVerificationResult = $this->doVerify();
63164 } catch (ExpectationFailedException $e) {
63165 $this->parameterVerificationResult = $e;
63166 throw $this->parameterVerificationResult;
63167 }
63168 }
63169 /**
63170 * Checks if the invocation $invocation matches the current rules. If it
63171 * does the rule will get the invoked() method called which should check
63172 * if an expectation is met.
63173 *
63174 * @throws ExpectationFailedException
63175 */
63176 public function verify(): void
63177 {
63178 $this->doVerify();
63179 }
63180 /**
63181 * @throws ExpectationFailedException
63182 */
63183 private function doVerify(): bool
63184 {
63185 if (isset($this->parameterVerificationResult)) {
63186 return $this->guardAgainstDuplicateEvaluationOfParameterConstraints();
63187 }
63188 if ($this->invocation === null) {
63189 throw new ExpectationFailedException('Doubled method does not exist.');
63190 }
63191 if (count($this->invocation->parameters()) < count($this->parameters)) {
63192 $message = 'Parameter count for invocation %s is too low.';
63193 // The user called `->with($this->anything())`, but may have meant
63194 // `->withAnyParameters()`.
63195 //
63196 // @see https://github.com/sebastianbergmann/phpunit-mock-objects/issues/199
63197 if (count($this->parameters) === 1 && $this->parameters[0]::class === IsAnything::class) {
63198 $message .= "\nTo allow 0 or more parameters with any value, omit ->with() or use ->withAnyParameters() instead.";
63199 }
63200 throw new ExpectationFailedException(sprintf($message, $this->invocation->toString()));
63201 }
63202 foreach ($this->parameters as $i => $parameter) {
63203 if ($parameter instanceof Callback && $parameter->isVariadic()) {
63204 $other = $this->invocation->parameters();
63205 } else {
63206 $other = $this->invocation->parameters()[$i];
63207 }
63208 $parameter->evaluate($other, sprintf('Parameter %s for invocation %s does not match expected value.', $i, $this->invocation->toString()));
63209 }
63210 return \true;
63211 }
63212 /**
63213 * @throws ExpectationFailedException
63214 */
63215 private function guardAgainstDuplicateEvaluationOfParameterConstraints(): bool
63216 {
63217 if ($this->parameterVerificationResult instanceof ExpectationFailedException) {
63218 throw $this->parameterVerificationResult;
63219 }
63220 return (bool) $this->parameterVerificationResult;
63221 }
63222 }
63223 <?php
63224
63225 declare (strict_types=1);
63226 /*
63227 * This file is part of PHPUnit.
63228 *
63229 * (c) Sebastian Bergmann <sebastian@phpunit.de>
63230 *
63231 * For the full copyright and license information, please view the LICENSE
63232 * file that was distributed with this source code.
63233 */
63234 namespace PHPUnit\Framework\MockObject\Rule;
63235
63236 use PHPUnit\Framework\ExpectationFailedException;
63237 use PHPUnit\Framework\MockObject\Invocation as BaseInvocation;
63238 /**
63239 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
63240 */
63241 interface ParametersRule
63242 {
63243 /**
63244 * @throws ExpectationFailedException if the invocation violates the rule
63245 */
63246 public function apply(BaseInvocation $invocation): void;
63247 public function verify(): void;
63248 }
63249 <?php
63250
63251 declare (strict_types=1);
63252 /*
63253 * This file is part of PHPUnit.
63254 *
63255 * (c) Sebastian Bergmann <sebastian@phpunit.de>
63256 *
63257 * For the full copyright and license information, please view the LICENSE
63258 * file that was distributed with this source code.
63259 */
63260 namespace PHPUnit\Framework\MockObject\Stub;
63261
63262 use function array_shift;
63263 use function count;
63264 use PHPUnit\Framework\MockObject\Invocation;
63265 use PHPUnit\Framework\MockObject\NoMoreReturnValuesConfiguredException;
63266 /**
63267 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
63268 *
63269 * @internal This class is not covered by the backward compatibility promise for PHPUnit
63270 */
63271 final class ConsecutiveCalls implements \PHPUnit\Framework\MockObject\Stub\Stub
63272 {
63273 private array $stack;
63274 private int $numberOfConfiguredReturnValues;
63275 public function __construct(array $stack)
63276 {
63277 $this->stack = $stack;
63278 $this->numberOfConfiguredReturnValues = count($stack);
63279 }
63280 /**
63281 * @throws NoMoreReturnValuesConfiguredException
63282 */
63283 public function invoke(Invocation $invocation): mixed
63284 {
63285 if (empty($this->stack)) {
63286 throw new NoMoreReturnValuesConfiguredException($invocation, $this->numberOfConfiguredReturnValues);
63287 }
63288 $value = array_shift($this->stack);
63289 if ($value instanceof \PHPUnit\Framework\MockObject\Stub\Stub) {
63290 $value = $value->invoke($invocation);
63291 }
63292 return $value;
63293 }
63294 }
63295 <?php
63296
63297 declare (strict_types=1);
63298 /*
63299 * This file is part of PHPUnit.
63300 *
63301 * (c) Sebastian Bergmann <sebastian@phpunit.de>
63302 *
63303 * For the full copyright and license information, please view the LICENSE
63304 * file that was distributed with this source code.
63305 */
63306 namespace PHPUnit\Framework\MockObject\Stub;
63307
63308 use PHPUnit\Framework\MockObject\Invocation;
63309 use Throwable;
63310 /**
63311 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
63312 *
63313 * @internal This class is not covered by the backward compatibility promise for PHPUnit
63314 */
63315 final class Exception implements \PHPUnit\Framework\MockObject\Stub\Stub
63316 {
63317 private readonly Throwable $exception;
63318 public function __construct(Throwable $exception)
63319 {
63320 $this->exception = $exception;
63321 }
63322 /**
63323 * @throws Throwable
63324 */
63325 public function invoke(Invocation $invocation): never
63326 {
63327 throw $this->exception;
63328 }
63329 }
63330 <?php
63331
63332 declare (strict_types=1);
63333 /*
63334 * This file is part of PHPUnit.
63335 *
63336 * (c) Sebastian Bergmann <sebastian@phpunit.de>
63337 *
63338 * For the full copyright and license information, please view the LICENSE
63339 * file that was distributed with this source code.
63340 */
63341 namespace PHPUnit\Framework\MockObject\Stub;
63342
63343 use PHPUnit\Framework\MockObject\Invocation;
63344 /**
63345 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
63346 *
63347 * @internal This class is not covered by the backward compatibility promise for PHPUnit
63348 */
63349 final class ReturnArgument implements \PHPUnit\Framework\MockObject\Stub\Stub
63350 {
63351 private readonly int $argumentIndex;
63352 public function __construct(int $argumentIndex)
63353 {
63354 $this->argumentIndex = $argumentIndex;
63355 }
63356 public function invoke(Invocation $invocation): mixed
63357 {
63358 return $invocation->parameters()[$this->argumentIndex] ?? null;
63359 }
63360 }
63361 <?php
63362
63363 declare (strict_types=1);
63364 /*
63365 * This file is part of PHPUnit.
63366 *
63367 * (c) Sebastian Bergmann <sebastian@phpunit.de>
63368 *
63369 * For the full copyright and license information, please view the LICENSE
63370 * file that was distributed with this source code.
63371 */
63372 namespace PHPUnit\Framework\MockObject\Stub;
63373
63374 use function call_user_func_array;
63375 use PHPUnit\Framework\MockObject\Invocation;
63376 /**
63377 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
63378 *
63379 * @internal This class is not covered by the backward compatibility promise for PHPUnit
63380 */
63381 final class ReturnCallback implements \PHPUnit\Framework\MockObject\Stub\Stub
63382 {
63383 /**
63384 * @var callable
63385 */
63386 private $callback;
63387 public function __construct(callable $callback)
63388 {
63389 $this->callback = $callback;
63390 }
63391 public function invoke(Invocation $invocation): mixed
63392 {
63393 return call_user_func_array($this->callback, $invocation->parameters());
63394 }
63395 }
63396 <?php
63397
63398 declare (strict_types=1);
63399 /*
63400 * This file is part of PHPUnit.
63401 *
63402 * (c) Sebastian Bergmann <sebastian@phpunit.de>
63403 *
63404 * For the full copyright and license information, please view the LICENSE
63405 * file that was distributed with this source code.
63406 */
63407 namespace PHPUnit\Framework\MockObject\Stub;
63408
63409 use PHPUnit\Framework\MockObject\Invocation;
63410 /**
63411 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
63412 *
63413 * @internal This class is not covered by the backward compatibility promise for PHPUnit
63414 */
63415 final class ReturnReference implements \PHPUnit\Framework\MockObject\Stub\Stub
63416 {
63417 private mixed $reference;
63418 public function __construct(mixed &$reference)
63419 {
63420 $this->reference =& $reference;
63421 }
63422 public function invoke(Invocation $invocation): mixed
63423 {
63424 return $this->reference;
63425 }
63426 }
63427 <?php
63428
63429 declare (strict_types=1);
63430 /*
63431 * This file is part of PHPUnit.
63432 *
63433 * (c) Sebastian Bergmann <sebastian@phpunit.de>
63434 *
63435 * For the full copyright and license information, please view the LICENSE
63436 * file that was distributed with this source code.
63437 */
63438 namespace PHPUnit\Framework\MockObject\Stub;
63439
63440 use PHPUnit\Framework\MockObject\Invocation;
63441 use PHPUnit\Framework\MockObject\RuntimeException;
63442 /**
63443 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
63444 *
63445 * @internal This class is not covered by the backward compatibility promise for PHPUnit
63446 */
63447 final class ReturnSelf implements \PHPUnit\Framework\MockObject\Stub\Stub
63448 {
63449 /**
63450 * @throws RuntimeException
63451 */
63452 public function invoke(Invocation $invocation): object
63453 {
63454 return $invocation->object();
63455 }
63456 }
63457 <?php
63458
63459 declare (strict_types=1);
63460 /*
63461 * This file is part of PHPUnit.
63462 *
63463 * (c) Sebastian Bergmann <sebastian@phpunit.de>
63464 *
63465 * For the full copyright and license information, please view the LICENSE
63466 * file that was distributed with this source code.
63467 */
63468 namespace PHPUnit\Framework\MockObject\Stub;
63469
63470 use PHPUnit\Framework\MockObject\Invocation;
63471 /**
63472 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
63473 *
63474 * @internal This class is not covered by the backward compatibility promise for PHPUnit
63475 */
63476 final class ReturnStub implements \PHPUnit\Framework\MockObject\Stub\Stub
63477 {
63478 private readonly mixed $value;
63479 public function __construct(mixed $value)
63480 {
63481 $this->value = $value;
63482 }
63483 public function invoke(Invocation $invocation): mixed
63484 {
63485 return $this->value;
63486 }
63487 }
63488 <?php
63489
63490 declare (strict_types=1);
63491 /*
63492 * This file is part of PHPUnit.
63493 *
63494 * (c) Sebastian Bergmann <sebastian@phpunit.de>
63495 *
63496 * For the full copyright and license information, please view the LICENSE
63497 * file that was distributed with this source code.
63498 */
63499 namespace PHPUnit\Framework\MockObject\Stub;
63500
63501 use function array_pop;
63502 use function count;
63503 use function is_array;
63504 use PHPUnit\Framework\MockObject\Invocation;
63505 /**
63506 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
63507 *
63508 * @internal This class is not covered by the backward compatibility promise for PHPUnit
63509 */
63510 final class ReturnValueMap implements \PHPUnit\Framework\MockObject\Stub\Stub
63511 {
63512 private readonly array $valueMap;
63513 public function __construct(array $valueMap)
63514 {
63515 $this->valueMap = $valueMap;
63516 }
63517 public function invoke(Invocation $invocation): mixed
63518 {
63519 $parameterCount = count($invocation->parameters());
63520 foreach ($this->valueMap as $map) {
63521 if (!is_array($map) || $parameterCount !== count($map) - 1) {
63522 continue;
63523 }
63524 $return = array_pop($map);
63525 if ($invocation->parameters() === $map) {
63526 return $return;
63527 }
63528 }
63529 return null;
63530 }
63531 }
63532 <?php
63533
63534 declare (strict_types=1);
63535 /*
63536 * This file is part of PHPUnit.
63537 *
63538 * (c) Sebastian Bergmann <sebastian@phpunit.de>
63539 *
63540 * For the full copyright and license information, please view the LICENSE
63541 * file that was distributed with this source code.
63542 */
63543 namespace PHPUnit\Framework\MockObject\Stub;
63544
63545 use PHPUnit\Framework\MockObject\Invocation;
63546 /**
63547 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
63548 *
63549 * @internal This interface is not covered by the backward compatibility promise for PHPUnit
63550 */
63551 interface Stub
63552 {
63553 /**
63554 * Fakes the processing of the invocation $invocation by returning a
63555 * specific value.
63556 */
63557 public function invoke(Invocation $invocation): mixed;
63558 }
63559 <?php
63560
63561 declare (strict_types=1);
63562 /*
63563 * This file is part of PHPUnit.
63564 *
63565 * (c) Sebastian Bergmann <sebastian@phpunit.de>
63566 *
63567 * For the full copyright and license information, please view the LICENSE
63568 * file that was distributed with this source code.
63569 */
63570 namespace PHPUnit\Framework;
63571
63572 /**
63573 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
63574 *
63575 * @internal This interface is not covered by the backward compatibility promise for PHPUnit
63576 */
63577 interface Reorderable
63578 {
63579 public function sortId(): string;
63580 /**
63581 * @psalm-return list<ExecutionOrderDependency>
63582 */
63583 public function provides(): array;
63584 /**
63585 * @psalm-return list<ExecutionOrderDependency>
63586 */
63587 public function requires(): array;
63588 }
63589 <?php
63590
63591 declare (strict_types=1);
63592 /*
63593 * This file is part of PHPUnit.
63594 *
63595 * (c) Sebastian Bergmann <sebastian@phpunit.de>
63596 *
63597 * For the full copyright and license information, please view the LICENSE
63598 * file that was distributed with this source code.
63599 */
63600 namespace PHPUnit\Framework;
63601
63602 /**
63603 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
63604 *
63605 * @internal This interface is not covered by the backward compatibility promise for PHPUnit
63606 */
63607 interface SelfDescribing
63608 {
63609 /**
63610 * Returns a string representation of the object.
63611 */
63612 public function toString(): string;
63613 }
63614 <?php
63615
63616 declare (strict_types=1);
63617 /*
63618 * This file is part of PHPUnit.
63619 *
63620 * (c) Sebastian Bergmann <sebastian@phpunit.de>
63621 *
63622 * For the full copyright and license information, please view the LICENSE
63623 * file that was distributed with this source code.
63624 */
63625 namespace PHPUnit\Framework;
63626
63627 use Countable;
63628 /**
63629 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
63630 */
63631 interface Test extends Countable
63632 {
63633 public function run(): void;
63634 }
63635 <?php
63636
63637 declare (strict_types=1);
63638 /*
63639 * This file is part of PHPUnit.
63640 *
63641 * (c) Sebastian Bergmann <sebastian@phpunit.de>
63642 *
63643 * For the full copyright and license information, please view the LICENSE
63644 * file that was distributed with this source code.
63645 */
63646 namespace PHPUnit\Framework;
63647
63648 use function assert;
63649 use PHPUnit\Metadata\Api\DataProvider;
63650 use PHPUnit\Metadata\Api\Groups;
63651 use PHPUnit\Metadata\Api\Requirements;
63652 use PHPUnit\Metadata\BackupGlobals;
63653 use PHPUnit\Metadata\BackupStaticProperties;
63654 use PHPUnit\Metadata\ExcludeGlobalVariableFromBackup;
63655 use PHPUnit\Metadata\ExcludeStaticPropertyFromBackup;
63656 use PHPUnit\Metadata\Parser\Registry as MetadataRegistry;
63657 use PHPUnit\Metadata\PreserveGlobalState;
63658 use PHPUnit\TextUI\Configuration\Registry as ConfigurationRegistry;
63659 use ReflectionClass;
63660 /**
63661 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
63662 *
63663 * @internal This class is not covered by the backward compatibility promise for PHPUnit
63664 */
63665 final class TestBuilder
63666 {
63667 /**
63668 * @psalm-param non-empty-string $methodName
63669 *
63670 * @throws InvalidDataProviderException
63671 */
63672 public function build(ReflectionClass $theClass, string $methodName): \PHPUnit\Framework\Test
63673 {
63674 $className = $theClass->getName();
63675 $data = null;
63676 if ($this->requirementsSatisfied($className, $methodName)) {
63677 $data = (new DataProvider())->providedData($className, $methodName);
63678 }
63679 if ($data !== null) {
63680 return $this->buildDataProviderTestSuite($methodName, $className, $data, $this->shouldTestMethodBeRunInSeparateProcess($className, $methodName), $this->shouldGlobalStateBePreserved($className, $methodName), $this->shouldAllTestMethodsOfTestClassBeRunInSingleSeparateProcess($className), $this->backupSettings($className, $methodName));
63681 }
63682 $test = new $className($methodName);
63683 assert($test instanceof \PHPUnit\Framework\TestCase);
63684 $this->configureTestCase($test, $this->shouldTestMethodBeRunInSeparateProcess($className, $methodName), $this->shouldGlobalStateBePreserved($className, $methodName), $this->shouldAllTestMethodsOfTestClassBeRunInSingleSeparateProcess($className), $this->backupSettings($className, $methodName));
63685 return $test;
63686 }
63687 /**
63688 * @psalm-param class-string $className
63689 * @psalm-param non-empty-string $methodName
63690 * @psalm-param array{backupGlobals: ?bool, backupGlobalsExcludeList: list<string>, backupStaticProperties: ?bool, backupStaticPropertiesExcludeList: array<string,list<string>>} $backupSettings
63691 */
63692 private function buildDataProviderTestSuite(string $methodName, string $className, array $data, bool $runTestInSeparateProcess, ?bool $preserveGlobalState, bool $runClassInSeparateProcess, array $backupSettings): \PHPUnit\Framework\DataProviderTestSuite
63693 {
63694 $dataProviderTestSuite = \PHPUnit\Framework\DataProviderTestSuite::empty($className . '::' . $methodName);
63695 $groups = (new Groups())->groups($className, $methodName);
63696 foreach ($data as $_dataName => $_data) {
63697 $_test = new $className($methodName);
63698 assert($_test instanceof \PHPUnit\Framework\TestCase);
63699 $_test->setData($_dataName, $_data);
63700 $this->configureTestCase($_test, $runTestInSeparateProcess, $preserveGlobalState, $runClassInSeparateProcess, $backupSettings);
63701 $dataProviderTestSuite->addTest($_test, $groups);
63702 }
63703 return $dataProviderTestSuite;
63704 }
63705 /**
63706 * @psalm-param array{backupGlobals: ?bool, backupGlobalsExcludeList: list<string>, backupStaticProperties: ?bool, backupStaticPropertiesExcludeList: array<string,list<string>>} $backupSettings
63707 */
63708 private function configureTestCase(\PHPUnit\Framework\TestCase $test, bool $runTestInSeparateProcess, ?bool $preserveGlobalState, bool $runClassInSeparateProcess, array $backupSettings): void
63709 {
63710 if ($runTestInSeparateProcess) {
63711 $test->setRunTestInSeparateProcess(\true);
63712 }
63713 if ($runClassInSeparateProcess) {
63714 $test->setRunClassInSeparateProcess(\true);
63715 }
63716 if ($preserveGlobalState !== null) {
63717 $test->setPreserveGlobalState($preserveGlobalState);
63718 }
63719 if ($backupSettings['backupGlobals'] !== null) {
63720 $test->setBackupGlobals($backupSettings['backupGlobals']);
63721 } else {
63722 $test->setBackupGlobals(ConfigurationRegistry::get()->backupGlobals());
63723 }
63724 $test->setBackupGlobalsExcludeList($backupSettings['backupGlobalsExcludeList']);
63725 if ($backupSettings['backupStaticProperties'] !== null) {
63726 $test->setBackupStaticProperties($backupSettings['backupStaticProperties']);
63727 } else {
63728 $test->setBackupStaticProperties(ConfigurationRegistry::get()->backupStaticProperties());
63729 }
63730 $test->setBackupStaticPropertiesExcludeList($backupSettings['backupStaticPropertiesExcludeList']);
63731 }
63732 /**
63733 * @psalm-param class-string $className
63734 * @psalm-param non-empty-string $methodName
63735 *
63736 * @psalm-return array{backupGlobals: ?bool, backupGlobalsExcludeList: list<string>, backupStaticProperties: ?bool, backupStaticPropertiesExcludeList: array<string,list<string>>}
63737 */
63738 private function backupSettings(string $className, string $methodName): array
63739 {
63740 $metadataForClass = MetadataRegistry::parser()->forClass($className);
63741 $metadataForMethod = MetadataRegistry::parser()->forMethod($className, $methodName);
63742 $metadataForClassAndMethod = MetadataRegistry::parser()->forClassAndMethod($className, $methodName);
63743 $backupGlobals = null;
63744 $backupGlobalsExcludeList = [];
63745 if ($metadataForMethod->isBackupGlobals()->isNotEmpty()) {
63746 $metadata = $metadataForMethod->isBackupGlobals()->asArray()[0];
63747 assert($metadata instanceof BackupGlobals);
63748 if ($metadata->enabled()) {
63749 $backupGlobals = \true;
63750 }
63751 } elseif ($metadataForClass->isBackupGlobals()->isNotEmpty()) {
63752 $metadata = $metadataForClass->isBackupGlobals()->asArray()[0];
63753 assert($metadata instanceof BackupGlobals);
63754 if ($metadata->enabled()) {
63755 $backupGlobals = \true;
63756 }
63757 }
63758 foreach ($metadataForClassAndMethod->isExcludeGlobalVariableFromBackup() as $metadata) {
63759 assert($metadata instanceof ExcludeGlobalVariableFromBackup);
63760 $backupGlobalsExcludeList[] = $metadata->globalVariableName();
63761 }
63762 $backupStaticProperties = null;
63763 $backupStaticPropertiesExcludeList = [];
63764 if ($metadataForMethod->isBackupStaticProperties()->isNotEmpty()) {
63765 $metadata = $metadataForMethod->isBackupStaticProperties()->asArray()[0];
63766 assert($metadata instanceof BackupStaticProperties);
63767 if ($metadata->enabled()) {
63768 $backupStaticProperties = \true;
63769 }
63770 } elseif ($metadataForClass->isBackupStaticProperties()->isNotEmpty()) {
63771 $metadata = $metadataForClass->isBackupStaticProperties()->asArray()[0];
63772 assert($metadata instanceof BackupStaticProperties);
63773 if ($metadata->enabled()) {
63774 $backupStaticProperties = \true;
63775 }
63776 }
63777 foreach ($metadataForClassAndMethod->isExcludeStaticPropertyFromBackup() as $metadata) {
63778 assert($metadata instanceof ExcludeStaticPropertyFromBackup);
63779 if (!isset($backupStaticPropertiesExcludeList[$metadata->className()])) {
63780 $backupStaticPropertiesExcludeList[$metadata->className()] = [];
63781 }
63782 $backupStaticPropertiesExcludeList[$metadata->className()][] = $metadata->propertyName();
63783 }
63784 return ['backupGlobals' => $backupGlobals, 'backupGlobalsExcludeList' => $backupGlobalsExcludeList, 'backupStaticProperties' => $backupStaticProperties, 'backupStaticPropertiesExcludeList' => $backupStaticPropertiesExcludeList];
63785 }
63786 /**
63787 * @psalm-param class-string $className
63788 * @psalm-param non-empty-string $methodName
63789 */
63790 private function shouldGlobalStateBePreserved(string $className, string $methodName): ?bool
63791 {
63792 $metadataForMethod = MetadataRegistry::parser()->forMethod($className, $methodName);
63793 if ($metadataForMethod->isPreserveGlobalState()->isNotEmpty()) {
63794 $metadata = $metadataForMethod->isPreserveGlobalState()->asArray()[0];
63795 assert($metadata instanceof PreserveGlobalState);
63796 return $metadata->enabled();
63797 }
63798 $metadataForClass = MetadataRegistry::parser()->forClass($className);
63799 if ($metadataForClass->isPreserveGlobalState()->isNotEmpty()) {
63800 $metadata = $metadataForClass->isPreserveGlobalState()->asArray()[0];
63801 assert($metadata instanceof PreserveGlobalState);
63802 return $metadata->enabled();
63803 }
63804 return null;
63805 }
63806 /**
63807 * @psalm-param class-string $className
63808 * @psalm-param non-empty-string $methodName
63809 */
63810 private function shouldTestMethodBeRunInSeparateProcess(string $className, string $methodName): bool
63811 {
63812 if (MetadataRegistry::parser()->forClass($className)->isRunTestsInSeparateProcesses()->isNotEmpty()) {
63813 return \true;
63814 }
63815 if (MetadataRegistry::parser()->forMethod($className, $methodName)->isRunInSeparateProcess()->isNotEmpty()) {
63816 return \true;
63817 }
63818 return \false;
63819 }
63820 /**
63821 * @psalm-param class-string $className
63822 */
63823 private function shouldAllTestMethodsOfTestClassBeRunInSingleSeparateProcess(string $className): bool
63824 {
63825 return MetadataRegistry::parser()->forClass($className)->isRunClassInSeparateProcess()->isNotEmpty();
63826 }
63827 /**
63828 * @psalm-param class-string $className
63829 * @psalm-param non-empty-string $methodName
63830 */
63831 private function requirementsSatisfied(string $className, string $methodName): bool
63832 {
63833 return (new Requirements())->requirementsNotSatisfiedFor($className, $methodName) === [];
63834 }
63835 }
63836 <?php
63837
63838 declare (strict_types=1);
63839 /*
63840 * This file is part of PHPUnit.
63841 *
63842 * (c) Sebastian Bergmann <sebastian@phpunit.de>
63843 *
63844 * For the full copyright and license information, please view the LICENSE
63845 * file that was distributed with this source code.
63846 */
63847 namespace PHPUnit\Framework;
63848
63849 use const LC_ALL;
63850 use const LC_COLLATE;
63851 use const LC_CTYPE;
63852 use const LC_MONETARY;
63853 use const LC_NUMERIC;
63854 use const LC_TIME;
63855 use const PATHINFO_FILENAME;
63856 use const PHP_EOL;
63857 use const PHP_URL_PATH;
63858 use function array_is_list;
63859 use function array_keys;
63860 use function array_map;
63861 use function array_merge;
63862 use function array_values;
63863 use function assert;
63864 use function basename;
63865 use function chdir;
63866 use function class_exists;
63867 use function clearstatcache;
63868 use function count;
63869 use function defined;
63870 use function explode;
63871 use function getcwd;
63872 use function implode;
63873 use function in_array;
63874 use function ini_set;
63875 use function is_array;
63876 use function is_callable;
63877 use function is_int;
63878 use function is_object;
63879 use function is_string;
63880 use function libxml_clear_errors;
63881 use function method_exists;
63882 use function ob_end_clean;
63883 use function ob_get_clean;
63884 use function ob_get_contents;
63885 use function ob_get_level;
63886 use function ob_start;
63887 use function parse_url;
63888 use function pathinfo;
63889 use function preg_replace;
63890 use function setlocale;
63891 use function sprintf;
63892 use function str_contains;
63893 use function trim;
63894 use AssertionError;
63895 use PHPUnitPHAR\DeepCopy\DeepCopy;
63896 use PHPUnit\Event;
63897 use PHPUnit\Event\NoPreviousThrowableException;
63898 use PHPUnit\Event\RuntimeException;
63899 use PHPUnit\Event\TestData\MoreThanOneDataSetFromDataProviderException;
63900 use PHPUnit\Framework\Constraint\Exception as ExceptionConstraint;
63901 use PHPUnit\Framework\Constraint\ExceptionCode;
63902 use PHPUnit\Framework\Constraint\ExceptionMessageIsOrContains;
63903 use PHPUnit\Framework\Constraint\ExceptionMessageMatchesRegularExpression;
63904 use PHPUnit\Framework\MockObject\Exception as MockObjectException;
63905 use PHPUnit\Framework\MockObject\Generator\Generator as MockGenerator;
63906 use PHPUnit\Framework\MockObject\MockBuilder;
63907 use PHPUnit\Framework\MockObject\MockObject;
63908 use PHPUnit\Framework\MockObject\MockObjectInternal;
63909 use PHPUnit\Framework\MockObject\Rule\AnyInvokedCount as AnyInvokedCountMatcher;
63910 use PHPUnit\Framework\MockObject\Rule\InvokedAtLeastCount as InvokedAtLeastCountMatcher;
63911 use PHPUnit\Framework\MockObject\Rule\InvokedAtLeastOnce as InvokedAtLeastOnceMatcher;
63912 use PHPUnit\Framework\MockObject\Rule\InvokedAtMostCount as InvokedAtMostCountMatcher;
63913 use PHPUnit\Framework\MockObject\Rule\InvokedCount;
63914 use PHPUnit\Framework\MockObject\Rule\InvokedCount as InvokedCountMatcher;
63915 use PHPUnit\Framework\MockObject\Stub;
63916 use PHPUnit\Framework\MockObject\Stub\ConsecutiveCalls as ConsecutiveCallsStub;
63917 use PHPUnit\Framework\MockObject\Stub\Exception as ExceptionStub;
63918 use PHPUnit\Framework\MockObject\Stub\ReturnArgument as ReturnArgumentStub;
63919 use PHPUnit\Framework\MockObject\Stub\ReturnCallback as ReturnCallbackStub;
63920 use PHPUnit\Framework\MockObject\Stub\ReturnSelf as ReturnSelfStub;
63921 use PHPUnit\Framework\MockObject\Stub\ReturnStub;
63922 use PHPUnit\Framework\MockObject\Stub\ReturnValueMap as ReturnValueMapStub;
63923 use PHPUnit\Framework\TestSize\TestSize;
63924 use PHPUnit\Framework\TestStatus\TestStatus;
63925 use PHPUnit\Metadata\Api\Groups;
63926 use PHPUnit\Metadata\Api\HookMethods;
63927 use PHPUnit\Metadata\Api\Requirements;
63928 use PHPUnit\Metadata\Parser\Registry as MetadataRegistry;
63929 use PHPUnit\TestRunner\TestResult\PassedTests;
63930 use PHPUnit\TextUI\Configuration\Registry as ConfigurationRegistry;
63931 use PHPUnit\Util\Cloner;
63932 use PHPUnit\Util\Test as TestUtil;
63933 use ReflectionClass;
63934 use ReflectionException;
63935 use ReflectionMethod;
63936 use ReflectionObject;
63937 use ReflectionParameter;
63938 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\UnintentionallyCoveredCodeException;
63939 use PHPUnitPHAR\SebastianBergmann\Comparator\Comparator;
63940 use PHPUnitPHAR\SebastianBergmann\Comparator\Factory as ComparatorFactory;
63941 use PHPUnitPHAR\SebastianBergmann\Diff\Differ;
63942 use PHPUnitPHAR\SebastianBergmann\Diff\Output\UnifiedDiffOutputBuilder;
63943 use PHPUnitPHAR\SebastianBergmann\Exporter\Exporter;
63944 use PHPUnitPHAR\SebastianBergmann\GlobalState\ExcludeList as GlobalStateExcludeList;
63945 use PHPUnitPHAR\SebastianBergmann\GlobalState\Restorer;
63946 use PHPUnitPHAR\SebastianBergmann\GlobalState\Snapshot;
63947 use PHPUnitPHAR\SebastianBergmann\Invoker\TimeoutException;
63948 use PHPUnitPHAR\SebastianBergmann\ObjectEnumerator\Enumerator;
63949 use PHPUnitPHAR\SebastianBergmann\RecursionContext\Context;
63950 use Throwable;
63951 /**
63952 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
63953 */
63954 abstract class TestCase extends \PHPUnit\Framework\Assert implements \PHPUnit\Framework\Reorderable, \PHPUnit\Framework\SelfDescribing, \PHPUnit\Framework\Test
63955 {
63956 private const LOCALE_CATEGORIES = [LC_ALL, LC_COLLATE, LC_CTYPE, LC_MONETARY, LC_NUMERIC, LC_TIME];
63957 private ?bool $backupGlobals = null;
63958 /**
63959 * @psalm-var list<string>
63960 */
63961 private array $backupGlobalsExcludeList = [];
63962 private ?bool $backupStaticProperties = null;
63963 /**
63964 * @psalm-var array<string,list<class-string>>
63965 */
63966 private array $backupStaticPropertiesExcludeList = [];
63967 private ?Snapshot $snapshot = null;
63968 private ?bool $runClassInSeparateProcess = null;
63969 private ?bool $runTestInSeparateProcess = null;
63970 private bool $preserveGlobalState = \false;
63971 private bool $inIsolation = \false;
63972 private ?string $expectedException = null;
63973 private ?string $expectedExceptionMessage = null;
63974 private ?string $expectedExceptionMessageRegExp = null;
63975 private null|int|string $expectedExceptionCode = null;
63976 /**
63977 * @psalm-var list<ExecutionOrderDependency>
63978 */
63979 private array $providedTests = [];
63980 private array $data = [];
63981 private int|string $dataName = '';
63982 /**
63983 * @psalm-var non-empty-string
63984 */
63985 private string $name;
63986 /**
63987 * @psalm-var list<string>
63988 */
63989 private array $groups = [];
63990 /**
63991 * @psalm-var list<ExecutionOrderDependency>
63992 */
63993 private array $dependencies = [];
63994 private array $dependencyInput = [];
63995 /**
63996 * @psalm-var array<string,string>
63997 */
63998 private array $iniSettings = [];
63999 private array $locale = [];
64000 /**
64001 * @psalm-var list<MockObjectInternal>
64002 */
64003 private array $mockObjects = [];
64004 private bool $registerMockObjectsFromTestArgumentsRecursively = \false;
64005 private TestStatus $status;
64006 private int $numberOfAssertionsPerformed = 0;
64007 private mixed $testResult = null;
64008 private string $output = '';
64009 private ?string $outputExpectedRegex = null;
64010 private ?string $outputExpectedString = null;
64011 private bool $outputBufferingActive = \false;
64012 private int $outputBufferingLevel;
64013 private bool $outputRetrievedForAssertion = \false;
64014 private bool $doesNotPerformAssertions = \false;
64015 /**
64016 * @psalm-var list<Comparator>
64017 */
64018 private array $customComparators = [];
64019 private ?Event\Code\TestMethod $testValueObjectForEvents = null;
64020 private bool $wasPrepared = \false;
64021 /**
64022 * @psalm-var array<class-string, true>
64023 */
64024 private array $failureTypes = [];
64025 /**
64026 * Returns a matcher that matches when the method is executed
64027 * zero or more times.
64028 */
64029 final public static function any(): AnyInvokedCountMatcher
64030 {
64031 return new AnyInvokedCountMatcher();
64032 }
64033 /**
64034 * Returns a matcher that matches when the method is never executed.
64035 */
64036 final public static function never(): InvokedCountMatcher
64037 {
64038 return new InvokedCountMatcher(0);
64039 }
64040 /**
64041 * Returns a matcher that matches when the method is executed
64042 * at least N times.
64043 */
64044 final public static function atLeast(int $requiredInvocations): InvokedAtLeastCountMatcher
64045 {
64046 return new InvokedAtLeastCountMatcher($requiredInvocations);
64047 }
64048 /**
64049 * Returns a matcher that matches when the method is executed at least once.
64050 */
64051 final public static function atLeastOnce(): InvokedAtLeastOnceMatcher
64052 {
64053 return new InvokedAtLeastOnceMatcher();
64054 }
64055 /**
64056 * Returns a matcher that matches when the method is executed exactly once.
64057 */
64058 final public static function once(): InvokedCountMatcher
64059 {
64060 return new InvokedCountMatcher(1);
64061 }
64062 /**
64063 * Returns a matcher that matches when the method is executed
64064 * exactly $count times.
64065 */
64066 final public static function exactly(int $count): InvokedCountMatcher
64067 {
64068 return new InvokedCountMatcher($count);
64069 }
64070 /**
64071 * Returns a matcher that matches when the method is executed
64072 * at most N times.
64073 */
64074 final public static function atMost(int $allowedInvocations): InvokedAtMostCountMatcher
64075 {
64076 return new InvokedAtMostCountMatcher($allowedInvocations);
64077 }
64078 /**
64079 * @deprecated Use <code>$double->willReturn()</code> instead of <code>$double->will($this->returnValue())</code>
64080 * @see https://github.com/sebastianbergmann/phpunit/issues/5423
64081 *
64082 * @codeCoverageIgnore
64083 */
64084 final public static function returnValue(mixed $value): ReturnStub
64085 {
64086 return new ReturnStub($value);
64087 }
64088 /**
64089 * @deprecated Use <code>$double->willReturnMap()</code> instead of <code>$double->will($this->returnValueMap())</code>
64090 * @see https://github.com/sebastianbergmann/phpunit/issues/5423
64091 *
64092 * @codeCoverageIgnore
64093 */
64094 final public static function returnValueMap(array $valueMap): ReturnValueMapStub
64095 {
64096 return new ReturnValueMapStub($valueMap);
64097 }
64098 /**
64099 * @deprecated Use <code>$double->willReturnArgument()</code> instead of <code>$double->will($this->returnArgument())</code>
64100 * @see https://github.com/sebastianbergmann/phpunit/issues/5423
64101 *
64102 * @codeCoverageIgnore
64103 */
64104 final public static function returnArgument(int $argumentIndex): ReturnArgumentStub
64105 {
64106 return new ReturnArgumentStub($argumentIndex);
64107 }
64108 /**
64109 * @deprecated Use <code>$double->willReturnCallback()</code> instead of <code>$double->will($this->returnCallback())</code>
64110 * @see https://github.com/sebastianbergmann/phpunit/issues/5423
64111 *
64112 * @codeCoverageIgnore
64113 */
64114 final public static function returnCallback(callable $callback): ReturnCallbackStub
64115 {
64116 return new ReturnCallbackStub($callback);
64117 }
64118 /**
64119 * @deprecated Use <code>$double->willReturnSelf()</code> instead of <code>$double->will($this->returnSelf())</code>
64120 * @see https://github.com/sebastianbergmann/phpunit/issues/5423
64121 *
64122 * @codeCoverageIgnore
64123 */
64124 final public static function returnSelf(): ReturnSelfStub
64125 {
64126 return new ReturnSelfStub();
64127 }
64128 final public static function throwException(Throwable $exception): ExceptionStub
64129 {
64130 return new ExceptionStub($exception);
64131 }
64132 /**
64133 * @deprecated Use <code>$double->willReturn()</code> instead of <code>$double->will($this->onConsecutiveCalls())</code>
64134 * @see https://github.com/sebastianbergmann/phpunit/issues/5423
64135 * @see https://github.com/sebastianbergmann/phpunit/issues/5425
64136 *
64137 * @codeCoverageIgnore
64138 */
64139 final public static function onConsecutiveCalls(mixed ...$arguments): ConsecutiveCallsStub
64140 {
64141 return new ConsecutiveCallsStub($arguments);
64142 }
64143 /**
64144 * @psalm-param non-empty-string $name
64145 *
64146 * @internal This method is not covered by the backward compatibility promise for PHPUnit
64147 */
64148 public function __construct(string $name)
64149 {
64150 $this->setName($name);
64151 $this->status = TestStatus::unknown();
64152 }
64153 /**
64154 * This method is called before the first test of this test class is run.
64155 *
64156 * @codeCoverageIgnore
64157 */
64158 public static function setUpBeforeClass(): void
64159 {
64160 }
64161 /**
64162 * This method is called after the last test of this test class is run.
64163 *
64164 * @codeCoverageIgnore
64165 */
64166 public static function tearDownAfterClass(): void
64167 {
64168 }
64169 /**
64170 * This method is called before each test.
64171 *
64172 * @codeCoverageIgnore
64173 */
64174 protected function setUp(): void
64175 {
64176 }
64177 /**
64178 * Performs assertions shared by all tests of a test case.
64179 *
64180 * This method is called between setUp() and test.
64181 *
64182 * @codeCoverageIgnore
64183 */
64184 protected function assertPreConditions(): void
64185 {
64186 }
64187 /**
64188 * Performs assertions shared by all tests of a test case.
64189 *
64190 * This method is called between test and tearDown().
64191 *
64192 * @codeCoverageIgnore
64193 */
64194 protected function assertPostConditions(): void
64195 {
64196 }
64197 /**
64198 * This method is called after each test.
64199 *
64200 * @codeCoverageIgnore
64201 */
64202 protected function tearDown(): void
64203 {
64204 }
64205 /**
64206 * Returns a string representation of the test case.
64207 *
64208 * @throws Exception
64209 *
64210 * @internal This method is not covered by the backward compatibility promise for PHPUnit
64211 */
64212 public function toString(): string
64213 {
64214 $buffer = sprintf('%s::%s', (new ReflectionClass($this))->getName(), $this->name);
64215 return $buffer . $this->dataSetAsStringWithData();
64216 }
64217 /**
64218 * @internal This method is not covered by the backward compatibility promise for PHPUnit
64219 */
64220 final public function count(): int
64221 {
64222 return 1;
64223 }
64224 final public function getActualOutputForAssertion(): string
64225 {
64226 $this->outputRetrievedForAssertion = \true;
64227 return $this->output();
64228 }
64229 final public function expectOutputRegex(string $expectedRegex): void
64230 {
64231 $this->outputExpectedRegex = $expectedRegex;
64232 }
64233 final public function expectOutputString(string $expectedString): void
64234 {
64235 $this->outputExpectedString = $expectedString;
64236 }
64237 /**
64238 * @psalm-param class-string<Throwable> $exception
64239 */
64240 final public function expectException(string $exception): void
64241 {
64242 $this->expectedException = $exception;
64243 }
64244 final public function expectExceptionCode(int|string $code): void
64245 {
64246 $this->expectedExceptionCode = $code;
64247 }
64248 final public function expectExceptionMessage(string $message): void
64249 {
64250 $this->expectedExceptionMessage = $message;
64251 }
64252 final public function expectExceptionMessageMatches(string $regularExpression): void
64253 {
64254 $this->expectedExceptionMessageRegExp = $regularExpression;
64255 }
64256 /**
64257 * Sets up an expectation for an exception to be raised by the code under test.
64258 * Information for expected exception class, expected exception message, and
64259 * expected exception code are retrieved from a given Exception object.
64260 */
64261 final public function expectExceptionObject(\Exception $exception): void
64262 {
64263 $this->expectException($exception::class);
64264 $this->expectExceptionMessage($exception->getMessage());
64265 $this->expectExceptionCode($exception->getCode());
64266 }
64267 final public function expectNotToPerformAssertions(): void
64268 {
64269 $this->doesNotPerformAssertions = \true;
64270 }
64271 /**
64272 * @internal This method is not covered by the backward compatibility promise for PHPUnit
64273 */
64274 final public function status(): TestStatus
64275 {
64276 return $this->status;
64277 }
64278 /**
64279 * @throws \PHPUnit\Runner\Exception
64280 * @throws \PHPUnit\Util\Exception
64281 * @throws \SebastianBergmann\CodeCoverage\InvalidArgumentException
64282 * @throws \SebastianBergmann\Template\InvalidArgumentException
64283 * @throws CodeCoverageException
64284 * @throws Exception
64285 * @throws MoreThanOneDataSetFromDataProviderException
64286 * @throws NoPreviousThrowableException
64287 * @throws ProcessIsolationException
64288 * @throws UnintentionallyCoveredCodeException
64289 *
64290 * @internal This method is not covered by the backward compatibility promise for PHPUnit
64291 */
64292 final public function run(): void
64293 {
64294 if (!$this->handleDependencies()) {
64295 return;
64296 }
64297 if (!$this->shouldRunInSeparateProcess() || $this->requirementsNotSatisfied()) {
64298 (new \PHPUnit\Framework\TestRunner())->run($this);
64299 } else {
64300 (new \PHPUnit\Framework\TestRunner())->runInSeparateProcess($this, $this->runClassInSeparateProcess && !$this->runTestInSeparateProcess, $this->preserveGlobalState);
64301 }
64302 }
64303 /**
64304 * Returns a builder object to create mock objects using a fluent interface.
64305 *
64306 * @psalm-template RealInstanceType of object
64307 *
64308 * @psalm-param class-string<RealInstanceType> $className
64309 *
64310 * @psalm-return MockBuilder<RealInstanceType>
64311 */
64312 final public function getMockBuilder(string $className): MockBuilder
64313 {
64314 return new MockBuilder($this, $className);
64315 }
64316 /**
64317 * @internal This method is not covered by the backward compatibility promise for PHPUnit
64318 */
64319 final public function groups(): array
64320 {
64321 return $this->groups;
64322 }
64323 /**
64324 * @internal This method is not covered by the backward compatibility promise for PHPUnit
64325 */
64326 final public function setGroups(array $groups): void
64327 {
64328 $this->groups = $groups;
64329 }
64330 /**
64331 * @internal This method is not covered by the backward compatibility promise for PHPUnit
64332 */
64333 final public function nameWithDataSet(): string
64334 {
64335 return $this->name . $this->dataSetAsString();
64336 }
64337 /**
64338 * @psalm-return non-empty-string
64339 *
64340 * @internal This method is not covered by the backward compatibility promise for PHPUnit
64341 */
64342 final public function name(): string
64343 {
64344 return $this->name;
64345 }
64346 /**
64347 * @internal This method is not covered by the backward compatibility promise for PHPUnit
64348 */
64349 final public function size(): TestSize
64350 {
64351 return (new Groups())->size(static::class, $this->name);
64352 }
64353 /**
64354 * @internal This method is not covered by the backward compatibility promise for PHPUnit
64355 */
64356 final public function hasUnexpectedOutput(): bool
64357 {
64358 if ($this->output === '') {
64359 return \false;
64360 }
64361 if ($this->expectsOutput()) {
64362 return \false;
64363 }
64364 return \true;
64365 }
64366 /**
64367 * @internal This method is not covered by the backward compatibility promise for PHPUnit
64368 */
64369 final public function output(): string
64370 {
64371 if (!$this->outputBufferingActive) {
64372 return $this->output;
64373 }
64374 return (string) ob_get_contents();
64375 }
64376 /**
64377 * @internal This method is not covered by the backward compatibility promise for PHPUnit
64378 */
64379 final public function doesNotPerformAssertions(): bool
64380 {
64381 return $this->doesNotPerformAssertions;
64382 }
64383 /**
64384 * @internal This method is not covered by the backward compatibility promise for PHPUnit
64385 */
64386 final public function expectsOutput(): bool
64387 {
64388 return $this->hasExpectationOnOutput() || $this->outputRetrievedForAssertion;
64389 }
64390 /**
64391 * @internal This method is not covered by the backward compatibility promise for PHPUnit
64392 *
64393 * @deprecated
64394 *
64395 * @codeCoverageIgnore
64396 */
64397 final public function registerMockObjectsFromTestArgumentsRecursively(): void
64398 {
64399 $this->registerMockObjectsFromTestArgumentsRecursively = \true;
64400 }
64401 /**
64402 * @throws Throwable
64403 *
64404 * @internal This method is not covered by the backward compatibility promise for PHPUnit
64405 */
64406 final public function runBare(): void
64407 {
64408 $emitter = Event\Facade::emitter();
64409 $emitter->testPreparationStarted($this->valueObjectForEvents());
64410 $this->snapshotGlobalState();
64411 $this->startOutputBuffering();
64412 clearstatcache();
64413 $hookMethods = (new HookMethods())->hookMethods(static::class);
64414 $hasMetRequirements = \false;
64415 $this->numberOfAssertionsPerformed = 0;
64416 $currentWorkingDirectory = getcwd();
64417 try {
64418 $this->checkRequirements();
64419 $hasMetRequirements = \true;
64420 if ($this->inIsolation) {
64421 // @codeCoverageIgnoreStart
64422 $this->invokeBeforeClassHookMethods($hookMethods, $emitter);
64423 // @codeCoverageIgnoreEnd
64424 }
64425 if (method_exists(static::class, $this->name) && MetadataRegistry::parser()->forClassAndMethod(static::class, $this->name)->isDoesNotPerformAssertions()->isNotEmpty()) {
64426 $this->doesNotPerformAssertions = \true;
64427 }
64428 $this->invokeBeforeTestHookMethods($hookMethods, $emitter);
64429 $this->invokePreConditionHookMethods($hookMethods, $emitter);
64430 $emitter->testPrepared($this->valueObjectForEvents());
64431 $this->wasPrepared = \true;
64432 $this->testResult = $this->runTest();
64433 $this->verifyMockObjects();
64434 $this->invokePostConditionHookMethods($hookMethods, $emitter);
64435 $this->status = TestStatus::success();
64436 } catch (\PHPUnit\Framework\IncompleteTest $e) {
64437 $this->status = TestStatus::incomplete($e->getMessage());
64438 $emitter->testMarkedAsIncomplete($this->valueObjectForEvents(), Event\Code\ThrowableBuilder::from($e));
64439 } catch (\PHPUnit\Framework\SkippedTest $e) {
64440 $this->status = TestStatus::skipped($e->getMessage());
64441 $emitter->testSkipped($this->valueObjectForEvents(), $e->getMessage());
64442 } catch (AssertionError|\PHPUnit\Framework\AssertionFailedError $e) {
64443 $this->handleExceptionFromInvokedCountMockObjectRule($e);
64444 if (!$this->wasPrepared) {
64445 $this->wasPrepared = \true;
64446 $emitter->testPreparationFailed($this->valueObjectForEvents());
64447 }
64448 $this->status = TestStatus::failure($e->getMessage());
64449 $emitter->testFailed($this->valueObjectForEvents(), Event\Code\ThrowableBuilder::from($e), Event\Code\ComparisonFailureBuilder::from($e));
64450 } catch (TimeoutException $e) {
64451 } catch (Throwable $_e) {
64452 if ($this->isRegisteredFailure($_e)) {
64453 $this->status = TestStatus::failure($_e->getMessage());
64454 $emitter->testFailed($this->valueObjectForEvents(), Event\Code\ThrowableBuilder::from($_e), null);
64455 } else {
64456 $e = $this->transformException($_e);
64457 $this->status = TestStatus::error($e->getMessage());
64458 $emitter->testErrored($this->valueObjectForEvents(), Event\Code\ThrowableBuilder::from($e));
64459 }
64460 }
64461 $outputBufferingStopped = \false;
64462 if (!isset($e) && $this->hasExpectationOnOutput() && $this->stopOutputBuffering()) {
64463 $outputBufferingStopped = \true;
64464 $this->performAssertionsOnOutput();
64465 }
64466 if ($this->status->isSuccess()) {
64467 $emitter->testPassed($this->valueObjectForEvents());
64468 if (!$this->usesDataProvider()) {
64469 PassedTests::instance()->testMethodPassed($this->valueObjectForEvents(), $this->testResult);
64470 }
64471 }
64472 try {
64473 $this->mockObjects = [];
64474 } catch (Throwable $t) {
64475 Event\Facade::emitter()->testErrored($this->valueObjectForEvents(), Event\Code\ThrowableBuilder::from($t));
64476 }
64477 // Tear down the fixture. An exception raised in tearDown() will be
64478 // caught and passed on when no exception was raised before.
64479 try {
64480 if ($hasMetRequirements) {
64481 $this->invokeAfterTestHookMethods($hookMethods, $emitter);
64482 if ($this->inIsolation) {
64483 // @codeCoverageIgnoreStart
64484 $this->invokeAfterClassHookMethods($hookMethods, $emitter);
64485 // @codeCoverageIgnoreEnd
64486 }
64487 }
64488 } catch (AssertionError|\PHPUnit\Framework\AssertionFailedError $e) {
64489 $this->status = TestStatus::failure($e->getMessage());
64490 $emitter->testFailed($this->valueObjectForEvents(), Event\Code\ThrowableBuilder::from($e), Event\Code\ComparisonFailureBuilder::from($e));
64491 } catch (Throwable $exceptionRaisedDuringTearDown) {
64492 if (!isset($e)) {
64493 $this->status = TestStatus::error($exceptionRaisedDuringTearDown->getMessage());
64494 $e = $exceptionRaisedDuringTearDown;
64495 $emitter->testErrored($this->valueObjectForEvents(), Event\Code\ThrowableBuilder::from($exceptionRaisedDuringTearDown));
64496 }
64497 }
64498 if (!$outputBufferingStopped) {
64499 $this->stopOutputBuffering();
64500 }
64501 clearstatcache();
64502 if ($currentWorkingDirectory !== getcwd()) {
64503 chdir($currentWorkingDirectory);
64504 }
64505 $this->restoreGlobalState();
64506 $this->unregisterCustomComparators();
64507 $this->cleanupIniSettings();
64508 $this->cleanupLocaleSettings();
64509 libxml_clear_errors();
64510 $this->testValueObjectForEvents = null;
64511 if (isset($e)) {
64512 $this->onNotSuccessfulTest($e);
64513 }
64514 }
64515 /**
64516 * @psalm-param non-empty-string $name
64517 *
64518 * @internal This method is not covered by the backward compatibility promise for PHPUnit
64519 */
64520 final public function setName(string $name): void
64521 {
64522 $this->name = $name;
64523 if (is_callable($this->sortId(), \true)) {
64524 $this->providedTests = [new \PHPUnit\Framework\ExecutionOrderDependency($this->sortId())];
64525 }
64526 }
64527 /**
64528 * @psalm-param list<ExecutionOrderDependency> $dependencies
64529 *
64530 * @internal This method is not covered by the backward compatibility promise for PHPUnit
64531 */
64532 final public function setDependencies(array $dependencies): void
64533 {
64534 $this->dependencies = $dependencies;
64535 }
64536 /**
64537 * @internal This method is not covered by the backward compatibility promise for PHPUnit
64538 *
64539 * @codeCoverageIgnore
64540 */
64541 final public function setDependencyInput(array $dependencyInput): void
64542 {
64543 $this->dependencyInput = $dependencyInput;
64544 }
64545 /**
64546 * @internal This method is not covered by the backward compatibility promise for PHPUnit
64547 */
64548 final public function dependencyInput(): array
64549 {
64550 return $this->dependencyInput;
64551 }
64552 /**
64553 * @internal This method is not covered by the backward compatibility promise for PHPUnit
64554 */
64555 final public function hasDependencyInput(): bool
64556 {
64557 return !empty($this->dependencyInput);
64558 }
64559 /**
64560 * @internal This method is not covered by the backward compatibility promise for PHPUnit
64561 */
64562 final public function setBackupGlobals(bool $backupGlobals): void
64563 {
64564 $this->backupGlobals = $backupGlobals;
64565 }
64566 /**
64567 * @internal This method is not covered by the backward compatibility promise for PHPUnit
64568 */
64569 final public function setBackupGlobalsExcludeList(array $backupGlobalsExcludeList): void
64570 {
64571 $this->backupGlobalsExcludeList = $backupGlobalsExcludeList;
64572 }
64573 /**
64574 * @internal This method is not covered by the backward compatibility promise for PHPUnit
64575 */
64576 final public function setBackupStaticProperties(bool $backupStaticProperties): void
64577 {
64578 $this->backupStaticProperties = $backupStaticProperties;
64579 }
64580 /**
64581 * @internal This method is not covered by the backward compatibility promise for PHPUnit
64582 */
64583 final public function setBackupStaticPropertiesExcludeList(array $backupStaticPropertiesExcludeList): void
64584 {
64585 $this->backupStaticPropertiesExcludeList = $backupStaticPropertiesExcludeList;
64586 }
64587 /**
64588 * @internal This method is not covered by the backward compatibility promise for PHPUnit
64589 */
64590 final public function setRunTestInSeparateProcess(bool $runTestInSeparateProcess): void
64591 {
64592 if ($this->runTestInSeparateProcess === null) {
64593 $this->runTestInSeparateProcess = $runTestInSeparateProcess;
64594 }
64595 }
64596 /**
64597 * @internal This method is not covered by the backward compatibility promise for PHPUnit
64598 */
64599 final public function setRunClassInSeparateProcess(bool $runClassInSeparateProcess): void
64600 {
64601 $this->runClassInSeparateProcess = $runClassInSeparateProcess;
64602 }
64603 /**
64604 * @internal This method is not covered by the backward compatibility promise for PHPUnit
64605 */
64606 final public function setPreserveGlobalState(bool $preserveGlobalState): void
64607 {
64608 $this->preserveGlobalState = $preserveGlobalState;
64609 }
64610 /**
64611 * @internal This method is not covered by the backward compatibility promise for PHPUnit
64612 *
64613 * @codeCoverageIgnore
64614 */
64615 final public function setInIsolation(bool $inIsolation): void
64616 {
64617 $this->inIsolation = $inIsolation;
64618 }
64619 /**
64620 * @internal This method is not covered by the backward compatibility promise for PHPUnit
64621 *
64622 * @codeCoverageIgnore
64623 */
64624 final public function result(): mixed
64625 {
64626 return $this->testResult;
64627 }
64628 /**
64629 * @internal This method is not covered by the backward compatibility promise for PHPUnit
64630 */
64631 final public function setResult(mixed $result): void
64632 {
64633 $this->testResult = $result;
64634 }
64635 /**
64636 * @internal This method is not covered by the backward compatibility promise for PHPUnit
64637 */
64638 final public function registerMockObject(MockObject $mockObject): void
64639 {
64640 assert($mockObject instanceof MockObjectInternal);
64641 $this->mockObjects[] = $mockObject;
64642 }
64643 /**
64644 * @internal This method is not covered by the backward compatibility promise for PHPUnit
64645 */
64646 final public function addToAssertionCount(int $count): void
64647 {
64648 $this->numberOfAssertionsPerformed += $count;
64649 }
64650 /**
64651 * @internal This method is not covered by the backward compatibility promise for PHPUnit
64652 */
64653 final public function numberOfAssertionsPerformed(): int
64654 {
64655 return $this->numberOfAssertionsPerformed;
64656 }
64657 /**
64658 * @internal This method is not covered by the backward compatibility promise for PHPUnit
64659 */
64660 final public function usesDataProvider(): bool
64661 {
64662 return !empty($this->data);
64663 }
64664 /**
64665 * @internal This method is not covered by the backward compatibility promise for PHPUnit
64666 */
64667 final public function dataName(): int|string
64668 {
64669 return $this->dataName;
64670 }
64671 /**
64672 * @internal This method is not covered by the backward compatibility promise for PHPUnit
64673 */
64674 final public function dataSetAsString(): string
64675 {
64676 $buffer = '';
64677 if (!empty($this->data)) {
64678 if (is_int($this->dataName)) {
64679 $buffer .= sprintf(' with data set #%d', $this->dataName);
64680 } else {
64681 $buffer .= sprintf(' with data set "%s"', $this->dataName);
64682 }
64683 }
64684 return $buffer;
64685 }
64686 /**
64687 * @internal This method is not covered by the backward compatibility promise for PHPUnit
64688 */
64689 final public function dataSetAsStringWithData(): string
64690 {
64691 if (empty($this->data)) {
64692 return '';
64693 }
64694 return $this->dataSetAsString() . sprintf(' (%s)', (new Exporter())->shortenedRecursiveExport($this->data));
64695 }
64696 /**
64697 * @internal This method is not covered by the backward compatibility promise for PHPUnit
64698 */
64699 final public function providedData(): array
64700 {
64701 return $this->data;
64702 }
64703 /**
64704 * @internal This method is not covered by the backward compatibility promise for PHPUnit
64705 */
64706 final public function sortId(): string
64707 {
64708 $id = $this->name;
64709 if (!str_contains($id, '::')) {
64710 $id = static::class . '::' . $id;
64711 }
64712 if ($this->usesDataProvider()) {
64713 $id .= $this->dataSetAsString();
64714 }
64715 return $id;
64716 }
64717 /**
64718 * @psalm-return list<ExecutionOrderDependency>
64719 *
64720 * @internal This method is not covered by the backward compatibility promise for PHPUnit
64721 */
64722 final public function provides(): array
64723 {
64724 return $this->providedTests;
64725 }
64726 /**
64727 * @psalm-return list<ExecutionOrderDependency>
64728 *
64729 * @internal This method is not covered by the backward compatibility promise for PHPUnit
64730 */
64731 final public function requires(): array
64732 {
64733 return $this->dependencies;
64734 }
64735 /**
64736 * @throws RuntimeException
64737 *
64738 * @internal This method is not covered by the backward compatibility promise for PHPUnit
64739 */
64740 final public function setData(int|string $dataName, array $data): void
64741 {
64742 $this->dataName = $dataName;
64743 $this->data = $data;
64744 if (array_is_list($data)) {
64745 return;
64746 }
64747 try {
64748 $reflector = new ReflectionMethod($this, $this->name);
64749 $parameters = array_map(static fn(ReflectionParameter $parameter) => $parameter->name, $reflector->getParameters());
64750 foreach (array_keys($data) as $parameter) {
64751 if (is_string($parameter) && !in_array($parameter, $parameters, \true)) {
64752 Event\Facade::emitter()->testTriggeredPhpunitDeprecation($this->valueObjectForEvents(), sprintf('Providing invalid named argument $%s for method %s::%s() is deprecated and will not be supported in PHPUnit 11.0.', $parameter, $this::class, $this->name));
64753 }
64754 }
64755 // @codeCoverageIgnoreStart
64756 } catch (ReflectionException $e) {
64757 throw new RuntimeException($e->getMessage(), $e->getCode(), $e);
64758 }
64759 // @codeCoverageIgnoreEnd
64760 }
64761 /**
64762 * @internal This method is not covered by the backward compatibility promise for PHPUnit
64763 *
64764 * @throws MoreThanOneDataSetFromDataProviderException
64765 */
64766 final public function valueObjectForEvents(): Event\Code\TestMethod
64767 {
64768 if ($this->testValueObjectForEvents !== null) {
64769 return $this->testValueObjectForEvents;
64770 }
64771 $this->testValueObjectForEvents = Event\Code\TestMethodBuilder::fromTestCase($this);
64772 return $this->testValueObjectForEvents;
64773 }
64774 /**
64775 * @internal This method is not covered by the backward compatibility promise for PHPUnit
64776 */
64777 final public function wasPrepared(): bool
64778 {
64779 return $this->wasPrepared;
64780 }
64781 final protected function registerComparator(Comparator $comparator): void
64782 {
64783 ComparatorFactory::getInstance()->register($comparator);
64784 Event\Facade::emitter()->testRegisteredComparator($comparator::class);
64785 $this->customComparators[] = $comparator;
64786 }
64787 /**
64788 * @psalm-param class-string $classOrInterface
64789 */
64790 final protected function registerFailureType(string $classOrInterface): void
64791 {
64792 $this->failureTypes[$classOrInterface] = \true;
64793 }
64794 /**
64795 * This method is a wrapper for the ini_set() function that automatically
64796 * resets the modified php.ini setting to its original value after the
64797 * test is run.
64798 *
64799 * @throws Exception
64800 *
64801 * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5214
64802 *
64803 * @codeCoverageIgnore
64804 */
64805 protected function iniSet(string $varName, string $newValue): void
64806 {
64807 $currentValue = ini_set($varName, $newValue);
64808 if ($currentValue !== \false) {
64809 $this->iniSettings[$varName] = $currentValue;
64810 } else {
64811 throw new \PHPUnit\Framework\Exception(sprintf('INI setting "%s" could not be set to "%s".', $varName, $newValue));
64812 }
64813 }
64814 /**
64815 * This method is a wrapper for the setlocale() function that automatically
64816 * resets the locale to its original value after the test is run.
64817 *
64818 * @throws Exception
64819 *
64820 * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5216
64821 *
64822 * @codeCoverageIgnore
64823 */
64824 protected function setLocale(mixed ...$arguments): void
64825 {
64826 if (count($arguments) < 2) {
64827 throw new \PHPUnit\Framework\Exception();
64828 }
64829 [$category, $locale] = $arguments;
64830 if (!in_array($category, self::LOCALE_CATEGORIES, \true)) {
64831 throw new \PHPUnit\Framework\Exception();
64832 }
64833 if (!is_array($locale) && !is_string($locale)) {
64834 throw new \PHPUnit\Framework\Exception();
64835 }
64836 $this->locale[$category] = setlocale($category, '0');
64837 $result = setlocale(...$arguments);
64838 if ($result === \false) {
64839 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.');
64840 }
64841 }
64842 /**
64843 * Creates a mock object for the specified interface or class.
64844 *
64845 * @psalm-template RealInstanceType of object
64846 *
64847 * @psalm-param class-string<RealInstanceType> $originalClassName
64848 *
64849 * @throws InvalidArgumentException
64850 * @throws MockObjectException
64851 * @throws NoPreviousThrowableException
64852 *
64853 * @psalm-return MockObject&RealInstanceType
64854 */
64855 protected function createMock(string $originalClassName): MockObject
64856 {
64857 $mock = (new MockGenerator())->testDouble($originalClassName, \true, callOriginalConstructor: \false, callOriginalClone: \false, cloneArguments: \false, allowMockingUnknownTypes: \false);
64858 assert($mock instanceof $originalClassName);
64859 assert($mock instanceof MockObject);
64860 $this->registerMockObject($mock);
64861 Event\Facade::emitter()->testCreatedMockObject($originalClassName);
64862 return $mock;
64863 }
64864 /**
64865 * @psalm-param list<class-string> $interfaces
64866 *
64867 * @throws MockObjectException
64868 */
64869 protected function createMockForIntersectionOfInterfaces(array $interfaces): MockObject
64870 {
64871 $mock = (new MockGenerator())->testDoubleForInterfaceIntersection($interfaces, \true);
64872 assert($mock instanceof MockObject);
64873 $this->registerMockObject($mock);
64874 Event\Facade::emitter()->testCreatedMockObjectForIntersectionOfInterfaces($interfaces);
64875 return $mock;
64876 }
64877 /**
64878 * Creates (and configures) a mock object for the specified interface or class.
64879 *
64880 * @psalm-template RealInstanceType of object
64881 *
64882 * @psalm-param class-string<RealInstanceType> $originalClassName
64883 *
64884 * @throws InvalidArgumentException
64885 * @throws MockObjectException
64886 * @throws NoPreviousThrowableException
64887 *
64888 * @psalm-return MockObject&RealInstanceType
64889 */
64890 protected function createConfiguredMock(string $originalClassName, array $configuration): MockObject
64891 {
64892 $o = $this->createMock($originalClassName);
64893 foreach ($configuration as $method => $return) {
64894 $o->method($method)->willReturn($return);
64895 }
64896 return $o;
64897 }
64898 /**
64899 * Creates a partial mock object for the specified interface or class.
64900 *
64901 * @psalm-param list<non-empty-string> $methods
64902 *
64903 * @psalm-template RealInstanceType of object
64904 *
64905 * @psalm-param class-string<RealInstanceType> $originalClassName
64906 *
64907 * @throws InvalidArgumentException
64908 * @throws MockObjectException
64909 *
64910 * @psalm-return MockObject&RealInstanceType
64911 */
64912 protected function createPartialMock(string $originalClassName, array $methods): MockObject
64913 {
64914 $partialMock = $this->getMockBuilder($originalClassName)->disableOriginalConstructor()->disableOriginalClone()->disableArgumentCloning()->disallowMockingUnknownTypes()->onlyMethods($methods)->getMock();
64915 Event\Facade::emitter()->testCreatedPartialMockObject($originalClassName, ...$methods);
64916 return $partialMock;
64917 }
64918 /**
64919 * Creates a test proxy for the specified class.
64920 *
64921 * @psalm-template RealInstanceType of object
64922 *
64923 * @psalm-param class-string<RealInstanceType> $originalClassName
64924 *
64925 * @throws InvalidArgumentException
64926 * @throws MockObjectException
64927 *
64928 * @psalm-return MockObject&RealInstanceType
64929 *
64930 * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5240
64931 */
64932 protected function createTestProxy(string $originalClassName, array $constructorArguments = []): MockObject
64933 {
64934 $testProxy = $this->getMockBuilder($originalClassName)->setConstructorArgs($constructorArguments)->enableProxyingToOriginalMethods()->getMock();
64935 Event\Facade::emitter()->testCreatedTestProxy($originalClassName, $constructorArguments);
64936 return $testProxy;
64937 }
64938 /**
64939 * Creates a mock object for the specified abstract class with all abstract
64940 * methods of the class mocked. Concrete methods are not mocked by default.
64941 * To mock concrete methods, use the 7th parameter ($mockedMethods).
64942 *
64943 * @psalm-template RealInstanceType of object
64944 *
64945 * @psalm-param class-string<RealInstanceType> $originalClassName
64946 *
64947 * @throws InvalidArgumentException
64948 * @throws MockObjectException
64949 *
64950 * @psalm-return MockObject&RealInstanceType
64951 *
64952 * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5241
64953 */
64954 protected function getMockForAbstractClass(string $originalClassName, array $arguments = [], string $mockClassName = '', bool $callOriginalConstructor = \true, bool $callOriginalClone = \true, bool $callAutoload = \true, array $mockedMethods = [], bool $cloneArguments = \false): MockObject
64955 {
64956 $mockObject = (new MockGenerator())->mockObjectForAbstractClass($originalClassName, $arguments, $mockClassName, $callOriginalConstructor, $callOriginalClone, $callAutoload, $mockedMethods, $cloneArguments);
64957 $this->registerMockObject($mockObject);
64958 Event\Facade::emitter()->testCreatedMockObjectForAbstractClass($originalClassName);
64959 assert($mockObject instanceof $originalClassName);
64960 assert($mockObject instanceof MockObject);
64961 return $mockObject;
64962 }
64963 /**
64964 * Creates a mock object based on the given WSDL file.
64965 *
64966 * @throws MockObjectException
64967 *
64968 * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5242
64969 */
64970 protected function getMockFromWsdl(string $wsdlFile, string $originalClassName = '', string $mockClassName = '', array $methods = [], bool $callOriginalConstructor = \true, array $options = []): MockObject
64971 {
64972 if ($originalClassName === '') {
64973 $fileName = pathinfo(basename(parse_url($wsdlFile, PHP_URL_PATH)), PATHINFO_FILENAME);
64974 $originalClassName = preg_replace('/\W/', '', $fileName);
64975 }
64976 if (!class_exists($originalClassName)) {
64977 eval((new MockGenerator())->generateClassFromWsdl($wsdlFile, $originalClassName, $methods, $options));
64978 }
64979 $mockObject = (new MockGenerator())->testDouble($originalClassName, \true, $methods, ['', $options], $mockClassName, $callOriginalConstructor, \false, \false);
64980 Event\Facade::emitter()->testCreatedMockObjectFromWsdl($wsdlFile, $originalClassName, $mockClassName, $methods, $callOriginalConstructor, $options);
64981 assert($mockObject instanceof MockObject);
64982 $this->registerMockObject($mockObject);
64983 return $mockObject;
64984 }
64985 /**
64986 * Creates a mock object for the specified trait with all abstract methods
64987 * of the trait mocked. Concrete methods to mock can be specified with the
64988 * `$mockedMethods` parameter.
64989 *
64990 * @psalm-param trait-string $traitName
64991 *
64992 * @throws InvalidArgumentException
64993 * @throws MockObjectException
64994 *
64995 * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5243
64996 */
64997 protected function getMockForTrait(string $traitName, array $arguments = [], string $mockClassName = '', bool $callOriginalConstructor = \true, bool $callOriginalClone = \true, bool $callAutoload = \true, array $mockedMethods = [], bool $cloneArguments = \false): MockObject
64998 {
64999 $mockObject = (new MockGenerator())->mockObjectForTrait($traitName, $arguments, $mockClassName, $callOriginalConstructor, $callOriginalClone, $callAutoload, $mockedMethods, $cloneArguments);
65000 $this->registerMockObject($mockObject);
65001 Event\Facade::emitter()->testCreatedMockObjectForTrait($traitName);
65002 return $mockObject;
65003 }
65004 /**
65005 * Creates an object that uses the specified trait.
65006 *
65007 * @psalm-param trait-string $traitName
65008 *
65009 * @throws MockObjectException
65010 *
65011 * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5244
65012 */
65013 protected function getObjectForTrait(string $traitName, array $arguments = [], string $traitClassName = '', bool $callOriginalConstructor = \true, bool $callOriginalClone = \true, bool $callAutoload = \true): object
65014 {
65015 return (new MockGenerator())->objectForTrait($traitName, $traitClassName, $callAutoload, $callOriginalConstructor, $arguments);
65016 }
65017 protected function transformException(Throwable $t): Throwable
65018 {
65019 return $t;
65020 }
65021 /**
65022 * This method is called when a test method did not execute successfully.
65023 *
65024 * @throws Throwable
65025 */
65026 protected function onNotSuccessfulTest(Throwable $t): never
65027 {
65028 throw $t;
65029 }
65030 /**
65031 * @throws AssertionFailedError
65032 * @throws Exception
65033 * @throws ExpectationFailedException
65034 * @throws Throwable
65035 */
65036 private function runTest(): mixed
65037 {
65038 $testArguments = array_merge($this->data, $this->dependencyInput);
65039 $this->registerMockObjectsFromTestArguments($testArguments);
65040 try {
65041 $testResult = $this->{$this->name}(...array_values($testArguments));
65042 } catch (Throwable $exception) {
65043 if (!$this->shouldExceptionExpectationsBeVerified($exception)) {
65044 throw $exception;
65045 }
65046 $this->verifyExceptionExpectations($exception);
65047 return null;
65048 }
65049 $this->expectedExceptionWasNotRaised();
65050 return $testResult;
65051 }
65052 /**
65053 * @throws Throwable
65054 */
65055 private function verifyMockObjects(): void
65056 {
65057 foreach ($this->mockObjects as $mockObject) {
65058 if ($mockObject->__phpunit_hasMatchers()) {
65059 $this->numberOfAssertionsPerformed++;
65060 }
65061 $mockObject->__phpunit_verify($this->shouldInvocationMockerBeReset($mockObject));
65062 }
65063 }
65064 /**
65065 * @throws SkippedTest
65066 */
65067 private function checkRequirements(): void
65068 {
65069 if (!$this->name || !method_exists($this, $this->name)) {
65070 return;
65071 }
65072 $missingRequirements = (new Requirements())->requirementsNotSatisfiedFor(static::class, $this->name);
65073 if (!empty($missingRequirements)) {
65074 $this->markTestSkipped(implode(PHP_EOL, $missingRequirements));
65075 }
65076 }
65077 private function handleDependencies(): bool
65078 {
65079 if ([] === $this->dependencies || $this->inIsolation) {
65080 return \true;
65081 }
65082 $passedTests = PassedTests::instance();
65083 foreach ($this->dependencies as $dependency) {
65084 if (!$dependency->isValid()) {
65085 $this->markErrorForInvalidDependency();
65086 return \false;
65087 }
65088 if ($dependency->targetIsClass()) {
65089 $dependencyClassName = $dependency->getTargetClassName();
65090 if (!class_exists($dependencyClassName)) {
65091 $this->markErrorForInvalidDependency($dependency);
65092 return \false;
65093 }
65094 if (!$passedTests->hasTestClassPassed($dependencyClassName)) {
65095 $this->markSkippedForMissingDependency($dependency);
65096 return \false;
65097 }
65098 continue;
65099 }
65100 $dependencyTarget = $dependency->getTarget();
65101 if (!$passedTests->hasTestMethodPassed($dependencyTarget)) {
65102 if (!$this->isCallableTestMethod($dependencyTarget)) {
65103 $this->markErrorForInvalidDependency($dependency);
65104 } else {
65105 $this->markSkippedForMissingDependency($dependency);
65106 }
65107 return \false;
65108 }
65109 if ($passedTests->isGreaterThan($dependencyTarget, $this->size())) {
65110 Event\Facade::emitter()->testConsideredRisky($this->valueObjectForEvents(), 'This test depends on a test that is larger than itself');
65111 return \true;
65112 }
65113 $returnValue = $passedTests->returnValue($dependencyTarget);
65114 if ($dependency->deepClone()) {
65115 $deepCopy = new DeepCopy();
65116 $deepCopy->skipUncloneable(\false);
65117 $this->dependencyInput[$dependencyTarget] = $deepCopy->copy($returnValue);
65118 } elseif ($dependency->shallowClone()) {
65119 $this->dependencyInput[$dependencyTarget] = clone $returnValue;
65120 } else {
65121 $this->dependencyInput[$dependencyTarget] = $returnValue;
65122 }
65123 }
65124 $this->testValueObjectForEvents = null;
65125 return \true;
65126 }
65127 /**
65128 * @throws Exception
65129 * @throws MoreThanOneDataSetFromDataProviderException
65130 * @throws NoPreviousThrowableException
65131 */
65132 private function markErrorForInvalidDependency(?\PHPUnit\Framework\ExecutionOrderDependency $dependency = null): void
65133 {
65134 $message = 'This test has an invalid dependency';
65135 if ($dependency !== null) {
65136 $message = sprintf('This test depends on "%s" which does not exist', $dependency->targetIsClass() ? $dependency->getTargetClassName() : $dependency->getTarget());
65137 }
65138 $exception = new \PHPUnit\Framework\InvalidDependencyException($message);
65139 Event\Facade::emitter()->testErrored($this->valueObjectForEvents(), Event\Code\ThrowableBuilder::from($exception));
65140 $this->status = TestStatus::error($message);
65141 }
65142 /**
65143 * @throws MoreThanOneDataSetFromDataProviderException
65144 */
65145 private function markSkippedForMissingDependency(\PHPUnit\Framework\ExecutionOrderDependency $dependency): void
65146 {
65147 $message = sprintf('This test depends on "%s" to pass', $dependency->getTarget());
65148 Event\Facade::emitter()->testSkipped($this->valueObjectForEvents(), $message);
65149 $this->status = TestStatus::skipped($message);
65150 }
65151 private function startOutputBuffering(): void
65152 {
65153 ob_start();
65154 $this->outputBufferingActive = \true;
65155 $this->outputBufferingLevel = ob_get_level();
65156 }
65157 /**
65158 * @throws MoreThanOneDataSetFromDataProviderException
65159 */
65160 private function stopOutputBuffering(): bool
65161 {
65162 $bufferingLevel = ob_get_level();
65163 if ($bufferingLevel !== $this->outputBufferingLevel) {
65164 if ($bufferingLevel > $this->outputBufferingLevel) {
65165 $message = 'Test code or tested code did not close its own output buffers';
65166 } else {
65167 $message = 'Test code or tested code closed output buffers other than its own';
65168 }
65169 while (ob_get_level() >= $this->outputBufferingLevel) {
65170 ob_end_clean();
65171 }
65172 Event\Facade::emitter()->testConsideredRisky($this->valueObjectForEvents(), $message);
65173 return \false;
65174 }
65175 $this->output = ob_get_clean();
65176 $this->outputBufferingActive = \false;
65177 $this->outputBufferingLevel = ob_get_level();
65178 return \true;
65179 }
65180 private function snapshotGlobalState(): void
65181 {
65182 if ($this->runTestInSeparateProcess || $this->inIsolation || !$this->backupGlobals && !$this->backupStaticProperties) {
65183 return;
65184 }
65185 $snapshot = $this->createGlobalStateSnapshot($this->backupGlobals === \true);
65186 $this->snapshot = $snapshot;
65187 }
65188 /**
65189 * @throws MoreThanOneDataSetFromDataProviderException
65190 */
65191 private function restoreGlobalState(): void
65192 {
65193 if (!$this->snapshot instanceof Snapshot) {
65194 return;
65195 }
65196 if (ConfigurationRegistry::get()->beStrictAboutChangesToGlobalState()) {
65197 $this->compareGlobalStateSnapshots($this->snapshot, $this->createGlobalStateSnapshot($this->backupGlobals === \true));
65198 }
65199 $restorer = new Restorer();
65200 if ($this->backupGlobals) {
65201 $restorer->restoreGlobalVariables($this->snapshot);
65202 }
65203 if ($this->backupStaticProperties) {
65204 $restorer->restoreStaticProperties($this->snapshot);
65205 }
65206 $this->snapshot = null;
65207 }
65208 private function createGlobalStateSnapshot(bool $backupGlobals): Snapshot
65209 {
65210 $excludeList = new GlobalStateExcludeList();
65211 foreach ($this->backupGlobalsExcludeList as $globalVariable) {
65212 $excludeList->addGlobalVariable($globalVariable);
65213 }
65214 if (!defined('PHPUNIT_TESTSUITE')) {
65215 $excludeList->addClassNamePrefix('PHPUnit');
65216 $excludeList->addClassNamePrefix('PHPUnitPHAR\SebastianBergmann\CodeCoverage');
65217 $excludeList->addClassNamePrefix('PHPUnitPHAR\SebastianBergmann\FileIterator');
65218 $excludeList->addClassNamePrefix('PHPUnitPHAR\SebastianBergmann\Invoker');
65219 $excludeList->addClassNamePrefix('PHPUnitPHAR\SebastianBergmann\Template');
65220 $excludeList->addClassNamePrefix('PHPUnitPHAR\SebastianBergmann\Timer');
65221 $excludeList->addStaticProperty(ComparatorFactory::class, 'instance');
65222 foreach ($this->backupStaticPropertiesExcludeList as $class => $properties) {
65223 foreach ($properties as $property) {
65224 $excludeList->addStaticProperty($class, $property);
65225 }
65226 }
65227 }
65228 return new Snapshot($excludeList, $backupGlobals, (bool) $this->backupStaticProperties, \false, \false, \false, \false, \false, \false, \false);
65229 }
65230 /**
65231 * @throws MoreThanOneDataSetFromDataProviderException
65232 */
65233 private function compareGlobalStateSnapshots(Snapshot $before, Snapshot $after): void
65234 {
65235 $backupGlobals = $this->backupGlobals === null || $this->backupGlobals;
65236 if ($backupGlobals) {
65237 $this->compareGlobalStateSnapshotPart($before->globalVariables(), $after->globalVariables(), "--- Global variables before the test\n+++ Global variables after the test\n");
65238 $this->compareGlobalStateSnapshotPart($before->superGlobalVariables(), $after->superGlobalVariables(), "--- Super-global variables before the test\n+++ Super-global variables after the test\n");
65239 }
65240 if ($this->backupStaticProperties) {
65241 $this->compareGlobalStateSnapshotPart($before->staticProperties(), $after->staticProperties(), "--- Static properties before the test\n+++ Static properties after the test\n");
65242 }
65243 }
65244 /**
65245 * @throws MoreThanOneDataSetFromDataProviderException
65246 */
65247 private function compareGlobalStateSnapshotPart(array $before, array $after, string $header): void
65248 {
65249 if ($before == $after) {
65250 return;
65251 }
65252 $differ = new Differ(new UnifiedDiffOutputBuilder($header));
65253 $exporter = new Exporter();
65254 Event\Facade::emitter()->testConsideredRisky($this->valueObjectForEvents(), 'This test modified global state but was not expected to do so' . PHP_EOL . trim($differ->diff($exporter->export($before), $exporter->export($after))));
65255 }
65256 private function shouldInvocationMockerBeReset(MockObject $mock): bool
65257 {
65258 $enumerator = new Enumerator();
65259 if (in_array($mock, $enumerator->enumerate($this->dependencyInput), \true)) {
65260 return \false;
65261 }
65262 if (!is_array($this->testResult) && !is_object($this->testResult)) {
65263 return \true;
65264 }
65265 return !in_array($mock, $enumerator->enumerate($this->testResult), \true);
65266 }
65267 /**
65268 * @deprecated
65269 */
65270 private function registerMockObjectsFromTestArguments(array $testArguments, Context $context = new Context()): void
65271 {
65272 if ($this->registerMockObjectsFromTestArgumentsRecursively) {
65273 foreach ((new Enumerator())->enumerate($testArguments) as $object) {
65274 if ($object instanceof MockObject) {
65275 $this->registerMockObject($object);
65276 }
65277 }
65278 } else {
65279 foreach ($testArguments as &$testArgument) {
65280 if ($testArgument instanceof MockObject) {
65281 $testArgument = Cloner::clone($testArgument);
65282 $this->registerMockObject($testArgument);
65283 } elseif (is_array($testArgument) && !$context->contains($testArgument)) {
65284 $testArgumentCopy = $testArgument;
65285 $context->add($testArgument);
65286 $this->registerMockObjectsFromTestArguments($testArgumentCopy, $context);
65287 }
65288 }
65289 }
65290 }
65291 private function unregisterCustomComparators(): void
65292 {
65293 $factory = ComparatorFactory::getInstance();
65294 foreach ($this->customComparators as $comparator) {
65295 $factory->unregister($comparator);
65296 }
65297 $this->customComparators = [];
65298 }
65299 private function cleanupIniSettings(): void
65300 {
65301 foreach ($this->iniSettings as $varName => $oldValue) {
65302 ini_set($varName, $oldValue);
65303 }
65304 $this->iniSettings = [];
65305 }
65306 private function cleanupLocaleSettings(): void
65307 {
65308 foreach ($this->locale as $category => $locale) {
65309 setlocale($category, $locale);
65310 }
65311 $this->locale = [];
65312 }
65313 /**
65314 * @throws Exception
65315 */
65316 private function shouldExceptionExpectationsBeVerified(Throwable $throwable): bool
65317 {
65318 $result = \false;
65319 if ($this->expectedException !== null || $this->expectedExceptionCode !== null || $this->expectedExceptionMessage !== null || $this->expectedExceptionMessageRegExp !== null) {
65320 $result = \true;
65321 }
65322 if ($throwable instanceof \PHPUnit\Framework\Exception) {
65323 $result = \false;
65324 }
65325 if (is_string($this->expectedException)) {
65326 try {
65327 $reflector = new ReflectionClass($this->expectedException);
65328 // @codeCoverageIgnoreStart
65329 } catch (ReflectionException $e) {
65330 throw new \PHPUnit\Framework\Exception($e->getMessage(), $e->getCode(), $e);
65331 }
65332 // @codeCoverageIgnoreEnd
65333 if ($this->expectedException === 'PHPUnit\Framework\Exception' || $this->expectedException === '\PHPUnit\Framework\Exception' || $reflector->isSubclassOf(\PHPUnit\Framework\Exception::class)) {
65334 $result = \true;
65335 }
65336 }
65337 return $result;
65338 }
65339 private function shouldRunInSeparateProcess(): bool
65340 {
65341 if ($this->inIsolation) {
65342 return \false;
65343 }
65344 if ($this->runTestInSeparateProcess) {
65345 return \true;
65346 }
65347 if ($this->runClassInSeparateProcess) {
65348 return \true;
65349 }
65350 return ConfigurationRegistry::get()->processIsolation();
65351 }
65352 private function isCallableTestMethod(string $dependency): bool
65353 {
65354 [$className, $methodName] = explode('::', $dependency);
65355 if (!class_exists($className)) {
65356 return \false;
65357 }
65358 $class = new ReflectionClass($className);
65359 if (!$class->isSubclassOf(__CLASS__)) {
65360 return \false;
65361 }
65362 if (!$class->hasMethod($methodName)) {
65363 return \false;
65364 }
65365 return TestUtil::isTestMethod($class->getMethod($methodName));
65366 }
65367 /**
65368 * @throws Exception
65369 * @throws ExpectationFailedException
65370 * @throws MoreThanOneDataSetFromDataProviderException
65371 * @throws NoPreviousThrowableException
65372 */
65373 private function performAssertionsOnOutput(): void
65374 {
65375 try {
65376 if ($this->outputExpectedRegex !== null) {
65377 $this->assertMatchesRegularExpression($this->outputExpectedRegex, $this->output);
65378 } elseif ($this->outputExpectedString !== null) {
65379 $this->assertSame($this->outputExpectedString, $this->output);
65380 }
65381 } catch (\PHPUnit\Framework\ExpectationFailedException $e) {
65382 $this->status = TestStatus::failure($e->getMessage());
65383 Event\Facade::emitter()->testFailed($this->valueObjectForEvents(), Event\Code\ThrowableBuilder::from($e), Event\Code\ComparisonFailureBuilder::from($e));
65384 throw $e;
65385 }
65386 }
65387 /**
65388 * @throws Throwable
65389 *
65390 * @codeCoverageIgnore
65391 */
65392 private function invokeBeforeClassHookMethods(array $hookMethods, Event\Emitter $emitter): void
65393 {
65394 $this->invokeHookMethods($hookMethods['beforeClass'], $emitter, 'beforeFirstTestMethodCalled', 'beforeFirstTestMethodErrored', 'beforeFirstTestMethodFinished');
65395 }
65396 /**
65397 * @throws Throwable
65398 */
65399 private function invokeBeforeTestHookMethods(array $hookMethods, Event\Emitter $emitter): void
65400 {
65401 $this->invokeHookMethods($hookMethods['before'], $emitter, 'beforeTestMethodCalled', 'beforeTestMethodErrored', 'beforeTestMethodFinished');
65402 }
65403 /**
65404 * @throws Throwable
65405 */
65406 private function invokePreConditionHookMethods(array $hookMethods, Event\Emitter $emitter): void
65407 {
65408 $this->invokeHookMethods($hookMethods['preCondition'], $emitter, 'preConditionCalled', 'preConditionErrored', 'preConditionFinished');
65409 }
65410 /**
65411 * @throws Throwable
65412 */
65413 private function invokePostConditionHookMethods(array $hookMethods, Event\Emitter $emitter): void
65414 {
65415 $this->invokeHookMethods($hookMethods['postCondition'], $emitter, 'postConditionCalled', 'postConditionErrored', 'postConditionFinished');
65416 }
65417 /**
65418 * @throws Throwable
65419 */
65420 private function invokeAfterTestHookMethods(array $hookMethods, Event\Emitter $emitter): void
65421 {
65422 $this->invokeHookMethods($hookMethods['after'], $emitter, 'afterTestMethodCalled', 'afterTestMethodErrored', 'afterTestMethodFinished');
65423 }
65424 /**
65425 * @throws Throwable
65426 *
65427 * @codeCoverageIgnore
65428 */
65429 private function invokeAfterClassHookMethods(array $hookMethods, Event\Emitter $emitter): void
65430 {
65431 $this->invokeHookMethods($hookMethods['afterClass'], $emitter, 'afterLastTestMethodCalled', 'afterLastTestMethodErrored', 'afterLastTestMethodFinished');
65432 }
65433 /**
65434 * @psalm-param list<non-empty-string> $hookMethods
65435 * @psalm-param 'beforeFirstTestMethodCalled'|'beforeTestMethodCalled'|'preConditionCalled'|'postConditionCalled'|'afterTestMethodCalled'|'afterLastTestMethodCalled' $calledMethod
65436 * @psalm-param 'beforeFirstTestMethodErrored'|'beforeTestMethodErrored'|'preConditionErrored'|'postConditionErrored'|'afterTestMethodErrored'|'afterLastTestMethodErrored' $erroredMethod
65437 * @psalm-param 'beforeFirstTestMethodFinished'|'beforeTestMethodFinished'|'preConditionFinished'|'postConditionFinished'|'afterTestMethodFinished'|'afterLastTestMethodFinished' $finishedMethod
65438 *
65439 * @throws Throwable
65440 */
65441 private function invokeHookMethods(array $hookMethods, Event\Emitter $emitter, string $calledMethod, string $erroredMethod, string $finishedMethod): void
65442 {
65443 $methodsInvoked = [];
65444 foreach ($hookMethods as $methodName) {
65445 if ($this->methodDoesNotExistOrIsDeclaredInTestCase($methodName)) {
65446 continue;
65447 }
65448 $methodInvoked = new Event\Code\ClassMethod(static::class, $methodName);
65449 try {
65450 $this->{$methodName}();
65451 } catch (Throwable $t) {
65452 }
65453 $emitter->{$calledMethod}(static::class, $methodInvoked);
65454 $methodsInvoked[] = $methodInvoked;
65455 if (isset($t)) {
65456 $emitter->{$erroredMethod}(static::class, $methodInvoked, Event\Code\ThrowableBuilder::from($t));
65457 break;
65458 }
65459 }
65460 if (!empty($methodsInvoked)) {
65461 $emitter->{$finishedMethod}(static::class, ...$methodsInvoked);
65462 }
65463 if (isset($t)) {
65464 throw $t;
65465 }
65466 }
65467 private function methodDoesNotExistOrIsDeclaredInTestCase(string $methodName): bool
65468 {
65469 $reflector = new ReflectionObject($this);
65470 return !$reflector->hasMethod($methodName) || $reflector->getMethod($methodName)->getDeclaringClass()->getName() === self::class;
65471 }
65472 /**
65473 * @throws ExpectationFailedException
65474 */
65475 private function verifyExceptionExpectations(\Exception|Throwable $exception): void
65476 {
65477 if ($this->expectedException !== null) {
65478 $this->assertThat($exception, new ExceptionConstraint($this->expectedException));
65479 }
65480 if ($this->expectedExceptionMessage !== null) {
65481 $this->assertThat($exception->getMessage(), new ExceptionMessageIsOrContains($this->expectedExceptionMessage));
65482 }
65483 if ($this->expectedExceptionMessageRegExp !== null) {
65484 $this->assertThat($exception->getMessage(), new ExceptionMessageMatchesRegularExpression($this->expectedExceptionMessageRegExp));
65485 }
65486 if ($this->expectedExceptionCode !== null) {
65487 $this->assertThat($exception->getCode(), new ExceptionCode($this->expectedExceptionCode));
65488 }
65489 }
65490 /**
65491 * @throws AssertionFailedError
65492 */
65493 private function expectedExceptionWasNotRaised(): void
65494 {
65495 if ($this->expectedException !== null) {
65496 $this->assertThat(null, new ExceptionConstraint($this->expectedException));
65497 } elseif ($this->expectedExceptionMessage !== null) {
65498 $this->numberOfAssertionsPerformed++;
65499 throw new \PHPUnit\Framework\AssertionFailedError(sprintf('Failed asserting that exception with message "%s" is thrown', $this->expectedExceptionMessage));
65500 } elseif ($this->expectedExceptionMessageRegExp !== null) {
65501 $this->numberOfAssertionsPerformed++;
65502 throw new \PHPUnit\Framework\AssertionFailedError(sprintf('Failed asserting that exception with message matching "%s" is thrown', $this->expectedExceptionMessageRegExp));
65503 } elseif ($this->expectedExceptionCode !== null) {
65504 $this->numberOfAssertionsPerformed++;
65505 throw new \PHPUnit\Framework\AssertionFailedError(sprintf('Failed asserting that exception with code "%s" is thrown', $this->expectedExceptionCode));
65506 }
65507 }
65508 private function isRegisteredFailure(Throwable $t): bool
65509 {
65510 foreach (array_keys($this->failureTypes) as $failureType) {
65511 if ($t instanceof $failureType) {
65512 return \true;
65513 }
65514 }
65515 return \false;
65516 }
65517 /**
65518 * @internal This method is not covered by the backward compatibility promise for PHPUnit
65519 */
65520 private function hasExpectationOnOutput(): bool
65521 {
65522 return is_string($this->outputExpectedString) || is_string($this->outputExpectedRegex);
65523 }
65524 private function requirementsNotSatisfied(): bool
65525 {
65526 return (new Requirements())->requirementsNotSatisfiedFor(static::class, $this->name) !== [];
65527 }
65528 /**
65529 * @see https://github.com/sebastianbergmann/phpunit/issues/6095
65530 */
65531 private function handleExceptionFromInvokedCountMockObjectRule(Throwable $t): void
65532 {
65533 if (!$t instanceof \PHPUnit\Framework\ExpectationFailedException) {
65534 return;
65535 }
65536 $trace = $t->getTrace();
65537 if (isset($trace[0]['class']) && $trace[0]['class'] === InvokedCount::class) {
65538 $this->numberOfAssertionsPerformed++;
65539 }
65540 }
65541 /**
65542 * Creates a test stub for the specified interface or class.
65543 *
65544 * @psalm-template RealInstanceType of object
65545 *
65546 * @psalm-param class-string<RealInstanceType> $originalClassName
65547 *
65548 * @throws InvalidArgumentException
65549 * @throws MockObjectException
65550 * @throws NoPreviousThrowableException
65551 *
65552 * @psalm-return Stub&RealInstanceType
65553 */
65554 protected static function createStub(string $originalClassName): Stub
65555 {
65556 $stub = (new MockGenerator())->testDouble($originalClassName, \true, callOriginalConstructor: \false, callOriginalClone: \false, cloneArguments: \false, allowMockingUnknownTypes: \false);
65557 Event\Facade::emitter()->testCreatedStub($originalClassName);
65558 assert($stub instanceof $originalClassName);
65559 assert($stub instanceof Stub);
65560 return $stub;
65561 }
65562 /**
65563 * @psalm-param list<class-string> $interfaces
65564 *
65565 * @throws MockObjectException
65566 */
65567 protected static function createStubForIntersectionOfInterfaces(array $interfaces): Stub
65568 {
65569 $stub = (new MockGenerator())->testDoubleForInterfaceIntersection($interfaces, \true);
65570 Event\Facade::emitter()->testCreatedStubForIntersectionOfInterfaces($interfaces);
65571 return $stub;
65572 }
65573 /**
65574 * Creates (and configures) a test stub for the specified interface or class.
65575 *
65576 * @psalm-template RealInstanceType of object
65577 *
65578 * @psalm-param class-string<RealInstanceType> $originalClassName
65579 *
65580 * @throws InvalidArgumentException
65581 * @throws MockObjectException
65582 * @throws NoPreviousThrowableException
65583 *
65584 * @psalm-return Stub&RealInstanceType
65585 */
65586 final protected static function createConfiguredStub(string $originalClassName, array $configuration): Stub
65587 {
65588 $o = self::createStub($originalClassName);
65589 foreach ($configuration as $method => $return) {
65590 $o->method($method)->willReturn($return);
65591 }
65592 return $o;
65593 }
65594 }
65595 <?php
65596
65597 declare (strict_types=1);
65598 /*
65599 * This file is part of PHPUnit.
65600 *
65601 * (c) Sebastian Bergmann <sebastian@phpunit.de>
65602 *
65603 * For the full copyright and license information, please view the LICENSE
65604 * file that was distributed with this source code.
65605 */
65606 namespace PHPUnit\Framework;
65607
65608 use const PHP_EOL;
65609 use function assert;
65610 use function defined;
65611 use function error_clear_last;
65612 use function extension_loaded;
65613 use function get_include_path;
65614 use function hrtime;
65615 use function serialize;
65616 use function sprintf;
65617 use function sys_get_temp_dir;
65618 use function tempnam;
65619 use function unlink;
65620 use function var_export;
65621 use function xdebug_is_debugger_active;
65622 use AssertionError;
65623 use PHPUnit\Event;
65624 use PHPUnit\Event\NoPreviousThrowableException;
65625 use PHPUnit\Event\TestData\MoreThanOneDataSetFromDataProviderException;
65626 use PHPUnit\Metadata\Api\CodeCoverage as CodeCoverageMetadataApi;
65627 use PHPUnit\Metadata\Parser\Registry as MetadataRegistry;
65628 use PHPUnit\Runner\CodeCoverage;
65629 use PHPUnit\Runner\ErrorHandler;
65630 use PHPUnit\TextUI\Configuration\Configuration;
65631 use PHPUnit\TextUI\Configuration\Registry as ConfigurationRegistry;
65632 use PHPUnit\Util\GlobalState;
65633 use PHPUnit\Util\PHP\AbstractPhpProcess;
65634 use ReflectionClass;
65635 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Exception as OriginalCodeCoverageException;
65636 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\InvalidArgumentException;
65637 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\UnintentionallyCoveredCodeException;
65638 use PHPUnitPHAR\SebastianBergmann\Invoker\Invoker;
65639 use PHPUnitPHAR\SebastianBergmann\Invoker\TimeoutException;
65640 use PHPUnitPHAR\SebastianBergmann\Template\Template;
65641 use Throwable;
65642 /**
65643 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
65644 *
65645 * @internal This class is not covered by the backward compatibility promise for PHPUnit
65646 */
65647 final class TestRunner
65648 {
65649 private ?bool $timeLimitCanBeEnforced = null;
65650 private readonly Configuration $configuration;
65651 public function __construct()
65652 {
65653 $this->configuration = ConfigurationRegistry::get();
65654 }
65655 /**
65656 * @throws \PHPUnit\Runner\Exception
65657 * @throws CodeCoverageException
65658 * @throws InvalidArgumentException
65659 * @throws MoreThanOneDataSetFromDataProviderException
65660 * @throws UnintentionallyCoveredCodeException
65661 */
65662 public function run(\PHPUnit\Framework\TestCase $test): void
65663 {
65664 \PHPUnit\Framework\Assert::resetCount();
65665 if ($this->configuration->registerMockObjectsFromTestArgumentsRecursively()) {
65666 $test->registerMockObjectsFromTestArgumentsRecursively();
65667 }
65668 $shouldCodeCoverageBeCollected = (new CodeCoverageMetadataApi())->shouldCodeCoverageBeCollectedFor($test::class, $test->name());
65669 $error = \false;
65670 $failure = \false;
65671 $incomplete = \false;
65672 $risky = \false;
65673 $skipped = \false;
65674 error_clear_last();
65675 if ($this->shouldErrorHandlerBeUsed($test)) {
65676 ErrorHandler::instance()->enable();
65677 }
65678 $collectCodeCoverage = CodeCoverage::instance()->isActive() && $shouldCodeCoverageBeCollected;
65679 if ($collectCodeCoverage) {
65680 CodeCoverage::instance()->start($test);
65681 }
65682 try {
65683 if ($this->canTimeLimitBeEnforced() && $this->shouldTimeLimitBeEnforced($test)) {
65684 $risky = $this->runTestWithTimeout($test);
65685 } else {
65686 $test->runBare();
65687 }
65688 } catch (\PHPUnit\Framework\AssertionFailedError $e) {
65689 $failure = \true;
65690 if ($e instanceof \PHPUnit\Framework\IncompleteTestError) {
65691 $incomplete = \true;
65692 } elseif ($e instanceof \PHPUnit\Framework\SkippedTest) {
65693 $skipped = \true;
65694 }
65695 } catch (AssertionError $e) {
65696 $test->addToAssertionCount(1);
65697 $failure = \true;
65698 $frame = $e->getTrace()[0];
65699 assert(isset($frame['file']));
65700 assert(isset($frame['line']));
65701 $e = new \PHPUnit\Framework\AssertionFailedError(sprintf('%s in %s:%s', $e->getMessage(), $frame['file'], $frame['line']));
65702 } catch (Throwable $e) {
65703 $error = \true;
65704 }
65705 $test->addToAssertionCount(\PHPUnit\Framework\Assert::getCount());
65706 if ($this->configuration->reportUselessTests() && !$test->doesNotPerformAssertions() && $test->numberOfAssertionsPerformed() === 0) {
65707 $risky = \true;
65708 }
65709 if (!$error && !$failure && !$incomplete && !$skipped && !$risky && $this->configuration->requireCoverageMetadata() && !$this->hasCoverageMetadata($test::class, $test->name())) {
65710 Event\Facade::emitter()->testConsideredRisky($test->valueObjectForEvents(), 'This test does not define a code coverage target but is expected to do so');
65711 $risky = \true;
65712 }
65713 if ($collectCodeCoverage) {
65714 $append = !$risky && !$incomplete && !$skipped;
65715 $linesToBeCovered = [];
65716 $linesToBeUsed = [];
65717 if ($append) {
65718 try {
65719 $linesToBeCovered = (new CodeCoverageMetadataApi())->linesToBeCovered($test::class, $test->name());
65720 $linesToBeUsed = (new CodeCoverageMetadataApi())->linesToBeUsed($test::class, $test->name());
65721 } catch (\PHPUnit\Framework\InvalidCoversTargetException $cce) {
65722 Event\Facade::emitter()->testTriggeredPhpunitWarning($test->valueObjectForEvents(), $cce->getMessage());
65723 $append = \false;
65724 }
65725 }
65726 try {
65727 CodeCoverage::instance()->stop($append, $linesToBeCovered, $linesToBeUsed);
65728 } catch (UnintentionallyCoveredCodeException $cce) {
65729 Event\Facade::emitter()->testConsideredRisky($test->valueObjectForEvents(), 'This test executed code that is not listed as code to be covered or used:' . PHP_EOL . $cce->getMessage());
65730 } catch (OriginalCodeCoverageException $cce) {
65731 $error = \true;
65732 $e = $e ?? $cce;
65733 }
65734 }
65735 ErrorHandler::instance()->disable();
65736 if (!$error && !$incomplete && !$skipped && $this->configuration->reportUselessTests() && !$test->doesNotPerformAssertions() && $test->numberOfAssertionsPerformed() === 0) {
65737 Event\Facade::emitter()->testConsideredRisky($test->valueObjectForEvents(), 'This test did not perform any assertions');
65738 }
65739 if ($test->doesNotPerformAssertions() && $test->numberOfAssertionsPerformed() > 0) {
65740 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' : ''));
65741 }
65742 if ($test->hasUnexpectedOutput()) {
65743 Event\Facade::emitter()->testPrintedUnexpectedOutput($test->output());
65744 }
65745 if ($this->configuration->disallowTestOutput() && $test->hasUnexpectedOutput()) {
65746 Event\Facade::emitter()->testConsideredRisky($test->valueObjectForEvents(), sprintf('Test code or tested code printed unexpected output: %s', $test->output()));
65747 }
65748 if ($test->wasPrepared()) {
65749 Event\Facade::emitter()->testFinished($test->valueObjectForEvents(), $test->numberOfAssertionsPerformed());
65750 }
65751 }
65752 /**
65753 * @throws \PHPUnit\Runner\Exception
65754 * @throws \PHPUnit\Util\Exception
65755 * @throws \SebastianBergmann\Template\InvalidArgumentException
65756 * @throws Exception
65757 * @throws MoreThanOneDataSetFromDataProviderException
65758 * @throws NoPreviousThrowableException
65759 * @throws ProcessIsolationException
65760 */
65761 public function runInSeparateProcess(\PHPUnit\Framework\TestCase $test, bool $runEntireClass, bool $preserveGlobalState): void
65762 {
65763 $class = new ReflectionClass($test);
65764 if ($runEntireClass) {
65765 $template = new Template(__DIR__ . '/../Util/PHP/Template/TestCaseClass.tpl');
65766 } else {
65767 $template = new Template(__DIR__ . '/../Util/PHP/Template/TestCaseMethod.tpl');
65768 }
65769 $bootstrap = '';
65770 $constants = '';
65771 $globals = '';
65772 $includedFiles = '';
65773 $iniSettings = '';
65774 if (ConfigurationRegistry::get()->hasBootstrap()) {
65775 $bootstrap = ConfigurationRegistry::get()->bootstrap();
65776 }
65777 if ($preserveGlobalState) {
65778 $constants = GlobalState::getConstantsAsString();
65779 $globals = GlobalState::getGlobalsAsString();
65780 $includedFiles = GlobalState::getIncludedFilesAsString();
65781 $iniSettings = GlobalState::getIniSettingsAsString();
65782 }
65783 $exportObjects = Event\Facade::emitter()->exportsObjects() ? 'true' : 'false';
65784 $coverage = CodeCoverage::instance()->isActive() ? 'true' : 'false';
65785 $linesToBeIgnored = var_export(CodeCoverage::instance()->linesToBeIgnored(), \true);
65786 if (defined('PHPUNIT_COMPOSER_INSTALL')) {
65787 $composerAutoload = var_export(PHPUNIT_COMPOSER_INSTALL, \true);
65788 } else {
65789 $composerAutoload = '\'\'';
65790 }
65791 if (defined('__PHPUNIT_PHAR__')) {
65792 $phar = var_export(__PHPUNIT_PHAR__, \true);
65793 } else {
65794 $phar = '\'\'';
65795 }
65796 $data = var_export(serialize($test->providedData()), \true);
65797 $dataName = var_export($test->dataName(), \true);
65798 $dependencyInput = var_export(serialize($test->dependencyInput()), \true);
65799 $includePath = var_export(get_include_path(), \true);
65800 // must do these fixes because TestCaseMethod.tpl has unserialize('{data}') in it, and we can't break BC
65801 // the lines above used to use addcslashes() rather than var_export(), which breaks null byte escape sequences
65802 $data = "'." . $data . ".'";
65803 $dataName = "'.(" . $dataName . ").'";
65804 $dependencyInput = "'." . $dependencyInput . ".'";
65805 $includePath = "'." . $includePath . ".'";
65806 $offset = hrtime();
65807 $serializedConfiguration = $this->saveConfigurationForChildProcess();
65808 $processResultFile = tempnam(sys_get_temp_dir(), 'phpunit_');
65809 $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];
65810 if (!$runEntireClass) {
65811 $var['methodName'] = $test->name();
65812 }
65813 $template->setVar($var);
65814 $php = AbstractPhpProcess::factory();
65815 $php->runTestJob($template->render(), $test, $processResultFile);
65816 @unlink($serializedConfiguration);
65817 }
65818 /**
65819 * @psalm-param class-string $className
65820 * @psalm-param non-empty-string $methodName
65821 */
65822 private function hasCoverageMetadata(string $className, string $methodName): bool
65823 {
65824 foreach (MetadataRegistry::parser()->forClassAndMethod($className, $methodName) as $metadata) {
65825 if ($metadata->isCovers()) {
65826 return \true;
65827 }
65828 if ($metadata->isCoversClass()) {
65829 return \true;
65830 }
65831 if ($metadata->isCoversFunction()) {
65832 return \true;
65833 }
65834 if ($metadata->isCoversNothing()) {
65835 return \true;
65836 }
65837 }
65838 return \false;
65839 }
65840 private function canTimeLimitBeEnforced(): bool
65841 {
65842 if ($this->timeLimitCanBeEnforced !== null) {
65843 return $this->timeLimitCanBeEnforced;
65844 }
65845 $this->timeLimitCanBeEnforced = (new Invoker())->canInvokeWithTimeout();
65846 return $this->timeLimitCanBeEnforced;
65847 }
65848 private function shouldTimeLimitBeEnforced(\PHPUnit\Framework\TestCase $test): bool
65849 {
65850 if (!$this->configuration->enforceTimeLimit()) {
65851 return \false;
65852 }
65853 if (!($this->configuration->defaultTimeLimit() || $test->size()->isKnown())) {
65854 return \false;
65855 }
65856 if (extension_loaded('xdebug') && xdebug_is_debugger_active()) {
65857 return \false;
65858 }
65859 return \true;
65860 }
65861 /**
65862 * @throws Throwable
65863 */
65864 private function runTestWithTimeout(\PHPUnit\Framework\TestCase $test): bool
65865 {
65866 $_timeout = $this->configuration->defaultTimeLimit();
65867 $testSize = $test->size();
65868 if ($testSize->isSmall()) {
65869 $_timeout = $this->configuration->timeoutForSmallTests();
65870 } elseif ($testSize->isMedium()) {
65871 $_timeout = $this->configuration->timeoutForMediumTests();
65872 } elseif ($testSize->isLarge()) {
65873 $_timeout = $this->configuration->timeoutForLargeTests();
65874 }
65875 try {
65876 (new Invoker())->invoke([$test, 'runBare'], [], $_timeout);
65877 } catch (TimeoutException) {
65878 Event\Facade::emitter()->testConsideredRisky($test->valueObjectForEvents(), sprintf('This test was aborted after %d second%s', $_timeout, $_timeout !== 1 ? 's' : ''));
65879 return \true;
65880 }
65881 return \false;
65882 }
65883 /**
65884 * @throws ProcessIsolationException
65885 */
65886 private function saveConfigurationForChildProcess(): string
65887 {
65888 $path = tempnam(sys_get_temp_dir(), 'phpunit_');
65889 if ($path === \false) {
65890 throw new \PHPUnit\Framework\ProcessIsolationException();
65891 }
65892 if (!ConfigurationRegistry::saveTo($path)) {
65893 throw new \PHPUnit\Framework\ProcessIsolationException();
65894 }
65895 return $path;
65896 }
65897 private function shouldErrorHandlerBeUsed(\PHPUnit\Framework\TestCase $test): bool
65898 {
65899 if (MetadataRegistry::parser()->forMethod($test::class, $test->name())->isWithoutErrorHandler()->isNotEmpty()) {
65900 return \false;
65901 }
65902 return \true;
65903 }
65904 }
65905 <?php
65906
65907 declare (strict_types=1);
65908 /*
65909 * This file is part of PHPUnit.
65910 *
65911 * (c) Sebastian Bergmann <sebastian@phpunit.de>
65912 *
65913 * For the full copyright and license information, please view the LICENSE
65914 * file that was distributed with this source code.
65915 */
65916 namespace PHPUnit\Framework\TestSize;
65917
65918 /**
65919 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
65920 *
65921 * @internal This class is not covered by the backward compatibility promise for PHPUnit
65922 *
65923 * @psalm-immutable
65924 */
65925 abstract class Known extends \PHPUnit\Framework\TestSize\TestSize
65926 {
65927 /**
65928 * @psalm-assert-if-true Known $this
65929 */
65930 public function isKnown(): bool
65931 {
65932 return \true;
65933 }
65934 abstract public function isGreaterThan(self $other): bool;
65935 }
65936 <?php
65937
65938 declare (strict_types=1);
65939 /*
65940 * This file is part of PHPUnit.
65941 *
65942 * (c) Sebastian Bergmann <sebastian@phpunit.de>
65943 *
65944 * For the full copyright and license information, please view the LICENSE
65945 * file that was distributed with this source code.
65946 */
65947 namespace PHPUnit\Framework\TestSize;
65948
65949 /**
65950 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
65951 *
65952 * @internal This class is not covered by the backward compatibility promise for PHPUnit
65953 *
65954 * @psalm-immutable
65955 */
65956 final class Large extends \PHPUnit\Framework\TestSize\Known
65957 {
65958 /**
65959 * @psalm-assert-if-true Large $this
65960 */
65961 public function isLarge(): bool
65962 {
65963 return \true;
65964 }
65965 public function isGreaterThan(\PHPUnit\Framework\TestSize\TestSize $other): bool
65966 {
65967 return !$other->isLarge();
65968 }
65969 public function asString(): string
65970 {
65971 return 'large';
65972 }
65973 }
65974 <?php
65975
65976 declare (strict_types=1);
65977 /*
65978 * This file is part of PHPUnit.
65979 *
65980 * (c) Sebastian Bergmann <sebastian@phpunit.de>
65981 *
65982 * For the full copyright and license information, please view the LICENSE
65983 * file that was distributed with this source code.
65984 */
65985 namespace PHPUnit\Framework\TestSize;
65986
65987 /**
65988 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
65989 *
65990 * @internal This class is not covered by the backward compatibility promise for PHPUnit
65991 *
65992 * @psalm-immutable
65993 */
65994 final class Medium extends \PHPUnit\Framework\TestSize\Known
65995 {
65996 /**
65997 * @psalm-assert-if-true Medium $this
65998 */
65999 public function isMedium(): bool
66000 {
66001 return \true;
66002 }
66003 public function isGreaterThan(\PHPUnit\Framework\TestSize\TestSize $other): bool
66004 {
66005 return $other->isSmall();
66006 }
66007 public function asString(): string
66008 {
66009 return 'medium';
66010 }
66011 }
66012 <?php
66013
66014 declare (strict_types=1);
66015 /*
66016 * This file is part of PHPUnit.
66017 *
66018 * (c) Sebastian Bergmann <sebastian@phpunit.de>
66019 *
66020 * For the full copyright and license information, please view the LICENSE
66021 * file that was distributed with this source code.
66022 */
66023 namespace PHPUnit\Framework\TestSize;
66024
66025 /**
66026 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
66027 *
66028 * @internal This class is not covered by the backward compatibility promise for PHPUnit
66029 *
66030 * @psalm-immutable
66031 */
66032 final class Small extends \PHPUnit\Framework\TestSize\Known
66033 {
66034 /**
66035 * @psalm-assert-if-true Small $this
66036 */
66037 public function isSmall(): bool
66038 {
66039 return \true;
66040 }
66041 public function isGreaterThan(\PHPUnit\Framework\TestSize\TestSize $other): bool
66042 {
66043 return \false;
66044 }
66045 public function asString(): string
66046 {
66047 return 'small';
66048 }
66049 }
66050 <?php
66051
66052 declare (strict_types=1);
66053 /*
66054 * This file is part of PHPUnit.
66055 *
66056 * (c) Sebastian Bergmann <sebastian@phpunit.de>
66057 *
66058 * For the full copyright and license information, please view the LICENSE
66059 * file that was distributed with this source code.
66060 */
66061 namespace PHPUnit\Framework\TestSize;
66062
66063 /**
66064 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
66065 *
66066 * @internal This class is not covered by the backward compatibility promise for PHPUnit
66067 *
66068 * @psalm-immutable
66069 */
66070 abstract class TestSize
66071 {
66072 public static function unknown(): self
66073 {
66074 return new \PHPUnit\Framework\TestSize\Unknown();
66075 }
66076 public static function small(): self
66077 {
66078 return new \PHPUnit\Framework\TestSize\Small();
66079 }
66080 public static function medium(): self
66081 {
66082 return new \PHPUnit\Framework\TestSize\Medium();
66083 }
66084 public static function large(): self
66085 {
66086 return new \PHPUnit\Framework\TestSize\Large();
66087 }
66088 /**
66089 * @psalm-assert-if-true Known $this
66090 */
66091 public function isKnown(): bool
66092 {
66093 return \false;
66094 }
66095 /**
66096 * @psalm-assert-if-true Unknown $this
66097 */
66098 public function isUnknown(): bool
66099 {
66100 return \false;
66101 }
66102 /**
66103 * @psalm-assert-if-true Small $this
66104 */
66105 public function isSmall(): bool
66106 {
66107 return \false;
66108 }
66109 /**
66110 * @psalm-assert-if-true Medium $this
66111 */
66112 public function isMedium(): bool
66113 {
66114 return \false;
66115 }
66116 /**
66117 * @psalm-assert-if-true Large $this
66118 */
66119 public function isLarge(): bool
66120 {
66121 return \false;
66122 }
66123 abstract public function asString(): string;
66124 }
66125 <?php
66126
66127 declare (strict_types=1);
66128 /*
66129 * This file is part of PHPUnit.
66130 *
66131 * (c) Sebastian Bergmann <sebastian@phpunit.de>
66132 *
66133 * For the full copyright and license information, please view the LICENSE
66134 * file that was distributed with this source code.
66135 */
66136 namespace PHPUnit\Framework\TestSize;
66137
66138 /**
66139 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
66140 *
66141 * @internal This class is not covered by the backward compatibility promise for PHPUnit
66142 *
66143 * @psalm-immutable
66144 */
66145 final class Unknown extends \PHPUnit\Framework\TestSize\TestSize
66146 {
66147 /**
66148 * @psalm-assert-if-true Unknown $this
66149 */
66150 public function isUnknown(): bool
66151 {
66152 return \true;
66153 }
66154 public function asString(): string
66155 {
66156 return 'unknown';
66157 }
66158 }
66159 <?php
66160
66161 declare (strict_types=1);
66162 /*
66163 * This file is part of PHPUnit.
66164 *
66165 * (c) Sebastian Bergmann <sebastian@phpunit.de>
66166 *
66167 * For the full copyright and license information, please view the LICENSE
66168 * file that was distributed with this source code.
66169 */
66170 namespace PHPUnit\Framework\TestStatus;
66171
66172 /**
66173 * @psalm-immutable
66174 *
66175 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
66176 *
66177 * @internal This class is not covered by the backward compatibility promise for PHPUnit
66178 */
66179 final class Deprecation extends \PHPUnit\Framework\TestStatus\Known
66180 {
66181 /**
66182 * @psalm-assert-if-true Deprecation $this
66183 */
66184 public function isDeprecation(): bool
66185 {
66186 return \true;
66187 }
66188 public function asInt(): int
66189 {
66190 return 4;
66191 }
66192 public function asString(): string
66193 {
66194 return 'deprecation';
66195 }
66196 }
66197 <?php
66198
66199 declare (strict_types=1);
66200 /*
66201 * This file is part of PHPUnit.
66202 *
66203 * (c) Sebastian Bergmann <sebastian@phpunit.de>
66204 *
66205 * For the full copyright and license information, please view the LICENSE
66206 * file that was distributed with this source code.
66207 */
66208 namespace PHPUnit\Framework\TestStatus;
66209
66210 /**
66211 * @psalm-immutable
66212 *
66213 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
66214 *
66215 * @internal This class is not covered by the backward compatibility promise for PHPUnit
66216 */
66217 final class Error extends \PHPUnit\Framework\TestStatus\Known
66218 {
66219 /**
66220 * @psalm-assert-if-true Error $this
66221 */
66222 public function isError(): bool
66223 {
66224 return \true;
66225 }
66226 public function asInt(): int
66227 {
66228 return 8;
66229 }
66230 public function asString(): string
66231 {
66232 return 'error';
66233 }
66234 }
66235 <?php
66236
66237 declare (strict_types=1);
66238 /*
66239 * This file is part of PHPUnit.
66240 *
66241 * (c) Sebastian Bergmann <sebastian@phpunit.de>
66242 *
66243 * For the full copyright and license information, please view the LICENSE
66244 * file that was distributed with this source code.
66245 */
66246 namespace PHPUnit\Framework\TestStatus;
66247
66248 /**
66249 * @psalm-immutable
66250 *
66251 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
66252 *
66253 * @internal This class is not covered by the backward compatibility promise for PHPUnit
66254 */
66255 final class Failure extends \PHPUnit\Framework\TestStatus\Known
66256 {
66257 /**
66258 * @psalm-assert-if-true Failure $this
66259 */
66260 public function isFailure(): bool
66261 {
66262 return \true;
66263 }
66264 public function asInt(): int
66265 {
66266 return 7;
66267 }
66268 public function asString(): string
66269 {
66270 return 'failure';
66271 }
66272 }
66273 <?php
66274
66275 declare (strict_types=1);
66276 /*
66277 * This file is part of PHPUnit.
66278 *
66279 * (c) Sebastian Bergmann <sebastian@phpunit.de>
66280 *
66281 * For the full copyright and license information, please view the LICENSE
66282 * file that was distributed with this source code.
66283 */
66284 namespace PHPUnit\Framework\TestStatus;
66285
66286 /**
66287 * @psalm-immutable
66288 *
66289 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
66290 *
66291 * @internal This class is not covered by the backward compatibility promise for PHPUnit
66292 */
66293 final class Incomplete extends \PHPUnit\Framework\TestStatus\Known
66294 {
66295 /**
66296 * @psalm-assert-if-true Incomplete $this
66297 */
66298 public function isIncomplete(): bool
66299 {
66300 return \true;
66301 }
66302 public function asInt(): int
66303 {
66304 return 2;
66305 }
66306 public function asString(): string
66307 {
66308 return 'incomplete';
66309 }
66310 }
66311 <?php
66312
66313 declare (strict_types=1);
66314 /*
66315 * This file is part of PHPUnit.
66316 *
66317 * (c) Sebastian Bergmann <sebastian@phpunit.de>
66318 *
66319 * For the full copyright and license information, please view the LICENSE
66320 * file that was distributed with this source code.
66321 */
66322 namespace PHPUnit\Framework\TestStatus;
66323
66324 /**
66325 * @psalm-immutable
66326 *
66327 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
66328 *
66329 * @internal This class is not covered by the backward compatibility promise for PHPUnit
66330 */
66331 abstract class Known extends \PHPUnit\Framework\TestStatus\TestStatus
66332 {
66333 /**
66334 * @psalm-assert-if-true Known $this
66335 */
66336 public function isKnown(): bool
66337 {
66338 return \true;
66339 }
66340 }
66341 <?php
66342
66343 declare (strict_types=1);
66344 /*
66345 * This file is part of PHPUnit.
66346 *
66347 * (c) Sebastian Bergmann <sebastian@phpunit.de>
66348 *
66349 * For the full copyright and license information, please view the LICENSE
66350 * file that was distributed with this source code.
66351 */
66352 namespace PHPUnit\Framework\TestStatus;
66353
66354 /**
66355 * @psalm-immutable
66356 *
66357 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
66358 *
66359 * @internal This class is not covered by the backward compatibility promise for PHPUnit
66360 */
66361 final class Notice extends \PHPUnit\Framework\TestStatus\Known
66362 {
66363 /**
66364 * @psalm-assert-if-true Notice $this
66365 */
66366 public function isNotice(): bool
66367 {
66368 return \true;
66369 }
66370 public function asInt(): int
66371 {
66372 return 3;
66373 }
66374 public function asString(): string
66375 {
66376 return 'notice';
66377 }
66378 }
66379 <?php
66380
66381 declare (strict_types=1);
66382 /*
66383 * This file is part of PHPUnit.
66384 *
66385 * (c) Sebastian Bergmann <sebastian@phpunit.de>
66386 *
66387 * For the full copyright and license information, please view the LICENSE
66388 * file that was distributed with this source code.
66389 */
66390 namespace PHPUnit\Framework\TestStatus;
66391
66392 /**
66393 * @psalm-immutable
66394 *
66395 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
66396 *
66397 * @internal This class is not covered by the backward compatibility promise for PHPUnit
66398 */
66399 final class Risky extends \PHPUnit\Framework\TestStatus\Known
66400 {
66401 /**
66402 * @psalm-assert-if-true Risky $this
66403 */
66404 public function isRisky(): bool
66405 {
66406 return \true;
66407 }
66408 public function asInt(): int
66409 {
66410 return 5;
66411 }
66412 public function asString(): string
66413 {
66414 return 'risky';
66415 }
66416 }
66417 <?php
66418
66419 declare (strict_types=1);
66420 /*
66421 * This file is part of PHPUnit.
66422 *
66423 * (c) Sebastian Bergmann <sebastian@phpunit.de>
66424 *
66425 * For the full copyright and license information, please view the LICENSE
66426 * file that was distributed with this source code.
66427 */
66428 namespace PHPUnit\Framework\TestStatus;
66429
66430 /**
66431 * @psalm-immutable
66432 *
66433 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
66434 *
66435 * @internal This class is not covered by the backward compatibility promise for PHPUnit
66436 */
66437 final class Skipped extends \PHPUnit\Framework\TestStatus\Known
66438 {
66439 /**
66440 * @psalm-assert-if-true Skipped $this
66441 */
66442 public function isSkipped(): bool
66443 {
66444 return \true;
66445 }
66446 public function asInt(): int
66447 {
66448 return 1;
66449 }
66450 public function asString(): string
66451 {
66452 return 'skipped';
66453 }
66454 }
66455 <?php
66456
66457 declare (strict_types=1);
66458 /*
66459 * This file is part of PHPUnit.
66460 *
66461 * (c) Sebastian Bergmann <sebastian@phpunit.de>
66462 *
66463 * For the full copyright and license information, please view the LICENSE
66464 * file that was distributed with this source code.
66465 */
66466 namespace PHPUnit\Framework\TestStatus;
66467
66468 /**
66469 * @psalm-immutable
66470 *
66471 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
66472 *
66473 * @internal This class is not covered by the backward compatibility promise for PHPUnit
66474 */
66475 final class Success extends \PHPUnit\Framework\TestStatus\Known
66476 {
66477 /**
66478 * @psalm-assert-if-true Success $this
66479 */
66480 public function isSuccess(): bool
66481 {
66482 return \true;
66483 }
66484 public function asInt(): int
66485 {
66486 return 0;
66487 }
66488 public function asString(): string
66489 {
66490 return 'success';
66491 }
66492 }
66493 <?php
66494
66495 declare (strict_types=1);
66496 /*
66497 * This file is part of PHPUnit.
66498 *
66499 * (c) Sebastian Bergmann <sebastian@phpunit.de>
66500 *
66501 * For the full copyright and license information, please view the LICENSE
66502 * file that was distributed with this source code.
66503 */
66504 namespace PHPUnit\Framework\TestStatus;
66505
66506 /**
66507 * @psalm-immutable
66508 *
66509 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
66510 *
66511 * @internal This class is not covered by the backward compatibility promise for PHPUnit
66512 */
66513 abstract class TestStatus
66514 {
66515 private readonly string $message;
66516 public static function from(int $status): self
66517 {
66518 return match ($status) {
66519 0 => self::success(),
66520 1 => self::skipped(),
66521 2 => self::incomplete(),
66522 3 => self::notice(),
66523 4 => self::deprecation(),
66524 5 => self::risky(),
66525 6 => self::warning(),
66526 7 => self::failure(),
66527 8 => self::error(),
66528 default => self::unknown(),
66529 };
66530 }
66531 public static function unknown(): self
66532 {
66533 return new \PHPUnit\Framework\TestStatus\Unknown();
66534 }
66535 public static function success(): self
66536 {
66537 return new \PHPUnit\Framework\TestStatus\Success();
66538 }
66539 public static function skipped(string $message = ''): self
66540 {
66541 return new \PHPUnit\Framework\TestStatus\Skipped($message);
66542 }
66543 public static function incomplete(string $message = ''): self
66544 {
66545 return new \PHPUnit\Framework\TestStatus\Incomplete($message);
66546 }
66547 public static function notice(string $message = ''): self
66548 {
66549 return new \PHPUnit\Framework\TestStatus\Notice($message);
66550 }
66551 public static function deprecation(string $message = ''): self
66552 {
66553 return new \PHPUnit\Framework\TestStatus\Deprecation($message);
66554 }
66555 public static function failure(string $message = ''): self
66556 {
66557 return new \PHPUnit\Framework\TestStatus\Failure($message);
66558 }
66559 public static function error(string $message = ''): self
66560 {
66561 return new \PHPUnit\Framework\TestStatus\Error($message);
66562 }
66563 public static function warning(string $message = ''): self
66564 {
66565 return new \PHPUnit\Framework\TestStatus\Warning($message);
66566 }
66567 public static function risky(string $message = ''): self
66568 {
66569 return new \PHPUnit\Framework\TestStatus\Risky($message);
66570 }
66571 private function __construct(string $message = '')
66572 {
66573 $this->message = $message;
66574 }
66575 /**
66576 * @psalm-assert-if-true Known $this
66577 */
66578 public function isKnown(): bool
66579 {
66580 return \false;
66581 }
66582 /**
66583 * @psalm-assert-if-true Unknown $this
66584 */
66585 public function isUnknown(): bool
66586 {
66587 return \false;
66588 }
66589 /**
66590 * @psalm-assert-if-true Success $this
66591 */
66592 public function isSuccess(): bool
66593 {
66594 return \false;
66595 }
66596 /**
66597 * @psalm-assert-if-true Skipped $this
66598 */
66599 public function isSkipped(): bool
66600 {
66601 return \false;
66602 }
66603 /**
66604 * @psalm-assert-if-true Incomplete $this
66605 */
66606 public function isIncomplete(): bool
66607 {
66608 return \false;
66609 }
66610 /**
66611 * @psalm-assert-if-true Notice $this
66612 */
66613 public function isNotice(): bool
66614 {
66615 return \false;
66616 }
66617 /**
66618 * @psalm-assert-if-true Deprecation $this
66619 */
66620 public function isDeprecation(): bool
66621 {
66622 return \false;
66623 }
66624 /**
66625 * @psalm-assert-if-true Failure $this
66626 */
66627 public function isFailure(): bool
66628 {
66629 return \false;
66630 }
66631 /**
66632 * @psalm-assert-if-true Error $this
66633 */
66634 public function isError(): bool
66635 {
66636 return \false;
66637 }
66638 /**
66639 * @psalm-assert-if-true Warning $this
66640 */
66641 public function isWarning(): bool
66642 {
66643 return \false;
66644 }
66645 /**
66646 * @psalm-assert-if-true Risky $this
66647 */
66648 public function isRisky(): bool
66649 {
66650 return \false;
66651 }
66652 public function message(): string
66653 {
66654 return $this->message;
66655 }
66656 public function isMoreImportantThan(self $other): bool
66657 {
66658 return $this->asInt() > $other->asInt();
66659 }
66660 abstract public function asInt(): int;
66661 abstract public function asString(): string;
66662 }
66663 <?php
66664
66665 declare (strict_types=1);
66666 /*
66667 * This file is part of PHPUnit.
66668 *
66669 * (c) Sebastian Bergmann <sebastian@phpunit.de>
66670 *
66671 * For the full copyright and license information, please view the LICENSE
66672 * file that was distributed with this source code.
66673 */
66674 namespace PHPUnit\Framework\TestStatus;
66675
66676 /**
66677 * @psalm-immutable
66678 *
66679 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
66680 *
66681 * @internal This class is not covered by the backward compatibility promise for PHPUnit
66682 */
66683 final class Unknown extends \PHPUnit\Framework\TestStatus\TestStatus
66684 {
66685 /**
66686 * @psalm-assert-if-true Unknown $this
66687 */
66688 public function isUnknown(): bool
66689 {
66690 return \true;
66691 }
66692 public function asInt(): int
66693 {
66694 return -1;
66695 }
66696 public function asString(): string
66697 {
66698 return 'unknown';
66699 }
66700 }
66701 <?php
66702
66703 declare (strict_types=1);
66704 /*
66705 * This file is part of PHPUnit.
66706 *
66707 * (c) Sebastian Bergmann <sebastian@phpunit.de>
66708 *
66709 * For the full copyright and license information, please view the LICENSE
66710 * file that was distributed with this source code.
66711 */
66712 namespace PHPUnit\Framework\TestStatus;
66713
66714 /**
66715 * @psalm-immutable
66716 *
66717 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
66718 *
66719 * @internal This class is not covered by the backward compatibility promise for PHPUnit
66720 */
66721 final class Warning extends \PHPUnit\Framework\TestStatus\Known
66722 {
66723 /**
66724 * @psalm-assert-if-true Warning $this
66725 */
66726 public function isWarning(): bool
66727 {
66728 return \true;
66729 }
66730 public function asInt(): int
66731 {
66732 return 6;
66733 }
66734 public function asString(): string
66735 {
66736 return 'warning';
66737 }
66738 }
66739 <?php
66740
66741 declare (strict_types=1);
66742 /*
66743 * This file is part of PHPUnit.
66744 *
66745 * (c) Sebastian Bergmann <sebastian@phpunit.de>
66746 *
66747 * For the full copyright and license information, please view the LICENSE
66748 * file that was distributed with this source code.
66749 */
66750 namespace PHPUnit\Framework;
66751
66752 use const PHP_EOL;
66753 use function array_keys;
66754 use function array_map;
66755 use function array_pop;
66756 use function array_reverse;
66757 use function assert;
66758 use function call_user_func;
66759 use function class_exists;
66760 use function count;
66761 use function implode;
66762 use function is_callable;
66763 use function is_file;
66764 use function is_subclass_of;
66765 use function sprintf;
66766 use function str_ends_with;
66767 use function str_starts_with;
66768 use function trim;
66769 use Iterator;
66770 use IteratorAggregate;
66771 use PHPUnit\Event;
66772 use PHPUnit\Event\Code\TestMethod;
66773 use PHPUnit\Event\NoPreviousThrowableException;
66774 use PHPUnit\Metadata\Api\Dependencies;
66775 use PHPUnit\Metadata\Api\Groups;
66776 use PHPUnit\Metadata\Api\HookMethods;
66777 use PHPUnit\Metadata\Api\Requirements;
66778 use PHPUnit\Metadata\MetadataCollection;
66779 use PHPUnit\Runner\Exception as RunnerException;
66780 use PHPUnit\Runner\Filter\Factory;
66781 use PHPUnit\Runner\PhptTestCase;
66782 use PHPUnit\Runner\TestSuiteLoader;
66783 use PHPUnit\TestRunner\TestResult\Facade as TestResultFacade;
66784 use PHPUnit\Util\Filter;
66785 use PHPUnit\Util\Reflection;
66786 use PHPUnit\Util\Test as TestUtil;
66787 use ReflectionClass;
66788 use ReflectionMethod;
66789 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\InvalidArgumentException;
66790 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\UnintentionallyCoveredCodeException;
66791 use Throwable;
66792 /**
66793 * @template-implements IteratorAggregate<int, Test>
66794 *
66795 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
66796 *
66797 * @internal This class is not covered by the backward compatibility promise for PHPUnit
66798 */
66799 class TestSuite implements IteratorAggregate, \PHPUnit\Framework\Reorderable, \PHPUnit\Framework\SelfDescribing, \PHPUnit\Framework\Test
66800 {
66801 /**
66802 * @psalm-var non-empty-string
66803 */
66804 private string $name;
66805 /**
66806 * @psalm-var array<string,list<Test>>
66807 */
66808 private array $groups = [];
66809 /**
66810 * @psalm-var ?list<ExecutionOrderDependency>
66811 */
66812 private ?array $requiredTests = null;
66813 /**
66814 * @psalm-var list<Test>
66815 */
66816 private array $tests = [];
66817 /**
66818 * @psalm-var ?list<ExecutionOrderDependency>
66819 */
66820 private ?array $providedTests = null;
66821 private ?Factory $iteratorFilter = null;
66822 private bool $wasRun = \false;
66823 /**
66824 * @psalm-param non-empty-string $name
66825 */
66826 public static function empty(string $name): static
66827 {
66828 return new static($name);
66829 }
66830 /**
66831 * @psalm-param class-string $className
66832 */
66833 public static function fromClassName(string $className): static
66834 {
66835 assert(class_exists($className));
66836 $class = new ReflectionClass($className);
66837 return static::fromClassReflector($class);
66838 }
66839 public static function fromClassReflector(ReflectionClass $class): static
66840 {
66841 $testSuite = new static($class->getName());
66842 $constructor = $class->getConstructor();
66843 if ($constructor !== null && !$constructor->isPublic()) {
66844 Event\Facade::emitter()->testRunnerTriggeredPhpunitWarning(sprintf('Class "%s" has no public constructor.', $class->getName()));
66845 return $testSuite;
66846 }
66847 foreach (Reflection::publicMethodsInTestClass($class) as $method) {
66848 if ($method->getDeclaringClass()->getName() === \PHPUnit\Framework\Assert::class) {
66849 continue;
66850 }
66851 if ($method->getDeclaringClass()->getName() === \PHPUnit\Framework\TestCase::class) {
66852 continue;
66853 }
66854 if (!TestUtil::isTestMethod($method)) {
66855 continue;
66856 }
66857 $testSuite->addTestMethod($class, $method);
66858 }
66859 if ($testSuite->isEmpty()) {
66860 Event\Facade::emitter()->testRunnerTriggeredPhpunitWarning(sprintf('No tests found in class "%s".', $class->getName()));
66861 }
66862 return $testSuite;
66863 }
66864 /**
66865 * @psalm-param non-empty-string $name
66866 */
66867 final private function __construct(string $name)
66868 {
66869 $this->name = $name;
66870 }
66871 /**
66872 * Returns a string representation of the test suite.
66873 */
66874 public function toString(): string
66875 {
66876 return $this->name();
66877 }
66878 /**
66879 * Adds a test to the suite.
66880 */
66881 public function addTest(\PHPUnit\Framework\Test $test, array $groups = []): void
66882 {
66883 $class = new ReflectionClass($test);
66884 if ($class->isAbstract()) {
66885 return;
66886 }
66887 $this->tests[] = $test;
66888 $this->clearCaches();
66889 if ($test instanceof self && empty($groups)) {
66890 $groups = $test->groups();
66891 }
66892 if ($this->containsOnlyVirtualGroups($groups)) {
66893 $groups[] = 'default';
66894 }
66895 foreach ($groups as $group) {
66896 if (!isset($this->groups[$group])) {
66897 $this->groups[$group] = [$test];
66898 } else {
66899 $this->groups[$group][] = $test;
66900 }
66901 }
66902 if ($test instanceof \PHPUnit\Framework\TestCase) {
66903 $test->setGroups($groups);
66904 }
66905 }
66906 /**
66907 * Adds the tests from the given class to the suite.
66908 *
66909 * @throws Exception
66910 */
66911 public function addTestSuite(ReflectionClass $testClass): void
66912 {
66913 if ($testClass->isAbstract()) {
66914 throw new \PHPUnit\Framework\Exception(sprintf('Class %s is abstract', $testClass->getName()));
66915 }
66916 if (!$testClass->isSubclassOf(\PHPUnit\Framework\TestCase::class)) {
66917 throw new \PHPUnit\Framework\Exception(sprintf('Class %s is not a subclass of %s', $testClass->getName(), \PHPUnit\Framework\TestCase::class));
66918 }
66919 $this->addTest(self::fromClassReflector($testClass));
66920 }
66921 /**
66922 * Wraps both <code>addTest()</code> and <code>addTestSuite</code>
66923 * as well as the separate import statements for the user's convenience.
66924 *
66925 * If the named file cannot be read or there are no new tests that can be
66926 * added, a <code>PHPUnit\Framework\WarningTestCase</code> will be created instead,
66927 * leaving the current test run untouched.
66928 *
66929 * @throws Exception
66930 */
66931 public function addTestFile(string $filename): void
66932 {
66933 try {
66934 if (str_ends_with($filename, '.phpt') && is_file($filename)) {
66935 $this->addTest(new PhptTestCase($filename));
66936 } else {
66937 $this->addTestSuite((new TestSuiteLoader())->load($filename));
66938 }
66939 } catch (RunnerException $e) {
66940 Event\Facade::emitter()->testRunnerTriggeredPhpunitWarning($e->getMessage());
66941 }
66942 }
66943 /**
66944 * Wrapper for addTestFile() that adds multiple test files.
66945 *
66946 * @throws Exception
66947 */
66948 public function addTestFiles(iterable $fileNames): void
66949 {
66950 foreach ($fileNames as $filename) {
66951 $this->addTestFile((string) $filename);
66952 }
66953 }
66954 /**
66955 * Counts the number of test cases that will be run by this test.
66956 */
66957 public function count(): int
66958 {
66959 $numTests = 0;
66960 foreach ($this as $test) {
66961 $numTests += count($test);
66962 }
66963 return $numTests;
66964 }
66965 public function isEmpty(): bool
66966 {
66967 foreach ($this as $test) {
66968 if (count($test) !== 0) {
66969 return \false;
66970 }
66971 }
66972 return \true;
66973 }
66974 /**
66975 * @psalm-return non-empty-string
66976 */
66977 public function name(): string
66978 {
66979 return $this->name;
66980 }
66981 /**
66982 * Returns the test groups of the suite.
66983 *
66984 * @psalm-return list<string>
66985 */
66986 public function groups(): array
66987 {
66988 return array_map('strval', array_keys($this->groups));
66989 }
66990 public function groupDetails(): array
66991 {
66992 return $this->groups;
66993 }
66994 /**
66995 * @throws CodeCoverageException
66996 * @throws Event\RuntimeException
66997 * @throws Exception
66998 * @throws InvalidArgumentException
66999 * @throws NoPreviousThrowableException
67000 * @throws UnintentionallyCoveredCodeException
67001 */
67002 public function run(): void
67003 {
67004 if ($this->wasRun) {
67005 // @codeCoverageIgnoreStart
67006 throw new \PHPUnit\Framework\Exception('The tests aggregated by this TestSuite were already run');
67007 // @codeCoverageIgnoreEnd
67008 }
67009 $this->wasRun = \true;
67010 if ($this->isEmpty()) {
67011 return;
67012 }
67013 $emitter = Event\Facade::emitter();
67014 $testSuiteValueObjectForEvents = Event\TestSuite\TestSuiteBuilder::from($this);
67015 $emitter->testSuiteStarted($testSuiteValueObjectForEvents);
67016 if (!$this->invokeMethodsBeforeFirstTest($emitter, $testSuiteValueObjectForEvents)) {
67017 return;
67018 }
67019 /** @psalm-var list<Test> $tests */
67020 $tests = [];
67021 foreach ($this as $test) {
67022 $tests[] = $test;
67023 }
67024 $tests = array_reverse($tests);
67025 $this->tests = [];
67026 $this->groups = [];
67027 while (($test = array_pop($tests)) !== null) {
67028 if (TestResultFacade::shouldStop()) {
67029 $emitter->testRunnerExecutionAborted();
67030 break;
67031 }
67032 $test->run();
67033 }
67034 $this->invokeMethodsAfterLastTest($emitter);
67035 $emitter->testSuiteFinished($testSuiteValueObjectForEvents);
67036 }
67037 /**
67038 * Returns the tests as an enumeration.
67039 *
67040 * @psalm-return list<Test>
67041 */
67042 public function tests(): array
67043 {
67044 return $this->tests;
67045 }
67046 /**
67047 * Set tests of the test suite.
67048 *
67049 * @psalm-param list<Test> $tests
67050 */
67051 public function setTests(array $tests): void
67052 {
67053 $this->tests = $tests;
67054 }
67055 /**
67056 * Mark the test suite as skipped.
67057 *
67058 * @throws SkippedTestSuiteError
67059 */
67060 public function markTestSuiteSkipped(string $message = ''): never
67061 {
67062 throw new \PHPUnit\Framework\SkippedTestSuiteError($message);
67063 }
67064 /**
67065 * Returns an iterator for this test suite.
67066 */
67067 public function getIterator(): Iterator
67068 {
67069 $iterator = new \PHPUnit\Framework\TestSuiteIterator($this);
67070 if ($this->iteratorFilter !== null) {
67071 $iterator = $this->iteratorFilter->factory($iterator, $this);
67072 }
67073 return $iterator;
67074 }
67075 public function injectFilter(Factory $filter): void
67076 {
67077 $this->iteratorFilter = $filter;
67078 foreach ($this as $test) {
67079 if ($test instanceof self) {
67080 $test->injectFilter($filter);
67081 }
67082 }
67083 }
67084 /**
67085 * @psalm-return list<ExecutionOrderDependency>
67086 */
67087 public function provides(): array
67088 {
67089 if ($this->providedTests === null) {
67090 $this->providedTests = [];
67091 if (is_callable($this->sortId(), \true)) {
67092 $this->providedTests[] = new \PHPUnit\Framework\ExecutionOrderDependency($this->sortId());
67093 }
67094 foreach ($this->tests as $test) {
67095 if (!$test instanceof \PHPUnit\Framework\Reorderable) {
67096 continue;
67097 }
67098 $this->providedTests = \PHPUnit\Framework\ExecutionOrderDependency::mergeUnique($this->providedTests, $test->provides());
67099 }
67100 }
67101 return $this->providedTests;
67102 }
67103 /**
67104 * @psalm-return list<ExecutionOrderDependency>
67105 */
67106 public function requires(): array
67107 {
67108 if ($this->requiredTests === null) {
67109 $this->requiredTests = [];
67110 foreach ($this->tests as $test) {
67111 if (!$test instanceof \PHPUnit\Framework\Reorderable) {
67112 continue;
67113 }
67114 $this->requiredTests = \PHPUnit\Framework\ExecutionOrderDependency::mergeUnique(\PHPUnit\Framework\ExecutionOrderDependency::filterInvalid($this->requiredTests), $test->requires());
67115 }
67116 $this->requiredTests = \PHPUnit\Framework\ExecutionOrderDependency::diff($this->requiredTests, $this->provides());
67117 }
67118 return $this->requiredTests;
67119 }
67120 public function sortId(): string
67121 {
67122 return $this->name() . '::class';
67123 }
67124 /**
67125 * @psalm-assert-if-true class-string $this->name
67126 */
67127 public function isForTestClass(): bool
67128 {
67129 return class_exists($this->name, \false) && is_subclass_of($this->name, \PHPUnit\Framework\TestCase::class);
67130 }
67131 /**
67132 * @throws Event\TestData\MoreThanOneDataSetFromDataProviderException
67133 * @throws Exception
67134 */
67135 protected function addTestMethod(ReflectionClass $class, ReflectionMethod $method): void
67136 {
67137 $className = $class->getName();
67138 $methodName = $method->getName();
67139 assert(!empty($methodName));
67140 try {
67141 $test = (new \PHPUnit\Framework\TestBuilder())->build($class, $methodName);
67142 } catch (\PHPUnit\Framework\InvalidDataProviderException $e) {
67143 Event\Facade::emitter()->testTriggeredPhpunitError(new TestMethod($className, $methodName, $class->getFileName(), $method->getStartLine(), Event\Code\TestDoxBuilder::fromClassNameAndMethodName($className, $methodName), MetadataCollection::fromArray([]), Event\TestData\TestDataCollection::fromArray([])), sprintf("The data provider specified for %s::%s is invalid\n%s", $className, $methodName, $this->throwableToString($e)));
67144 return;
67145 }
67146 if ($test instanceof \PHPUnit\Framework\TestCase || $test instanceof \PHPUnit\Framework\DataProviderTestSuite) {
67147 $test->setDependencies(Dependencies::dependencies($class->getName(), $methodName));
67148 }
67149 $this->addTest($test, (new Groups())->groups($class->getName(), $methodName));
67150 }
67151 private function clearCaches(): void
67152 {
67153 $this->providedTests = null;
67154 $this->requiredTests = null;
67155 }
67156 private function containsOnlyVirtualGroups(array $groups): bool
67157 {
67158 foreach ($groups as $group) {
67159 if (!str_starts_with($group, '__phpunit_')) {
67160 return \false;
67161 }
67162 }
67163 return \true;
67164 }
67165 private function methodDoesNotExistOrIsDeclaredInTestCase(string $methodName): bool
67166 {
67167 $reflector = new ReflectionClass($this->name);
67168 return !$reflector->hasMethod($methodName) || $reflector->getMethod($methodName)->getDeclaringClass()->getName() === \PHPUnit\Framework\TestCase::class;
67169 }
67170 /**
67171 * @throws Exception
67172 */
67173 private function throwableToString(Throwable $t): string
67174 {
67175 $message = $t->getMessage();
67176 if (empty(trim($message))) {
67177 $message = '<no message>';
67178 }
67179 if ($t instanceof \PHPUnit\Framework\InvalidDataProviderException) {
67180 return sprintf("%s\n%s", $message, Filter::getFilteredStacktrace($t));
67181 }
67182 return sprintf("%s: %s\n%s", $t::class, $message, Filter::getFilteredStacktrace($t));
67183 }
67184 /**
67185 * @throws Exception
67186 * @throws NoPreviousThrowableException
67187 */
67188 private function invokeMethodsBeforeFirstTest(Event\Emitter $emitter, Event\TestSuite\TestSuite $testSuiteValueObjectForEvents): bool
67189 {
67190 if (!$this->isForTestClass()) {
67191 return \true;
67192 }
67193 $methods = (new HookMethods())->hookMethods($this->name)['beforeClass'];
67194 $calledMethods = [];
67195 $emitCalledEvent = \true;
67196 $result = \true;
67197 foreach ($methods as $method) {
67198 if ($this->methodDoesNotExistOrIsDeclaredInTestCase($method)) {
67199 continue;
67200 }
67201 $calledMethod = new Event\Code\ClassMethod($this->name, $method);
67202 try {
67203 $missingRequirements = (new Requirements())->requirementsNotSatisfiedFor($this->name, $method);
67204 if ($missingRequirements !== []) {
67205 $emitCalledEvent = \false;
67206 $this->markTestSuiteSkipped(implode(PHP_EOL, $missingRequirements));
67207 }
67208 call_user_func([$this->name, $method]);
67209 } catch (Throwable $t) {
67210 }
67211 /** @psalm-suppress RedundantCondition */
67212 if ($emitCalledEvent) {
67213 $emitter->beforeFirstTestMethodCalled($this->name, $calledMethod);
67214 $calledMethods[] = $calledMethod;
67215 }
67216 if (isset($t) && $t instanceof \PHPUnit\Framework\SkippedTest) {
67217 $emitter->testSuiteSkipped($testSuiteValueObjectForEvents, $t->getMessage());
67218 return \false;
67219 }
67220 if (isset($t)) {
67221 $emitter->beforeFirstTestMethodErrored($this->name, $calledMethod, Event\Code\ThrowableBuilder::from($t));
67222 $result = \false;
67223 }
67224 }
67225 if (!empty($calledMethods)) {
67226 $emitter->beforeFirstTestMethodFinished($this->name, ...$calledMethods);
67227 }
67228 return $result;
67229 }
67230 private function invokeMethodsAfterLastTest(Event\Emitter $emitter): void
67231 {
67232 if (!$this->isForTestClass()) {
67233 return;
67234 }
67235 $methods = (new HookMethods())->hookMethods($this->name)['afterClass'];
67236 $calledMethods = [];
67237 foreach ($methods as $method) {
67238 if ($this->methodDoesNotExistOrIsDeclaredInTestCase($method)) {
67239 continue;
67240 }
67241 $calledMethod = new Event\Code\ClassMethod($this->name, $method);
67242 try {
67243 call_user_func([$this->name, $method]);
67244 } catch (Throwable $t) {
67245 }
67246 $emitter->afterLastTestMethodCalled($this->name, $calledMethod);
67247 $calledMethods[] = $calledMethod;
67248 if (isset($t)) {
67249 $emitter->afterLastTestMethodErrored($this->name, $calledMethod, Event\Code\ThrowableBuilder::from($t));
67250 }
67251 }
67252 if (!empty($calledMethods)) {
67253 $emitter->afterLastTestMethodFinished($this->name, ...$calledMethods);
67254 }
67255 }
67256 }
67257 <?php
67258
67259 declare (strict_types=1);
67260 /*
67261 * This file is part of PHPUnit.
67262 *
67263 * (c) Sebastian Bergmann <sebastian@phpunit.de>
67264 *
67265 * For the full copyright and license information, please view the LICENSE
67266 * file that was distributed with this source code.
67267 */
67268 namespace PHPUnit\Framework;
67269
67270 use function assert;
67271 use function count;
67272 use RecursiveIterator;
67273 /**
67274 * @template-implements RecursiveIterator<int, Test>
67275 *
67276 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
67277 *
67278 * @internal This class is not covered by the backward compatibility promise for PHPUnit
67279 */
67280 final class TestSuiteIterator implements RecursiveIterator
67281 {
67282 private int $position = 0;
67283 /**
67284 * @psalm-var list<Test>
67285 */
67286 private readonly array $tests;
67287 public function __construct(\PHPUnit\Framework\TestSuite $testSuite)
67288 {
67289 $this->tests = $testSuite->tests();
67290 }
67291 public function rewind(): void
67292 {
67293 $this->position = 0;
67294 }
67295 public function valid(): bool
67296 {
67297 return $this->position < count($this->tests);
67298 }
67299 public function key(): int
67300 {
67301 return $this->position;
67302 }
67303 public function current(): \PHPUnit\Framework\Test
67304 {
67305 return $this->tests[$this->position];
67306 }
67307 public function next(): void
67308 {
67309 $this->position++;
67310 }
67311 /**
67312 * @throws NoChildTestSuiteException
67313 */
67314 public function getChildren(): self
67315 {
67316 if (!$this->hasChildren()) {
67317 throw new \PHPUnit\Framework\NoChildTestSuiteException('The current item is not a TestSuite instance and therefore does not have any children.');
67318 }
67319 $current = $this->current();
67320 assert($current instanceof \PHPUnit\Framework\TestSuite);
67321 return new self($current);
67322 }
67323 public function hasChildren(): bool
67324 {
67325 return $this->valid() && $this->current() instanceof \PHPUnit\Framework\TestSuite;
67326 }
67327 }
67328 <?php
67329
67330 declare (strict_types=1);
67331 /*
67332 * This file is part of PHPUnit.
67333 *
67334 * (c) Sebastian Bergmann <sebastian@phpunit.de>
67335 *
67336 * For the full copyright and license information, please view the LICENSE
67337 * file that was distributed with this source code.
67338 */
67339 namespace PHPUnit\Logging;
67340
67341 use const FILE_APPEND;
67342 use const LOCK_EX;
67343 use const PHP_EOL;
67344 use const PHP_OS_FAMILY;
67345 use function file_put_contents;
67346 use function implode;
67347 use function preg_split;
67348 use function str_repeat;
67349 use function strlen;
67350 use PHPUnit\Event\Event;
67351 use PHPUnit\Event\Tracer\Tracer;
67352 /**
67353 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
67354 *
67355 * @internal This class is not covered by the backward compatibility promise for PHPUnit
67356 */
67357 final class EventLogger implements Tracer
67358 {
67359 private readonly string $path;
67360 private readonly bool $includeTelemetryInfo;
67361 public function __construct(string $path, bool $includeTelemetryInfo)
67362 {
67363 $this->path = $path;
67364 $this->includeTelemetryInfo = $includeTelemetryInfo;
67365 }
67366 public function trace(Event $event): void
67367 {
67368 $telemetryInfo = $this->telemetryInfo($event);
67369 $indentation = PHP_EOL . str_repeat(' ', strlen($telemetryInfo));
67370 $lines = preg_split('/\r\n|\r|\n/', $event->asString());
67371 $flags = FILE_APPEND;
67372 if (!(PHP_OS_FAMILY === 'Windows' || PHP_OS_FAMILY === 'Darwin') || $this->path !== 'php://stdout') {
67373 $flags |= LOCK_EX;
67374 }
67375 file_put_contents($this->path, $telemetryInfo . implode($indentation, $lines) . PHP_EOL, $flags);
67376 }
67377 private function telemetryInfo(Event $event): string
67378 {
67379 if (!$this->includeTelemetryInfo) {
67380 return '';
67381 }
67382 return $event->telemetryInfo()->asString() . ' ';
67383 }
67384 }
67385 <?php
67386
67387 declare (strict_types=1);
67388 /*
67389 * This file is part of PHPUnit.
67390 *
67391 * (c) Sebastian Bergmann <sebastian@phpunit.de>
67392 *
67393 * For the full copyright and license information, please view the LICENSE
67394 * file that was distributed with this source code.
67395 */
67396 namespace PHPUnit\Logging\JUnit;
67397
67398 use const PHP_EOL;
67399 use function assert;
67400 use function basename;
67401 use function is_int;
67402 use function sprintf;
67403 use function str_replace;
67404 use function trim;
67405 use DOMDocument;
67406 use DOMElement;
67407 use PHPUnit\Event\Code\Test;
67408 use PHPUnit\Event\Code\TestMethod;
67409 use PHPUnit\Event\EventFacadeIsSealedException;
67410 use PHPUnit\Event\Facade;
67411 use PHPUnit\Event\InvalidArgumentException;
67412 use PHPUnit\Event\Telemetry\HRTime;
67413 use PHPUnit\Event\Telemetry\Info;
67414 use PHPUnit\Event\Test\Errored;
67415 use PHPUnit\Event\Test\Failed;
67416 use PHPUnit\Event\Test\Finished;
67417 use PHPUnit\Event\Test\MarkedIncomplete;
67418 use PHPUnit\Event\Test\PreparationStarted;
67419 use PHPUnit\Event\Test\Prepared;
67420 use PHPUnit\Event\Test\PrintedUnexpectedOutput;
67421 use PHPUnit\Event\Test\Skipped;
67422 use PHPUnit\Event\TestSuite\Started;
67423 use PHPUnit\Event\UnknownSubscriberTypeException;
67424 use PHPUnit\TextUI\Output\Printer;
67425 use PHPUnit\Util\Xml;
67426 /**
67427 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
67428 *
67429 * @internal This class is not covered by the backward compatibility promise for PHPUnit
67430 */
67431 final class JunitXmlLogger
67432 {
67433 private readonly Printer $printer;
67434 private DOMDocument $document;
67435 private DOMElement $root;
67436 /**
67437 * @var DOMElement[]
67438 */
67439 private array $testSuites = [];
67440 /**
67441 * @psalm-var array<int,int>
67442 */
67443 private array $testSuiteTests = [0];
67444 /**
67445 * @psalm-var array<int,int>
67446 */
67447 private array $testSuiteAssertions = [0];
67448 /**
67449 * @psalm-var array<int,int>
67450 */
67451 private array $testSuiteErrors = [0];
67452 /**
67453 * @psalm-var array<int,int>
67454 */
67455 private array $testSuiteFailures = [0];
67456 /**
67457 * @psalm-var array<int,int>
67458 */
67459 private array $testSuiteSkipped = [0];
67460 /**
67461 * @psalm-var array<int,int>
67462 */
67463 private array $testSuiteTimes = [0];
67464 private int $testSuiteLevel = 0;
67465 private ?DOMElement $currentTestCase = null;
67466 private ?HRTime $time = null;
67467 private bool $prepared = \false;
67468 private bool $preparationFailed = \false;
67469 private ?string $unexpectedOutput = null;
67470 /**
67471 * @throws EventFacadeIsSealedException
67472 * @throws UnknownSubscriberTypeException
67473 */
67474 public function __construct(Printer $printer, Facade $facade)
67475 {
67476 $this->printer = $printer;
67477 $this->registerSubscribers($facade);
67478 $this->createDocument();
67479 }
67480 public function flush(): void
67481 {
67482 $this->printer->print($this->document->saveXML());
67483 $this->printer->flush();
67484 }
67485 public function testSuiteStarted(Started $event): void
67486 {
67487 $testSuite = $this->document->createElement('testsuite');
67488 $testSuite->setAttribute('name', $event->testSuite()->name());
67489 if ($event->testSuite()->isForTestClass()) {
67490 $testSuite->setAttribute('file', $event->testSuite()->file());
67491 }
67492 if ($this->testSuiteLevel > 0) {
67493 $this->testSuites[$this->testSuiteLevel]->appendChild($testSuite);
67494 } else {
67495 $this->root->appendChild($testSuite);
67496 }
67497 $this->testSuiteLevel++;
67498 $this->testSuites[$this->testSuiteLevel] = $testSuite;
67499 $this->testSuiteTests[$this->testSuiteLevel] = 0;
67500 $this->testSuiteAssertions[$this->testSuiteLevel] = 0;
67501 $this->testSuiteErrors[$this->testSuiteLevel] = 0;
67502 $this->testSuiteFailures[$this->testSuiteLevel] = 0;
67503 $this->testSuiteSkipped[$this->testSuiteLevel] = 0;
67504 $this->testSuiteTimes[$this->testSuiteLevel] = 0;
67505 }
67506 public function testSuiteFinished(): void
67507 {
67508 $this->testSuites[$this->testSuiteLevel]->setAttribute('tests', (string) $this->testSuiteTests[$this->testSuiteLevel]);
67509 $this->testSuites[$this->testSuiteLevel]->setAttribute('assertions', (string) $this->testSuiteAssertions[$this->testSuiteLevel]);
67510 $this->testSuites[$this->testSuiteLevel]->setAttribute('errors', (string) $this->testSuiteErrors[$this->testSuiteLevel]);
67511 $this->testSuites[$this->testSuiteLevel]->setAttribute('failures', (string) $this->testSuiteFailures[$this->testSuiteLevel]);
67512 $this->testSuites[$this->testSuiteLevel]->setAttribute('skipped', (string) $this->testSuiteSkipped[$this->testSuiteLevel]);
67513 $this->testSuites[$this->testSuiteLevel]->setAttribute('time', sprintf('%F', $this->testSuiteTimes[$this->testSuiteLevel]));
67514 if ($this->testSuiteLevel > 1) {
67515 $this->testSuiteTests[$this->testSuiteLevel - 1] += $this->testSuiteTests[$this->testSuiteLevel];
67516 $this->testSuiteAssertions[$this->testSuiteLevel - 1] += $this->testSuiteAssertions[$this->testSuiteLevel];
67517 $this->testSuiteErrors[$this->testSuiteLevel - 1] += $this->testSuiteErrors[$this->testSuiteLevel];
67518 $this->testSuiteFailures[$this->testSuiteLevel - 1] += $this->testSuiteFailures[$this->testSuiteLevel];
67519 $this->testSuiteSkipped[$this->testSuiteLevel - 1] += $this->testSuiteSkipped[$this->testSuiteLevel];
67520 $this->testSuiteTimes[$this->testSuiteLevel - 1] += $this->testSuiteTimes[$this->testSuiteLevel];
67521 }
67522 $this->testSuiteLevel--;
67523 }
67524 /**
67525 * @throws InvalidArgumentException
67526 */
67527 public function testPreparationStarted(PreparationStarted $event): void
67528 {
67529 $this->createTestCase($event);
67530 }
67531 /**
67532 * @throws InvalidArgumentException
67533 */
67534 public function testPreparationFailed(): void
67535 {
67536 $this->preparationFailed = \true;
67537 }
67538 /**
67539 * @throws InvalidArgumentException
67540 */
67541 public function testPrepared(): void
67542 {
67543 $this->prepared = \true;
67544 }
67545 public function testPrintedUnexpectedOutput(PrintedUnexpectedOutput $event): void
67546 {
67547 $this->unexpectedOutput = $event->output();
67548 }
67549 /**
67550 * @throws InvalidArgumentException
67551 */
67552 public function testFinished(Finished $event): void
67553 {
67554 if (!$this->prepared || $this->preparationFailed) {
67555 return;
67556 }
67557 $this->handleFinish($event->telemetryInfo(), $event->numberOfAssertionsPerformed());
67558 }
67559 /**
67560 * @throws InvalidArgumentException
67561 */
67562 public function testMarkedIncomplete(MarkedIncomplete $event): void
67563 {
67564 $this->handleIncompleteOrSkipped($event);
67565 }
67566 /**
67567 * @throws InvalidArgumentException
67568 */
67569 public function testSkipped(Skipped $event): void
67570 {
67571 $this->handleIncompleteOrSkipped($event);
67572 }
67573 /**
67574 * @throws InvalidArgumentException
67575 */
67576 public function testErrored(Errored $event): void
67577 {
67578 $this->handleFault($event, 'error');
67579 $this->testSuiteErrors[$this->testSuiteLevel]++;
67580 }
67581 /**
67582 * @throws InvalidArgumentException
67583 */
67584 public function testFailed(Failed $event): void
67585 {
67586 $this->handleFault($event, 'failure');
67587 $this->testSuiteFailures[$this->testSuiteLevel]++;
67588 }
67589 /**
67590 * @throws InvalidArgumentException
67591 */
67592 private function handleFinish(Info $telemetryInfo, int $numberOfAssertionsPerformed): void
67593 {
67594 assert($this->currentTestCase !== null);
67595 assert($this->time !== null);
67596 $time = $telemetryInfo->time()->duration($this->time)->asFloat();
67597 $this->testSuiteAssertions[$this->testSuiteLevel] += $numberOfAssertionsPerformed;
67598 $this->currentTestCase->setAttribute('assertions', (string) $numberOfAssertionsPerformed);
67599 $this->currentTestCase->setAttribute('time', sprintf('%F', $time));
67600 if ($this->unexpectedOutput !== null) {
67601 $systemOut = $this->document->createElement('system-out', Xml::prepareString($this->unexpectedOutput));
67602 $this->currentTestCase->appendChild($systemOut);
67603 }
67604 $this->testSuites[$this->testSuiteLevel]->appendChild($this->currentTestCase);
67605 $this->testSuiteTests[$this->testSuiteLevel]++;
67606 $this->testSuiteTimes[$this->testSuiteLevel] += $time;
67607 $this->currentTestCase = null;
67608 $this->time = null;
67609 $this->prepared = \false;
67610 $this->unexpectedOutput = null;
67611 }
67612 /**
67613 * @throws EventFacadeIsSealedException
67614 * @throws UnknownSubscriberTypeException
67615 */
67616 private function registerSubscribers(Facade $facade): void
67617 {
67618 $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\TestPrintedUnexpectedOutputSubscriber($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));
67619 }
67620 private function createDocument(): void
67621 {
67622 $this->document = new DOMDocument('1.0', 'UTF-8');
67623 $this->document->formatOutput = \true;
67624 $this->root = $this->document->createElement('testsuites');
67625 $this->document->appendChild($this->root);
67626 }
67627 /**
67628 * @throws InvalidArgumentException
67629 */
67630 private function handleFault(Errored|Failed $event, string $type): void
67631 {
67632 if (!$this->prepared) {
67633 $this->createTestCase($event);
67634 }
67635 assert($this->currentTestCase !== null);
67636 $buffer = $this->testAsString($event->test());
67637 $throwable = $event->throwable();
67638 $buffer .= trim($throwable->description() . PHP_EOL . $throwable->stackTrace());
67639 $fault = $this->document->createElement($type, Xml::prepareString($buffer));
67640 $fault->setAttribute('type', $throwable->className());
67641 $this->currentTestCase->appendChild($fault);
67642 if (!$this->prepared) {
67643 $this->handleFinish($event->telemetryInfo(), 0);
67644 }
67645 }
67646 /**
67647 * @throws InvalidArgumentException
67648 */
67649 private function handleIncompleteOrSkipped(MarkedIncomplete|Skipped $event): void
67650 {
67651 if (!$this->prepared) {
67652 $this->createTestCase($event);
67653 }
67654 assert($this->currentTestCase !== null);
67655 $skipped = $this->document->createElement('skipped');
67656 $this->currentTestCase->appendChild($skipped);
67657 $this->testSuiteSkipped[$this->testSuiteLevel]++;
67658 if (!$this->prepared) {
67659 $this->handleFinish($event->telemetryInfo(), 0);
67660 }
67661 }
67662 /**
67663 * @throws InvalidArgumentException
67664 */
67665 private function testAsString(Test $test): string
67666 {
67667 if ($test->isPhpt()) {
67668 return basename($test->file());
67669 }
67670 assert($test instanceof TestMethod);
67671 return sprintf('%s::%s%s', $test->className(), $this->name($test), PHP_EOL);
67672 }
67673 /**
67674 * @throws InvalidArgumentException
67675 */
67676 private function name(Test $test): string
67677 {
67678 if ($test->isPhpt()) {
67679 return basename($test->file());
67680 }
67681 assert($test instanceof TestMethod);
67682 if (!$test->testData()->hasDataFromDataProvider()) {
67683 return $test->methodName();
67684 }
67685 $dataSetName = $test->testData()->dataFromDataProvider()->dataSetName();
67686 if (is_int($dataSetName)) {
67687 return sprintf('%s with data set #%d', $test->methodName(), $dataSetName);
67688 }
67689 return sprintf('%s with data set "%s"', $test->methodName(), $dataSetName);
67690 }
67691 /**
67692 * @throws InvalidArgumentException
67693 *
67694 * @psalm-assert !null $this->currentTestCase
67695 */
67696 private function createTestCase(Errored|Failed|MarkedIncomplete|PreparationStarted|Prepared|Skipped $event): void
67697 {
67698 $testCase = $this->document->createElement('testcase');
67699 $test = $event->test();
67700 $testCase->setAttribute('name', $this->name($test));
67701 $testCase->setAttribute('file', $test->file());
67702 if ($test->isTestMethod()) {
67703 assert($test instanceof TestMethod);
67704 $testCase->setAttribute('line', (string) $test->line());
67705 $testCase->setAttribute('class', $test->className());
67706 $testCase->setAttribute('classname', str_replace('\\', '.', $test->className()));
67707 }
67708 $this->currentTestCase = $testCase;
67709 $this->time = $event->telemetryInfo()->time();
67710 }
67711 }
67712 <?php
67713
67714 declare (strict_types=1);
67715 /*
67716 * This file is part of PHPUnit.
67717 *
67718 * (c) Sebastian Bergmann <sebastian@phpunit.de>
67719 *
67720 * For the full copyright and license information, please view the LICENSE
67721 * file that was distributed with this source code.
67722 */
67723 namespace PHPUnit\Logging\JUnit;
67724
67725 /**
67726 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
67727 *
67728 * @internal This class is not covered by the backward compatibility promise for PHPUnit
67729 */
67730 abstract class Subscriber
67731 {
67732 private readonly \PHPUnit\Logging\JUnit\JunitXmlLogger $logger;
67733 public function __construct(\PHPUnit\Logging\JUnit\JunitXmlLogger $logger)
67734 {
67735 $this->logger = $logger;
67736 }
67737 protected function logger(): \PHPUnit\Logging\JUnit\JunitXmlLogger
67738 {
67739 return $this->logger;
67740 }
67741 }
67742 <?php
67743
67744 declare (strict_types=1);
67745 /*
67746 * This file is part of PHPUnit.
67747 *
67748 * (c) Sebastian Bergmann <sebastian@phpunit.de>
67749 *
67750 * For the full copyright and license information, please view the LICENSE
67751 * file that was distributed with this source code.
67752 */
67753 namespace PHPUnit\Logging\JUnit;
67754
67755 use PHPUnit\Event\InvalidArgumentException;
67756 use PHPUnit\Event\Test\Errored;
67757 use PHPUnit\Event\Test\ErroredSubscriber;
67758 /**
67759 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
67760 *
67761 * @internal This class is not covered by the backward compatibility promise for PHPUnit
67762 */
67763 final class TestErroredSubscriber extends \PHPUnit\Logging\JUnit\Subscriber implements ErroredSubscriber
67764 {
67765 /**
67766 * @throws InvalidArgumentException
67767 */
67768 public function notify(Errored $event): void
67769 {
67770 $this->logger()->testErrored($event);
67771 }
67772 }
67773 <?php
67774
67775 declare (strict_types=1);
67776 /*
67777 * This file is part of PHPUnit.
67778 *
67779 * (c) Sebastian Bergmann <sebastian@phpunit.de>
67780 *
67781 * For the full copyright and license information, please view the LICENSE
67782 * file that was distributed with this source code.
67783 */
67784 namespace PHPUnit\Logging\JUnit;
67785
67786 use PHPUnit\Event\InvalidArgumentException;
67787 use PHPUnit\Event\Test\Failed;
67788 use PHPUnit\Event\Test\FailedSubscriber;
67789 /**
67790 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
67791 *
67792 * @internal This class is not covered by the backward compatibility promise for PHPUnit
67793 */
67794 final class TestFailedSubscriber extends \PHPUnit\Logging\JUnit\Subscriber implements FailedSubscriber
67795 {
67796 /**
67797 * @throws InvalidArgumentException
67798 */
67799 public function notify(Failed $event): void
67800 {
67801 $this->logger()->testFailed($event);
67802 }
67803 }
67804 <?php
67805
67806 declare (strict_types=1);
67807 /*
67808 * This file is part of PHPUnit.
67809 *
67810 * (c) Sebastian Bergmann <sebastian@phpunit.de>
67811 *
67812 * For the full copyright and license information, please view the LICENSE
67813 * file that was distributed with this source code.
67814 */
67815 namespace PHPUnit\Logging\JUnit;
67816
67817 use PHPUnit\Event\InvalidArgumentException;
67818 use PHPUnit\Event\Test\Finished;
67819 use PHPUnit\Event\Test\FinishedSubscriber;
67820 /**
67821 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
67822 *
67823 * @internal This class is not covered by the backward compatibility promise for PHPUnit
67824 */
67825 final class TestFinishedSubscriber extends \PHPUnit\Logging\JUnit\Subscriber implements FinishedSubscriber
67826 {
67827 /**
67828 * @throws InvalidArgumentException
67829 */
67830 public function notify(Finished $event): void
67831 {
67832 $this->logger()->testFinished($event);
67833 }
67834 }
67835 <?php
67836
67837 declare (strict_types=1);
67838 /*
67839 * This file is part of PHPUnit.
67840 *
67841 * (c) Sebastian Bergmann <sebastian@phpunit.de>
67842 *
67843 * For the full copyright and license information, please view the LICENSE
67844 * file that was distributed with this source code.
67845 */
67846 namespace PHPUnit\Logging\JUnit;
67847
67848 use PHPUnit\Event\InvalidArgumentException;
67849 use PHPUnit\Event\Test\MarkedIncomplete;
67850 use PHPUnit\Event\Test\MarkedIncompleteSubscriber;
67851 /**
67852 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
67853 *
67854 * @internal This class is not covered by the backward compatibility promise for PHPUnit
67855 */
67856 final class TestMarkedIncompleteSubscriber extends \PHPUnit\Logging\JUnit\Subscriber implements MarkedIncompleteSubscriber
67857 {
67858 /**
67859 * @throws InvalidArgumentException
67860 */
67861 public function notify(MarkedIncomplete $event): void
67862 {
67863 $this->logger()->testMarkedIncomplete($event);
67864 }
67865 }
67866 <?php
67867
67868 declare (strict_types=1);
67869 /*
67870 * This file is part of PHPUnit.
67871 *
67872 * (c) Sebastian Bergmann <sebastian@phpunit.de>
67873 *
67874 * For the full copyright and license information, please view the LICENSE
67875 * file that was distributed with this source code.
67876 */
67877 namespace PHPUnit\Logging\JUnit;
67878
67879 use PHPUnit\Event\InvalidArgumentException;
67880 use PHPUnit\Event\Test\PreparationFailed;
67881 use PHPUnit\Event\Test\PreparationFailedSubscriber;
67882 /**
67883 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
67884 *
67885 * @internal This class is not covered by the backward compatibility promise for PHPUnit
67886 */
67887 final class TestPreparationFailedSubscriber extends \PHPUnit\Logging\JUnit\Subscriber implements PreparationFailedSubscriber
67888 {
67889 /**
67890 * @throws InvalidArgumentException
67891 */
67892 public function notify(PreparationFailed $event): void
67893 {
67894 $this->logger()->testPreparationFailed();
67895 }
67896 }
67897 <?php
67898
67899 declare (strict_types=1);
67900 /*
67901 * This file is part of PHPUnit.
67902 *
67903 * (c) Sebastian Bergmann <sebastian@phpunit.de>
67904 *
67905 * For the full copyright and license information, please view the LICENSE
67906 * file that was distributed with this source code.
67907 */
67908 namespace PHPUnit\Logging\JUnit;
67909
67910 use PHPUnit\Event\InvalidArgumentException;
67911 use PHPUnit\Event\Test\PreparationStarted;
67912 use PHPUnit\Event\Test\PreparationStartedSubscriber;
67913 /**
67914 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
67915 *
67916 * @internal This class is not covered by the backward compatibility promise for PHPUnit
67917 */
67918 final class TestPreparationStartedSubscriber extends \PHPUnit\Logging\JUnit\Subscriber implements PreparationStartedSubscriber
67919 {
67920 /**
67921 * @throws InvalidArgumentException
67922 */
67923 public function notify(PreparationStarted $event): void
67924 {
67925 $this->logger()->testPreparationStarted($event);
67926 }
67927 }
67928 <?php
67929
67930 declare (strict_types=1);
67931 /*
67932 * This file is part of PHPUnit.
67933 *
67934 * (c) Sebastian Bergmann <sebastian@phpunit.de>
67935 *
67936 * For the full copyright and license information, please view the LICENSE
67937 * file that was distributed with this source code.
67938 */
67939 namespace PHPUnit\Logging\JUnit;
67940
67941 use PHPUnit\Event\InvalidArgumentException;
67942 use PHPUnit\Event\Test\Prepared;
67943 use PHPUnit\Event\Test\PreparedSubscriber;
67944 /**
67945 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
67946 *
67947 * @internal This class is not covered by the backward compatibility promise for PHPUnit
67948 */
67949 final class TestPreparedSubscriber extends \PHPUnit\Logging\JUnit\Subscriber implements PreparedSubscriber
67950 {
67951 /**
67952 * @throws InvalidArgumentException
67953 */
67954 public function notify(Prepared $event): void
67955 {
67956 $this->logger()->testPrepared();
67957 }
67958 }
67959 <?php
67960
67961 declare (strict_types=1);
67962 /*
67963 * This file is part of PHPUnit.
67964 *
67965 * (c) Sebastian Bergmann <sebastian@phpunit.de>
67966 *
67967 * For the full copyright and license information, please view the LICENSE
67968 * file that was distributed with this source code.
67969 */
67970 namespace PHPUnit\Logging\JUnit;
67971
67972 use PHPUnit\Event\Test\PrintedUnexpectedOutput;
67973 use PHPUnit\Event\Test\PrintedUnexpectedOutputSubscriber;
67974 /**
67975 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
67976 *
67977 * @internal This class is not covered by the backward compatibility promise for PHPUnit
67978 */
67979 final class TestPrintedUnexpectedOutputSubscriber extends \PHPUnit\Logging\JUnit\Subscriber implements PrintedUnexpectedOutputSubscriber
67980 {
67981 public function notify(PrintedUnexpectedOutput $event): void
67982 {
67983 $this->logger()->testPrintedUnexpectedOutput($event);
67984 }
67985 }
67986 <?php
67987
67988 declare (strict_types=1);
67989 /*
67990 * This file is part of PHPUnit.
67991 *
67992 * (c) Sebastian Bergmann <sebastian@phpunit.de>
67993 *
67994 * For the full copyright and license information, please view the LICENSE
67995 * file that was distributed with this source code.
67996 */
67997 namespace PHPUnit\Logging\JUnit;
67998
67999 use PHPUnit\Event\TestRunner\ExecutionFinished;
68000 use PHPUnit\Event\TestRunner\ExecutionFinishedSubscriber;
68001 /**
68002 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
68003 *
68004 * @internal This class is not covered by the backward compatibility promise for PHPUnit
68005 */
68006 final class TestRunnerExecutionFinishedSubscriber extends \PHPUnit\Logging\JUnit\Subscriber implements ExecutionFinishedSubscriber
68007 {
68008 public function notify(ExecutionFinished $event): void
68009 {
68010 $this->logger()->flush();
68011 }
68012 }
68013 <?php
68014
68015 declare (strict_types=1);
68016 /*
68017 * This file is part of PHPUnit.
68018 *
68019 * (c) Sebastian Bergmann <sebastian@phpunit.de>
68020 *
68021 * For the full copyright and license information, please view the LICENSE
68022 * file that was distributed with this source code.
68023 */
68024 namespace PHPUnit\Logging\JUnit;
68025
68026 use PHPUnit\Event\InvalidArgumentException;
68027 use PHPUnit\Event\Test\Skipped;
68028 use PHPUnit\Event\Test\SkippedSubscriber;
68029 /**
68030 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
68031 *
68032 * @internal This class is not covered by the backward compatibility promise for PHPUnit
68033 */
68034 final class TestSkippedSubscriber extends \PHPUnit\Logging\JUnit\Subscriber implements SkippedSubscriber
68035 {
68036 /**
68037 * @throws InvalidArgumentException
68038 */
68039 public function notify(Skipped $event): void
68040 {
68041 $this->logger()->testSkipped($event);
68042 }
68043 }
68044 <?php
68045
68046 declare (strict_types=1);
68047 /*
68048 * This file is part of PHPUnit.
68049 *
68050 * (c) Sebastian Bergmann <sebastian@phpunit.de>
68051 *
68052 * For the full copyright and license information, please view the LICENSE
68053 * file that was distributed with this source code.
68054 */
68055 namespace PHPUnit\Logging\JUnit;
68056
68057 use PHPUnit\Event\TestSuite\Finished;
68058 use PHPUnit\Event\TestSuite\FinishedSubscriber;
68059 /**
68060 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
68061 *
68062 * @internal This class is not covered by the backward compatibility promise for PHPUnit
68063 */
68064 final class TestSuiteFinishedSubscriber extends \PHPUnit\Logging\JUnit\Subscriber implements FinishedSubscriber
68065 {
68066 public function notify(Finished $event): void
68067 {
68068 $this->logger()->testSuiteFinished();
68069 }
68070 }
68071 <?php
68072
68073 declare (strict_types=1);
68074 /*
68075 * This file is part of PHPUnit.
68076 *
68077 * (c) Sebastian Bergmann <sebastian@phpunit.de>
68078 *
68079 * For the full copyright and license information, please view the LICENSE
68080 * file that was distributed with this source code.
68081 */
68082 namespace PHPUnit\Logging\JUnit;
68083
68084 use PHPUnit\Event\TestSuite\Started;
68085 use PHPUnit\Event\TestSuite\StartedSubscriber;
68086 /**
68087 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
68088 *
68089 * @internal This class is not covered by the backward compatibility promise for PHPUnit
68090 */
68091 final class TestSuiteStartedSubscriber extends \PHPUnit\Logging\JUnit\Subscriber implements StartedSubscriber
68092 {
68093 public function notify(Started $event): void
68094 {
68095 $this->logger()->testSuiteStarted($event);
68096 }
68097 }
68098 <?php
68099
68100 declare (strict_types=1);
68101 /*
68102 * This file is part of PHPUnit.
68103 *
68104 * (c) Sebastian Bergmann <sebastian@phpunit.de>
68105 *
68106 * For the full copyright and license information, please view the LICENSE
68107 * file that was distributed with this source code.
68108 */
68109 namespace PHPUnit\Logging\TeamCity;
68110
68111 /**
68112 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
68113 *
68114 * @internal This class is not covered by the backward compatibility promise for PHPUnit
68115 */
68116 abstract class Subscriber
68117 {
68118 private readonly \PHPUnit\Logging\TeamCity\TeamCityLogger $logger;
68119 public function __construct(\PHPUnit\Logging\TeamCity\TeamCityLogger $logger)
68120 {
68121 $this->logger = $logger;
68122 }
68123 protected function logger(): \PHPUnit\Logging\TeamCity\TeamCityLogger
68124 {
68125 return $this->logger;
68126 }
68127 }
68128 <?php
68129
68130 declare (strict_types=1);
68131 /*
68132 * This file is part of PHPUnit.
68133 *
68134 * (c) Sebastian Bergmann <sebastian@phpunit.de>
68135 *
68136 * For the full copyright and license information, please view the LICENSE
68137 * file that was distributed with this source code.
68138 */
68139 namespace PHPUnit\Logging\TeamCity;
68140
68141 use PHPUnit\Event\InvalidArgumentException;
68142 use PHPUnit\Event\Test\ConsideredRisky;
68143 use PHPUnit\Event\Test\ConsideredRiskySubscriber;
68144 /**
68145 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
68146 *
68147 * @internal This class is not covered by the backward compatibility promise for PHPUnit
68148 */
68149 final class TestConsideredRiskySubscriber extends \PHPUnit\Logging\TeamCity\Subscriber implements ConsideredRiskySubscriber
68150 {
68151 /**
68152 * @throws InvalidArgumentException
68153 */
68154 public function notify(ConsideredRisky $event): void
68155 {
68156 $this->logger()->testConsideredRisky($event);
68157 }
68158 }
68159 <?php
68160
68161 declare (strict_types=1);
68162 /*
68163 * This file is part of PHPUnit.
68164 *
68165 * (c) Sebastian Bergmann <sebastian@phpunit.de>
68166 *
68167 * For the full copyright and license information, please view the LICENSE
68168 * file that was distributed with this source code.
68169 */
68170 namespace PHPUnit\Logging\TeamCity;
68171
68172 use PHPUnit\Event\InvalidArgumentException;
68173 use PHPUnit\Event\Test\Errored;
68174 use PHPUnit\Event\Test\ErroredSubscriber;
68175 /**
68176 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
68177 *
68178 * @internal This class is not covered by the backward compatibility promise for PHPUnit
68179 */
68180 final class TestErroredSubscriber extends \PHPUnit\Logging\TeamCity\Subscriber implements ErroredSubscriber
68181 {
68182 /**
68183 * @throws InvalidArgumentException
68184 */
68185 public function notify(Errored $event): void
68186 {
68187 $this->logger()->testErrored($event);
68188 }
68189 }
68190 <?php
68191
68192 declare (strict_types=1);
68193 /*
68194 * This file is part of PHPUnit.
68195 *
68196 * (c) Sebastian Bergmann <sebastian@phpunit.de>
68197 *
68198 * For the full copyright and license information, please view the LICENSE
68199 * file that was distributed with this source code.
68200 */
68201 namespace PHPUnit\Logging\TeamCity;
68202
68203 use PHPUnit\Event\InvalidArgumentException;
68204 use PHPUnit\Event\Test\Failed;
68205 use PHPUnit\Event\Test\FailedSubscriber;
68206 /**
68207 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
68208 *
68209 * @internal This class is not covered by the backward compatibility promise for PHPUnit
68210 */
68211 final class TestFailedSubscriber extends \PHPUnit\Logging\TeamCity\Subscriber implements FailedSubscriber
68212 {
68213 /**
68214 * @throws InvalidArgumentException
68215 */
68216 public function notify(Failed $event): void
68217 {
68218 $this->logger()->testFailed($event);
68219 }
68220 }
68221 <?php
68222
68223 declare (strict_types=1);
68224 /*
68225 * This file is part of PHPUnit.
68226 *
68227 * (c) Sebastian Bergmann <sebastian@phpunit.de>
68228 *
68229 * For the full copyright and license information, please view the LICENSE
68230 * file that was distributed with this source code.
68231 */
68232 namespace PHPUnit\Logging\TeamCity;
68233
68234 use PHPUnit\Event\InvalidArgumentException;
68235 use PHPUnit\Event\Test\Finished;
68236 use PHPUnit\Event\Test\FinishedSubscriber;
68237 /**
68238 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
68239 *
68240 * @internal This class is not covered by the backward compatibility promise for PHPUnit
68241 */
68242 final class TestFinishedSubscriber extends \PHPUnit\Logging\TeamCity\Subscriber implements FinishedSubscriber
68243 {
68244 /**
68245 * @throws InvalidArgumentException
68246 */
68247 public function notify(Finished $event): void
68248 {
68249 $this->logger()->testFinished($event);
68250 }
68251 }
68252 <?php
68253
68254 declare (strict_types=1);
68255 /*
68256 * This file is part of PHPUnit.
68257 *
68258 * (c) Sebastian Bergmann <sebastian@phpunit.de>
68259 *
68260 * For the full copyright and license information, please view the LICENSE
68261 * file that was distributed with this source code.
68262 */
68263 namespace PHPUnit\Logging\TeamCity;
68264
68265 use PHPUnit\Event\InvalidArgumentException;
68266 use PHPUnit\Event\Test\MarkedIncomplete;
68267 use PHPUnit\Event\Test\MarkedIncompleteSubscriber;
68268 /**
68269 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
68270 *
68271 * @internal This class is not covered by the backward compatibility promise for PHPUnit
68272 */
68273 final class TestMarkedIncompleteSubscriber extends \PHPUnit\Logging\TeamCity\Subscriber implements MarkedIncompleteSubscriber
68274 {
68275 /**
68276 * @throws InvalidArgumentException
68277 */
68278 public function notify(MarkedIncomplete $event): void
68279 {
68280 $this->logger()->testMarkedIncomplete($event);
68281 }
68282 }
68283 <?php
68284
68285 declare (strict_types=1);
68286 /*
68287 * This file is part of PHPUnit.
68288 *
68289 * (c) Sebastian Bergmann <sebastian@phpunit.de>
68290 *
68291 * For the full copyright and license information, please view the LICENSE
68292 * file that was distributed with this source code.
68293 */
68294 namespace PHPUnit\Logging\TeamCity;
68295
68296 use PHPUnit\Event\Test\Prepared;
68297 use PHPUnit\Event\Test\PreparedSubscriber;
68298 /**
68299 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
68300 *
68301 * @internal This class is not covered by the backward compatibility promise for PHPUnit
68302 */
68303 final class TestPreparedSubscriber extends \PHPUnit\Logging\TeamCity\Subscriber implements PreparedSubscriber
68304 {
68305 public function notify(Prepared $event): void
68306 {
68307 $this->logger()->testPrepared($event);
68308 }
68309 }
68310 <?php
68311
68312 declare (strict_types=1);
68313 /*
68314 * This file is part of PHPUnit.
68315 *
68316 * (c) Sebastian Bergmann <sebastian@phpunit.de>
68317 *
68318 * For the full copyright and license information, please view the LICENSE
68319 * file that was distributed with this source code.
68320 */
68321 namespace PHPUnit\Logging\TeamCity;
68322
68323 use PHPUnit\Event\TestRunner\ExecutionFinished;
68324 use PHPUnit\Event\TestRunner\ExecutionFinishedSubscriber;
68325 /**
68326 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
68327 *
68328 * @internal This class is not covered by the backward compatibility promise for PHPUnit
68329 */
68330 final class TestRunnerExecutionFinishedSubscriber extends \PHPUnit\Logging\TeamCity\Subscriber implements ExecutionFinishedSubscriber
68331 {
68332 public function notify(ExecutionFinished $event): void
68333 {
68334 $this->logger()->flush();
68335 }
68336 }
68337 <?php
68338
68339 declare (strict_types=1);
68340 /*
68341 * This file is part of PHPUnit.
68342 *
68343 * (c) Sebastian Bergmann <sebastian@phpunit.de>
68344 *
68345 * For the full copyright and license information, please view the LICENSE
68346 * file that was distributed with this source code.
68347 */
68348 namespace PHPUnit\Logging\TeamCity;
68349
68350 use PHPUnit\Event\InvalidArgumentException;
68351 use PHPUnit\Event\Test\Skipped;
68352 use PHPUnit\Event\Test\SkippedSubscriber;
68353 /**
68354 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
68355 *
68356 * @internal This class is not covered by the backward compatibility promise for PHPUnit
68357 */
68358 final class TestSkippedSubscriber extends \PHPUnit\Logging\TeamCity\Subscriber implements SkippedSubscriber
68359 {
68360 /**
68361 * @throws InvalidArgumentException
68362 */
68363 public function notify(Skipped $event): void
68364 {
68365 $this->logger()->testSkipped($event);
68366 }
68367 }
68368 <?php
68369
68370 declare (strict_types=1);
68371 /*
68372 * This file is part of PHPUnit.
68373 *
68374 * (c) Sebastian Bergmann <sebastian@phpunit.de>
68375 *
68376 * For the full copyright and license information, please view the LICENSE
68377 * file that was distributed with this source code.
68378 */
68379 namespace PHPUnit\Logging\TeamCity;
68380
68381 use PHPUnit\Event\InvalidArgumentException;
68382 use PHPUnit\Event\Test\BeforeFirstTestMethodErrored;
68383 use PHPUnit\Event\Test\BeforeFirstTestMethodErroredSubscriber;
68384 /**
68385 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
68386 *
68387 * @internal This class is not covered by the backward compatibility promise for PHPUnit
68388 */
68389 final class TestSuiteBeforeFirstTestMethodErroredSubscriber extends \PHPUnit\Logging\TeamCity\Subscriber implements BeforeFirstTestMethodErroredSubscriber
68390 {
68391 /**
68392 * @throws InvalidArgumentException
68393 */
68394 public function notify(BeforeFirstTestMethodErrored $event): void
68395 {
68396 $this->logger()->beforeFirstTestMethodErrored($event);
68397 }
68398 }
68399 <?php
68400
68401 declare (strict_types=1);
68402 /*
68403 * This file is part of PHPUnit.
68404 *
68405 * (c) Sebastian Bergmann <sebastian@phpunit.de>
68406 *
68407 * For the full copyright and license information, please view the LICENSE
68408 * file that was distributed with this source code.
68409 */
68410 namespace PHPUnit\Logging\TeamCity;
68411
68412 use PHPUnit\Event\TestSuite\Finished;
68413 use PHPUnit\Event\TestSuite\FinishedSubscriber;
68414 /**
68415 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
68416 *
68417 * @internal This class is not covered by the backward compatibility promise for PHPUnit
68418 */
68419 final class TestSuiteFinishedSubscriber extends \PHPUnit\Logging\TeamCity\Subscriber implements FinishedSubscriber
68420 {
68421 public function notify(Finished $event): void
68422 {
68423 $this->logger()->testSuiteFinished($event);
68424 }
68425 }
68426 <?php
68427
68428 declare (strict_types=1);
68429 /*
68430 * This file is part of PHPUnit.
68431 *
68432 * (c) Sebastian Bergmann <sebastian@phpunit.de>
68433 *
68434 * For the full copyright and license information, please view the LICENSE
68435 * file that was distributed with this source code.
68436 */
68437 namespace PHPUnit\Logging\TeamCity;
68438
68439 use PHPUnit\Event\InvalidArgumentException;
68440 use PHPUnit\Event\TestSuite\Skipped;
68441 use PHPUnit\Event\TestSuite\SkippedSubscriber;
68442 /**
68443 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
68444 *
68445 * @internal This class is not covered by the backward compatibility promise for PHPUnit
68446 */
68447 final class TestSuiteSkippedSubscriber extends \PHPUnit\Logging\TeamCity\Subscriber implements SkippedSubscriber
68448 {
68449 /**
68450 * @throws InvalidArgumentException
68451 */
68452 public function notify(Skipped $event): void
68453 {
68454 $this->logger()->testSuiteSkipped($event);
68455 }
68456 }
68457 <?php
68458
68459 declare (strict_types=1);
68460 /*
68461 * This file is part of PHPUnit.
68462 *
68463 * (c) Sebastian Bergmann <sebastian@phpunit.de>
68464 *
68465 * For the full copyright and license information, please view the LICENSE
68466 * file that was distributed with this source code.
68467 */
68468 namespace PHPUnit\Logging\TeamCity;
68469
68470 use PHPUnit\Event\TestSuite\Started;
68471 use PHPUnit\Event\TestSuite\StartedSubscriber;
68472 /**
68473 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
68474 *
68475 * @internal This class is not covered by the backward compatibility promise for PHPUnit
68476 */
68477 final class TestSuiteStartedSubscriber extends \PHPUnit\Logging\TeamCity\Subscriber implements StartedSubscriber
68478 {
68479 public function notify(Started $event): void
68480 {
68481 $this->logger()->testSuiteStarted($event);
68482 }
68483 }
68484 <?php
68485
68486 declare (strict_types=1);
68487 /*
68488 * This file is part of PHPUnit.
68489 *
68490 * (c) Sebastian Bergmann <sebastian@phpunit.de>
68491 *
68492 * For the full copyright and license information, please view the LICENSE
68493 * file that was distributed with this source code.
68494 */
68495 namespace PHPUnit\Logging\TeamCity;
68496
68497 use function assert;
68498 use function getmypid;
68499 use function ini_get;
68500 use function is_a;
68501 use function round;
68502 use function sprintf;
68503 use function str_replace;
68504 use function stripos;
68505 use PHPUnit\Event\Code\TestMethod;
68506 use PHPUnit\Event\Code\Throwable;
68507 use PHPUnit\Event\Event;
68508 use PHPUnit\Event\EventFacadeIsSealedException;
68509 use PHPUnit\Event\Facade;
68510 use PHPUnit\Event\InvalidArgumentException;
68511 use PHPUnit\Event\Telemetry\HRTime;
68512 use PHPUnit\Event\Test\BeforeFirstTestMethodErrored;
68513 use PHPUnit\Event\Test\ConsideredRisky;
68514 use PHPUnit\Event\Test\Errored;
68515 use PHPUnit\Event\Test\Failed;
68516 use PHPUnit\Event\Test\Finished;
68517 use PHPUnit\Event\Test\MarkedIncomplete;
68518 use PHPUnit\Event\Test\Prepared;
68519 use PHPUnit\Event\Test\Skipped;
68520 use PHPUnit\Event\TestSuite\Finished as TestSuiteFinished;
68521 use PHPUnit\Event\TestSuite\Skipped as TestSuiteSkipped;
68522 use PHPUnit\Event\TestSuite\Started as TestSuiteStarted;
68523 use PHPUnit\Event\TestSuite\TestSuiteForTestClass;
68524 use PHPUnit\Event\TestSuite\TestSuiteForTestMethodWithDataProvider;
68525 use PHPUnit\Event\UnknownSubscriberTypeException;
68526 use PHPUnit\Framework\Exception as FrameworkException;
68527 use PHPUnit\TextUI\Output\Printer;
68528 /**
68529 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
68530 *
68531 * @internal This class is not covered by the backward compatibility promise for PHPUnit
68532 */
68533 final class TeamCityLogger
68534 {
68535 private readonly Printer $printer;
68536 private bool $isSummaryTestCountPrinted = \false;
68537 private ?HRTime $time = null;
68538 private ?int $flowId;
68539 /**
68540 * @throws EventFacadeIsSealedException
68541 * @throws UnknownSubscriberTypeException
68542 */
68543 public function __construct(Printer $printer, Facade $facade)
68544 {
68545 $this->printer = $printer;
68546 $this->registerSubscribers($facade);
68547 $this->setFlowId();
68548 }
68549 public function testSuiteStarted(TestSuiteStarted $event): void
68550 {
68551 $testSuite = $event->testSuite();
68552 if (!$this->isSummaryTestCountPrinted) {
68553 $this->isSummaryTestCountPrinted = \true;
68554 $this->writeMessage('testCount', ['count' => $testSuite->count()]);
68555 }
68556 $parameters = ['name' => $testSuite->name()];
68557 if ($testSuite->isForTestClass()) {
68558 assert($testSuite instanceof TestSuiteForTestClass);
68559 $parameters['locationHint'] = sprintf('php_qn://%s::\%s', $testSuite->file(), $testSuite->name());
68560 } elseif ($testSuite->isForTestMethodWithDataProvider()) {
68561 assert($testSuite instanceof TestSuiteForTestMethodWithDataProvider);
68562 $parameters['locationHint'] = sprintf('php_qn://%s::\%s', $testSuite->file(), $testSuite->name());
68563 $parameters['name'] = $testSuite->methodName();
68564 }
68565 $this->writeMessage('testSuiteStarted', $parameters);
68566 }
68567 public function testSuiteFinished(TestSuiteFinished $event): void
68568 {
68569 $testSuite = $event->testSuite();
68570 $parameters = ['name' => $testSuite->name()];
68571 if ($testSuite->isForTestMethodWithDataProvider()) {
68572 assert($testSuite instanceof TestSuiteForTestMethodWithDataProvider);
68573 $parameters['name'] = $testSuite->methodName();
68574 }
68575 $this->writeMessage('testSuiteFinished', $parameters);
68576 }
68577 public function testPrepared(Prepared $event): void
68578 {
68579 $test = $event->test();
68580 $parameters = ['name' => $test->name()];
68581 if ($test->isTestMethod()) {
68582 assert($test instanceof TestMethod);
68583 $parameters['locationHint'] = sprintf('php_qn://%s::\%s::%s', $test->file(), $test->className(), $test->name());
68584 }
68585 $this->writeMessage('testStarted', $parameters);
68586 $this->time = $event->telemetryInfo()->time();
68587 }
68588 /**
68589 * @throws InvalidArgumentException
68590 */
68591 public function testMarkedIncomplete(MarkedIncomplete $event): void
68592 {
68593 if ($this->time === null) {
68594 // @codeCoverageIgnoreStart
68595 $this->time = $event->telemetryInfo()->time();
68596 // @codeCoverageIgnoreEnd
68597 }
68598 $this->writeMessage('testIgnored', ['name' => $event->test()->name(), 'message' => $event->throwable()->message(), 'details' => $this->details($event->throwable()), 'duration' => $this->duration($event)]);
68599 }
68600 /**
68601 * @throws InvalidArgumentException
68602 */
68603 public function testSkipped(Skipped $event): void
68604 {
68605 if ($this->time === null) {
68606 $this->time = $event->telemetryInfo()->time();
68607 }
68608 $parameters = ['name' => $event->test()->name(), 'message' => $event->message()];
68609 $parameters['duration'] = $this->duration($event);
68610 $this->writeMessage('testIgnored', $parameters);
68611 }
68612 /**
68613 * @throws InvalidArgumentException
68614 */
68615 public function testSuiteSkipped(TestSuiteSkipped $event): void
68616 {
68617 if ($this->time === null) {
68618 $this->time = $event->telemetryInfo()->time();
68619 }
68620 $parameters = ['name' => $event->testSuite()->name(), 'message' => $event->message()];
68621 $parameters['duration'] = $this->duration($event);
68622 $this->writeMessage('testIgnored', $parameters);
68623 $this->writeMessage('testSuiteFinished', $parameters);
68624 }
68625 /**
68626 * @throws InvalidArgumentException
68627 */
68628 public function beforeFirstTestMethodErrored(BeforeFirstTestMethodErrored $event): void
68629 {
68630 if ($this->time === null) {
68631 $this->time = $event->telemetryInfo()->time();
68632 }
68633 $parameters = ['name' => $event->testClassName(), 'message' => $this->message($event->throwable()), 'details' => $this->details($event->throwable()), 'duration' => $this->duration($event)];
68634 $this->writeMessage('testFailed', $parameters);
68635 $this->writeMessage('testSuiteFinished', $parameters);
68636 }
68637 /**
68638 * @throws InvalidArgumentException
68639 */
68640 public function testErrored(Errored $event): void
68641 {
68642 if ($this->time === null) {
68643 $this->time = $event->telemetryInfo()->time();
68644 }
68645 $this->writeMessage('testFailed', ['name' => $event->test()->name(), 'message' => $this->message($event->throwable()), 'details' => $this->details($event->throwable()), 'duration' => $this->duration($event)]);
68646 }
68647 /**
68648 * @throws InvalidArgumentException
68649 */
68650 public function testFailed(Failed $event): void
68651 {
68652 if ($this->time === null) {
68653 // @codeCoverageIgnoreStart
68654 $this->time = $event->telemetryInfo()->time();
68655 // @codeCoverageIgnoreEnd
68656 }
68657 $parameters = ['name' => $event->test()->name(), 'message' => $this->message($event->throwable()), 'details' => $this->details($event->throwable()), 'duration' => $this->duration($event)];
68658 if ($event->hasComparisonFailure()) {
68659 $parameters['type'] = 'comparisonFailure';
68660 $parameters['actual'] = $event->comparisonFailure()->actual();
68661 $parameters['expected'] = $event->comparisonFailure()->expected();
68662 }
68663 $this->writeMessage('testFailed', $parameters);
68664 }
68665 /**
68666 * @throws InvalidArgumentException
68667 */
68668 public function testConsideredRisky(ConsideredRisky $event): void
68669 {
68670 if ($this->time === null) {
68671 // @codeCoverageIgnoreStart
68672 $this->time = $event->telemetryInfo()->time();
68673 // @codeCoverageIgnoreEnd
68674 }
68675 $this->writeMessage('testFailed', ['name' => $event->test()->name(), 'message' => $event->message(), 'details' => '', 'duration' => $this->duration($event)]);
68676 }
68677 /**
68678 * @throws InvalidArgumentException
68679 */
68680 public function testFinished(Finished $event): void
68681 {
68682 $this->writeMessage('testFinished', ['name' => $event->test()->name(), 'duration' => $this->duration($event)]);
68683 $this->time = null;
68684 }
68685 public function flush(): void
68686 {
68687 $this->printer->flush();
68688 }
68689 /**
68690 * @throws EventFacadeIsSealedException
68691 * @throws UnknownSubscriberTypeException
68692 */
68693 private function registerSubscribers(Facade $facade): void
68694 {
68695 $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\TestSuiteSkippedSubscriber($this), new \PHPUnit\Logging\TeamCity\TestConsideredRiskySubscriber($this), new \PHPUnit\Logging\TeamCity\TestRunnerExecutionFinishedSubscriber($this), new \PHPUnit\Logging\TeamCity\TestSuiteBeforeFirstTestMethodErroredSubscriber($this));
68696 }
68697 private function setFlowId(): void
68698 {
68699 if (stripos(ini_get('disable_functions'), 'getmypid') === \false) {
68700 $this->flowId = getmypid();
68701 }
68702 }
68703 private function writeMessage(string $eventName, array $parameters = []): void
68704 {
68705 $this->printer->print(sprintf('##teamcity[%s', $eventName));
68706 if ($this->flowId !== null) {
68707 $parameters['flowId'] = $this->flowId;
68708 }
68709 foreach ($parameters as $key => $value) {
68710 $this->printer->print(sprintf(" %s='%s'", $key, $this->escape((string) $value)));
68711 }
68712 $this->printer->print("]\n");
68713 }
68714 /**
68715 * @throws InvalidArgumentException
68716 */
68717 private function duration(Event $event): int
68718 {
68719 if ($this->time === null) {
68720 // @codeCoverageIgnoreStart
68721 return 0;
68722 // @codeCoverageIgnoreEnd
68723 }
68724 return (int) round($event->telemetryInfo()->time()->duration($this->time)->asFloat() * 1000);
68725 }
68726 private function escape(string $string): string
68727 {
68728 return str_replace(['|', "'", "\n", "\r", ']', '['], ['||', "|'", '|n', '|r', '|]', '|['], $string);
68729 }
68730 private function message(Throwable $throwable): string
68731 {
68732 if (is_a($throwable->className(), FrameworkException::class, \true)) {
68733 return $throwable->message();
68734 }
68735 $buffer = $throwable->className();
68736 if (!empty($throwable->message())) {
68737 $buffer .= ': ' . $throwable->message();
68738 }
68739 return $buffer;
68740 }
68741 private function details(Throwable $throwable): string
68742 {
68743 $buffer = $throwable->stackTrace();
68744 while ($throwable->hasPrevious()) {
68745 $throwable = $throwable->previous();
68746 $buffer .= sprintf("\nCaused by\n%s\n%s", $throwable->description(), $throwable->stackTrace());
68747 }
68748 return $buffer;
68749 }
68750 }
68751 <?php
68752
68753 declare (strict_types=1);
68754 /*
68755 * This file is part of PHPUnit.
68756 *
68757 * (c) Sebastian Bergmann <sebastian@phpunit.de>
68758 *
68759 * For the full copyright and license information, please view the LICENSE
68760 * file that was distributed with this source code.
68761 */
68762 namespace PHPUnit\Logging\TestDox;
68763
68764 use function sprintf;
68765 /**
68766 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
68767 *
68768 * @internal This class is not covered by the backward compatibility promise for PHPUnit
68769 */
68770 final class HtmlRenderer
68771 {
68772 /**
68773 * @var string
68774 */
68775 private const PAGE_HEADER = <<<'EOT'
68776 <!doctype html>
68777 <html lang="en">
68778 <head>
68779 <meta charset="utf-8"/>
68780 <title>Test Documentation</title>
68781 <style>
68782 body {
68783 text-rendering: optimizeLegibility;
68784 font-family: Source SansSerif Pro, Arial, sans-serif;
68785 font-variant-ligatures: common-ligatures;
68786 font-kerning: normal;
68787 margin-left: 2rem;
68788 background-color: #fff;
68789 color: #000;
68790 }
68791
68792 body > ul > li {
68793 font-size: larger;
68794 }
68795
68796 h2 {
68797 font-size: larger;
68798 text-decoration-line: underline;
68799 text-decoration-thickness: 2px;
68800 margin: 0;
68801 padding: 0.5rem 0;
68802 }
68803
68804 ul {
68805 list-style: none;
68806 margin: 0 0 2rem;
68807 padding: 0 0 0 1rem;
68808 text-indent: -1rem;
68809 }
68810
68811 .success:before {
68812 color: #4e9a06;
68813 content: '✓';
68814 padding-right: 0.5rem;
68815 }
68816
68817 .defect {
68818 color: #a40000;
68819 }
68820
68821 .defect:before {
68822 color: #a40000;
68823 content: '✗';
68824 padding-right: 0.5rem;
68825 }
68826 </style>
68827 </head>
68828 <body>
68829 EOT;
68830 /**
68831 * @var string
68832 */
68833 private const CLASS_HEADER = <<<'EOT'
68834
68835 <h2>%s</h2>
68836 <ul>
68837
68838 EOT;
68839 /**
68840 * @var string
68841 */
68842 private const CLASS_FOOTER = <<<'EOT'
68843 </ul>
68844 EOT;
68845 /**
68846 * @var string
68847 */
68848 private const PAGE_FOOTER = <<<'EOT'
68849
68850 </body>
68851 </html>
68852 EOT;
68853 /**
68854 * @psalm-param array<string, TestResultCollection> $tests
68855 */
68856 public function render(array $tests): string
68857 {
68858 $buffer = self::PAGE_HEADER;
68859 foreach ($tests as $prettifiedClassName => $_tests) {
68860 $buffer .= sprintf(self::CLASS_HEADER, $prettifiedClassName);
68861 foreach ($this->reduce($_tests) as $prettifiedMethodName => $outcome) {
68862 $buffer .= sprintf(" <li class=\"%s\">%s</li>\n", $outcome, $prettifiedMethodName);
68863 }
68864 $buffer .= self::CLASS_FOOTER;
68865 }
68866 return $buffer . self::PAGE_FOOTER;
68867 }
68868 /**
68869 * @psalm-return array<string, 'success'|'defect'>
68870 */
68871 private function reduce(\PHPUnit\Logging\TestDox\TestResultCollection $tests): array
68872 {
68873 $result = [];
68874 foreach ($tests as $test) {
68875 $prettifiedMethodName = $test->test()->testDox()->prettifiedMethodName();
68876 if (!isset($result[$prettifiedMethodName])) {
68877 $result[$prettifiedMethodName] = $test->status()->isSuccess() ? 'success' : 'defect';
68878 continue;
68879 }
68880 if ($test->status()->isSuccess()) {
68881 continue;
68882 }
68883 $result[$prettifiedMethodName] = 'defect';
68884 }
68885 return $result;
68886 }
68887 }
68888 <?php
68889
68890 declare (strict_types=1);
68891 /*
68892 * This file is part of PHPUnit.
68893 *
68894 * (c) Sebastian Bergmann <sebastian@phpunit.de>
68895 *
68896 * For the full copyright and license information, please view the LICENSE
68897 * file that was distributed with this source code.
68898 */
68899 namespace PHPUnit\Logging\TestDox;
68900
68901 use function array_key_exists;
68902 use function array_keys;
68903 use function array_map;
68904 use function array_pop;
68905 use function array_values;
68906 use function assert;
68907 use function class_exists;
68908 use function explode;
68909 use function gettype;
68910 use function implode;
68911 use function is_bool;
68912 use function is_float;
68913 use function is_int;
68914 use function is_object;
68915 use function is_scalar;
68916 use function method_exists;
68917 use function preg_quote;
68918 use function preg_replace;
68919 use function rtrim;
68920 use function sprintf;
68921 use function str_contains;
68922 use function str_ends_with;
68923 use function str_replace;
68924 use function str_starts_with;
68925 use function strlen;
68926 use function strtolower;
68927 use function strtoupper;
68928 use function substr;
68929 use function trim;
68930 use PHPUnit\Framework\TestCase;
68931 use PHPUnit\Metadata\Parser\Registry as MetadataRegistry;
68932 use PHPUnit\Metadata\TestDox;
68933 use PHPUnit\Util\Color;
68934 use ReflectionEnum;
68935 use ReflectionMethod;
68936 use ReflectionObject;
68937 use PHPUnitPHAR\SebastianBergmann\Exporter\Exporter;
68938 /**
68939 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
68940 *
68941 * @internal This class is not covered by the backward compatibility promise for PHPUnit
68942 */
68943 final class NamePrettifier
68944 {
68945 /**
68946 * @psalm-var array<string, int>
68947 */
68948 private static array $strings = [];
68949 /**
68950 * @psalm-param class-string $className
68951 */
68952 public function prettifyTestClassName(string $className): string
68953 {
68954 if (class_exists($className)) {
68955 $classLevelTestDox = MetadataRegistry::parser()->forClass($className)->isTestDox();
68956 if ($classLevelTestDox->isNotEmpty()) {
68957 $classLevelTestDox = $classLevelTestDox->asArray()[0];
68958 assert($classLevelTestDox instanceof TestDox);
68959 return $classLevelTestDox->text();
68960 }
68961 }
68962 $parts = explode('\\', $className);
68963 $className = array_pop($parts);
68964 if (str_ends_with($className, 'Test')) {
68965 $className = substr($className, 0, strlen($className) - strlen('Test'));
68966 }
68967 if (str_starts_with($className, 'Tests')) {
68968 $className = substr($className, strlen('Tests'));
68969 } elseif (str_starts_with($className, 'Test')) {
68970 $className = substr($className, strlen('Test'));
68971 }
68972 if (empty($className)) {
68973 $className = 'UnnamedTests';
68974 }
68975 if (!empty($parts)) {
68976 $parts[] = $className;
68977 $fullyQualifiedName = implode('\\', $parts);
68978 } else {
68979 $fullyQualifiedName = $className;
68980 }
68981 $result = preg_replace('/(?<=[[:lower:]])(?=[[:upper:]])/u', ' ', $className);
68982 if ($fullyQualifiedName !== $className) {
68983 return $result . ' (' . $fullyQualifiedName . ')';
68984 }
68985 return $result;
68986 }
68987 // NOTE: this method is on a hot path and very performance sensitive. change with care.
68988 public function prettifyTestMethodName(string $name): string
68989 {
68990 if ($name === '') {
68991 return '';
68992 }
68993 $string = rtrim($name, '0123456789');
68994 if (array_key_exists($string, self::$strings)) {
68995 $name = $string;
68996 } elseif ($string === $name) {
68997 self::$strings[$string] = 1;
68998 }
68999 if (str_starts_with($name, 'test_')) {
69000 $name = substr($name, 5);
69001 } elseif (str_starts_with($name, 'test')) {
69002 $name = substr($name, 4);
69003 }
69004 if ($name === '') {
69005 return '';
69006 }
69007 $name[0] = strtoupper($name[0]);
69008 $noUnderscore = str_replace('_', ' ', $name);
69009 if ($noUnderscore !== $name) {
69010 return trim($noUnderscore);
69011 }
69012 $wasNumeric = \false;
69013 $buffer = '';
69014 $len = strlen($name);
69015 for ($i = 0; $i < $len; $i++) {
69016 if ($i > 0 && $name[$i] >= 'A' && $name[$i] <= 'Z') {
69017 $buffer .= ' ' . strtolower($name[$i]);
69018 } else {
69019 $isNumeric = $name[$i] >= '0' && $name[$i] <= '9';
69020 if (!$wasNumeric && $isNumeric) {
69021 $buffer .= ' ';
69022 $wasNumeric = \true;
69023 }
69024 if ($wasNumeric && !$isNumeric) {
69025 $wasNumeric = \false;
69026 }
69027 $buffer .= $name[$i];
69028 }
69029 }
69030 return $buffer;
69031 }
69032 public function prettifyTestCase(TestCase $test, bool $colorize): string
69033 {
69034 $annotationWithPlaceholders = \false;
69035 $methodLevelTestDox = MetadataRegistry::parser()->forMethod($test::class, $test->name())->isTestDox()->isMethodLevel();
69036 if ($methodLevelTestDox->isNotEmpty()) {
69037 $methodLevelTestDox = $methodLevelTestDox->asArray()[0];
69038 assert($methodLevelTestDox instanceof TestDox);
69039 $result = $methodLevelTestDox->text();
69040 if (str_contains($result, '$')) {
69041 $annotation = $result;
69042 $providedData = $this->mapTestMethodParameterNamesToProvidedDataValues($test, $colorize);
69043 $variables = array_map(static fn(string $variable): string => sprintf('/%s(?=\b)/', preg_quote($variable, '/')), array_keys($providedData));
69044 $result = preg_replace($variables, $providedData, $annotation);
69045 $annotationWithPlaceholders = \true;
69046 }
69047 } else {
69048 $result = $this->prettifyTestMethodName($test->name());
69049 }
69050 if (!$annotationWithPlaceholders && $test->usesDataProvider()) {
69051 $result .= $this->prettifyDataSet($test, $colorize);
69052 }
69053 return $result;
69054 }
69055 public function prettifyDataSet(TestCase $test, bool $colorize): string
69056 {
69057 if (!$colorize) {
69058 return $test->dataSetAsString();
69059 }
69060 if (is_int($test->dataName())) {
69061 return Color::dim(' with data set ') . Color::colorize('fg-cyan', (string) $test->dataName());
69062 }
69063 return Color::dim(' with ') . Color::colorize('fg-cyan', Color::visualizeWhitespace($test->dataName()));
69064 }
69065 private function mapTestMethodParameterNamesToProvidedDataValues(TestCase $test, bool $colorize): array
69066 {
69067 assert(method_exists($test, $test->name()));
69068 /** @noinspection PhpUnhandledExceptionInspection */
69069 $reflector = new ReflectionMethod($test::class, $test->name());
69070 $providedData = [];
69071 $providedDataValues = array_values($test->providedData());
69072 $i = 0;
69073 $providedData['$_dataName'] = $test->dataName();
69074 foreach ($reflector->getParameters() as $parameter) {
69075 if (!array_key_exists($i, $providedDataValues) && $parameter->isDefaultValueAvailable()) {
69076 $providedDataValues[$i] = $parameter->getDefaultValue();
69077 }
69078 $value = $providedDataValues[$i++] ?? null;
69079 if (is_object($value)) {
69080 $value = $this->objectToString($value);
69081 }
69082 if (!is_scalar($value)) {
69083 $value = gettype($value);
69084 if ($value === 'NULL') {
69085 $value = 'null';
69086 }
69087 }
69088 if (is_bool($value) || is_int($value) || is_float($value)) {
69089 $value = (new Exporter())->export($value);
69090 }
69091 if ($value === '') {
69092 if ($colorize) {
69093 $value = Color::colorize('dim,underlined', 'empty');
69094 } else {
69095 $value = "''";
69096 }
69097 }
69098 $providedData['$' . $parameter->getName()] = str_replace('$', '\$', $value);
69099 }
69100 if ($colorize) {
69101 $providedData = array_map(static fn($value) => Color::colorize('fg-cyan', Color::visualizeWhitespace((string) $value, \true)), $providedData);
69102 }
69103 return $providedData;
69104 }
69105 /**
69106 * @return non-empty-string
69107 */
69108 private function objectToString(object $value): string
69109 {
69110 $reflector = new ReflectionObject($value);
69111 if ($reflector->isEnum()) {
69112 $enumReflector = new ReflectionEnum($value);
69113 if ($enumReflector->isBacked()) {
69114 return (string) $value->value;
69115 }
69116 return $value->name;
69117 }
69118 if ($reflector->hasMethod('__toString')) {
69119 return $value->__toString();
69120 }
69121 return $value::class;
69122 }
69123 }
69124 <?php
69125
69126 declare (strict_types=1);
69127 /*
69128 * This file is part of PHPUnit.
69129 *
69130 * (c) Sebastian Bergmann <sebastian@phpunit.de>
69131 *
69132 * For the full copyright and license information, please view the LICENSE
69133 * file that was distributed with this source code.
69134 */
69135 namespace PHPUnit\Logging\TestDox;
69136
69137 use function sprintf;
69138 /**
69139 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
69140 *
69141 * @internal This class is not covered by the backward compatibility promise for PHPUnit
69142 */
69143 final class PlainTextRenderer
69144 {
69145 /**
69146 * @psalm-param array<string, TestResultCollection> $tests
69147 */
69148 public function render(array $tests): string
69149 {
69150 $buffer = '';
69151 foreach ($tests as $prettifiedClassName => $_tests) {
69152 $buffer .= $prettifiedClassName . "\n";
69153 foreach ($this->reduce($_tests) as $prettifiedMethodName => $outcome) {
69154 $buffer .= sprintf(' [%s] %s' . "\n", $outcome, $prettifiedMethodName);
69155 }
69156 $buffer .= "\n";
69157 }
69158 return $buffer;
69159 }
69160 /**
69161 * @psalm-return array<string, 'x'|' '>
69162 */
69163 private function reduce(\PHPUnit\Logging\TestDox\TestResultCollection $tests): array
69164 {
69165 $result = [];
69166 foreach ($tests as $test) {
69167 $prettifiedMethodName = $test->test()->testDox()->prettifiedMethodName();
69168 $success = \true;
69169 if ($test->status()->isError() || $test->status()->isFailure() || $test->status()->isIncomplete() || $test->status()->isSkipped()) {
69170 $success = \false;
69171 }
69172 if (!isset($result[$prettifiedMethodName])) {
69173 $result[$prettifiedMethodName] = $success ? 'x' : ' ';
69174 continue;
69175 }
69176 if ($success) {
69177 continue;
69178 }
69179 $result[$prettifiedMethodName] = ' ';
69180 }
69181 return $result;
69182 }
69183 }
69184 <?php
69185
69186 declare (strict_types=1);
69187 /*
69188 * This file is part of PHPUnit.
69189 *
69190 * (c) Sebastian Bergmann <sebastian@phpunit.de>
69191 *
69192 * For the full copyright and license information, please view the LICENSE
69193 * file that was distributed with this source code.
69194 */
69195 namespace PHPUnit\Logging\TestDox;
69196
69197 /**
69198 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
69199 *
69200 * @internal This class is not covered by the backward compatibility promise for PHPUnit
69201 */
69202 abstract class Subscriber
69203 {
69204 private readonly \PHPUnit\Logging\TestDox\TestResultCollector $collector;
69205 public function __construct(\PHPUnit\Logging\TestDox\TestResultCollector $collector)
69206 {
69207 $this->collector = $collector;
69208 }
69209 protected function collector(): \PHPUnit\Logging\TestDox\TestResultCollector
69210 {
69211 return $this->collector;
69212 }
69213 }
69214 <?php
69215
69216 declare (strict_types=1);
69217 /*
69218 * This file is part of PHPUnit.
69219 *
69220 * (c) Sebastian Bergmann <sebastian@phpunit.de>
69221 *
69222 * For the full copyright and license information, please view the LICENSE
69223 * file that was distributed with this source code.
69224 */
69225 namespace PHPUnit\Logging\TestDox;
69226
69227 use PHPUnit\Event\Test\ConsideredRisky;
69228 use PHPUnit\Event\Test\ConsideredRiskySubscriber;
69229 /**
69230 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
69231 *
69232 * @internal This class is not covered by the backward compatibility promise for PHPUnit
69233 */
69234 final class TestConsideredRiskySubscriber extends \PHPUnit\Logging\TestDox\Subscriber implements ConsideredRiskySubscriber
69235 {
69236 public function notify(ConsideredRisky $event): void
69237 {
69238 $this->collector()->testConsideredRisky($event);
69239 }
69240 }
69241 <?php
69242
69243 declare (strict_types=1);
69244 /*
69245 * This file is part of PHPUnit.
69246 *
69247 * (c) Sebastian Bergmann <sebastian@phpunit.de>
69248 *
69249 * For the full copyright and license information, please view the LICENSE
69250 * file that was distributed with this source code.
69251 */
69252 namespace PHPUnit\Logging\TestDox;
69253
69254 use PHPUnit\Event\Test\Errored;
69255 use PHPUnit\Event\Test\ErroredSubscriber;
69256 /**
69257 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
69258 *
69259 * @internal This class is not covered by the backward compatibility promise for PHPUnit
69260 */
69261 final class TestErroredSubscriber extends \PHPUnit\Logging\TestDox\Subscriber implements ErroredSubscriber
69262 {
69263 public function notify(Errored $event): void
69264 {
69265 $this->collector()->testErrored($event);
69266 }
69267 }
69268 <?php
69269
69270 declare (strict_types=1);
69271 /*
69272 * This file is part of PHPUnit.
69273 *
69274 * (c) Sebastian Bergmann <sebastian@phpunit.de>
69275 *
69276 * For the full copyright and license information, please view the LICENSE
69277 * file that was distributed with this source code.
69278 */
69279 namespace PHPUnit\Logging\TestDox;
69280
69281 use PHPUnit\Event\Test\Failed;
69282 use PHPUnit\Event\Test\FailedSubscriber;
69283 /**
69284 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
69285 *
69286 * @internal This class is not covered by the backward compatibility promise for PHPUnit
69287 */
69288 final class TestFailedSubscriber extends \PHPUnit\Logging\TestDox\Subscriber implements FailedSubscriber
69289 {
69290 public function notify(Failed $event): void
69291 {
69292 $this->collector()->testFailed($event);
69293 }
69294 }
69295 <?php
69296
69297 declare (strict_types=1);
69298 /*
69299 * This file is part of PHPUnit.
69300 *
69301 * (c) Sebastian Bergmann <sebastian@phpunit.de>
69302 *
69303 * For the full copyright and license information, please view the LICENSE
69304 * file that was distributed with this source code.
69305 */
69306 namespace PHPUnit\Logging\TestDox;
69307
69308 use PHPUnit\Event\InvalidArgumentException;
69309 use PHPUnit\Event\Test\Finished;
69310 use PHPUnit\Event\Test\FinishedSubscriber;
69311 /**
69312 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
69313 *
69314 * @internal This class is not covered by the backward compatibility promise for PHPUnit
69315 */
69316 final class TestFinishedSubscriber extends \PHPUnit\Logging\TestDox\Subscriber implements FinishedSubscriber
69317 {
69318 /**
69319 * @throws InvalidArgumentException
69320 */
69321 public function notify(Finished $event): void
69322 {
69323 $this->collector()->testFinished($event);
69324 }
69325 }
69326 <?php
69327
69328 declare (strict_types=1);
69329 /*
69330 * This file is part of PHPUnit.
69331 *
69332 * (c) Sebastian Bergmann <sebastian@phpunit.de>
69333 *
69334 * For the full copyright and license information, please view the LICENSE
69335 * file that was distributed with this source code.
69336 */
69337 namespace PHPUnit\Logging\TestDox;
69338
69339 use PHPUnit\Event\Test\MarkedIncomplete;
69340 use PHPUnit\Event\Test\MarkedIncompleteSubscriber;
69341 /**
69342 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
69343 *
69344 * @internal This class is not covered by the backward compatibility promise for PHPUnit
69345 */
69346 final class TestMarkedIncompleteSubscriber extends \PHPUnit\Logging\TestDox\Subscriber implements MarkedIncompleteSubscriber
69347 {
69348 public function notify(MarkedIncomplete $event): void
69349 {
69350 $this->collector()->testMarkedIncomplete($event);
69351 }
69352 }
69353 <?php
69354
69355 declare (strict_types=1);
69356 /*
69357 * This file is part of PHPUnit.
69358 *
69359 * (c) Sebastian Bergmann <sebastian@phpunit.de>
69360 *
69361 * For the full copyright and license information, please view the LICENSE
69362 * file that was distributed with this source code.
69363 */
69364 namespace PHPUnit\Logging\TestDox;
69365
69366 use PHPUnit\Event\Test\Passed;
69367 use PHPUnit\Event\Test\PassedSubscriber;
69368 /**
69369 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
69370 *
69371 * @internal This class is not covered by the backward compatibility promise for PHPUnit
69372 */
69373 final class TestPassedSubscriber extends \PHPUnit\Logging\TestDox\Subscriber implements PassedSubscriber
69374 {
69375 public function notify(Passed $event): void
69376 {
69377 $this->collector()->testPassed($event);
69378 }
69379 }
69380 <?php
69381
69382 declare (strict_types=1);
69383 /*
69384 * This file is part of PHPUnit.
69385 *
69386 * (c) Sebastian Bergmann <sebastian@phpunit.de>
69387 *
69388 * For the full copyright and license information, please view the LICENSE
69389 * file that was distributed with this source code.
69390 */
69391 namespace PHPUnit\Logging\TestDox;
69392
69393 use PHPUnit\Event\Test\Prepared;
69394 use PHPUnit\Event\Test\PreparedSubscriber;
69395 /**
69396 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
69397 *
69398 * @internal This class is not covered by the backward compatibility promise for PHPUnit
69399 */
69400 final class TestPreparedSubscriber extends \PHPUnit\Logging\TestDox\Subscriber implements PreparedSubscriber
69401 {
69402 public function notify(Prepared $event): void
69403 {
69404 $this->collector()->testPrepared($event);
69405 }
69406 }
69407 <?php
69408
69409 declare (strict_types=1);
69410 /*
69411 * This file is part of PHPUnit.
69412 *
69413 * (c) Sebastian Bergmann <sebastian@phpunit.de>
69414 *
69415 * For the full copyright and license information, please view the LICENSE
69416 * file that was distributed with this source code.
69417 */
69418 namespace PHPUnit\Logging\TestDox;
69419
69420 use PHPUnit\Event\Test\Skipped;
69421 use PHPUnit\Event\Test\SkippedSubscriber;
69422 /**
69423 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
69424 *
69425 * @internal This class is not covered by the backward compatibility promise for PHPUnit
69426 */
69427 final class TestSkippedSubscriber extends \PHPUnit\Logging\TestDox\Subscriber implements SkippedSubscriber
69428 {
69429 public function notify(Skipped $event): void
69430 {
69431 $this->collector()->testSkipped($event);
69432 }
69433 }
69434 <?php
69435
69436 declare (strict_types=1);
69437 /*
69438 * This file is part of PHPUnit.
69439 *
69440 * (c) Sebastian Bergmann <sebastian@phpunit.de>
69441 *
69442 * For the full copyright and license information, please view the LICENSE
69443 * file that was distributed with this source code.
69444 */
69445 namespace PHPUnit\Logging\TestDox;
69446
69447 use PHPUnit\Event\Test\DeprecationTriggered;
69448 use PHPUnit\Event\Test\DeprecationTriggeredSubscriber;
69449 /**
69450 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
69451 *
69452 * @internal This class is not covered by the backward compatibility promise for PHPUnit
69453 */
69454 final class TestTriggeredDeprecationSubscriber extends \PHPUnit\Logging\TestDox\Subscriber implements DeprecationTriggeredSubscriber
69455 {
69456 public function notify(DeprecationTriggered $event): void
69457 {
69458 $this->collector()->testTriggeredDeprecation($event);
69459 }
69460 }
69461 <?php
69462
69463 declare (strict_types=1);
69464 /*
69465 * This file is part of PHPUnit.
69466 *
69467 * (c) Sebastian Bergmann <sebastian@phpunit.de>
69468 *
69469 * For the full copyright and license information, please view the LICENSE
69470 * file that was distributed with this source code.
69471 */
69472 namespace PHPUnit\Logging\TestDox;
69473
69474 use PHPUnit\Event\Test\NoticeTriggered;
69475 use PHPUnit\Event\Test\NoticeTriggeredSubscriber;
69476 /**
69477 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
69478 *
69479 * @internal This class is not covered by the backward compatibility promise for PHPUnit
69480 */
69481 final class TestTriggeredNoticeSubscriber extends \PHPUnit\Logging\TestDox\Subscriber implements NoticeTriggeredSubscriber
69482 {
69483 public function notify(NoticeTriggered $event): void
69484 {
69485 $this->collector()->testTriggeredNotice($event);
69486 }
69487 }
69488 <?php
69489
69490 declare (strict_types=1);
69491 /*
69492 * This file is part of PHPUnit.
69493 *
69494 * (c) Sebastian Bergmann <sebastian@phpunit.de>
69495 *
69496 * For the full copyright and license information, please view the LICENSE
69497 * file that was distributed with this source code.
69498 */
69499 namespace PHPUnit\Logging\TestDox;
69500
69501 use PHPUnit\Event\Test\PhpDeprecationTriggered;
69502 use PHPUnit\Event\Test\PhpDeprecationTriggeredSubscriber;
69503 /**
69504 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
69505 *
69506 * @internal This class is not covered by the backward compatibility promise for PHPUnit
69507 */
69508 final class TestTriggeredPhpDeprecationSubscriber extends \PHPUnit\Logging\TestDox\Subscriber implements PhpDeprecationTriggeredSubscriber
69509 {
69510 public function notify(PhpDeprecationTriggered $event): void
69511 {
69512 $this->collector()->testTriggeredPhpDeprecation($event);
69513 }
69514 }
69515 <?php
69516
69517 declare (strict_types=1);
69518 /*
69519 * This file is part of PHPUnit.
69520 *
69521 * (c) Sebastian Bergmann <sebastian@phpunit.de>
69522 *
69523 * For the full copyright and license information, please view the LICENSE
69524 * file that was distributed with this source code.
69525 */
69526 namespace PHPUnit\Logging\TestDox;
69527
69528 use PHPUnit\Event\Test\PhpNoticeTriggered;
69529 use PHPUnit\Event\Test\PhpNoticeTriggeredSubscriber;
69530 /**
69531 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
69532 *
69533 * @internal This class is not covered by the backward compatibility promise for PHPUnit
69534 */
69535 final class TestTriggeredPhpNoticeSubscriber extends \PHPUnit\Logging\TestDox\Subscriber implements PhpNoticeTriggeredSubscriber
69536 {
69537 public function notify(PhpNoticeTriggered $event): void
69538 {
69539 $this->collector()->testTriggeredPhpNotice($event);
69540 }
69541 }
69542 <?php
69543
69544 declare (strict_types=1);
69545 /*
69546 * This file is part of PHPUnit.
69547 *
69548 * (c) Sebastian Bergmann <sebastian@phpunit.de>
69549 *
69550 * For the full copyright and license information, please view the LICENSE
69551 * file that was distributed with this source code.
69552 */
69553 namespace PHPUnit\Logging\TestDox;
69554
69555 use PHPUnit\Event\Test\PhpWarningTriggered;
69556 use PHPUnit\Event\Test\PhpWarningTriggeredSubscriber;
69557 /**
69558 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
69559 *
69560 * @internal This class is not covered by the backward compatibility promise for PHPUnit
69561 */
69562 final class TestTriggeredPhpWarningSubscriber extends \PHPUnit\Logging\TestDox\Subscriber implements PhpWarningTriggeredSubscriber
69563 {
69564 public function notify(PhpWarningTriggered $event): void
69565 {
69566 $this->collector()->testTriggeredPhpWarning($event);
69567 }
69568 }
69569 <?php
69570
69571 declare (strict_types=1);
69572 /*
69573 * This file is part of PHPUnit.
69574 *
69575 * (c) Sebastian Bergmann <sebastian@phpunit.de>
69576 *
69577 * For the full copyright and license information, please view the LICENSE
69578 * file that was distributed with this source code.
69579 */
69580 namespace PHPUnit\Logging\TestDox;
69581
69582 use PHPUnit\Event\Test\PhpunitDeprecationTriggered;
69583 use PHPUnit\Event\Test\PhpunitDeprecationTriggeredSubscriber;
69584 /**
69585 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
69586 *
69587 * @internal This class is not covered by the backward compatibility promise for PHPUnit
69588 */
69589 final class TestTriggeredPhpunitDeprecationSubscriber extends \PHPUnit\Logging\TestDox\Subscriber implements PhpunitDeprecationTriggeredSubscriber
69590 {
69591 public function notify(PhpunitDeprecationTriggered $event): void
69592 {
69593 $this->collector()->testTriggeredPhpunitDeprecation($event);
69594 }
69595 }
69596 <?php
69597
69598 declare (strict_types=1);
69599 /*
69600 * This file is part of PHPUnit.
69601 *
69602 * (c) Sebastian Bergmann <sebastian@phpunit.de>
69603 *
69604 * For the full copyright and license information, please view the LICENSE
69605 * file that was distributed with this source code.
69606 */
69607 namespace PHPUnit\Logging\TestDox;
69608
69609 use PHPUnit\Event\Test\PhpunitErrorTriggered;
69610 use PHPUnit\Event\Test\PhpunitErrorTriggeredSubscriber;
69611 /**
69612 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
69613 *
69614 * @internal This class is not covered by the backward compatibility promise for PHPUnit
69615 */
69616 final class TestTriggeredPhpunitErrorSubscriber extends \PHPUnit\Logging\TestDox\Subscriber implements PhpunitErrorTriggeredSubscriber
69617 {
69618 public function notify(PhpunitErrorTriggered $event): void
69619 {
69620 $this->collector()->testTriggeredPhpunitError($event);
69621 }
69622 }
69623 <?php
69624
69625 declare (strict_types=1);
69626 /*
69627 * This file is part of PHPUnit.
69628 *
69629 * (c) Sebastian Bergmann <sebastian@phpunit.de>
69630 *
69631 * For the full copyright and license information, please view the LICENSE
69632 * file that was distributed with this source code.
69633 */
69634 namespace PHPUnit\Logging\TestDox;
69635
69636 use PHPUnit\Event\Test\PhpunitWarningTriggered;
69637 use PHPUnit\Event\Test\PhpunitWarningTriggeredSubscriber;
69638 /**
69639 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
69640 *
69641 * @internal This class is not covered by the backward compatibility promise for PHPUnit
69642 */
69643 final class TestTriggeredPhpunitWarningSubscriber extends \PHPUnit\Logging\TestDox\Subscriber implements PhpunitWarningTriggeredSubscriber
69644 {
69645 public function notify(PhpunitWarningTriggered $event): void
69646 {
69647 $this->collector()->testTriggeredPhpunitWarning($event);
69648 }
69649 }
69650 <?php
69651
69652 declare (strict_types=1);
69653 /*
69654 * This file is part of PHPUnit.
69655 *
69656 * (c) Sebastian Bergmann <sebastian@phpunit.de>
69657 *
69658 * For the full copyright and license information, please view the LICENSE
69659 * file that was distributed with this source code.
69660 */
69661 namespace PHPUnit\Logging\TestDox;
69662
69663 use PHPUnit\Event\Test\WarningTriggered;
69664 use PHPUnit\Event\Test\WarningTriggeredSubscriber;
69665 /**
69666 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
69667 *
69668 * @internal This class is not covered by the backward compatibility promise for PHPUnit
69669 */
69670 final class TestTriggeredWarningSubscriber extends \PHPUnit\Logging\TestDox\Subscriber implements WarningTriggeredSubscriber
69671 {
69672 public function notify(WarningTriggered $event): void
69673 {
69674 $this->collector()->testTriggeredWarning($event);
69675 }
69676 }
69677 <?php
69678
69679 declare (strict_types=1);
69680 /*
69681 * This file is part of PHPUnit.
69682 *
69683 * (c) Sebastian Bergmann <sebastian@phpunit.de>
69684 *
69685 * For the full copyright and license information, please view the LICENSE
69686 * file that was distributed with this source code.
69687 */
69688 namespace PHPUnit\Logging\TestDox;
69689
69690 use PHPUnit\Event\Code\TestMethod;
69691 use PHPUnit\Event\Code\Throwable;
69692 use PHPUnit\Framework\TestStatus\TestStatus;
69693 /**
69694 * @psalm-immutable
69695 *
69696 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
69697 *
69698 * @internal This class is not covered by the backward compatibility promise for PHPUnit
69699 */
69700 final class TestResult
69701 {
69702 private readonly TestMethod $test;
69703 private readonly TestStatus $status;
69704 private readonly ?Throwable $throwable;
69705 public function __construct(TestMethod $test, TestStatus $status, ?Throwable $throwable)
69706 {
69707 $this->test = $test;
69708 $this->status = $status;
69709 $this->throwable = $throwable;
69710 }
69711 public function test(): TestMethod
69712 {
69713 return $this->test;
69714 }
69715 public function status(): TestStatus
69716 {
69717 return $this->status;
69718 }
69719 /**
69720 * @psalm-assert-if-true !null $this->throwable
69721 */
69722 public function hasThrowable(): bool
69723 {
69724 return $this->throwable !== null;
69725 }
69726 public function throwable(): ?Throwable
69727 {
69728 return $this->throwable;
69729 }
69730 }
69731 <?php
69732
69733 declare (strict_types=1);
69734 /*
69735 * This file is part of PHPUnit.
69736 *
69737 * (c) Sebastian Bergmann <sebastian@phpunit.de>
69738 *
69739 * For the full copyright and license information, please view the LICENSE
69740 * file that was distributed with this source code.
69741 */
69742 namespace PHPUnit\Logging\TestDox;
69743
69744 use IteratorAggregate;
69745 /**
69746 * @template-implements IteratorAggregate<int, TestResult>
69747 *
69748 * @psalm-immutable
69749 *
69750 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
69751 *
69752 * @internal This class is not covered by the backward compatibility promise for PHPUnit
69753 */
69754 final class TestResultCollection implements IteratorAggregate
69755 {
69756 /**
69757 * @psalm-var list<TestResult>
69758 */
69759 private readonly array $testResults;
69760 /**
69761 * @psalm-param list<TestResult> $testResults
69762 */
69763 public static function fromArray(array $testResults): self
69764 {
69765 return new self(...$testResults);
69766 }
69767 private function __construct(\PHPUnit\Logging\TestDox\TestResult ...$testResults)
69768 {
69769 $this->testResults = $testResults;
69770 }
69771 /**
69772 * @psalm-return list<TestResult>
69773 */
69774 public function asArray(): array
69775 {
69776 return $this->testResults;
69777 }
69778 public function getIterator(): \PHPUnit\Logging\TestDox\TestResultCollectionIterator
69779 {
69780 return new \PHPUnit\Logging\TestDox\TestResultCollectionIterator($this);
69781 }
69782 }
69783 <?php
69784
69785 declare (strict_types=1);
69786 /*
69787 * This file is part of PHPUnit.
69788 *
69789 * (c) Sebastian Bergmann <sebastian@phpunit.de>
69790 *
69791 * For the full copyright and license information, please view the LICENSE
69792 * file that was distributed with this source code.
69793 */
69794 namespace PHPUnit\Logging\TestDox;
69795
69796 use function count;
69797 use Iterator;
69798 /**
69799 * @template-implements Iterator<int, TestResult>
69800 *
69801 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
69802 *
69803 * @internal This class is not covered by the backward compatibility promise for PHPUnit
69804 */
69805 final class TestResultCollectionIterator implements Iterator
69806 {
69807 /**
69808 * @psalm-var list<TestResult>
69809 */
69810 private readonly array $testResults;
69811 private int $position = 0;
69812 public function __construct(\PHPUnit\Logging\TestDox\TestResultCollection $testResults)
69813 {
69814 $this->testResults = $testResults->asArray();
69815 }
69816 public function rewind(): void
69817 {
69818 $this->position = 0;
69819 }
69820 public function valid(): bool
69821 {
69822 return $this->position < count($this->testResults);
69823 }
69824 public function key(): int
69825 {
69826 return $this->position;
69827 }
69828 public function current(): \PHPUnit\Logging\TestDox\TestResult
69829 {
69830 return $this->testResults[$this->position];
69831 }
69832 public function next(): void
69833 {
69834 $this->position++;
69835 }
69836 }
69837 <?php
69838
69839 declare (strict_types=1);
69840 /*
69841 * This file is part of PHPUnit.
69842 *
69843 * (c) Sebastian Bergmann <sebastian@phpunit.de>
69844 *
69845 * For the full copyright and license information, please view the LICENSE
69846 * file that was distributed with this source code.
69847 */
69848 namespace PHPUnit\Logging\TestDox;
69849
69850 use function array_keys;
69851 use function array_merge;
69852 use function assert;
69853 use function is_subclass_of;
69854 use function ksort;
69855 use function uksort;
69856 use function usort;
69857 use PHPUnit\Event\Code\TestMethod;
69858 use PHPUnit\Event\Code\Throwable;
69859 use PHPUnit\Event\EventFacadeIsSealedException;
69860 use PHPUnit\Event\Facade;
69861 use PHPUnit\Event\InvalidArgumentException;
69862 use PHPUnit\Event\Test\ConsideredRisky;
69863 use PHPUnit\Event\Test\DeprecationTriggered;
69864 use PHPUnit\Event\Test\Errored;
69865 use PHPUnit\Event\Test\Failed;
69866 use PHPUnit\Event\Test\Finished;
69867 use PHPUnit\Event\Test\MarkedIncomplete;
69868 use PHPUnit\Event\Test\NoticeTriggered;
69869 use PHPUnit\Event\Test\Passed;
69870 use PHPUnit\Event\Test\PhpDeprecationTriggered;
69871 use PHPUnit\Event\Test\PhpNoticeTriggered;
69872 use PHPUnit\Event\Test\PhpunitDeprecationTriggered;
69873 use PHPUnit\Event\Test\PhpunitErrorTriggered;
69874 use PHPUnit\Event\Test\PhpunitWarningTriggered;
69875 use PHPUnit\Event\Test\PhpWarningTriggered;
69876 use PHPUnit\Event\Test\Prepared;
69877 use PHPUnit\Event\Test\Skipped;
69878 use PHPUnit\Event\Test\WarningTriggered;
69879 use PHPUnit\Event\UnknownSubscriberTypeException;
69880 use PHPUnit\Framework\TestStatus\TestStatus;
69881 use PHPUnit\Logging\TestDox\TestResult as TestDoxTestMethod;
69882 use PHPUnit\TextUI\Configuration\Source;
69883 use PHPUnit\TextUI\Configuration\SourceFilter;
69884 use ReflectionMethod;
69885 /**
69886 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
69887 *
69888 * @internal This class is not covered by the backward compatibility promise for PHPUnit
69889 */
69890 final class TestResultCollector
69891 {
69892 private readonly Source $source;
69893 /**
69894 * @psalm-var array<string, list<TestDoxTestMethod>>
69895 */
69896 private array $tests = [];
69897 private ?TestStatus $status = null;
69898 private ?Throwable $throwable = null;
69899 private bool $prepared = \false;
69900 /**
69901 * @throws EventFacadeIsSealedException
69902 * @throws UnknownSubscriberTypeException
69903 */
69904 public function __construct(Facade $facade, Source $source)
69905 {
69906 $this->source = $source;
69907 $this->registerSubscribers($facade);
69908 }
69909 /**
69910 * @psalm-return array<string, TestResultCollection>
69911 */
69912 public function testMethodsGroupedByClass(): array
69913 {
69914 $result = [];
69915 foreach ($this->tests as $prettifiedClassName => $tests) {
69916 $testsByDeclaringClass = [];
69917 foreach ($tests as $test) {
69918 $declaringClassName = (new ReflectionMethod($test->test()->className(), $test->test()->methodName()))->getDeclaringClass()->getName();
69919 if (!isset($testsByDeclaringClass[$declaringClassName])) {
69920 $testsByDeclaringClass[$declaringClassName] = [];
69921 }
69922 $testsByDeclaringClass[$declaringClassName][] = $test;
69923 }
69924 foreach (array_keys($testsByDeclaringClass) as $declaringClassName) {
69925 usort($testsByDeclaringClass[$declaringClassName], static function (TestDoxTestMethod $a, TestDoxTestMethod $b): int {
69926 return $a->test()->line() <=> $b->test()->line();
69927 });
69928 }
69929 uksort(
69930 $testsByDeclaringClass,
69931 /**
69932 * @psalm-param class-string $a
69933 * @psalm-param class-string $b
69934 */
69935 static function (string $a, string $b): int {
69936 if (is_subclass_of($b, $a)) {
69937 return -1;
69938 }
69939 if (is_subclass_of($a, $b)) {
69940 return 1;
69941 }
69942 return 0;
69943 }
69944 );
69945 $tests = [];
69946 foreach ($testsByDeclaringClass as $_tests) {
69947 $tests = array_merge($tests, $_tests);
69948 }
69949 $result[$prettifiedClassName] = \PHPUnit\Logging\TestDox\TestResultCollection::fromArray($tests);
69950 }
69951 ksort($result);
69952 return $result;
69953 }
69954 public function testPrepared(Prepared $event): void
69955 {
69956 if (!$event->test()->isTestMethod()) {
69957 return;
69958 }
69959 $this->status = TestStatus::unknown();
69960 $this->throwable = null;
69961 $this->prepared = \true;
69962 }
69963 public function testErrored(Errored $event): void
69964 {
69965 if (!$event->test()->isTestMethod()) {
69966 return;
69967 }
69968 $this->status = TestStatus::error($event->throwable()->message());
69969 $this->throwable = $event->throwable();
69970 if (!$this->prepared) {
69971 $test = $event->test();
69972 assert($test instanceof TestMethod);
69973 $this->process($test);
69974 }
69975 }
69976 public function testFailed(Failed $event): void
69977 {
69978 if (!$event->test()->isTestMethod()) {
69979 return;
69980 }
69981 $this->status = TestStatus::failure($event->throwable()->message());
69982 $this->throwable = $event->throwable();
69983 }
69984 public function testPassed(Passed $event): void
69985 {
69986 if (!$event->test()->isTestMethod()) {
69987 return;
69988 }
69989 $this->updateTestStatus(TestStatus::success());
69990 }
69991 public function testSkipped(Skipped $event): void
69992 {
69993 if (!$event->test()->isTestMethod()) {
69994 return;
69995 }
69996 $this->updateTestStatus(TestStatus::skipped($event->message()));
69997 }
69998 public function testMarkedIncomplete(MarkedIncomplete $event): void
69999 {
70000 if (!$event->test()->isTestMethod()) {
70001 return;
70002 }
70003 $this->updateTestStatus(TestStatus::incomplete($event->throwable()->message()));
70004 $this->throwable = $event->throwable();
70005 }
70006 public function testConsideredRisky(ConsideredRisky $event): void
70007 {
70008 if (!$event->test()->isTestMethod()) {
70009 return;
70010 }
70011 $this->updateTestStatus(TestStatus::risky());
70012 }
70013 public function testTriggeredDeprecation(DeprecationTriggered $event): void
70014 {
70015 if (!$event->test()->isTestMethod()) {
70016 return;
70017 }
70018 if ($event->ignoredByTest()) {
70019 return;
70020 }
70021 if ($event->ignoredByBaseline()) {
70022 return;
70023 }
70024 if (!$this->source->ignoreSuppressionOfDeprecations() && $event->wasSuppressed()) {
70025 return;
70026 }
70027 if ($this->source->restrictDeprecations() && !SourceFilter::instance()->includes($event->file())) {
70028 return;
70029 }
70030 $this->updateTestStatus(TestStatus::deprecation());
70031 }
70032 public function testTriggeredNotice(NoticeTriggered $event): void
70033 {
70034 if (!$event->test()->isTestMethod()) {
70035 return;
70036 }
70037 if ($event->ignoredByBaseline()) {
70038 return;
70039 }
70040 if (!$this->source->ignoreSuppressionOfNotices() && $event->wasSuppressed()) {
70041 return;
70042 }
70043 if ($this->source->restrictNotices() && !SourceFilter::instance()->includes($event->file())) {
70044 return;
70045 }
70046 $this->updateTestStatus(TestStatus::notice());
70047 }
70048 public function testTriggeredWarning(WarningTriggered $event): void
70049 {
70050 if (!$event->test()->isTestMethod()) {
70051 return;
70052 }
70053 if ($event->ignoredByBaseline()) {
70054 return;
70055 }
70056 if (!$this->source->ignoreSuppressionOfWarnings() && $event->wasSuppressed()) {
70057 return;
70058 }
70059 if ($this->source->restrictWarnings() && !SourceFilter::instance()->includes($event->file())) {
70060 return;
70061 }
70062 $this->updateTestStatus(TestStatus::warning());
70063 }
70064 public function testTriggeredPhpDeprecation(PhpDeprecationTriggered $event): void
70065 {
70066 if (!$event->test()->isTestMethod()) {
70067 return;
70068 }
70069 if ($event->ignoredByTest()) {
70070 return;
70071 }
70072 if ($event->ignoredByBaseline()) {
70073 return;
70074 }
70075 if (!$this->source->ignoreSuppressionOfPhpDeprecations() && $event->wasSuppressed()) {
70076 return;
70077 }
70078 if ($this->source->restrictDeprecations() && !SourceFilter::instance()->includes($event->file())) {
70079 return;
70080 }
70081 $this->updateTestStatus(TestStatus::deprecation());
70082 }
70083 public function testTriggeredPhpNotice(PhpNoticeTriggered $event): void
70084 {
70085 if (!$event->test()->isTestMethod()) {
70086 return;
70087 }
70088 if ($event->ignoredByBaseline()) {
70089 return;
70090 }
70091 if (!$this->source->ignoreSuppressionOfPhpNotices() && $event->wasSuppressed()) {
70092 return;
70093 }
70094 if ($this->source->restrictNotices() && !SourceFilter::instance()->includes($event->file())) {
70095 return;
70096 }
70097 $this->updateTestStatus(TestStatus::notice());
70098 }
70099 public function testTriggeredPhpWarning(PhpWarningTriggered $event): void
70100 {
70101 if (!$event->test()->isTestMethod()) {
70102 return;
70103 }
70104 if ($event->ignoredByBaseline()) {
70105 return;
70106 }
70107 if (!$this->source->ignoreSuppressionOfPhpWarnings() && $event->wasSuppressed()) {
70108 return;
70109 }
70110 if ($this->source->restrictWarnings() && !SourceFilter::instance()->includes($event->file())) {
70111 return;
70112 }
70113 $this->updateTestStatus(TestStatus::warning());
70114 }
70115 public function testTriggeredPhpunitDeprecation(PhpunitDeprecationTriggered $event): void
70116 {
70117 if (!$event->test()->isTestMethod()) {
70118 return;
70119 }
70120 $this->updateTestStatus(TestStatus::deprecation());
70121 }
70122 public function testTriggeredPhpunitError(PhpunitErrorTriggered $event): void
70123 {
70124 if (!$event->test()->isTestMethod()) {
70125 return;
70126 }
70127 $this->updateTestStatus(TestStatus::error());
70128 }
70129 public function testTriggeredPhpunitWarning(PhpunitWarningTriggered $event): void
70130 {
70131 if (!$event->test()->isTestMethod()) {
70132 return;
70133 }
70134 $this->updateTestStatus(TestStatus::warning());
70135 }
70136 /**
70137 * @throws InvalidArgumentException
70138 */
70139 public function testFinished(Finished $event): void
70140 {
70141 if (!$event->test()->isTestMethod()) {
70142 return;
70143 }
70144 $test = $event->test();
70145 assert($test instanceof TestMethod);
70146 $this->process($test);
70147 $this->status = null;
70148 $this->throwable = null;
70149 $this->prepared = \false;
70150 }
70151 /**
70152 * @throws EventFacadeIsSealedException
70153 * @throws UnknownSubscriberTypeException
70154 */
70155 private function registerSubscribers(Facade $facade): void
70156 {
70157 $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));
70158 }
70159 private function updateTestStatus(TestStatus $status): void
70160 {
70161 if ($this->status !== null && $this->status->isMoreImportantThan($status)) {
70162 return;
70163 }
70164 $this->status = $status;
70165 }
70166 private function process(TestMethod $test): void
70167 {
70168 if (!isset($this->tests[$test->testDox()->prettifiedClassName()])) {
70169 $this->tests[$test->testDox()->prettifiedClassName()] = [];
70170 }
70171 $this->tests[$test->testDox()->prettifiedClassName()][] = new TestDoxTestMethod($test, $this->status, $this->throwable);
70172 }
70173 }
70174 <?php
70175
70176 declare (strict_types=1);
70177 /*
70178 * This file is part of PHPUnit.
70179 *
70180 * (c) Sebastian Bergmann <sebastian@phpunit.de>
70181 *
70182 * For the full copyright and license information, please view the LICENSE
70183 * file that was distributed with this source code.
70184 */
70185 namespace PHPUnit\Metadata;
70186
70187 /**
70188 * @psalm-immutable
70189 *
70190 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
70191 */
70192 final class After extends \PHPUnit\Metadata\Metadata
70193 {
70194 /**
70195 * @psalm-assert-if-true After $this
70196 */
70197 public function isAfter(): bool
70198 {
70199 return \true;
70200 }
70201 }
70202 <?php
70203
70204 declare (strict_types=1);
70205 /*
70206 * This file is part of PHPUnit.
70207 *
70208 * (c) Sebastian Bergmann <sebastian@phpunit.de>
70209 *
70210 * For the full copyright and license information, please view the LICENSE
70211 * file that was distributed with this source code.
70212 */
70213 namespace PHPUnit\Metadata;
70214
70215 /**
70216 * @psalm-immutable
70217 *
70218 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
70219 */
70220 final class AfterClass extends \PHPUnit\Metadata\Metadata
70221 {
70222 /**
70223 * @psalm-assert-if-true AfterClass $this
70224 */
70225 public function isAfterClass(): bool
70226 {
70227 return \true;
70228 }
70229 }
70230 <?php
70231
70232 declare (strict_types=1);
70233 /*
70234 * This file is part of PHPUnit.
70235 *
70236 * (c) Sebastian Bergmann <sebastian@phpunit.de>
70237 *
70238 * For the full copyright and license information, please view the LICENSE
70239 * file that was distributed with this source code.
70240 */
70241 namespace PHPUnit\Metadata\Api;
70242
70243 use function array_unique;
70244 use function array_values;
70245 use function assert;
70246 use function count;
70247 use function interface_exists;
70248 use function sprintf;
70249 use function str_starts_with;
70250 use PHPUnit\Framework\CodeCoverageException;
70251 use PHPUnit\Framework\InvalidCoversTargetException;
70252 use PHPUnit\Framework\TestSuite;
70253 use PHPUnit\Metadata\Covers;
70254 use PHPUnit\Metadata\CoversClass;
70255 use PHPUnit\Metadata\CoversDefaultClass;
70256 use PHPUnit\Metadata\CoversFunction;
70257 use PHPUnit\Metadata\IgnoreClassForCodeCoverage;
70258 use PHPUnit\Metadata\IgnoreFunctionForCodeCoverage;
70259 use PHPUnit\Metadata\IgnoreMethodForCodeCoverage;
70260 use PHPUnit\Metadata\Parser\Registry;
70261 use PHPUnit\Metadata\Uses;
70262 use PHPUnit\Metadata\UsesClass;
70263 use PHPUnit\Metadata\UsesDefaultClass;
70264 use PHPUnit\Metadata\UsesFunction;
70265 use RecursiveIteratorIterator;
70266 use PHPUnitPHAR\SebastianBergmann\CodeUnit\CodeUnitCollection;
70267 use PHPUnitPHAR\SebastianBergmann\CodeUnit\Exception as CodeUnitException;
70268 use PHPUnitPHAR\SebastianBergmann\CodeUnit\InvalidCodeUnitException;
70269 use PHPUnitPHAR\SebastianBergmann\CodeUnit\Mapper;
70270 /**
70271 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
70272 *
70273 * @internal This class is not covered by the backward compatibility promise for PHPUnit
70274 */
70275 final class CodeCoverage
70276 {
70277 /**
70278 * @psalm-param class-string $className
70279 * @psalm-param non-empty-string $methodName
70280 *
70281 * @throws CodeCoverageException
70282 *
70283 * @psalm-return array<string,list<int>>|false
70284 */
70285 public function linesToBeCovered(string $className, string $methodName): array|false
70286 {
70287 if (!$this->shouldCodeCoverageBeCollectedFor($className, $methodName)) {
70288 return \false;
70289 }
70290 $metadataForClass = Registry::parser()->forClass($className);
70291 $classShortcut = null;
70292 if ($metadataForClass->isCoversDefaultClass()->isNotEmpty()) {
70293 if (count($metadataForClass->isCoversDefaultClass()) > 1) {
70294 throw new CodeCoverageException(sprintf('More than one @coversDefaultClass annotation for class or interface "%s"', $className));
70295 }
70296 $metadata = $metadataForClass->isCoversDefaultClass()->asArray()[0];
70297 assert($metadata instanceof CoversDefaultClass);
70298 $classShortcut = $metadata->className();
70299 }
70300 $codeUnits = CodeUnitCollection::fromList();
70301 $mapper = new Mapper();
70302 foreach (Registry::parser()->forClassAndMethod($className, $methodName) as $metadata) {
70303 if (!$metadata->isCoversClass() && !$metadata->isCoversFunction() && !$metadata->isCovers()) {
70304 continue;
70305 }
70306 assert($metadata instanceof CoversClass || $metadata instanceof CoversFunction || $metadata instanceof Covers);
70307 if ($metadata->isCoversClass() || $metadata->isCoversFunction()) {
70308 $codeUnits = $codeUnits->mergeWith($this->mapToCodeUnits($metadata));
70309 } elseif ($metadata->isCovers()) {
70310 assert($metadata instanceof Covers);
70311 $target = $metadata->target();
70312 if (interface_exists($target)) {
70313 throw new InvalidCoversTargetException(sprintf('Trying to @cover interface "%s".', $target));
70314 }
70315 if ($classShortcut !== null && str_starts_with($target, '::')) {
70316 $target = $classShortcut . $target;
70317 }
70318 try {
70319 $codeUnits = $codeUnits->mergeWith($mapper->stringToCodeUnits($target));
70320 } catch (InvalidCodeUnitException $e) {
70321 throw new InvalidCoversTargetException(sprintf('"@covers %s" is invalid', $target), $e->getCode(), $e);
70322 }
70323 }
70324 }
70325 return $mapper->codeUnitsToSourceLines($codeUnits);
70326 }
70327 /**
70328 * @psalm-param class-string $className
70329 * @psalm-param non-empty-string $methodName
70330 *
70331 * @throws CodeCoverageException
70332 *
70333 * @psalm-return array<string,list<int>>
70334 */
70335 public function linesToBeUsed(string $className, string $methodName): array
70336 {
70337 $metadataForClass = Registry::parser()->forClass($className);
70338 $classShortcut = null;
70339 if ($metadataForClass->isUsesDefaultClass()->isNotEmpty()) {
70340 if (count($metadataForClass->isUsesDefaultClass()) > 1) {
70341 throw new CodeCoverageException(sprintf('More than one @usesDefaultClass annotation for class or interface "%s"', $className));
70342 }
70343 $metadata = $metadataForClass->isUsesDefaultClass()->asArray()[0];
70344 assert($metadata instanceof UsesDefaultClass);
70345 $classShortcut = $metadata->className();
70346 }
70347 $codeUnits = CodeUnitCollection::fromList();
70348 $mapper = new Mapper();
70349 foreach (Registry::parser()->forClassAndMethod($className, $methodName) as $metadata) {
70350 if (!$metadata->isUsesClass() && !$metadata->isUsesFunction() && !$metadata->isUses()) {
70351 continue;
70352 }
70353 assert($metadata instanceof UsesClass || $metadata instanceof UsesFunction || $metadata instanceof Uses);
70354 if ($metadata->isUsesClass() || $metadata->isUsesFunction()) {
70355 $codeUnits = $codeUnits->mergeWith($this->mapToCodeUnits($metadata));
70356 } elseif ($metadata->isUses()) {
70357 assert($metadata instanceof Uses);
70358 $target = $metadata->target();
70359 if ($classShortcut !== null && str_starts_with($target, '::')) {
70360 $target = $classShortcut . $target;
70361 }
70362 try {
70363 $codeUnits = $codeUnits->mergeWith($mapper->stringToCodeUnits($target));
70364 } catch (InvalidCodeUnitException $e) {
70365 throw new InvalidCoversTargetException(sprintf('"@uses %s" is invalid', $target), $e->getCode(), $e);
70366 }
70367 }
70368 }
70369 return $mapper->codeUnitsToSourceLines($codeUnits);
70370 }
70371 /**
70372 * @psalm-return array<string,list<int>>
70373 */
70374 public function linesToBeIgnored(TestSuite $testSuite): array
70375 {
70376 $codeUnits = CodeUnitCollection::fromList();
70377 $mapper = new Mapper();
70378 foreach ($this->testCaseClassesIn($testSuite) as $testCaseClassName) {
70379 $codeUnits = $codeUnits->mergeWith($this->codeUnitsIgnoredBy($testCaseClassName));
70380 }
70381 return $mapper->codeUnitsToSourceLines($codeUnits);
70382 }
70383 /**
70384 * @psalm-param class-string $className
70385 * @psalm-param non-empty-string $methodName
70386 */
70387 public function shouldCodeCoverageBeCollectedFor(string $className, string $methodName): bool
70388 {
70389 $metadataForClass = Registry::parser()->forClass($className);
70390 $metadataForMethod = Registry::parser()->forMethod($className, $methodName);
70391 if ($metadataForMethod->isCoversNothing()->isNotEmpty()) {
70392 return \false;
70393 }
70394 if ($metadataForMethod->isCovers()->isNotEmpty() || $metadataForMethod->isCoversClass()->isNotEmpty() || $metadataForMethod->isCoversFunction()->isNotEmpty()) {
70395 return \true;
70396 }
70397 if ($metadataForClass->isCoversNothing()->isNotEmpty()) {
70398 return \false;
70399 }
70400 return \true;
70401 }
70402 /**
70403 * @psalm-return list<class-string>
70404 */
70405 private function testCaseClassesIn(TestSuite $testSuite): array
70406 {
70407 $classNames = [];
70408 foreach (new RecursiveIteratorIterator($testSuite) as $test) {
70409 $classNames[] = $test::class;
70410 }
70411 return array_values(array_unique($classNames));
70412 }
70413 /**
70414 * @psalm-param class-string $className
70415 */
70416 private function codeUnitsIgnoredBy(string $className): CodeUnitCollection
70417 {
70418 $codeUnits = CodeUnitCollection::fromList();
70419 $mapper = new Mapper();
70420 foreach (Registry::parser()->forClass($className) as $metadata) {
70421 if ($metadata instanceof IgnoreClassForCodeCoverage) {
70422 $codeUnits = $codeUnits->mergeWith($mapper->stringToCodeUnits($metadata->className()));
70423 }
70424 if ($metadata instanceof IgnoreMethodForCodeCoverage) {
70425 $codeUnits = $codeUnits->mergeWith($mapper->stringToCodeUnits($metadata->className() . '::' . $metadata->methodName()));
70426 }
70427 if ($metadata instanceof IgnoreFunctionForCodeCoverage) {
70428 $codeUnits = $codeUnits->mergeWith($mapper->stringToCodeUnits('::' . $metadata->functionName()));
70429 }
70430 }
70431 return $codeUnits;
70432 }
70433 /**
70434 * @throws InvalidCoversTargetException
70435 */
70436 private function mapToCodeUnits(CoversClass|CoversFunction|UsesClass|UsesFunction $metadata): CodeUnitCollection
70437 {
70438 $mapper = new Mapper();
70439 try {
70440 return $mapper->stringToCodeUnits($metadata->asStringForCodeUnitMapper());
70441 } catch (CodeUnitException $e) {
70442 if ($metadata->isCoversClass() || $metadata->isUsesClass()) {
70443 if (interface_exists($metadata->className())) {
70444 $type = 'Interface';
70445 } else {
70446 $type = 'Class';
70447 }
70448 } else {
70449 $type = 'Function';
70450 }
70451 throw new InvalidCoversTargetException(sprintf('%s "%s" is not a valid target for code coverage', $type, $metadata->asStringForCodeUnitMapper()), $e->getCode(), $e);
70452 }
70453 }
70454 }
70455 <?php
70456
70457 declare (strict_types=1);
70458 /*
70459 * This file is part of PHPUnit.
70460 *
70461 * (c) Sebastian Bergmann <sebastian@phpunit.de>
70462 *
70463 * For the full copyright and license information, please view the LICENSE
70464 * file that was distributed with this source code.
70465 */
70466 namespace PHPUnit\Metadata\Api;
70467
70468 use const JSON_ERROR_NONE;
70469 use const PREG_OFFSET_CAPTURE;
70470 use function array_key_exists;
70471 use function assert;
70472 use function explode;
70473 use function get_debug_type;
70474 use function is_array;
70475 use function is_int;
70476 use function is_string;
70477 use function json_decode;
70478 use function json_last_error;
70479 use function json_last_error_msg;
70480 use function preg_match;
70481 use function preg_replace;
70482 use function rtrim;
70483 use function sprintf;
70484 use function str_replace;
70485 use function strlen;
70486 use function substr;
70487 use function trim;
70488 use PHPUnit\Event;
70489 use PHPUnit\Event\Code\TestMethod;
70490 use PHPUnit\Event\TestData\MoreThanOneDataSetFromDataProviderException;
70491 use PHPUnit\Event\TestData\TestDataCollection;
70492 use PHPUnit\Framework\InvalidDataProviderException;
70493 use PHPUnit\Metadata\DataProvider as DataProviderMetadata;
70494 use PHPUnit\Metadata\MetadataCollection;
70495 use PHPUnit\Metadata\Parser\Registry as MetadataRegistry;
70496 use PHPUnit\Metadata\TestWith;
70497 use PHPUnit\Util\Reflection;
70498 use PHPUnit\Util\Test;
70499 use ReflectionClass;
70500 use ReflectionMethod;
70501 use Throwable;
70502 /**
70503 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
70504 *
70505 * @internal This class is not covered by the backward compatibility promise for PHPUnit
70506 */
70507 final class DataProvider
70508 {
70509 /**
70510 * @psalm-param class-string $className
70511 * @psalm-param non-empty-string $methodName
70512 *
70513 * @throws InvalidDataProviderException
70514 */
70515 public function providedData(string $className, string $methodName): ?array
70516 {
70517 $dataProvider = MetadataRegistry::parser()->forMethod($className, $methodName)->isDataProvider();
70518 $testWith = MetadataRegistry::parser()->forMethod($className, $methodName)->isTestWith();
70519 if ($dataProvider->isEmpty() && $testWith->isEmpty()) {
70520 return $this->dataProvidedByTestWithAnnotation($className, $methodName);
70521 }
70522 if ($dataProvider->isNotEmpty()) {
70523 $data = $this->dataProvidedByMethods($className, $methodName, $dataProvider);
70524 } else {
70525 $data = $this->dataProvidedByMetadata($testWith);
70526 }
70527 if ($data === []) {
70528 throw new InvalidDataProviderException('Empty data set provided by data provider');
70529 }
70530 foreach ($data as $key => $value) {
70531 if (!is_array($value)) {
70532 throw new InvalidDataProviderException(sprintf('Data set %s is invalid', is_int($key) ? '#' . $key : '"' . $key . '"'));
70533 }
70534 }
70535 return $data;
70536 }
70537 /**
70538 * @psalm-param class-string $className
70539 * @psalm-param non-empty-string $methodName
70540 *
70541 * @throws InvalidDataProviderException
70542 */
70543 private function dataProvidedByMethods(string $className, string $methodName, MetadataCollection $dataProvider): array
70544 {
70545 $testMethod = new Event\Code\ClassMethod($className, $methodName);
70546 $methodsCalled = [];
70547 $result = [];
70548 foreach ($dataProvider as $_dataProvider) {
70549 assert($_dataProvider instanceof DataProviderMetadata);
70550 $dataProviderMethod = new Event\Code\ClassMethod($_dataProvider->className(), $_dataProvider->methodName());
70551 Event\Facade::emitter()->dataProviderMethodCalled($testMethod, $dataProviderMethod);
70552 $methodsCalled[] = $dataProviderMethod;
70553 try {
70554 $class = new ReflectionClass($_dataProvider->className());
70555 $method = $class->getMethod($_dataProvider->methodName());
70556 if (Test::isTestMethod($method)) {
70557 Event\Facade::emitter()->testRunnerTriggeredPhpunitWarning(sprintf('Method %s::%s() used by test method %s::%s() is also a test method', $_dataProvider->className(), $_dataProvider->methodName(), $className, $methodName));
70558 }
70559 $object = null;
70560 if (!$method->isPublic()) {
70561 Event\Facade::emitter()->testTriggeredPhpunitDeprecation($this->valueObjectForTestMethodWithoutTestData($className, $methodName), sprintf('Data Provider method %s::%s() is not public', $_dataProvider->className(), $_dataProvider->methodName()));
70562 }
70563 if (!$method->isStatic()) {
70564 Event\Facade::emitter()->testTriggeredPhpunitDeprecation($this->valueObjectForTestMethodWithoutTestData($className, $methodName), sprintf('Data Provider method %s::%s() is not static', $_dataProvider->className(), $_dataProvider->methodName()));
70565 $object = $class->newInstanceWithoutConstructor();
70566 }
70567 if ($method->getNumberOfParameters() === 0) {
70568 $data = $method->invoke($object);
70569 } else {
70570 Event\Facade::emitter()->testTriggeredPhpunitDeprecation($this->valueObjectForTestMethodWithoutTestData($className, $methodName), sprintf('Data Provider method %s::%s() expects an argument', $_dataProvider->className(), $_dataProvider->methodName()));
70571 $data = $method->invoke($object, $_dataProvider->methodName());
70572 }
70573 } catch (Throwable $e) {
70574 Event\Facade::emitter()->dataProviderMethodFinished($testMethod, ...$methodsCalled);
70575 throw new InvalidDataProviderException($e->getMessage(), $e->getCode(), $e);
70576 }
70577 foreach ($data as $key => $value) {
70578 if (is_int($key)) {
70579 $result[] = $value;
70580 } elseif (is_string($key)) {
70581 if (array_key_exists($key, $result)) {
70582 Event\Facade::emitter()->dataProviderMethodFinished($testMethod, ...$methodsCalled);
70583 throw new InvalidDataProviderException(sprintf('The key "%s" has already been defined by a previous data provider', $key));
70584 }
70585 $result[$key] = $value;
70586 } else {
70587 throw new InvalidDataProviderException(sprintf('The key must be an integer or a string, %s given', get_debug_type($key)));
70588 }
70589 }
70590 }
70591 Event\Facade::emitter()->dataProviderMethodFinished($testMethod, ...$methodsCalled);
70592 return $result;
70593 }
70594 private function dataProvidedByMetadata(MetadataCollection $testWith): array
70595 {
70596 $result = [];
70597 foreach ($testWith as $_testWith) {
70598 assert($_testWith instanceof TestWith);
70599 $result[] = $_testWith->data();
70600 }
70601 return $result;
70602 }
70603 /**
70604 * @psalm-param class-string $className
70605 *
70606 * @throws InvalidDataProviderException
70607 */
70608 private function dataProvidedByTestWithAnnotation(string $className, string $methodName): ?array
70609 {
70610 $docComment = (new ReflectionMethod($className, $methodName))->getDocComment();
70611 if ($docComment === \false) {
70612 return null;
70613 }
70614 $docComment = str_replace("\r\n", "\n", $docComment);
70615 $docComment = preg_replace('/\n\s*\*\s?/', "\n", $docComment);
70616 $docComment = substr($docComment, 0, -1);
70617 $docComment = rtrim($docComment, "\n");
70618 if (!preg_match('/@testWith\s+/', $docComment, $matches, PREG_OFFSET_CAPTURE)) {
70619 return null;
70620 }
70621 $offset = strlen($matches[0][0]) + (int) $matches[0][1];
70622 $annotationContent = substr($docComment, $offset);
70623 $data = [];
70624 foreach (explode("\n", $annotationContent) as $candidateRow) {
70625 $candidateRow = trim($candidateRow);
70626 if ($candidateRow === '' || $candidateRow[0] !== '[') {
70627 break;
70628 }
70629 $dataSet = json_decode($candidateRow, \true);
70630 if (json_last_error() !== JSON_ERROR_NONE) {
70631 throw new InvalidDataProviderException('The data set for the @testWith annotation cannot be parsed: ' . json_last_error_msg());
70632 }
70633 $data[] = $dataSet;
70634 }
70635 if (!$data) {
70636 throw new InvalidDataProviderException('The data set for the @testWith annotation cannot be parsed.');
70637 }
70638 return $data;
70639 }
70640 /**
70641 * @psalm-param class-string $className
70642 * @psalm-param non-empty-string $methodName
70643 *
70644 * @throws MoreThanOneDataSetFromDataProviderException
70645 */
70646 private function valueObjectForTestMethodWithoutTestData(string $className, string $methodName): TestMethod
70647 {
70648 $location = Reflection::sourceLocationFor($className, $methodName);
70649 return new TestMethod($className, $methodName, $location['file'], $location['line'], Event\Code\TestDoxBuilder::fromClassNameAndMethodName($className, $methodName), MetadataRegistry::parser()->forClassAndMethod($className, $methodName), TestDataCollection::fromArray([]));
70650 }
70651 }
70652 <?php
70653
70654 declare (strict_types=1);
70655 /*
70656 * This file is part of PHPUnit.
70657 *
70658 * (c) Sebastian Bergmann <sebastian@phpunit.de>
70659 *
70660 * For the full copyright and license information, please view the LICENSE
70661 * file that was distributed with this source code.
70662 */
70663 namespace PHPUnit\Metadata\Api;
70664
70665 use function assert;
70666 use PHPUnit\Framework\ExecutionOrderDependency;
70667 use PHPUnit\Metadata\DependsOnClass;
70668 use PHPUnit\Metadata\DependsOnMethod;
70669 use PHPUnit\Metadata\Parser\Registry;
70670 /**
70671 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
70672 *
70673 * @internal This class is not covered by the backward compatibility promise for PHPUnit
70674 */
70675 final class Dependencies
70676 {
70677 /**
70678 * @psalm-param class-string $className
70679 * @psalm-param non-empty-string $methodName
70680 *
70681 * @psalm-return list<ExecutionOrderDependency>
70682 */
70683 public static function dependencies(string $className, string $methodName): array
70684 {
70685 $dependencies = [];
70686 foreach (Registry::parser()->forClassAndMethod($className, $methodName)->isDepends() as $metadata) {
70687 if ($metadata->isDependsOnClass()) {
70688 assert($metadata instanceof DependsOnClass);
70689 $dependencies[] = ExecutionOrderDependency::forClass($metadata);
70690 continue;
70691 }
70692 assert($metadata instanceof DependsOnMethod);
70693 if (empty($metadata->methodName())) {
70694 $dependencies[] = ExecutionOrderDependency::invalid();
70695 continue;
70696 }
70697 $dependencies[] = ExecutionOrderDependency::forMethod($metadata);
70698 }
70699 return $dependencies;
70700 }
70701 }
70702 <?php
70703
70704 declare (strict_types=1);
70705 /*
70706 * This file is part of PHPUnit.
70707 *
70708 * (c) Sebastian Bergmann <sebastian@phpunit.de>
70709 *
70710 * For the full copyright and license information, please view the LICENSE
70711 * file that was distributed with this source code.
70712 */
70713 namespace PHPUnit\Metadata\Api;
70714
70715 use function array_flip;
70716 use function array_key_exists;
70717 use function array_unique;
70718 use function assert;
70719 use function strtolower;
70720 use function trim;
70721 use PHPUnit\Framework\TestSize\TestSize;
70722 use PHPUnit\Metadata\Covers;
70723 use PHPUnit\Metadata\CoversClass;
70724 use PHPUnit\Metadata\CoversFunction;
70725 use PHPUnit\Metadata\Group;
70726 use PHPUnit\Metadata\Parser\Registry;
70727 use PHPUnit\Metadata\Uses;
70728 use PHPUnit\Metadata\UsesClass;
70729 use PHPUnit\Metadata\UsesFunction;
70730 /**
70731 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
70732 *
70733 * @internal This class is not covered by the backward compatibility promise for PHPUnit
70734 */
70735 final class Groups
70736 {
70737 /**
70738 * @var array<string, array<int, string>>
70739 */
70740 private static array $groupCache = [];
70741 /**
70742 * @psalm-param class-string $className
70743 * @psalm-param non-empty-string $methodName
70744 *
70745 * @psalm-return array<int, string>
70746 */
70747 public function groups(string $className, string $methodName, bool $includeVirtual = \true): array
70748 {
70749 $key = $className . '::' . $methodName . '::' . $includeVirtual;
70750 if (array_key_exists($key, self::$groupCache)) {
70751 return self::$groupCache[$key];
70752 }
70753 $groups = [];
70754 foreach (Registry::parser()->forClassAndMethod($className, $methodName)->isGroup() as $group) {
70755 assert($group instanceof Group);
70756 $groups[] = $group->groupName();
70757 }
70758 if ($groups === []) {
70759 $groups[] = 'default';
70760 }
70761 if (!$includeVirtual) {
70762 return self::$groupCache[$key] = array_unique($groups);
70763 }
70764 foreach (Registry::parser()->forClassAndMethod($className, $methodName) as $metadata) {
70765 if ($metadata->isCoversClass() || $metadata->isCoversFunction()) {
70766 assert($metadata instanceof CoversClass || $metadata instanceof CoversFunction);
70767 $groups[] = '__phpunit_covers_' . $this->canonicalizeName($metadata->asStringForCodeUnitMapper());
70768 continue;
70769 }
70770 if ($metadata->isCovers()) {
70771 assert($metadata instanceof Covers);
70772 $groups[] = '__phpunit_covers_' . $this->canonicalizeName($metadata->target());
70773 continue;
70774 }
70775 if ($metadata->isUsesClass() || $metadata->isUsesFunction()) {
70776 assert($metadata instanceof UsesClass || $metadata instanceof UsesFunction);
70777 $groups[] = '__phpunit_uses_' . $this->canonicalizeName($metadata->asStringForCodeUnitMapper());
70778 continue;
70779 }
70780 if ($metadata->isUses()) {
70781 assert($metadata instanceof Uses);
70782 $groups[] = '__phpunit_uses_' . $this->canonicalizeName($metadata->target());
70783 }
70784 }
70785 return self::$groupCache[$key] = array_unique($groups);
70786 }
70787 /**
70788 * @psalm-param class-string $className
70789 * @psalm-param non-empty-string $methodName
70790 */
70791 public function size(string $className, string $methodName): TestSize
70792 {
70793 $groups = array_flip($this->groups($className, $methodName));
70794 if (isset($groups['large'])) {
70795 return TestSize::large();
70796 }
70797 if (isset($groups['medium'])) {
70798 return TestSize::medium();
70799 }
70800 if (isset($groups['small'])) {
70801 return TestSize::small();
70802 }
70803 return TestSize::unknown();
70804 }
70805 private function canonicalizeName(string $name): string
70806 {
70807 return strtolower(trim($name, '\\'));
70808 }
70809 }
70810 <?php
70811
70812 declare (strict_types=1);
70813 /*
70814 * This file is part of PHPUnit.
70815 *
70816 * (c) Sebastian Bergmann <sebastian@phpunit.de>
70817 *
70818 * For the full copyright and license information, please view the LICENSE
70819 * file that was distributed with this source code.
70820 */
70821 namespace PHPUnit\Metadata\Api;
70822
70823 use function array_unshift;
70824 use function assert;
70825 use function class_exists;
70826 use PHPUnit\Metadata\Parser\Registry;
70827 use PHPUnit\Util\Reflection;
70828 use ReflectionClass;
70829 /**
70830 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
70831 *
70832 * @internal This class is not covered by the backward compatibility promise for PHPUnit
70833 */
70834 final class HookMethods
70835 {
70836 /**
70837 * @psalm-var array<class-string, array{beforeClass: list<non-empty-string>, before: list<non-empty-string>, preCondition: list<non-empty-string>, postCondition: list<non-empty-string>, after: list<non-empty-string>, afterClass: list<non-empty-string>}>
70838 */
70839 private static array $hookMethods = [];
70840 /**
70841 * @psalm-param class-string $className
70842 *
70843 * @psalm-return array{beforeClass: list<non-empty-string>, before: list<non-empty-string>, preCondition: list<non-empty-string>, postCondition: list<non-empty-string>, after: list<non-empty-string>, afterClass: list<non-empty-string>}
70844 */
70845 public function hookMethods(string $className): array
70846 {
70847 if (!class_exists($className)) {
70848 return self::emptyHookMethodsArray();
70849 }
70850 if (isset(self::$hookMethods[$className])) {
70851 return self::$hookMethods[$className];
70852 }
70853 self::$hookMethods[$className] = self::emptyHookMethodsArray();
70854 foreach (Reflection::methodsInTestClass(new ReflectionClass($className)) as $method) {
70855 $methodName = $method->getName();
70856 assert(!empty($methodName));
70857 $metadata = Registry::parser()->forMethod($className, $methodName);
70858 if ($method->isStatic()) {
70859 if ($metadata->isBeforeClass()->isNotEmpty()) {
70860 array_unshift(self::$hookMethods[$className]['beforeClass'], $methodName);
70861 }
70862 if ($metadata->isAfterClass()->isNotEmpty()) {
70863 self::$hookMethods[$className]['afterClass'][] = $methodName;
70864 }
70865 }
70866 if ($metadata->isBefore()->isNotEmpty()) {
70867 array_unshift(self::$hookMethods[$className]['before'], $methodName);
70868 }
70869 if ($metadata->isPreCondition()->isNotEmpty()) {
70870 array_unshift(self::$hookMethods[$className]['preCondition'], $methodName);
70871 }
70872 if ($metadata->isPostCondition()->isNotEmpty()) {
70873 self::$hookMethods[$className]['postCondition'][] = $methodName;
70874 }
70875 if ($metadata->isAfter()->isNotEmpty()) {
70876 self::$hookMethods[$className]['after'][] = $methodName;
70877 }
70878 }
70879 return self::$hookMethods[$className];
70880 }
70881 /**
70882 * @psalm-return array{beforeClass: list<non-empty-string>, before: list<non-empty-string>, preCondition: list<non-empty-string>, postCondition: list<non-empty-string>, after: list<non-empty-string>, afterClass: list<non-empty-string>}
70883 */
70884 private function emptyHookMethodsArray(): array
70885 {
70886 return ['beforeClass' => ['setUpBeforeClass'], 'before' => ['setUp'], 'preCondition' => ['assertPreConditions'], 'postCondition' => ['assertPostConditions'], 'after' => ['tearDown'], 'afterClass' => ['tearDownAfterClass']];
70887 }
70888 }
70889 <?php
70890
70891 declare (strict_types=1);
70892 /*
70893 * This file is part of PHPUnit.
70894 *
70895 * (c) Sebastian Bergmann <sebastian@phpunit.de>
70896 *
70897 * For the full copyright and license information, please view the LICENSE
70898 * file that was distributed with this source code.
70899 */
70900 namespace PHPUnit\Metadata\Api;
70901
70902 use const PHP_OS;
70903 use const PHP_OS_FAMILY;
70904 use const PHP_VERSION;
70905 use function addcslashes;
70906 use function assert;
70907 use function extension_loaded;
70908 use function function_exists;
70909 use function ini_get;
70910 use function method_exists;
70911 use function phpversion;
70912 use function preg_match;
70913 use function sprintf;
70914 use PHPUnit\Metadata\Parser\Registry;
70915 use PHPUnit\Metadata\RequiresFunction;
70916 use PHPUnit\Metadata\RequiresMethod;
70917 use PHPUnit\Metadata\RequiresOperatingSystem;
70918 use PHPUnit\Metadata\RequiresOperatingSystemFamily;
70919 use PHPUnit\Metadata\RequiresPhp;
70920 use PHPUnit\Metadata\RequiresPhpExtension;
70921 use PHPUnit\Metadata\RequiresPhpunit;
70922 use PHPUnit\Metadata\RequiresSetting;
70923 use PHPUnit\Runner\Version;
70924 /**
70925 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
70926 *
70927 * @internal This class is not covered by the backward compatibility promise for PHPUnit
70928 */
70929 final class Requirements
70930 {
70931 /**
70932 * @psalm-param class-string $className
70933 * @psalm-param non-empty-string $methodName
70934 *
70935 * @psalm-return list<string>
70936 */
70937 public function requirementsNotSatisfiedFor(string $className, string $methodName): array
70938 {
70939 $notSatisfied = [];
70940 foreach (Registry::parser()->forClassAndMethod($className, $methodName) as $metadata) {
70941 if ($metadata->isRequiresPhp()) {
70942 assert($metadata instanceof RequiresPhp);
70943 if (!$metadata->versionRequirement()->isSatisfiedBy(PHP_VERSION)) {
70944 $notSatisfied[] = sprintf('PHP %s is required.', $metadata->versionRequirement()->asString());
70945 }
70946 }
70947 if ($metadata->isRequiresPhpExtension()) {
70948 assert($metadata instanceof RequiresPhpExtension);
70949 if (!extension_loaded($metadata->extension()) || $metadata->hasVersionRequirement() && !$metadata->versionRequirement()->isSatisfiedBy(phpversion($metadata->extension()))) {
70950 $notSatisfied[] = sprintf('PHP extension %s%s is required.', $metadata->extension(), $metadata->hasVersionRequirement() ? ' ' . $metadata->versionRequirement()->asString() : '');
70951 }
70952 }
70953 if ($metadata->isRequiresPhpunit()) {
70954 assert($metadata instanceof RequiresPhpunit);
70955 if (!$metadata->versionRequirement()->isSatisfiedBy(Version::id())) {
70956 $notSatisfied[] = sprintf('PHPUnit %s is required.', $metadata->versionRequirement()->asString());
70957 }
70958 }
70959 if ($metadata->isRequiresOperatingSystemFamily()) {
70960 assert($metadata instanceof RequiresOperatingSystemFamily);
70961 if ($metadata->operatingSystemFamily() !== PHP_OS_FAMILY) {
70962 $notSatisfied[] = sprintf('Operating system %s is required.', $metadata->operatingSystemFamily());
70963 }
70964 }
70965 if ($metadata->isRequiresOperatingSystem()) {
70966 assert($metadata instanceof RequiresOperatingSystem);
70967 $pattern = sprintf('/%s/i', addcslashes($metadata->operatingSystem(), '/'));
70968 if (!preg_match($pattern, PHP_OS)) {
70969 $notSatisfied[] = sprintf('Operating system %s is required.', $metadata->operatingSystem());
70970 }
70971 }
70972 if ($metadata->isRequiresFunction()) {
70973 assert($metadata instanceof RequiresFunction);
70974 if (!function_exists($metadata->functionName())) {
70975 $notSatisfied[] = sprintf('Function %s() is required.', $metadata->functionName());
70976 }
70977 }
70978 if ($metadata->isRequiresMethod()) {
70979 assert($metadata instanceof RequiresMethod);
70980 if (!method_exists($metadata->className(), $metadata->methodName())) {
70981 $notSatisfied[] = sprintf('Method %s::%s() is required.', $metadata->className(), $metadata->methodName());
70982 }
70983 }
70984 if ($metadata->isRequiresSetting()) {
70985 assert($metadata instanceof RequiresSetting);
70986 if (ini_get($metadata->setting()) !== $metadata->value()) {
70987 $notSatisfied[] = sprintf('Setting "%s" is required to be "%s".', $metadata->setting(), $metadata->value());
70988 }
70989 }
70990 }
70991 return $notSatisfied;
70992 }
70993 }
70994 <?php
70995
70996 declare (strict_types=1);
70997 /*
70998 * This file is part of PHPUnit.
70999 *
71000 * (c) Sebastian Bergmann <sebastian@phpunit.de>
71001 *
71002 * For the full copyright and license information, please view the LICENSE
71003 * file that was distributed with this source code.
71004 */
71005 namespace PHPUnit\Metadata;
71006
71007 /**
71008 * @psalm-immutable
71009 *
71010 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
71011 */
71012 final class BackupGlobals extends \PHPUnit\Metadata\Metadata
71013 {
71014 private readonly bool $enabled;
71015 /**
71016 * @psalm-param 0|1 $level
71017 */
71018 protected function __construct(int $level, bool $enabled)
71019 {
71020 parent::__construct($level);
71021 $this->enabled = $enabled;
71022 }
71023 /**
71024 * @psalm-assert-if-true BackupGlobals $this
71025 */
71026 public function isBackupGlobals(): bool
71027 {
71028 return \true;
71029 }
71030 public function enabled(): bool
71031 {
71032 return $this->enabled;
71033 }
71034 }
71035 <?php
71036
71037 declare (strict_types=1);
71038 /*
71039 * This file is part of PHPUnit.
71040 *
71041 * (c) Sebastian Bergmann <sebastian@phpunit.de>
71042 *
71043 * For the full copyright and license information, please view the LICENSE
71044 * file that was distributed with this source code.
71045 */
71046 namespace PHPUnit\Metadata;
71047
71048 /**
71049 * @psalm-immutable
71050 *
71051 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
71052 */
71053 final class BackupStaticProperties extends \PHPUnit\Metadata\Metadata
71054 {
71055 private readonly bool $enabled;
71056 /**
71057 * @psalm-param 0|1 $level
71058 */
71059 protected function __construct(int $level, bool $enabled)
71060 {
71061 parent::__construct($level);
71062 $this->enabled = $enabled;
71063 }
71064 /**
71065 * @psalm-assert-if-true BackupStaticProperties $this
71066 */
71067 public function isBackupStaticProperties(): bool
71068 {
71069 return \true;
71070 }
71071 public function enabled(): bool
71072 {
71073 return $this->enabled;
71074 }
71075 }
71076 <?php
71077
71078 declare (strict_types=1);
71079 /*
71080 * This file is part of PHPUnit.
71081 *
71082 * (c) Sebastian Bergmann <sebastian@phpunit.de>
71083 *
71084 * For the full copyright and license information, please view the LICENSE
71085 * file that was distributed with this source code.
71086 */
71087 namespace PHPUnit\Metadata;
71088
71089 /**
71090 * @psalm-immutable
71091 *
71092 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
71093 */
71094 final class Before extends \PHPUnit\Metadata\Metadata
71095 {
71096 /**
71097 * @psalm-assert-if-true Before $this
71098 */
71099 public function isBefore(): bool
71100 {
71101 return \true;
71102 }
71103 }
71104 <?php
71105
71106 declare (strict_types=1);
71107 /*
71108 * This file is part of PHPUnit.
71109 *
71110 * (c) Sebastian Bergmann <sebastian@phpunit.de>
71111 *
71112 * For the full copyright and license information, please view the LICENSE
71113 * file that was distributed with this source code.
71114 */
71115 namespace PHPUnit\Metadata;
71116
71117 /**
71118 * @psalm-immutable
71119 *
71120 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
71121 */
71122 final class BeforeClass extends \PHPUnit\Metadata\Metadata
71123 {
71124 /**
71125 * @psalm-assert-if-true BeforeClass $this
71126 */
71127 public function isBeforeClass(): bool
71128 {
71129 return \true;
71130 }
71131 }
71132 <?php
71133
71134 declare (strict_types=1);
71135 /*
71136 * This file is part of PHPUnit.
71137 *
71138 * (c) Sebastian Bergmann <sebastian@phpunit.de>
71139 *
71140 * For the full copyright and license information, please view the LICENSE
71141 * file that was distributed with this source code.
71142 */
71143 namespace PHPUnit\Metadata;
71144
71145 /**
71146 * @psalm-immutable
71147 *
71148 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
71149 */
71150 final class Covers extends \PHPUnit\Metadata\Metadata
71151 {
71152 /**
71153 * @psalm-var non-empty-string
71154 */
71155 private readonly string $target;
71156 /**
71157 * @psalm-param 0|1 $level
71158 * @psalm-param non-empty-string $target
71159 */
71160 protected function __construct(int $level, string $target)
71161 {
71162 parent::__construct($level);
71163 $this->target = $target;
71164 }
71165 /**
71166 * @psalm-assert-if-true Covers $this
71167 */
71168 public function isCovers(): bool
71169 {
71170 return \true;
71171 }
71172 /**
71173 * @psalm-return non-empty-string
71174 */
71175 public function target(): string
71176 {
71177 return $this->target;
71178 }
71179 }
71180 <?php
71181
71182 declare (strict_types=1);
71183 /*
71184 * This file is part of PHPUnit.
71185 *
71186 * (c) Sebastian Bergmann <sebastian@phpunit.de>
71187 *
71188 * For the full copyright and license information, please view the LICENSE
71189 * file that was distributed with this source code.
71190 */
71191 namespace PHPUnit\Metadata;
71192
71193 /**
71194 * @psalm-immutable
71195 *
71196 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
71197 */
71198 final class CoversClass extends \PHPUnit\Metadata\Metadata
71199 {
71200 /**
71201 * @psalm-var class-string
71202 */
71203 private readonly string $className;
71204 /**
71205 * @psalm-param 0|1 $level
71206 * @psalm-param class-string $className
71207 */
71208 protected function __construct(int $level, string $className)
71209 {
71210 parent::__construct($level);
71211 $this->className = $className;
71212 }
71213 /**
71214 * @psalm-assert-if-true CoversClass $this
71215 */
71216 public function isCoversClass(): bool
71217 {
71218 return \true;
71219 }
71220 /**
71221 * @psalm-return class-string
71222 */
71223 public function className(): string
71224 {
71225 return $this->className;
71226 }
71227 /**
71228 * @psalm-return class-string
71229 *
71230 * @internal This method is not covered by the backward compatibility promise for PHPUnit
71231 */
71232 public function asStringForCodeUnitMapper(): string
71233 {
71234 return $this->className;
71235 }
71236 }
71237 <?php
71238
71239 declare (strict_types=1);
71240 /*
71241 * This file is part of PHPUnit.
71242 *
71243 * (c) Sebastian Bergmann <sebastian@phpunit.de>
71244 *
71245 * For the full copyright and license information, please view the LICENSE
71246 * file that was distributed with this source code.
71247 */
71248 namespace PHPUnit\Metadata;
71249
71250 /**
71251 * @psalm-immutable
71252 *
71253 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
71254 */
71255 final class CoversDefaultClass extends \PHPUnit\Metadata\Metadata
71256 {
71257 /**
71258 * @psalm-var class-string
71259 */
71260 private readonly string $className;
71261 /**
71262 * @psalm-param 0|1 $level
71263 * @psalm-param class-string $className
71264 */
71265 protected function __construct(int $level, string $className)
71266 {
71267 parent::__construct($level);
71268 $this->className = $className;
71269 }
71270 /**
71271 * @psalm-assert-if-true CoversDefaultClass $this
71272 */
71273 public function isCoversDefaultClass(): bool
71274 {
71275 return \true;
71276 }
71277 /**
71278 * @psalm-return class-string
71279 */
71280 public function className(): string
71281 {
71282 return $this->className;
71283 }
71284 }
71285 <?php
71286
71287 declare (strict_types=1);
71288 /*
71289 * This file is part of PHPUnit.
71290 *
71291 * (c) Sebastian Bergmann <sebastian@phpunit.de>
71292 *
71293 * For the full copyright and license information, please view the LICENSE
71294 * file that was distributed with this source code.
71295 */
71296 namespace PHPUnit\Metadata;
71297
71298 /**
71299 * @psalm-immutable
71300 *
71301 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
71302 */
71303 final class CoversFunction extends \PHPUnit\Metadata\Metadata
71304 {
71305 /**
71306 * @psalm-var non-empty-string
71307 */
71308 private readonly string $functionName;
71309 /**
71310 * @psalm-param 0|1 $level
71311 * @psalm-param non-empty-string $functionName
71312 */
71313 protected function __construct(int $level, string $functionName)
71314 {
71315 parent::__construct($level);
71316 $this->functionName = $functionName;
71317 }
71318 /**
71319 * @psalm-assert-if-true CoversFunction $this
71320 */
71321 public function isCoversFunction(): bool
71322 {
71323 return \true;
71324 }
71325 /**
71326 * @psalm-return non-empty-string
71327 */
71328 public function functionName(): string
71329 {
71330 return $this->functionName;
71331 }
71332 /**
71333 * @internal This method is not covered by the backward compatibility promise for PHPUnit
71334 */
71335 public function asStringForCodeUnitMapper(): string
71336 {
71337 return '::' . $this->functionName;
71338 }
71339 }
71340 <?php
71341
71342 declare (strict_types=1);
71343 /*
71344 * This file is part of PHPUnit.
71345 *
71346 * (c) Sebastian Bergmann <sebastian@phpunit.de>
71347 *
71348 * For the full copyright and license information, please view the LICENSE
71349 * file that was distributed with this source code.
71350 */
71351 namespace PHPUnit\Metadata;
71352
71353 /**
71354 * @psalm-immutable
71355 *
71356 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
71357 */
71358 final class CoversNothing extends \PHPUnit\Metadata\Metadata
71359 {
71360 /**
71361 * @psalm-assert-if-true CoversNothing $this
71362 */
71363 public function isCoversNothing(): bool
71364 {
71365 return \true;
71366 }
71367 }
71368 <?php
71369
71370 declare (strict_types=1);
71371 /*
71372 * This file is part of PHPUnit.
71373 *
71374 * (c) Sebastian Bergmann <sebastian@phpunit.de>
71375 *
71376 * For the full copyright and license information, please view the LICENSE
71377 * file that was distributed with this source code.
71378 */
71379 namespace PHPUnit\Metadata;
71380
71381 /**
71382 * @psalm-immutable
71383 *
71384 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
71385 */
71386 final class DataProvider extends \PHPUnit\Metadata\Metadata
71387 {
71388 /**
71389 * @psalm-var class-string
71390 */
71391 private readonly string $className;
71392 /**
71393 * @psalm-var non-empty-string
71394 */
71395 private readonly string $methodName;
71396 /**
71397 * @psalm-param 0|1 $level
71398 * @psalm-param class-string $className
71399 * @psalm-param non-empty-string $methodName
71400 */
71401 protected function __construct(int $level, string $className, string $methodName)
71402 {
71403 parent::__construct($level);
71404 $this->className = $className;
71405 $this->methodName = $methodName;
71406 }
71407 /**
71408 * @psalm-assert-if-true DataProvider $this
71409 */
71410 public function isDataProvider(): bool
71411 {
71412 return \true;
71413 }
71414 /**
71415 * @psalm-return class-string
71416 */
71417 public function className(): string
71418 {
71419 return $this->className;
71420 }
71421 /**
71422 * @psalm-return non-empty-string
71423 */
71424 public function methodName(): string
71425 {
71426 return $this->methodName;
71427 }
71428 }
71429 <?php
71430
71431 declare (strict_types=1);
71432 /*
71433 * This file is part of PHPUnit.
71434 *
71435 * (c) Sebastian Bergmann <sebastian@phpunit.de>
71436 *
71437 * For the full copyright and license information, please view the LICENSE
71438 * file that was distributed with this source code.
71439 */
71440 namespace PHPUnit\Metadata;
71441
71442 /**
71443 * @psalm-immutable
71444 *
71445 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
71446 */
71447 final class DependsOnClass extends \PHPUnit\Metadata\Metadata
71448 {
71449 /**
71450 * @psalm-var class-string
71451 */
71452 private readonly string $className;
71453 private readonly bool $deepClone;
71454 private readonly bool $shallowClone;
71455 /**
71456 * @psalm-param 0|1 $level
71457 * @psalm-param class-string $className
71458 */
71459 protected function __construct(int $level, string $className, bool $deepClone, bool $shallowClone)
71460 {
71461 parent::__construct($level);
71462 $this->className = $className;
71463 $this->deepClone = $deepClone;
71464 $this->shallowClone = $shallowClone;
71465 }
71466 /**
71467 * @psalm-assert-if-true DependsOnClass $this
71468 */
71469 public function isDependsOnClass(): bool
71470 {
71471 return \true;
71472 }
71473 /**
71474 * @psalm-return class-string
71475 */
71476 public function className(): string
71477 {
71478 return $this->className;
71479 }
71480 public function deepClone(): bool
71481 {
71482 return $this->deepClone;
71483 }
71484 public function shallowClone(): bool
71485 {
71486 return $this->shallowClone;
71487 }
71488 }
71489 <?php
71490
71491 declare (strict_types=1);
71492 /*
71493 * This file is part of PHPUnit.
71494 *
71495 * (c) Sebastian Bergmann <sebastian@phpunit.de>
71496 *
71497 * For the full copyright and license information, please view the LICENSE
71498 * file that was distributed with this source code.
71499 */
71500 namespace PHPUnit\Metadata;
71501
71502 /**
71503 * @psalm-immutable
71504 *
71505 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
71506 */
71507 final class DependsOnMethod extends \PHPUnit\Metadata\Metadata
71508 {
71509 /**
71510 * @psalm-var class-string
71511 */
71512 private readonly string $className;
71513 /**
71514 * @psalm-var non-empty-string
71515 */
71516 private readonly string $methodName;
71517 private readonly bool $deepClone;
71518 private readonly bool $shallowClone;
71519 /**
71520 * @psalm-param 0|1 $level
71521 * @psalm-param class-string $className
71522 * @psalm-param non-empty-string $methodName
71523 */
71524 protected function __construct(int $level, string $className, string $methodName, bool $deepClone, bool $shallowClone)
71525 {
71526 parent::__construct($level);
71527 $this->className = $className;
71528 $this->methodName = $methodName;
71529 $this->deepClone = $deepClone;
71530 $this->shallowClone = $shallowClone;
71531 }
71532 /**
71533 * @psalm-assert-if-true DependsOnMethod $this
71534 */
71535 public function isDependsOnMethod(): bool
71536 {
71537 return \true;
71538 }
71539 /**
71540 * @psalm-return class-string
71541 */
71542 public function className(): string
71543 {
71544 return $this->className;
71545 }
71546 /**
71547 * @psalm-return non-empty-string
71548 */
71549 public function methodName(): string
71550 {
71551 return $this->methodName;
71552 }
71553 public function deepClone(): bool
71554 {
71555 return $this->deepClone;
71556 }
71557 public function shallowClone(): bool
71558 {
71559 return $this->shallowClone;
71560 }
71561 }
71562 <?php
71563
71564 declare (strict_types=1);
71565 /*
71566 * This file is part of PHPUnit.
71567 *
71568 * (c) Sebastian Bergmann <sebastian@phpunit.de>
71569 *
71570 * For the full copyright and license information, please view the LICENSE
71571 * file that was distributed with this source code.
71572 */
71573 namespace PHPUnit\Metadata;
71574
71575 /**
71576 * @psalm-immutable
71577 *
71578 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
71579 */
71580 final class DoesNotPerformAssertions extends \PHPUnit\Metadata\Metadata
71581 {
71582 /**
71583 * @psalm-assert-if-true DoesNotPerformAssertions $this
71584 */
71585 public function isDoesNotPerformAssertions(): bool
71586 {
71587 return \true;
71588 }
71589 }
71590 <?php
71591
71592 declare (strict_types=1);
71593 /*
71594 * This file is part of PHPUnit.
71595 *
71596 * (c) Sebastian Bergmann <sebastian@phpunit.de>
71597 *
71598 * For the full copyright and license information, please view the LICENSE
71599 * file that was distributed with this source code.
71600 */
71601 namespace PHPUnit\Metadata;
71602
71603 use function sprintf;
71604 use PHPUnit\Exception;
71605 use RuntimeException;
71606 /**
71607 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
71608 *
71609 * @internal This class is not covered by the backward compatibility promise for PHPUnit
71610 */
71611 final class AnnotationsAreNotSupportedForInternalClassesException extends RuntimeException implements Exception
71612 {
71613 /**
71614 * @psalm-param class-string $className
71615 */
71616 public function __construct(string $className)
71617 {
71618 parent::__construct(sprintf('Annotations can only be parsed for user-defined classes, trying to parse annotations for class "%s"', $className));
71619 }
71620 }
71621 <?php
71622
71623 declare (strict_types=1);
71624 /*
71625 * This file is part of PHPUnit.
71626 *
71627 * (c) Sebastian Bergmann <sebastian@phpunit.de>
71628 *
71629 * For the full copyright and license information, please view the LICENSE
71630 * file that was distributed with this source code.
71631 */
71632 namespace PHPUnit\Metadata;
71633
71634 interface Exception extends \PHPUnit\Exception
71635 {
71636 }
71637 <?php
71638
71639 declare (strict_types=1);
71640 /*
71641 * This file is part of PHPUnit.
71642 *
71643 * (c) Sebastian Bergmann <sebastian@phpunit.de>
71644 *
71645 * For the full copyright and license information, please view the LICENSE
71646 * file that was distributed with this source code.
71647 */
71648 namespace PHPUnit\Metadata;
71649
71650 use const PHP_EOL;
71651 use function sprintf;
71652 use PHPUnit\Exception;
71653 use RuntimeException;
71654 /**
71655 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
71656 *
71657 * @internal This class is not covered by the backward compatibility promise for PHPUnit
71658 */
71659 final class InvalidAttributeException extends RuntimeException implements Exception
71660 {
71661 /**
71662 * @param non-empty-string $attributeName
71663 * @param non-empty-string $target
71664 * @param non-empty-string $file
71665 * @param positive-int $line
71666 * @param non-empty-string $message
71667 */
71668 public function __construct(string $attributeName, string $target, string $file, int $line, string $message)
71669 {
71670 parent::__construct(sprintf('Invalid attribute %s for %s in %s:%d%s%s', $attributeName, $target, $file, $line, PHP_EOL, $message));
71671 }
71672 }
71673 <?php
71674
71675 declare (strict_types=1);
71676 /*
71677 * This file is part of PHPUnit.
71678 *
71679 * (c) Sebastian Bergmann <sebastian@phpunit.de>
71680 *
71681 * For the full copyright and license information, please view the LICENSE
71682 * file that was distributed with this source code.
71683 */
71684 namespace PHPUnit\Metadata;
71685
71686 use RuntimeException;
71687 final class InvalidVersionRequirementException extends RuntimeException implements \PHPUnit\Metadata\Exception
71688 {
71689 }
71690 <?php
71691
71692 declare (strict_types=1);
71693 /*
71694 * This file is part of PHPUnit.
71695 *
71696 * (c) Sebastian Bergmann <sebastian@phpunit.de>
71697 *
71698 * For the full copyright and license information, please view the LICENSE
71699 * file that was distributed with this source code.
71700 */
71701 namespace PHPUnit\Metadata;
71702
71703 use RuntimeException;
71704 final class NoVersionRequirementException extends RuntimeException implements \PHPUnit\Metadata\Exception
71705 {
71706 }
71707 <?php
71708
71709 declare (strict_types=1);
71710 /*
71711 * This file is part of PHPUnit.
71712 *
71713 * (c) Sebastian Bergmann <sebastian@phpunit.de>
71714 *
71715 * For the full copyright and license information, please view the LICENSE
71716 * file that was distributed with this source code.
71717 */
71718 namespace PHPUnit\Metadata;
71719
71720 use PHPUnit\Exception;
71721 use RuntimeException;
71722 /**
71723 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
71724 *
71725 * @internal This class is not covered by the backward compatibility promise for PHPUnit
71726 */
71727 final class ReflectionException extends RuntimeException implements Exception
71728 {
71729 }
71730 <?php
71731
71732 declare (strict_types=1);
71733 /*
71734 * This file is part of PHPUnit.
71735 *
71736 * (c) Sebastian Bergmann <sebastian@phpunit.de>
71737 *
71738 * For the full copyright and license information, please view the LICENSE
71739 * file that was distributed with this source code.
71740 */
71741 namespace PHPUnit\Metadata;
71742
71743 /**
71744 * @psalm-immutable
71745 *
71746 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
71747 */
71748 final class ExcludeGlobalVariableFromBackup extends \PHPUnit\Metadata\Metadata
71749 {
71750 /**
71751 * @psalm-var non-empty-string
71752 */
71753 private readonly string $globalVariableName;
71754 /**
71755 * @psalm-param 0|1 $level
71756 * @psalm-param non-empty-string $globalVariableName
71757 */
71758 protected function __construct(int $level, string $globalVariableName)
71759 {
71760 parent::__construct($level);
71761 $this->globalVariableName = $globalVariableName;
71762 }
71763 /**
71764 * @psalm-assert-if-true ExcludeGlobalVariableFromBackup $this
71765 */
71766 public function isExcludeGlobalVariableFromBackup(): bool
71767 {
71768 return \true;
71769 }
71770 /**
71771 * @psalm-return non-empty-string
71772 */
71773 public function globalVariableName(): string
71774 {
71775 return $this->globalVariableName;
71776 }
71777 }
71778 <?php
71779
71780 declare (strict_types=1);
71781 /*
71782 * This file is part of PHPUnit.
71783 *
71784 * (c) Sebastian Bergmann <sebastian@phpunit.de>
71785 *
71786 * For the full copyright and license information, please view the LICENSE
71787 * file that was distributed with this source code.
71788 */
71789 namespace PHPUnit\Metadata;
71790
71791 /**
71792 * @psalm-immutable
71793 *
71794 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
71795 */
71796 final class ExcludeStaticPropertyFromBackup extends \PHPUnit\Metadata\Metadata
71797 {
71798 /**
71799 * @psalm-var class-string
71800 */
71801 private readonly string $className;
71802 /**
71803 * @psalm-var non-empty-string
71804 */
71805 private readonly string $propertyName;
71806 /**
71807 * @psalm-param 0|1 $level
71808 * @psalm-param class-string $className
71809 * @psalm-param non-empty-string $propertyName
71810 */
71811 protected function __construct(int $level, string $className, string $propertyName)
71812 {
71813 parent::__construct($level);
71814 $this->className = $className;
71815 $this->propertyName = $propertyName;
71816 }
71817 /**
71818 * @psalm-assert-if-true ExcludeStaticPropertyFromBackup $this
71819 */
71820 public function isExcludeStaticPropertyFromBackup(): bool
71821 {
71822 return \true;
71823 }
71824 /**
71825 * @psalm-return class-string
71826 */
71827 public function className(): string
71828 {
71829 return $this->className;
71830 }
71831 /**
71832 * @psalm-return non-empty-string
71833 */
71834 public function propertyName(): string
71835 {
71836 return $this->propertyName;
71837 }
71838 }
71839 <?php
71840
71841 declare (strict_types=1);
71842 /*
71843 * This file is part of PHPUnit.
71844 *
71845 * (c) Sebastian Bergmann <sebastian@phpunit.de>
71846 *
71847 * For the full copyright and license information, please view the LICENSE
71848 * file that was distributed with this source code.
71849 */
71850 namespace PHPUnit\Metadata;
71851
71852 /**
71853 * @psalm-immutable
71854 *
71855 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
71856 */
71857 final class Group extends \PHPUnit\Metadata\Metadata
71858 {
71859 /**
71860 * @psalm-var non-empty-string
71861 */
71862 private readonly string $groupName;
71863 /**
71864 * @psalm-param 0|1 $level
71865 * @psalm-param non-empty-string $groupName
71866 */
71867 protected function __construct(int $level, string $groupName)
71868 {
71869 parent::__construct($level);
71870 $this->groupName = $groupName;
71871 }
71872 /**
71873 * @psalm-assert-if-true Group $this
71874 */
71875 public function isGroup(): bool
71876 {
71877 return \true;
71878 }
71879 /**
71880 * @psalm-return non-empty-string
71881 */
71882 public function groupName(): string
71883 {
71884 return $this->groupName;
71885 }
71886 }
71887 <?php
71888
71889 declare (strict_types=1);
71890 /*
71891 * This file is part of PHPUnit.
71892 *
71893 * (c) Sebastian Bergmann <sebastian@phpunit.de>
71894 *
71895 * For the full copyright and license information, please view the LICENSE
71896 * file that was distributed with this source code.
71897 */
71898 namespace PHPUnit\Metadata;
71899
71900 /**
71901 * @psalm-immutable
71902 *
71903 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
71904 *
71905 * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5513
71906 */
71907 final class IgnoreClassForCodeCoverage extends \PHPUnit\Metadata\Metadata
71908 {
71909 /**
71910 * @psalm-var class-string
71911 */
71912 private readonly string $className;
71913 /**
71914 * @psalm-param 0|1 $level
71915 * @psalm-param class-string $className
71916 */
71917 protected function __construct(int $level, string $className)
71918 {
71919 parent::__construct($level);
71920 $this->className = $className;
71921 }
71922 /**
71923 * @psalm-assert-if-true IgnoreClassForCodeCoverage $this
71924 */
71925 public function isIgnoreClassForCodeCoverage(): bool
71926 {
71927 return \true;
71928 }
71929 /**
71930 * @psalm-return class-string
71931 */
71932 public function className(): string
71933 {
71934 return $this->className;
71935 }
71936 }
71937 <?php
71938
71939 declare (strict_types=1);
71940 /*
71941 * This file is part of PHPUnit.
71942 *
71943 * (c) Sebastian Bergmann <sebastian@phpunit.de>
71944 *
71945 * For the full copyright and license information, please view the LICENSE
71946 * file that was distributed with this source code.
71947 */
71948 namespace PHPUnit\Metadata;
71949
71950 /**
71951 * @psalm-immutable
71952 *
71953 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
71954 */
71955 final class IgnoreDeprecations extends \PHPUnit\Metadata\Metadata
71956 {
71957 /**
71958 * @psalm-assert-if-true IgnoreDeprecations $this
71959 */
71960 public function isIgnoreDeprecations(): bool
71961 {
71962 return \true;
71963 }
71964 }
71965 <?php
71966
71967 declare (strict_types=1);
71968 /*
71969 * This file is part of PHPUnit.
71970 *
71971 * (c) Sebastian Bergmann <sebastian@phpunit.de>
71972 *
71973 * For the full copyright and license information, please view the LICENSE
71974 * file that was distributed with this source code.
71975 */
71976 namespace PHPUnit\Metadata;
71977
71978 /**
71979 * @psalm-immutable
71980 *
71981 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
71982 *
71983 * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5513
71984 */
71985 final class IgnoreFunctionForCodeCoverage extends \PHPUnit\Metadata\Metadata
71986 {
71987 /**
71988 * @psalm-var non-empty-string
71989 */
71990 private readonly string $functionName;
71991 /**
71992 * @psalm-param 0|1 $level
71993 * @psalm-param non-empty-string $functionName
71994 */
71995 protected function __construct(int $level, string $functionName)
71996 {
71997 parent::__construct($level);
71998 $this->functionName = $functionName;
71999 }
72000 /**
72001 * @psalm-assert-if-true IgnoreFunctionForCodeCoverage $this
72002 */
72003 public function isIgnoreFunctionForCodeCoverage(): bool
72004 {
72005 return \true;
72006 }
72007 /**
72008 * @psalm-return non-empty-string
72009 */
72010 public function functionName(): string
72011 {
72012 return $this->functionName;
72013 }
72014 }
72015 <?php
72016
72017 declare (strict_types=1);
72018 /*
72019 * This file is part of PHPUnit.
72020 *
72021 * (c) Sebastian Bergmann <sebastian@phpunit.de>
72022 *
72023 * For the full copyright and license information, please view the LICENSE
72024 * file that was distributed with this source code.
72025 */
72026 namespace PHPUnit\Metadata;
72027
72028 /**
72029 * @psalm-immutable
72030 *
72031 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
72032 *
72033 * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5513
72034 */
72035 final class IgnoreMethodForCodeCoverage extends \PHPUnit\Metadata\Metadata
72036 {
72037 /**
72038 * @psalm-var class-string
72039 */
72040 private readonly string $className;
72041 /**
72042 * @psalm-var non-empty-string
72043 */
72044 private readonly string $methodName;
72045 /**
72046 * @psalm-param 0|1 $level
72047 * @psalm-param class-string $className
72048 * @psalm-param non-empty-string $methodName
72049 */
72050 protected function __construct(int $level, string $className, string $methodName)
72051 {
72052 parent::__construct($level);
72053 $this->className = $className;
72054 $this->methodName = $methodName;
72055 }
72056 /**
72057 * @psalm-assert-if-true IgnoreMethodForCodeCoverage $this
72058 */
72059 public function isIgnoreMethodForCodeCoverage(): bool
72060 {
72061 return \true;
72062 }
72063 /**
72064 * @psalm-return class-string
72065 */
72066 public function className(): string
72067 {
72068 return $this->className;
72069 }
72070 /**
72071 * @psalm-return non-empty-string
72072 */
72073 public function methodName(): string
72074 {
72075 return $this->methodName;
72076 }
72077 }
72078 <?php
72079
72080 declare (strict_types=1);
72081 /*
72082 * This file is part of PHPUnit.
72083 *
72084 * (c) Sebastian Bergmann <sebastian@phpunit.de>
72085 *
72086 * For the full copyright and license information, please view the LICENSE
72087 * file that was distributed with this source code.
72088 */
72089 namespace PHPUnit\Metadata;
72090
72091 use PHPUnit\Metadata\Version\Requirement;
72092 /**
72093 * @psalm-immutable
72094 *
72095 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
72096 */
72097 abstract class Metadata
72098 {
72099 private const CLASS_LEVEL = 0;
72100 private const METHOD_LEVEL = 1;
72101 /**
72102 * @psalm-var 0|1
72103 */
72104 private readonly int $level;
72105 public static function after(): \PHPUnit\Metadata\After
72106 {
72107 return new \PHPUnit\Metadata\After(self::METHOD_LEVEL);
72108 }
72109 public static function afterClass(): \PHPUnit\Metadata\AfterClass
72110 {
72111 return new \PHPUnit\Metadata\AfterClass(self::METHOD_LEVEL);
72112 }
72113 public static function backupGlobalsOnClass(bool $enabled): \PHPUnit\Metadata\BackupGlobals
72114 {
72115 return new \PHPUnit\Metadata\BackupGlobals(self::CLASS_LEVEL, $enabled);
72116 }
72117 public static function backupGlobalsOnMethod(bool $enabled): \PHPUnit\Metadata\BackupGlobals
72118 {
72119 return new \PHPUnit\Metadata\BackupGlobals(self::METHOD_LEVEL, $enabled);
72120 }
72121 public static function backupStaticPropertiesOnClass(bool $enabled): \PHPUnit\Metadata\BackupStaticProperties
72122 {
72123 return new \PHPUnit\Metadata\BackupStaticProperties(self::CLASS_LEVEL, $enabled);
72124 }
72125 public static function backupStaticPropertiesOnMethod(bool $enabled): \PHPUnit\Metadata\BackupStaticProperties
72126 {
72127 return new \PHPUnit\Metadata\BackupStaticProperties(self::METHOD_LEVEL, $enabled);
72128 }
72129 public static function before(): \PHPUnit\Metadata\Before
72130 {
72131 return new \PHPUnit\Metadata\Before(self::METHOD_LEVEL);
72132 }
72133 public static function beforeClass(): \PHPUnit\Metadata\BeforeClass
72134 {
72135 return new \PHPUnit\Metadata\BeforeClass(self::METHOD_LEVEL);
72136 }
72137 /**
72138 * @psalm-param class-string $className
72139 */
72140 public static function coversClass(string $className): \PHPUnit\Metadata\CoversClass
72141 {
72142 return new \PHPUnit\Metadata\CoversClass(self::CLASS_LEVEL, $className);
72143 }
72144 /**
72145 * @psalm-param non-empty-string $functionName
72146 */
72147 public static function coversFunction(string $functionName): \PHPUnit\Metadata\CoversFunction
72148 {
72149 return new \PHPUnit\Metadata\CoversFunction(self::CLASS_LEVEL, $functionName);
72150 }
72151 /**
72152 * @psalm-param non-empty-string $target
72153 */
72154 public static function coversOnClass(string $target): \PHPUnit\Metadata\Covers
72155 {
72156 return new \PHPUnit\Metadata\Covers(self::CLASS_LEVEL, $target);
72157 }
72158 /**
72159 * @psalm-param non-empty-string $target
72160 */
72161 public static function coversOnMethod(string $target): \PHPUnit\Metadata\Covers
72162 {
72163 return new \PHPUnit\Metadata\Covers(self::METHOD_LEVEL, $target);
72164 }
72165 /**
72166 * @psalm-param class-string $className
72167 */
72168 public static function coversDefaultClass(string $className): \PHPUnit\Metadata\CoversDefaultClass
72169 {
72170 return new \PHPUnit\Metadata\CoversDefaultClass(self::CLASS_LEVEL, $className);
72171 }
72172 public static function coversNothingOnClass(): \PHPUnit\Metadata\CoversNothing
72173 {
72174 return new \PHPUnit\Metadata\CoversNothing(self::CLASS_LEVEL);
72175 }
72176 public static function coversNothingOnMethod(): \PHPUnit\Metadata\CoversNothing
72177 {
72178 return new \PHPUnit\Metadata\CoversNothing(self::METHOD_LEVEL);
72179 }
72180 /**
72181 * @psalm-param class-string $className
72182 * @psalm-param non-empty-string $methodName
72183 */
72184 public static function dataProvider(string $className, string $methodName): \PHPUnit\Metadata\DataProvider
72185 {
72186 return new \PHPUnit\Metadata\DataProvider(self::METHOD_LEVEL, $className, $methodName);
72187 }
72188 /**
72189 * @psalm-param class-string $className
72190 */
72191 public static function dependsOnClass(string $className, bool $deepClone, bool $shallowClone): \PHPUnit\Metadata\DependsOnClass
72192 {
72193 return new \PHPUnit\Metadata\DependsOnClass(self::METHOD_LEVEL, $className, $deepClone, $shallowClone);
72194 }
72195 /**
72196 * @psalm-param class-string $className
72197 * @psalm-param non-empty-string $methodName
72198 */
72199 public static function dependsOnMethod(string $className, string $methodName, bool $deepClone, bool $shallowClone): \PHPUnit\Metadata\DependsOnMethod
72200 {
72201 return new \PHPUnit\Metadata\DependsOnMethod(self::METHOD_LEVEL, $className, $methodName, $deepClone, $shallowClone);
72202 }
72203 public static function doesNotPerformAssertionsOnClass(): \PHPUnit\Metadata\DoesNotPerformAssertions
72204 {
72205 return new \PHPUnit\Metadata\DoesNotPerformAssertions(self::CLASS_LEVEL);
72206 }
72207 public static function doesNotPerformAssertionsOnMethod(): \PHPUnit\Metadata\DoesNotPerformAssertions
72208 {
72209 return new \PHPUnit\Metadata\DoesNotPerformAssertions(self::METHOD_LEVEL);
72210 }
72211 /**
72212 * @psalm-param non-empty-string $globalVariableName
72213 */
72214 public static function excludeGlobalVariableFromBackupOnClass(string $globalVariableName): \PHPUnit\Metadata\ExcludeGlobalVariableFromBackup
72215 {
72216 return new \PHPUnit\Metadata\ExcludeGlobalVariableFromBackup(self::CLASS_LEVEL, $globalVariableName);
72217 }
72218 /**
72219 * @psalm-param non-empty-string $globalVariableName
72220 */
72221 public static function excludeGlobalVariableFromBackupOnMethod(string $globalVariableName): \PHPUnit\Metadata\ExcludeGlobalVariableFromBackup
72222 {
72223 return new \PHPUnit\Metadata\ExcludeGlobalVariableFromBackup(self::METHOD_LEVEL, $globalVariableName);
72224 }
72225 /**
72226 * @psalm-param class-string $className
72227 * @psalm-param non-empty-string $propertyName
72228 */
72229 public static function excludeStaticPropertyFromBackupOnClass(string $className, string $propertyName): \PHPUnit\Metadata\ExcludeStaticPropertyFromBackup
72230 {
72231 return new \PHPUnit\Metadata\ExcludeStaticPropertyFromBackup(self::CLASS_LEVEL, $className, $propertyName);
72232 }
72233 /**
72234 * @psalm-param class-string $className
72235 * @psalm-param non-empty-string $propertyName
72236 */
72237 public static function excludeStaticPropertyFromBackupOnMethod(string $className, string $propertyName): \PHPUnit\Metadata\ExcludeStaticPropertyFromBackup
72238 {
72239 return new \PHPUnit\Metadata\ExcludeStaticPropertyFromBackup(self::METHOD_LEVEL, $className, $propertyName);
72240 }
72241 /**
72242 * @psalm-param non-empty-string $groupName
72243 */
72244 public static function groupOnClass(string $groupName): \PHPUnit\Metadata\Group
72245 {
72246 return new \PHPUnit\Metadata\Group(self::CLASS_LEVEL, $groupName);
72247 }
72248 /**
72249 * @psalm-param non-empty-string $groupName
72250 */
72251 public static function groupOnMethod(string $groupName): \PHPUnit\Metadata\Group
72252 {
72253 return new \PHPUnit\Metadata\Group(self::METHOD_LEVEL, $groupName);
72254 }
72255 public static function ignoreDeprecationsOnClass(): \PHPUnit\Metadata\IgnoreDeprecations
72256 {
72257 return new \PHPUnit\Metadata\IgnoreDeprecations(self::CLASS_LEVEL);
72258 }
72259 public static function ignoreDeprecationsOnMethod(): \PHPUnit\Metadata\IgnoreDeprecations
72260 {
72261 return new \PHPUnit\Metadata\IgnoreDeprecations(self::METHOD_LEVEL);
72262 }
72263 /**
72264 * @psalm-param class-string $className
72265 */
72266 public static function ignoreClassForCodeCoverage(string $className): \PHPUnit\Metadata\IgnoreClassForCodeCoverage
72267 {
72268 return new \PHPUnit\Metadata\IgnoreClassForCodeCoverage(self::CLASS_LEVEL, $className);
72269 }
72270 /**
72271 * @psalm-param class-string $className
72272 * @psalm-param non-empty-string $methodName
72273 */
72274 public static function ignoreMethodForCodeCoverage(string $className, string $methodName): \PHPUnit\Metadata\IgnoreMethodForCodeCoverage
72275 {
72276 return new \PHPUnit\Metadata\IgnoreMethodForCodeCoverage(self::CLASS_LEVEL, $className, $methodName);
72277 }
72278 /**
72279 * @psalm-param non-empty-string $functionName
72280 */
72281 public static function ignoreFunctionForCodeCoverage(string $functionName): \PHPUnit\Metadata\IgnoreFunctionForCodeCoverage
72282 {
72283 return new \PHPUnit\Metadata\IgnoreFunctionForCodeCoverage(self::CLASS_LEVEL, $functionName);
72284 }
72285 public static function postCondition(): \PHPUnit\Metadata\PostCondition
72286 {
72287 return new \PHPUnit\Metadata\PostCondition(self::METHOD_LEVEL);
72288 }
72289 public static function preCondition(): \PHPUnit\Metadata\PreCondition
72290 {
72291 return new \PHPUnit\Metadata\PreCondition(self::METHOD_LEVEL);
72292 }
72293 public static function preserveGlobalStateOnClass(bool $enabled): \PHPUnit\Metadata\PreserveGlobalState
72294 {
72295 return new \PHPUnit\Metadata\PreserveGlobalState(self::CLASS_LEVEL, $enabled);
72296 }
72297 public static function preserveGlobalStateOnMethod(bool $enabled): \PHPUnit\Metadata\PreserveGlobalState
72298 {
72299 return new \PHPUnit\Metadata\PreserveGlobalState(self::METHOD_LEVEL, $enabled);
72300 }
72301 /**
72302 * @psalm-param non-empty-string $functionName
72303 */
72304 public static function requiresFunctionOnClass(string $functionName): \PHPUnit\Metadata\RequiresFunction
72305 {
72306 return new \PHPUnit\Metadata\RequiresFunction(self::CLASS_LEVEL, $functionName);
72307 }
72308 /**
72309 * @psalm-param non-empty-string $functionName
72310 */
72311 public static function requiresFunctionOnMethod(string $functionName): \PHPUnit\Metadata\RequiresFunction
72312 {
72313 return new \PHPUnit\Metadata\RequiresFunction(self::METHOD_LEVEL, $functionName);
72314 }
72315 /**
72316 * @psalm-param class-string $className
72317 * @psalm-param non-empty-string $methodName
72318 */
72319 public static function requiresMethodOnClass(string $className, string $methodName): \PHPUnit\Metadata\RequiresMethod
72320 {
72321 return new \PHPUnit\Metadata\RequiresMethod(self::CLASS_LEVEL, $className, $methodName);
72322 }
72323 /**
72324 * @psalm-param class-string $className
72325 * @psalm-param non-empty-string $methodName
72326 */
72327 public static function requiresMethodOnMethod(string $className, string $methodName): \PHPUnit\Metadata\RequiresMethod
72328 {
72329 return new \PHPUnit\Metadata\RequiresMethod(self::METHOD_LEVEL, $className, $methodName);
72330 }
72331 /**
72332 * @psalm-param non-empty-string $operatingSystem
72333 */
72334 public static function requiresOperatingSystemOnClass(string $operatingSystem): \PHPUnit\Metadata\RequiresOperatingSystem
72335 {
72336 return new \PHPUnit\Metadata\RequiresOperatingSystem(self::CLASS_LEVEL, $operatingSystem);
72337 }
72338 /**
72339 * @psalm-param non-empty-string $operatingSystem
72340 */
72341 public static function requiresOperatingSystemOnMethod(string $operatingSystem): \PHPUnit\Metadata\RequiresOperatingSystem
72342 {
72343 return new \PHPUnit\Metadata\RequiresOperatingSystem(self::METHOD_LEVEL, $operatingSystem);
72344 }
72345 /**
72346 * @psalm-param non-empty-string $operatingSystemFamily
72347 */
72348 public static function requiresOperatingSystemFamilyOnClass(string $operatingSystemFamily): \PHPUnit\Metadata\RequiresOperatingSystemFamily
72349 {
72350 return new \PHPUnit\Metadata\RequiresOperatingSystemFamily(self::CLASS_LEVEL, $operatingSystemFamily);
72351 }
72352 /**
72353 * @psalm-param non-empty-string $operatingSystemFamily
72354 */
72355 public static function requiresOperatingSystemFamilyOnMethod(string $operatingSystemFamily): \PHPUnit\Metadata\RequiresOperatingSystemFamily
72356 {
72357 return new \PHPUnit\Metadata\RequiresOperatingSystemFamily(self::METHOD_LEVEL, $operatingSystemFamily);
72358 }
72359 public static function requiresPhpOnClass(Requirement $versionRequirement): \PHPUnit\Metadata\RequiresPhp
72360 {
72361 return new \PHPUnit\Metadata\RequiresPhp(self::CLASS_LEVEL, $versionRequirement);
72362 }
72363 public static function requiresPhpOnMethod(Requirement $versionRequirement): \PHPUnit\Metadata\RequiresPhp
72364 {
72365 return new \PHPUnit\Metadata\RequiresPhp(self::METHOD_LEVEL, $versionRequirement);
72366 }
72367 /**
72368 * @psalm-param non-empty-string $extension
72369 */
72370 public static function requiresPhpExtensionOnClass(string $extension, ?Requirement $versionRequirement): \PHPUnit\Metadata\RequiresPhpExtension
72371 {
72372 return new \PHPUnit\Metadata\RequiresPhpExtension(self::CLASS_LEVEL, $extension, $versionRequirement);
72373 }
72374 /**
72375 * @psalm-param non-empty-string $extension
72376 */
72377 public static function requiresPhpExtensionOnMethod(string $extension, ?Requirement $versionRequirement): \PHPUnit\Metadata\RequiresPhpExtension
72378 {
72379 return new \PHPUnit\Metadata\RequiresPhpExtension(self::METHOD_LEVEL, $extension, $versionRequirement);
72380 }
72381 public static function requiresPhpunitOnClass(Requirement $versionRequirement): \PHPUnit\Metadata\RequiresPhpunit
72382 {
72383 return new \PHPUnit\Metadata\RequiresPhpunit(self::CLASS_LEVEL, $versionRequirement);
72384 }
72385 public static function requiresPhpunitOnMethod(Requirement $versionRequirement): \PHPUnit\Metadata\RequiresPhpunit
72386 {
72387 return new \PHPUnit\Metadata\RequiresPhpunit(self::METHOD_LEVEL, $versionRequirement);
72388 }
72389 /**
72390 * @psalm-param non-empty-string $setting
72391 * @psalm-param non-empty-string $value
72392 */
72393 public static function requiresSettingOnClass(string $setting, string $value): \PHPUnit\Metadata\RequiresSetting
72394 {
72395 return new \PHPUnit\Metadata\RequiresSetting(self::CLASS_LEVEL, $setting, $value);
72396 }
72397 /**
72398 * @psalm-param non-empty-string $setting
72399 * @psalm-param non-empty-string $value
72400 */
72401 public static function requiresSettingOnMethod(string $setting, string $value): \PHPUnit\Metadata\RequiresSetting
72402 {
72403 return new \PHPUnit\Metadata\RequiresSetting(self::METHOD_LEVEL, $setting, $value);
72404 }
72405 public static function runClassInSeparateProcess(): \PHPUnit\Metadata\RunClassInSeparateProcess
72406 {
72407 return new \PHPUnit\Metadata\RunClassInSeparateProcess(self::CLASS_LEVEL);
72408 }
72409 public static function runTestsInSeparateProcesses(): \PHPUnit\Metadata\RunTestsInSeparateProcesses
72410 {
72411 return new \PHPUnit\Metadata\RunTestsInSeparateProcesses(self::CLASS_LEVEL);
72412 }
72413 public static function runInSeparateProcess(): \PHPUnit\Metadata\RunInSeparateProcess
72414 {
72415 return new \PHPUnit\Metadata\RunInSeparateProcess(self::METHOD_LEVEL);
72416 }
72417 public static function test(): \PHPUnit\Metadata\Test
72418 {
72419 return new \PHPUnit\Metadata\Test(self::METHOD_LEVEL);
72420 }
72421 /**
72422 * @psalm-param non-empty-string $text
72423 */
72424 public static function testDoxOnClass(string $text): \PHPUnit\Metadata\TestDox
72425 {
72426 return new \PHPUnit\Metadata\TestDox(self::CLASS_LEVEL, $text);
72427 }
72428 /**
72429 * @psalm-param non-empty-string $text
72430 */
72431 public static function testDoxOnMethod(string $text): \PHPUnit\Metadata\TestDox
72432 {
72433 return new \PHPUnit\Metadata\TestDox(self::METHOD_LEVEL, $text);
72434 }
72435 public static function testWith(mixed $data): \PHPUnit\Metadata\TestWith
72436 {
72437 return new \PHPUnit\Metadata\TestWith(self::METHOD_LEVEL, $data);
72438 }
72439 /**
72440 * @psalm-param class-string $className
72441 */
72442 public static function usesClass(string $className): \PHPUnit\Metadata\UsesClass
72443 {
72444 return new \PHPUnit\Metadata\UsesClass(self::CLASS_LEVEL, $className);
72445 }
72446 /**
72447 * @psalm-param non-empty-string $functionName
72448 */
72449 public static function usesFunction(string $functionName): \PHPUnit\Metadata\UsesFunction
72450 {
72451 return new \PHPUnit\Metadata\UsesFunction(self::CLASS_LEVEL, $functionName);
72452 }
72453 /**
72454 * @psalm-param non-empty-string $target
72455 */
72456 public static function usesOnClass(string $target): \PHPUnit\Metadata\Uses
72457 {
72458 return new \PHPUnit\Metadata\Uses(self::CLASS_LEVEL, $target);
72459 }
72460 /**
72461 * @psalm-param non-empty-string $target
72462 */
72463 public static function usesOnMethod(string $target): \PHPUnit\Metadata\Uses
72464 {
72465 return new \PHPUnit\Metadata\Uses(self::METHOD_LEVEL, $target);
72466 }
72467 /**
72468 * @psalm-param class-string $className
72469 */
72470 public static function usesDefaultClass(string $className): \PHPUnit\Metadata\UsesDefaultClass
72471 {
72472 return new \PHPUnit\Metadata\UsesDefaultClass(self::CLASS_LEVEL, $className);
72473 }
72474 public static function withoutErrorHandler(): \PHPUnit\Metadata\WithoutErrorHandler
72475 {
72476 return new \PHPUnit\Metadata\WithoutErrorHandler(self::METHOD_LEVEL);
72477 }
72478 /**
72479 * @psalm-param 0|1 $level
72480 */
72481 protected function __construct(int $level)
72482 {
72483 $this->level = $level;
72484 }
72485 public function isClassLevel(): bool
72486 {
72487 return $this->level === self::CLASS_LEVEL;
72488 }
72489 public function isMethodLevel(): bool
72490 {
72491 return $this->level === self::METHOD_LEVEL;
72492 }
72493 /**
72494 * @psalm-assert-if-true After $this
72495 */
72496 public function isAfter(): bool
72497 {
72498 return \false;
72499 }
72500 /**
72501 * @psalm-assert-if-true AfterClass $this
72502 */
72503 public function isAfterClass(): bool
72504 {
72505 return \false;
72506 }
72507 /**
72508 * @psalm-assert-if-true BackupGlobals $this
72509 */
72510 public function isBackupGlobals(): bool
72511 {
72512 return \false;
72513 }
72514 /**
72515 * @psalm-assert-if-true BackupStaticProperties $this
72516 */
72517 public function isBackupStaticProperties(): bool
72518 {
72519 return \false;
72520 }
72521 /**
72522 * @psalm-assert-if-true BeforeClass $this
72523 */
72524 public function isBeforeClass(): bool
72525 {
72526 return \false;
72527 }
72528 /**
72529 * @psalm-assert-if-true Before $this
72530 */
72531 public function isBefore(): bool
72532 {
72533 return \false;
72534 }
72535 /**
72536 * @psalm-assert-if-true Covers $this
72537 */
72538 public function isCovers(): bool
72539 {
72540 return \false;
72541 }
72542 /**
72543 * @psalm-assert-if-true CoversClass $this
72544 */
72545 public function isCoversClass(): bool
72546 {
72547 return \false;
72548 }
72549 /**
72550 * @psalm-assert-if-true CoversDefaultClass $this
72551 */
72552 public function isCoversDefaultClass(): bool
72553 {
72554 return \false;
72555 }
72556 /**
72557 * @psalm-assert-if-true CoversFunction $this
72558 */
72559 public function isCoversFunction(): bool
72560 {
72561 return \false;
72562 }
72563 /**
72564 * @psalm-assert-if-true CoversNothing $this
72565 */
72566 public function isCoversNothing(): bool
72567 {
72568 return \false;
72569 }
72570 /**
72571 * @psalm-assert-if-true DataProvider $this
72572 */
72573 public function isDataProvider(): bool
72574 {
72575 return \false;
72576 }
72577 /**
72578 * @psalm-assert-if-true DependsOnClass $this
72579 */
72580 public function isDependsOnClass(): bool
72581 {
72582 return \false;
72583 }
72584 /**
72585 * @psalm-assert-if-true DependsOnMethod $this
72586 */
72587 public function isDependsOnMethod(): bool
72588 {
72589 return \false;
72590 }
72591 /**
72592 * @psalm-assert-if-true DoesNotPerformAssertions $this
72593 */
72594 public function isDoesNotPerformAssertions(): bool
72595 {
72596 return \false;
72597 }
72598 /**
72599 * @psalm-assert-if-true ExcludeGlobalVariableFromBackup $this
72600 */
72601 public function isExcludeGlobalVariableFromBackup(): bool
72602 {
72603 return \false;
72604 }
72605 /**
72606 * @psalm-assert-if-true ExcludeStaticPropertyFromBackup $this
72607 */
72608 public function isExcludeStaticPropertyFromBackup(): bool
72609 {
72610 return \false;
72611 }
72612 /**
72613 * @psalm-assert-if-true Group $this
72614 */
72615 public function isGroup(): bool
72616 {
72617 return \false;
72618 }
72619 /**
72620 * @psalm-assert-if-true IgnoreDeprecations $this
72621 */
72622 public function isIgnoreDeprecations(): bool
72623 {
72624 return \false;
72625 }
72626 /**
72627 * @psalm-assert-if-true IgnoreClassForCodeCoverage $this
72628 */
72629 public function isIgnoreClassForCodeCoverage(): bool
72630 {
72631 return \false;
72632 }
72633 /**
72634 * @psalm-assert-if-true IgnoreMethodForCodeCoverage $this
72635 */
72636 public function isIgnoreMethodForCodeCoverage(): bool
72637 {
72638 return \false;
72639 }
72640 /**
72641 * @psalm-assert-if-true IgnoreFunctionForCodeCoverage $this
72642 */
72643 public function isIgnoreFunctionForCodeCoverage(): bool
72644 {
72645 return \false;
72646 }
72647 /**
72648 * @psalm-assert-if-true RunClassInSeparateProcess $this
72649 */
72650 public function isRunClassInSeparateProcess(): bool
72651 {
72652 return \false;
72653 }
72654 /**
72655 * @psalm-assert-if-true RunInSeparateProcess $this
72656 */
72657 public function isRunInSeparateProcess(): bool
72658 {
72659 return \false;
72660 }
72661 /**
72662 * @psalm-assert-if-true RunTestsInSeparateProcesses $this
72663 */
72664 public function isRunTestsInSeparateProcesses(): bool
72665 {
72666 return \false;
72667 }
72668 /**
72669 * @psalm-assert-if-true Test $this
72670 */
72671 public function isTest(): bool
72672 {
72673 return \false;
72674 }
72675 /**
72676 * @psalm-assert-if-true PreCondition $this
72677 */
72678 public function isPreCondition(): bool
72679 {
72680 return \false;
72681 }
72682 /**
72683 * @psalm-assert-if-true PostCondition $this
72684 */
72685 public function isPostCondition(): bool
72686 {
72687 return \false;
72688 }
72689 /**
72690 * @psalm-assert-if-true PreserveGlobalState $this
72691 */
72692 public function isPreserveGlobalState(): bool
72693 {
72694 return \false;
72695 }
72696 /**
72697 * @psalm-assert-if-true RequiresMethod $this
72698 */
72699 public function isRequiresMethod(): bool
72700 {
72701 return \false;
72702 }
72703 /**
72704 * @psalm-assert-if-true RequiresFunction $this
72705 */
72706 public function isRequiresFunction(): bool
72707 {
72708 return \false;
72709 }
72710 /**
72711 * @psalm-assert-if-true RequiresOperatingSystem $this
72712 */
72713 public function isRequiresOperatingSystem(): bool
72714 {
72715 return \false;
72716 }
72717 /**
72718 * @psalm-assert-if-true RequiresOperatingSystemFamily $this
72719 */
72720 public function isRequiresOperatingSystemFamily(): bool
72721 {
72722 return \false;
72723 }
72724 /**
72725 * @psalm-assert-if-true RequiresPhp $this
72726 */
72727 public function isRequiresPhp(): bool
72728 {
72729 return \false;
72730 }
72731 /**
72732 * @psalm-assert-if-true RequiresPhpExtension $this
72733 */
72734 public function isRequiresPhpExtension(): bool
72735 {
72736 return \false;
72737 }
72738 /**
72739 * @psalm-assert-if-true RequiresPhpunit $this
72740 */
72741 public function isRequiresPhpunit(): bool
72742 {
72743 return \false;
72744 }
72745 /**
72746 * @psalm-assert-if-true RequiresSetting $this
72747 */
72748 public function isRequiresSetting(): bool
72749 {
72750 return \false;
72751 }
72752 /**
72753 * @psalm-assert-if-true TestDox $this
72754 */
72755 public function isTestDox(): bool
72756 {
72757 return \false;
72758 }
72759 /**
72760 * @psalm-assert-if-true TestWith $this
72761 */
72762 public function isTestWith(): bool
72763 {
72764 return \false;
72765 }
72766 /**
72767 * @psalm-assert-if-true Uses $this
72768 */
72769 public function isUses(): bool
72770 {
72771 return \false;
72772 }
72773 /**
72774 * @psalm-assert-if-true UsesClass $this
72775 */
72776 public function isUsesClass(): bool
72777 {
72778 return \false;
72779 }
72780 /**
72781 * @psalm-assert-if-true UsesDefaultClass $this
72782 */
72783 public function isUsesDefaultClass(): bool
72784 {
72785 return \false;
72786 }
72787 /**
72788 * @psalm-assert-if-true UsesFunction $this
72789 */
72790 public function isUsesFunction(): bool
72791 {
72792 return \false;
72793 }
72794 /**
72795 * @psalm-assert-if-true WithoutErrorHandler $this
72796 */
72797 public function isWithoutErrorHandler(): bool
72798 {
72799 return \false;
72800 }
72801 }
72802 <?php
72803
72804 declare (strict_types=1);
72805 /*
72806 * This file is part of PHPUnit.
72807 *
72808 * (c) Sebastian Bergmann <sebastian@phpunit.de>
72809 *
72810 * For the full copyright and license information, please view the LICENSE
72811 * file that was distributed with this source code.
72812 */
72813 namespace PHPUnit\Metadata;
72814
72815 use function array_filter;
72816 use function array_merge;
72817 use function count;
72818 use Countable;
72819 use IteratorAggregate;
72820 /**
72821 * @template-implements IteratorAggregate<int, Metadata>
72822 *
72823 * @psalm-immutable
72824 *
72825 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
72826 */
72827 final class MetadataCollection implements Countable, IteratorAggregate
72828 {
72829 /**
72830 * @psalm-var list<Metadata>
72831 */
72832 private readonly array $metadata;
72833 /**
72834 * @psalm-param list<Metadata> $metadata
72835 */
72836 public static function fromArray(array $metadata): self
72837 {
72838 return new self(...$metadata);
72839 }
72840 private function __construct(\PHPUnit\Metadata\Metadata ...$metadata)
72841 {
72842 $this->metadata = $metadata;
72843 }
72844 /**
72845 * @psalm-return list<Metadata>
72846 */
72847 public function asArray(): array
72848 {
72849 return $this->metadata;
72850 }
72851 public function count(): int
72852 {
72853 return count($this->metadata);
72854 }
72855 public function isEmpty(): bool
72856 {
72857 return $this->count() === 0;
72858 }
72859 public function isNotEmpty(): bool
72860 {
72861 return $this->count() > 0;
72862 }
72863 public function getIterator(): \PHPUnit\Metadata\MetadataCollectionIterator
72864 {
72865 return new \PHPUnit\Metadata\MetadataCollectionIterator($this);
72866 }
72867 public function mergeWith(self $other): self
72868 {
72869 return new self(...array_merge($this->asArray(), $other->asArray()));
72870 }
72871 public function isClassLevel(): self
72872 {
72873 return new self(...array_filter($this->metadata, static fn(\PHPUnit\Metadata\Metadata $metadata): bool => $metadata->isClassLevel()));
72874 }
72875 public function isMethodLevel(): self
72876 {
72877 return new self(...array_filter($this->metadata, static fn(\PHPUnit\Metadata\Metadata $metadata): bool => $metadata->isMethodLevel()));
72878 }
72879 public function isAfter(): self
72880 {
72881 return new self(...array_filter($this->metadata, static fn(\PHPUnit\Metadata\Metadata $metadata): bool => $metadata->isAfter()));
72882 }
72883 public function isAfterClass(): self
72884 {
72885 return new self(...array_filter($this->metadata, static fn(\PHPUnit\Metadata\Metadata $metadata): bool => $metadata->isAfterClass()));
72886 }
72887 public function isBackupGlobals(): self
72888 {
72889 return new self(...array_filter($this->metadata, static fn(\PHPUnit\Metadata\Metadata $metadata): bool => $metadata->isBackupGlobals()));
72890 }
72891 public function isBackupStaticProperties(): self
72892 {
72893 return new self(...array_filter($this->metadata, static fn(\PHPUnit\Metadata\Metadata $metadata): bool => $metadata->isBackupStaticProperties()));
72894 }
72895 public function isBeforeClass(): self
72896 {
72897 return new self(...array_filter($this->metadata, static fn(\PHPUnit\Metadata\Metadata $metadata): bool => $metadata->isBeforeClass()));
72898 }
72899 public function isBefore(): self
72900 {
72901 return new self(...array_filter($this->metadata, static fn(\PHPUnit\Metadata\Metadata $metadata): bool => $metadata->isBefore()));
72902 }
72903 public function isCovers(): self
72904 {
72905 return new self(...array_filter($this->metadata, static fn(\PHPUnit\Metadata\Metadata $metadata): bool => $metadata->isCovers()));
72906 }
72907 public function isCoversClass(): self
72908 {
72909 return new self(...array_filter($this->metadata, static fn(\PHPUnit\Metadata\Metadata $metadata): bool => $metadata->isCoversClass()));
72910 }
72911 public function isCoversDefaultClass(): self
72912 {
72913 return new self(...array_filter($this->metadata, static fn(\PHPUnit\Metadata\Metadata $metadata): bool => $metadata->isCoversDefaultClass()));
72914 }
72915 public function isCoversFunction(): self
72916 {
72917 return new self(...array_filter($this->metadata, static fn(\PHPUnit\Metadata\Metadata $metadata): bool => $metadata->isCoversFunction()));
72918 }
72919 public function isExcludeGlobalVariableFromBackup(): self
72920 {
72921 return new self(...array_filter($this->metadata, static fn(\PHPUnit\Metadata\Metadata $metadata): bool => $metadata->isExcludeGlobalVariableFromBackup()));
72922 }
72923 public function isExcludeStaticPropertyFromBackup(): self
72924 {
72925 return new self(...array_filter($this->metadata, static fn(\PHPUnit\Metadata\Metadata $metadata): bool => $metadata->isExcludeStaticPropertyFromBackup()));
72926 }
72927 public function isCoversNothing(): self
72928 {
72929 return new self(...array_filter($this->metadata, static fn(\PHPUnit\Metadata\Metadata $metadata): bool => $metadata->isCoversNothing()));
72930 }
72931 public function isDataProvider(): self
72932 {
72933 return new self(...array_filter($this->metadata, static fn(\PHPUnit\Metadata\Metadata $metadata): bool => $metadata->isDataProvider()));
72934 }
72935 public function isDepends(): self
72936 {
72937 return new self(...array_filter($this->metadata, static fn(\PHPUnit\Metadata\Metadata $metadata): bool => $metadata->isDependsOnClass() || $metadata->isDependsOnMethod()));
72938 }
72939 public function isDependsOnClass(): self
72940 {
72941 return new self(...array_filter($this->metadata, static fn(\PHPUnit\Metadata\Metadata $metadata): bool => $metadata->isDependsOnClass()));
72942 }
72943 public function isDependsOnMethod(): self
72944 {
72945 return new self(...array_filter($this->metadata, static fn(\PHPUnit\Metadata\Metadata $metadata): bool => $metadata->isDependsOnMethod()));
72946 }
72947 public function isDoesNotPerformAssertions(): self
72948 {
72949 return new self(...array_filter($this->metadata, static fn(\PHPUnit\Metadata\Metadata $metadata): bool => $metadata->isDoesNotPerformAssertions()));
72950 }
72951 public function isGroup(): self
72952 {
72953 return new self(...array_filter($this->metadata, static fn(\PHPUnit\Metadata\Metadata $metadata): bool => $metadata->isGroup()));
72954 }
72955 public function isIgnoreDeprecations(): self
72956 {
72957 return new self(...array_filter($this->metadata, static fn(\PHPUnit\Metadata\Metadata $metadata): bool => $metadata->isIgnoreDeprecations()));
72958 }
72959 /**
72960 * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5513
72961 */
72962 public function isIgnoreClassForCodeCoverage(): self
72963 {
72964 return new self(...array_filter($this->metadata, static fn(\PHPUnit\Metadata\Metadata $metadata): bool => $metadata->isIgnoreClassForCodeCoverage()));
72965 }
72966 /**
72967 * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5513
72968 */
72969 public function isIgnoreMethodForCodeCoverage(): self
72970 {
72971 return new self(...array_filter($this->metadata, static fn(\PHPUnit\Metadata\Metadata $metadata): bool => $metadata->isIgnoreMethodForCodeCoverage()));
72972 }
72973 /**
72974 * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5513
72975 */
72976 public function isIgnoreFunctionForCodeCoverage(): self
72977 {
72978 return new self(...array_filter($this->metadata, static fn(\PHPUnit\Metadata\Metadata $metadata): bool => $metadata->isIgnoreFunctionForCodeCoverage()));
72979 }
72980 public function isRunClassInSeparateProcess(): self
72981 {
72982 return new self(...array_filter($this->metadata, static fn(\PHPUnit\Metadata\Metadata $metadata): bool => $metadata->isRunClassInSeparateProcess()));
72983 }
72984 public function isRunInSeparateProcess(): self
72985 {
72986 return new self(...array_filter($this->metadata, static fn(\PHPUnit\Metadata\Metadata $metadata): bool => $metadata->isRunInSeparateProcess()));
72987 }
72988 public function isRunTestsInSeparateProcesses(): self
72989 {
72990 return new self(...array_filter($this->metadata, static fn(\PHPUnit\Metadata\Metadata $metadata): bool => $metadata->isRunTestsInSeparateProcesses()));
72991 }
72992 public function isTest(): self
72993 {
72994 return new self(...array_filter($this->metadata, static fn(\PHPUnit\Metadata\Metadata $metadata): bool => $metadata->isTest()));
72995 }
72996 public function isPreCondition(): self
72997 {
72998 return new self(...array_filter($this->metadata, static fn(\PHPUnit\Metadata\Metadata $metadata): bool => $metadata->isPreCondition()));
72999 }
73000 public function isPostCondition(): self
73001 {
73002 return new self(...array_filter($this->metadata, static fn(\PHPUnit\Metadata\Metadata $metadata): bool => $metadata->isPostCondition()));
73003 }
73004 public function isPreserveGlobalState(): self
73005 {
73006 return new self(...array_filter($this->metadata, static fn(\PHPUnit\Metadata\Metadata $metadata): bool => $metadata->isPreserveGlobalState()));
73007 }
73008 public function isRequiresMethod(): self
73009 {
73010 return new self(...array_filter($this->metadata, static fn(\PHPUnit\Metadata\Metadata $metadata): bool => $metadata->isRequiresMethod()));
73011 }
73012 public function isRequiresFunction(): self
73013 {
73014 return new self(...array_filter($this->metadata, static fn(\PHPUnit\Metadata\Metadata $metadata): bool => $metadata->isRequiresFunction()));
73015 }
73016 public function isRequiresOperatingSystem(): self
73017 {
73018 return new self(...array_filter($this->metadata, static fn(\PHPUnit\Metadata\Metadata $metadata): bool => $metadata->isRequiresOperatingSystem()));
73019 }
73020 public function isRequiresOperatingSystemFamily(): self
73021 {
73022 return new self(...array_filter($this->metadata, static fn(\PHPUnit\Metadata\Metadata $metadata): bool => $metadata->isRequiresOperatingSystemFamily()));
73023 }
73024 public function isRequiresPhp(): self
73025 {
73026 return new self(...array_filter($this->metadata, static fn(\PHPUnit\Metadata\Metadata $metadata): bool => $metadata->isRequiresPhp()));
73027 }
73028 public function isRequiresPhpExtension(): self
73029 {
73030 return new self(...array_filter($this->metadata, static fn(\PHPUnit\Metadata\Metadata $metadata): bool => $metadata->isRequiresPhpExtension()));
73031 }
73032 public function isRequiresPhpunit(): self
73033 {
73034 return new self(...array_filter($this->metadata, static fn(\PHPUnit\Metadata\Metadata $metadata): bool => $metadata->isRequiresPhpunit()));
73035 }
73036 public function isRequiresSetting(): self
73037 {
73038 return new self(...array_filter($this->metadata, static fn(\PHPUnit\Metadata\Metadata $metadata): bool => $metadata->isRequiresSetting()));
73039 }
73040 public function isTestDox(): self
73041 {
73042 return new self(...array_filter($this->metadata, static fn(\PHPUnit\Metadata\Metadata $metadata): bool => $metadata->isTestDox()));
73043 }
73044 public function isTestWith(): self
73045 {
73046 return new self(...array_filter($this->metadata, static fn(\PHPUnit\Metadata\Metadata $metadata): bool => $metadata->isTestWith()));
73047 }
73048 public function isUses(): self
73049 {
73050 return new self(...array_filter($this->metadata, static fn(\PHPUnit\Metadata\Metadata $metadata): bool => $metadata->isUses()));
73051 }
73052 public function isUsesClass(): self
73053 {
73054 return new self(...array_filter($this->metadata, static fn(\PHPUnit\Metadata\Metadata $metadata): bool => $metadata->isUsesClass()));
73055 }
73056 public function isUsesDefaultClass(): self
73057 {
73058 return new self(...array_filter($this->metadata, static fn(\PHPUnit\Metadata\Metadata $metadata): bool => $metadata->isUsesDefaultClass()));
73059 }
73060 public function isUsesFunction(): self
73061 {
73062 return new self(...array_filter($this->metadata, static fn(\PHPUnit\Metadata\Metadata $metadata): bool => $metadata->isUsesFunction()));
73063 }
73064 public function isWithoutErrorHandler(): self
73065 {
73066 return new self(...array_filter($this->metadata, static fn(\PHPUnit\Metadata\Metadata $metadata): bool => $metadata->isWithoutErrorHandler()));
73067 }
73068 }
73069 <?php
73070
73071 declare (strict_types=1);
73072 /*
73073 * This file is part of PHPUnit.
73074 *
73075 * (c) Sebastian Bergmann <sebastian@phpunit.de>
73076 *
73077 * For the full copyright and license information, please view the LICENSE
73078 * file that was distributed with this source code.
73079 */
73080 namespace PHPUnit\Metadata;
73081
73082 use function count;
73083 use Iterator;
73084 /**
73085 * @template-implements Iterator<int, Metadata>
73086 *
73087 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
73088 */
73089 final class MetadataCollectionIterator implements Iterator
73090 {
73091 /**
73092 * @psalm-var list<Metadata>
73093 */
73094 private readonly array $metadata;
73095 private int $position = 0;
73096 public function __construct(\PHPUnit\Metadata\MetadataCollection $metadata)
73097 {
73098 $this->metadata = $metadata->asArray();
73099 }
73100 public function rewind(): void
73101 {
73102 $this->position = 0;
73103 }
73104 public function valid(): bool
73105 {
73106 return $this->position < count($this->metadata);
73107 }
73108 public function key(): int
73109 {
73110 return $this->position;
73111 }
73112 public function current(): \PHPUnit\Metadata\Metadata
73113 {
73114 return $this->metadata[$this->position];
73115 }
73116 public function next(): void
73117 {
73118 $this->position++;
73119 }
73120 }
73121 <?php
73122
73123 declare (strict_types=1);
73124 /*
73125 * This file is part of PHPUnit.
73126 *
73127 * (c) Sebastian Bergmann <sebastian@phpunit.de>
73128 *
73129 * For the full copyright and license information, please view the LICENSE
73130 * file that was distributed with this source code.
73131 */
73132 namespace PHPUnit\Metadata\Annotation\Parser;
73133
73134 use function array_filter;
73135 use function array_map;
73136 use function array_merge;
73137 use function array_values;
73138 use function count;
73139 use function preg_match;
73140 use function preg_match_all;
73141 use function preg_replace;
73142 use function preg_split;
73143 use function realpath;
73144 use function substr;
73145 use function trim;
73146 use PHPUnitPHAR\PharIo\Version\Exception as PharIoVersionException;
73147 use PHPUnitPHAR\PharIo\Version\VersionConstraintParser;
73148 use PHPUnit\Metadata\AnnotationsAreNotSupportedForInternalClassesException;
73149 use PHPUnit\Metadata\InvalidVersionRequirementException;
73150 use ReflectionClass;
73151 use ReflectionFunctionAbstract;
73152 use ReflectionMethod;
73153 /**
73154 * This is an abstraction around a PHPUnit-specific docBlock,
73155 * allowing us to ask meaningful questions about a specific
73156 * reflection symbol.
73157 *
73158 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
73159 *
73160 * @internal This class is not covered by the backward compatibility promise for PHPUnit
73161 */
73162 final class DocBlock
73163 {
73164 private const REGEX_REQUIRES_VERSION = '/@requires\s+(?P<name>PHP(?:Unit)?)\s+(?P<operator>[<>=!]{0,2})\s*(?P<version>[\d\.-]+(dev|(RC|alpha|beta)[\d\.])?)[ \t]*\r?$/m';
73165 private const REGEX_REQUIRES_VERSION_CONSTRAINT = '/@requires\s+(?P<name>PHP(?:Unit)?)\s+(?P<constraint>[\d\t \-.|~^]+)[ \t]*\r?$/m';
73166 private const REGEX_REQUIRES_OS = '/@requires\s+(?P<name>OS(?:FAMILY)?)\s+(?P<value>.+?)[ \t]*\r?$/m';
73167 private const REGEX_REQUIRES_SETTING = '/@requires\s+(?P<name>setting)\s+(?P<setting>([^ ]+?))\s*(?P<value>[\w\.-]+[\w\.]?)?[ \t]*\r?$/m';
73168 private const REGEX_REQUIRES = '/@requires\s+(?P<name>function|extension)\s+(?P<value>([^\s<>=!]+))\s*(?P<operator>[<>=!]{0,2})\s*(?P<version>[\d\.-]+[\d\.]?)?[ \t]*\r?$/m';
73169 private readonly string $docComment;
73170 /**
73171 * @psalm-var array<string, array<int, string>> pre-parsed annotations indexed by name and occurrence index
73172 */
73173 private readonly array $symbolAnnotations;
73174 /**
73175 * @psalm-var null|(array{
73176 * __OFFSET: array<string, int>&array{__FILE: string},
73177 * setting?: array<string, string>,
73178 * extension_versions?: array<string, array{version: string, operator: string}>
73179 * }&array<
73180 * string,
73181 * string|array{version: string, operator: string}|array{constraint: string}|array<int|string, string>
73182 * >)
73183 */
73184 private ?array $parsedRequirements = null;
73185 private readonly int $startLine;
73186 private readonly string $fileName;
73187 /**
73188 * @throws AnnotationsAreNotSupportedForInternalClassesException
73189 */
73190 public static function ofClass(ReflectionClass $class): self
73191 {
73192 if ($class->isInternal()) {
73193 throw new AnnotationsAreNotSupportedForInternalClassesException($class->getName());
73194 }
73195 return new self((string) $class->getDocComment(), self::extractAnnotationsFromReflector($class), $class->getStartLine(), $class->getFileName());
73196 }
73197 /**
73198 * @throws AnnotationsAreNotSupportedForInternalClassesException
73199 */
73200 public static function ofMethod(ReflectionMethod $method): self
73201 {
73202 if ($method->getDeclaringClass()->isInternal()) {
73203 throw new AnnotationsAreNotSupportedForInternalClassesException($method->getDeclaringClass()->getName());
73204 }
73205 return new self((string) $method->getDocComment(), self::extractAnnotationsFromReflector($method), $method->getStartLine(), $method->getFileName());
73206 }
73207 /**
73208 * Note: we do not preserve an instance of the reflection object, since it cannot be safely (de-)serialized.
73209 *
73210 * @param array<string, array<int, string>> $symbolAnnotations
73211 */
73212 private function __construct(string $docComment, array $symbolAnnotations, int $startLine, string $fileName)
73213 {
73214 $this->docComment = $docComment;
73215 $this->symbolAnnotations = $symbolAnnotations;
73216 $this->startLine = $startLine;
73217 $this->fileName = $fileName;
73218 }
73219 /**
73220 * @throws InvalidVersionRequirementException
73221 *
73222 * @psalm-return array{
73223 * __OFFSET: array<string, int>&array{__FILE: string},
73224 * setting?: array<string, string>,
73225 * extension_versions?: array<string, array{version: string, operator: string}>
73226 * }&array<
73227 * string,
73228 * string|array{version: string, operator: string}|array{constraint: string}|array<int|string, string>
73229 * >
73230 */
73231 public function requirements(): array
73232 {
73233 if ($this->parsedRequirements !== null) {
73234 return $this->parsedRequirements;
73235 }
73236 $offset = $this->startLine;
73237 $requires = [];
73238 $recordedSettings = [];
73239 $extensionVersions = [];
73240 $recordedOffsets = ['__FILE' => realpath($this->fileName)];
73241 // Trim docblock markers, split it into lines and rewind offset to start of docblock
73242 $lines = preg_replace(['#^/\*{2}#', '#\*/$#'], '', preg_split('/\r\n|\r|\n/', $this->docComment));
73243 $offset -= count($lines);
73244 foreach ($lines as $line) {
73245 if (preg_match(self::REGEX_REQUIRES_OS, $line, $matches)) {
73246 $requires[$matches['name']] = $matches['value'];
73247 $recordedOffsets[$matches['name']] = $offset;
73248 }
73249 if (preg_match(self::REGEX_REQUIRES_VERSION, $line, $matches)) {
73250 $requires[$matches['name']] = ['version' => $matches['version'], 'operator' => $matches['operator']];
73251 $recordedOffsets[$matches['name']] = $offset;
73252 }
73253 if (preg_match(self::REGEX_REQUIRES_VERSION_CONSTRAINT, $line, $matches)) {
73254 if (!empty($requires[$matches['name']])) {
73255 $offset++;
73256 continue;
73257 }
73258 try {
73259 $versionConstraintParser = new VersionConstraintParser();
73260 $requires[$matches['name'] . '_constraint'] = ['constraint' => $versionConstraintParser->parse(trim($matches['constraint']))];
73261 $recordedOffsets[$matches['name'] . '_constraint'] = $offset;
73262 } catch (PharIoVersionException $e) {
73263 throw new InvalidVersionRequirementException($e->getMessage(), $e->getCode(), $e);
73264 }
73265 }
73266 if (preg_match(self::REGEX_REQUIRES_SETTING, $line, $matches)) {
73267 $recordedSettings[$matches['setting']] = $matches['value'];
73268 $recordedOffsets['__SETTING_' . $matches['setting']] = $offset;
73269 }
73270 if (preg_match(self::REGEX_REQUIRES, $line, $matches)) {
73271 $name = $matches['name'] . 's';
73272 if (!isset($requires[$name])) {
73273 $requires[$name] = [];
73274 }
73275 $requires[$name][] = $matches['value'];
73276 $recordedOffsets[$matches['name'] . '_' . $matches['value']] = $offset;
73277 if ($name === 'extensions' && !empty($matches['version'])) {
73278 $extensionVersions[$matches['value']] = ['version' => $matches['version'], 'operator' => $matches['operator']];
73279 }
73280 }
73281 $offset++;
73282 }
73283 return $this->parsedRequirements = array_merge($requires, ['__OFFSET' => $recordedOffsets], array_filter(['setting' => $recordedSettings, 'extension_versions' => $extensionVersions]));
73284 }
73285 public function symbolAnnotations(): array
73286 {
73287 return $this->symbolAnnotations;
73288 }
73289 /**
73290 * @psalm-return array<string, array<int, string>>
73291 */
73292 private static function parseDocBlock(string $docBlock): array
73293 {
73294 // Strip away the docblock header and footer to ease parsing of one line annotations
73295 $docBlock = substr($docBlock, 3, -2);
73296 $annotations = [];
73297 if (preg_match_all('/@(?P<name>[A-Za-z_-]+)(?:[ \t]+(?P<value>.*?))?[ \t]*\r?$/m', $docBlock, $matches)) {
73298 $numMatches = count($matches[0]);
73299 for ($i = 0; $i < $numMatches; $i++) {
73300 $annotations[$matches['name'][$i]][] = $matches['value'][$i];
73301 }
73302 }
73303 return $annotations;
73304 }
73305 private static function extractAnnotationsFromReflector(ReflectionClass|ReflectionFunctionAbstract $reflector): array
73306 {
73307 $annotations = [];
73308 if ($reflector instanceof ReflectionClass) {
73309 $annotations = array_merge($annotations, ...array_map(static fn(ReflectionClass $trait): array => self::parseDocBlock((string) $trait->getDocComment()), array_values($reflector->getTraits())));
73310 }
73311 return array_merge($annotations, self::parseDocBlock((string) $reflector->getDocComment()));
73312 }
73313 }
73314 <?php
73315
73316 declare (strict_types=1);
73317 /*
73318 * This file is part of PHPUnit.
73319 *
73320 * (c) Sebastian Bergmann <sebastian@phpunit.de>
73321 *
73322 * For the full copyright and license information, please view the LICENSE
73323 * file that was distributed with this source code.
73324 */
73325 namespace PHPUnit\Metadata\Annotation\Parser;
73326
73327 use function array_key_exists;
73328 use PHPUnit\Metadata\AnnotationsAreNotSupportedForInternalClassesException;
73329 use PHPUnit\Metadata\ReflectionException;
73330 use ReflectionClass;
73331 use ReflectionMethod;
73332 /**
73333 * Reflection information, and therefore DocBlock information, is static within
73334 * a single PHP process. It is therefore okay to use a Singleton registry here.
73335 *
73336 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
73337 *
73338 * @internal This class is not covered by the backward compatibility promise for PHPUnit
73339 */
73340 final class Registry
73341 {
73342 private static ?\PHPUnit\Metadata\Annotation\Parser\Registry $instance = null;
73343 /**
73344 * @psalm-var array<string, DocBlock> indexed by class name
73345 */
73346 private array $classDocBlocks = [];
73347 /**
73348 * @psalm-var array<string, array<string, DocBlock>> indexed by class name and method name
73349 */
73350 private array $methodDocBlocks = [];
73351 public static function getInstance(): self
73352 {
73353 return self::$instance ?? self::$instance = new self();
73354 }
73355 /**
73356 * @psalm-param class-string $class
73357 *
73358 * @throws AnnotationsAreNotSupportedForInternalClassesException
73359 * @throws ReflectionException
73360 */
73361 public function forClassName(string $class): \PHPUnit\Metadata\Annotation\Parser\DocBlock
73362 {
73363 if (array_key_exists($class, $this->classDocBlocks)) {
73364 return $this->classDocBlocks[$class];
73365 }
73366 try {
73367 $reflection = new ReflectionClass($class);
73368 // @codeCoverageIgnoreStart
73369 } catch (\ReflectionException $e) {
73370 throw new ReflectionException($e->getMessage(), $e->getCode(), $e);
73371 }
73372 // @codeCoverageIgnoreEnd
73373 return $this->classDocBlocks[$class] = \PHPUnit\Metadata\Annotation\Parser\DocBlock::ofClass($reflection);
73374 }
73375 /**
73376 * @psalm-param class-string $classInHierarchy
73377 *
73378 * @throws AnnotationsAreNotSupportedForInternalClassesException
73379 * @throws ReflectionException
73380 */
73381 public function forMethod(string $classInHierarchy, string $method): \PHPUnit\Metadata\Annotation\Parser\DocBlock
73382 {
73383 if (isset($this->methodDocBlocks[$classInHierarchy][$method])) {
73384 return $this->methodDocBlocks[$classInHierarchy][$method];
73385 }
73386 try {
73387 $reflection = new ReflectionMethod($classInHierarchy, $method);
73388 // @codeCoverageIgnoreStart
73389 } catch (\ReflectionException $e) {
73390 throw new ReflectionException($e->getMessage(), $e->getCode(), $e);
73391 }
73392 // @codeCoverageIgnoreEnd
73393 return $this->methodDocBlocks[$classInHierarchy][$method] = \PHPUnit\Metadata\Annotation\Parser\DocBlock::ofMethod($reflection);
73394 }
73395 }
73396 <?php
73397
73398 declare (strict_types=1);
73399 /*
73400 * This file is part of PHPUnit.
73401 *
73402 * (c) Sebastian Bergmann <sebastian@phpunit.de>
73403 *
73404 * For the full copyright and license information, please view the LICENSE
73405 * file that was distributed with this source code.
73406 */
73407 namespace PHPUnit\Metadata\Parser;
73408
73409 use function array_merge;
73410 use function assert;
73411 use function class_exists;
73412 use function count;
73413 use function explode;
73414 use function method_exists;
73415 use function preg_replace;
73416 use function rtrim;
73417 use function sprintf;
73418 use function str_contains;
73419 use function str_starts_with;
73420 use function strlen;
73421 use function substr;
73422 use function trim;
73423 use PHPUnit\Event\Facade as EventFacade;
73424 use PHPUnit\Metadata\Annotation\Parser\Registry as AnnotationRegistry;
73425 use PHPUnit\Metadata\AnnotationsAreNotSupportedForInternalClassesException;
73426 use PHPUnit\Metadata\InvalidVersionRequirementException;
73427 use PHPUnit\Metadata\Metadata;
73428 use PHPUnit\Metadata\MetadataCollection;
73429 use PHPUnit\Metadata\ReflectionException;
73430 use PHPUnit\Metadata\Version\ComparisonRequirement;
73431 use PHPUnit\Metadata\Version\ConstraintRequirement;
73432 use PHPUnit\Util\InvalidVersionOperatorException;
73433 use PHPUnit\Util\VersionComparisonOperator;
73434 /**
73435 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
73436 *
73437 * @internal This class is not covered by the backward compatibility promise for PHPUnit
73438 */
73439 final class AnnotationParser implements \PHPUnit\Metadata\Parser\Parser
73440 {
73441 /**
73442 * @psalm-param class-string $className
73443 *
73444 * @throws AnnotationsAreNotSupportedForInternalClassesException
73445 * @throws InvalidVersionOperatorException
73446 * @throws ReflectionException
73447 */
73448 public function forClass(string $className): MetadataCollection
73449 {
73450 assert(class_exists($className));
73451 $result = [];
73452 foreach (AnnotationRegistry::getInstance()->forClassName($className)->symbolAnnotations() as $annotation => $values) {
73453 switch ($annotation) {
73454 case 'backupGlobals':
73455 $result[] = Metadata::backupGlobalsOnClass($this->stringToBool($values[0]));
73456 break;
73457 case 'backupStaticAttributes':
73458 case 'backupStaticProperties':
73459 $result[] = Metadata::backupStaticPropertiesOnClass($this->stringToBool($values[0]));
73460 break;
73461 case 'covers':
73462 foreach ($values as $value) {
73463 $value = $this->cleanUpCoversOrUsesTarget($value);
73464 $result[] = Metadata::coversOnClass($value);
73465 }
73466 break;
73467 case 'coversDefaultClass':
73468 foreach ($values as $value) {
73469 $result[] = Metadata::coversDefaultClass($value);
73470 }
73471 break;
73472 case 'coversNothing':
73473 $result[] = Metadata::coversNothingOnClass();
73474 break;
73475 case 'doesNotPerformAssertions':
73476 $result[] = Metadata::doesNotPerformAssertionsOnClass();
73477 break;
73478 case 'group':
73479 case 'ticket':
73480 foreach ($values as $value) {
73481 $result[] = Metadata::groupOnClass($value);
73482 }
73483 break;
73484 case 'large':
73485 $result[] = Metadata::groupOnClass('large');
73486 break;
73487 case 'medium':
73488 $result[] = Metadata::groupOnClass('medium');
73489 break;
73490 case 'preserveGlobalState':
73491 $result[] = Metadata::preserveGlobalStateOnClass($this->stringToBool($values[0]));
73492 break;
73493 case 'runClassInSeparateProcess':
73494 $result[] = Metadata::runClassInSeparateProcess();
73495 break;
73496 case 'runTestsInSeparateProcesses':
73497 $result[] = Metadata::runTestsInSeparateProcesses();
73498 break;
73499 case 'small':
73500 $result[] = Metadata::groupOnClass('small');
73501 break;
73502 case 'testdox':
73503 $result[] = Metadata::testDoxOnClass($values[0]);
73504 break;
73505 case 'uses':
73506 foreach ($values as $value) {
73507 $value = $this->cleanUpCoversOrUsesTarget($value);
73508 $result[] = Metadata::usesOnClass($value);
73509 }
73510 break;
73511 case 'usesDefaultClass':
73512 foreach ($values as $value) {
73513 $result[] = Metadata::usesDefaultClass($value);
73514 }
73515 break;
73516 }
73517 }
73518 try {
73519 $result = array_merge($result, $this->parseRequirements(AnnotationRegistry::getInstance()->forClassName($className)->requirements(), 'class'));
73520 } catch (InvalidVersionRequirementException $e) {
73521 EventFacade::emitter()->testRunnerTriggeredPhpunitWarning(sprintf('Class %s is annotated using an invalid version requirement: %s', $className, $e->getMessage()));
73522 }
73523 return MetadataCollection::fromArray($result);
73524 }
73525 /**
73526 * @psalm-param class-string $className
73527 * @psalm-param non-empty-string $methodName
73528 *
73529 * @throws AnnotationsAreNotSupportedForInternalClassesException
73530 * @throws InvalidVersionOperatorException
73531 * @throws ReflectionException
73532 */
73533 public function forMethod(string $className, string $methodName): MetadataCollection
73534 {
73535 assert(class_exists($className));
73536 assert(method_exists($className, $methodName));
73537 $result = [];
73538 foreach (AnnotationRegistry::getInstance()->forMethod($className, $methodName)->symbolAnnotations() as $annotation => $values) {
73539 switch ($annotation) {
73540 case 'after':
73541 $result[] = Metadata::after();
73542 break;
73543 case 'afterClass':
73544 $result[] = Metadata::afterClass();
73545 break;
73546 case 'backupGlobals':
73547 $result[] = Metadata::backupGlobalsOnMethod($this->stringToBool($values[0]));
73548 break;
73549 case 'backupStaticAttributes':
73550 case 'backupStaticProperties':
73551 $result[] = Metadata::backupStaticPropertiesOnMethod($this->stringToBool($values[0]));
73552 break;
73553 case 'before':
73554 $result[] = Metadata::before();
73555 break;
73556 case 'beforeClass':
73557 $result[] = Metadata::beforeClass();
73558 break;
73559 case 'covers':
73560 foreach ($values as $value) {
73561 $value = $this->cleanUpCoversOrUsesTarget($value);
73562 $result[] = Metadata::coversOnMethod($value);
73563 }
73564 break;
73565 case 'coversNothing':
73566 $result[] = Metadata::coversNothingOnMethod();
73567 break;
73568 case 'dataProvider':
73569 foreach ($values as $value) {
73570 $value = rtrim($value, " ()\n\r\t\v\x00");
73571 if (str_contains($value, '::')) {
73572 $result[] = Metadata::dataProvider(...explode('::', $value));
73573 continue;
73574 }
73575 $result[] = Metadata::dataProvider($className, $value);
73576 }
73577 break;
73578 case 'depends':
73579 foreach ($values as $value) {
73580 $deepClone = \false;
73581 $shallowClone = \false;
73582 if (str_starts_with($value, 'clone ')) {
73583 $deepClone = \true;
73584 $value = substr($value, strlen('clone '));
73585 } elseif (str_starts_with($value, '!clone ')) {
73586 $value = substr($value, strlen('!clone '));
73587 } elseif (str_starts_with($value, 'shallowClone ')) {
73588 $shallowClone = \true;
73589 $value = substr($value, strlen('shallowClone '));
73590 } elseif (str_starts_with($value, '!shallowClone ')) {
73591 $value = substr($value, strlen('!shallowClone '));
73592 }
73593 if (str_contains($value, '::')) {
73594 [$_className, $_methodName] = explode('::', $value);
73595 assert($_className !== '');
73596 assert($_methodName !== '');
73597 if ($_methodName === 'class') {
73598 $result[] = Metadata::dependsOnClass($_className, $deepClone, $shallowClone);
73599 continue;
73600 }
73601 $result[] = Metadata::dependsOnMethod($_className, $_methodName, $deepClone, $shallowClone);
73602 continue;
73603 }
73604 $result[] = Metadata::dependsOnMethod($className, $value, $deepClone, $shallowClone);
73605 }
73606 break;
73607 case 'doesNotPerformAssertions':
73608 $result[] = Metadata::doesNotPerformAssertionsOnMethod();
73609 break;
73610 case 'excludeGlobalVariableFromBackup':
73611 foreach ($values as $value) {
73612 $result[] = Metadata::excludeGlobalVariableFromBackupOnMethod($value);
73613 }
73614 break;
73615 case 'excludeStaticPropertyFromBackup':
73616 foreach ($values as $value) {
73617 $tmp = explode(' ', $value);
73618 if (count($tmp) !== 2) {
73619 continue;
73620 }
73621 $result[] = Metadata::excludeStaticPropertyFromBackupOnMethod(trim($tmp[0]), trim($tmp[1]));
73622 }
73623 break;
73624 case 'group':
73625 case 'ticket':
73626 foreach ($values as $value) {
73627 $result[] = Metadata::groupOnMethod($value);
73628 }
73629 break;
73630 case 'large':
73631 $result[] = Metadata::groupOnMethod('large');
73632 break;
73633 case 'medium':
73634 $result[] = Metadata::groupOnMethod('medium');
73635 break;
73636 case 'postCondition':
73637 $result[] = Metadata::postCondition();
73638 break;
73639 case 'preCondition':
73640 $result[] = Metadata::preCondition();
73641 break;
73642 case 'preserveGlobalState':
73643 $result[] = Metadata::preserveGlobalStateOnMethod($this->stringToBool($values[0]));
73644 break;
73645 case 'runInSeparateProcess':
73646 $result[] = Metadata::runInSeparateProcess();
73647 break;
73648 case 'small':
73649 $result[] = Metadata::groupOnMethod('small');
73650 break;
73651 case 'test':
73652 $result[] = Metadata::test();
73653 break;
73654 case 'testdox':
73655 $result[] = Metadata::testDoxOnMethod($values[0]);
73656 break;
73657 case 'uses':
73658 foreach ($values as $value) {
73659 $value = $this->cleanUpCoversOrUsesTarget($value);
73660 $result[] = Metadata::usesOnMethod($value);
73661 }
73662 break;
73663 }
73664 }
73665 if (method_exists($className, $methodName)) {
73666 try {
73667 $result = array_merge($result, $this->parseRequirements(AnnotationRegistry::getInstance()->forMethod($className, $methodName)->requirements(), 'method'));
73668 } catch (InvalidVersionRequirementException $e) {
73669 EventFacade::emitter()->testRunnerTriggeredPhpunitWarning(sprintf('Method %s::%s is annotated using an invalid version requirement: %s', $className, $methodName, $e->getMessage()));
73670 }
73671 }
73672 return MetadataCollection::fromArray($result);
73673 }
73674 /**
73675 * @psalm-param class-string $className
73676 * @psalm-param non-empty-string $methodName
73677 *
73678 * @throws AnnotationsAreNotSupportedForInternalClassesException
73679 * @throws InvalidVersionOperatorException
73680 * @throws ReflectionException
73681 */
73682 public function forClassAndMethod(string $className, string $methodName): MetadataCollection
73683 {
73684 return $this->forClass($className)->mergeWith($this->forMethod($className, $methodName));
73685 }
73686 private function stringToBool(string $value): bool
73687 {
73688 if ($value === 'enabled') {
73689 return \true;
73690 }
73691 return \false;
73692 }
73693 private function cleanUpCoversOrUsesTarget(string $value): string
73694 {
73695 $value = preg_replace('/[\s()]+$/', '', $value);
73696 return explode(' ', $value, 2)[0];
73697 }
73698 /**
73699 * @throws InvalidVersionOperatorException
73700 *
73701 * @psalm-return list<Metadata>
73702 */
73703 private function parseRequirements(array $requirements, string $level): array
73704 {
73705 $result = [];
73706 if (!empty($requirements['PHP'])) {
73707 $versionRequirement = new ComparisonRequirement($requirements['PHP']['version'], new VersionComparisonOperator(empty($requirements['PHP']['operator']) ? '>=' : $requirements['PHP']['operator']));
73708 if ($level === 'class') {
73709 $result[] = Metadata::requiresPhpOnClass($versionRequirement);
73710 } else {
73711 $result[] = Metadata::requiresPhpOnMethod($versionRequirement);
73712 }
73713 } elseif (!empty($requirements['PHP_constraint'])) {
73714 $versionRequirement = new ConstraintRequirement($requirements['PHP_constraint']['constraint']);
73715 if ($level === 'class') {
73716 $result[] = Metadata::requiresPhpOnClass($versionRequirement);
73717 } else {
73718 $result[] = Metadata::requiresPhpOnMethod($versionRequirement);
73719 }
73720 }
73721 if (!empty($requirements['extensions'])) {
73722 foreach ($requirements['extensions'] as $extension) {
73723 if (isset($requirements['extension_versions'][$extension])) {
73724 continue;
73725 }
73726 if ($level === 'class') {
73727 $result[] = Metadata::requiresPhpExtensionOnClass($extension, null);
73728 } else {
73729 $result[] = Metadata::requiresPhpExtensionOnMethod($extension, null);
73730 }
73731 }
73732 }
73733 if (!empty($requirements['extension_versions'])) {
73734 foreach ($requirements['extension_versions'] as $extension => $version) {
73735 $versionRequirement = new ComparisonRequirement($version['version'], new VersionComparisonOperator(empty($version['operator']) ? '>=' : $version['operator']));
73736 if ($level === 'class') {
73737 $result[] = Metadata::requiresPhpExtensionOnClass($extension, $versionRequirement);
73738 } else {
73739 $result[] = Metadata::requiresPhpExtensionOnMethod($extension, $versionRequirement);
73740 }
73741 }
73742 }
73743 if (!empty($requirements['PHPUnit'])) {
73744 $versionRequirement = new ComparisonRequirement($requirements['PHPUnit']['version'], new VersionComparisonOperator(empty($requirements['PHPUnit']['operator']) ? '>=' : $requirements['PHPUnit']['operator']));
73745 if ($level === 'class') {
73746 $result[] = Metadata::requiresPhpunitOnClass($versionRequirement);
73747 } else {
73748 $result[] = Metadata::requiresPhpunitOnMethod($versionRequirement);
73749 }
73750 } elseif (!empty($requirements['PHPUnit_constraint'])) {
73751 $versionRequirement = new ConstraintRequirement($requirements['PHPUnit_constraint']['constraint']);
73752 if ($level === 'class') {
73753 $result[] = Metadata::requiresPhpunitOnClass($versionRequirement);
73754 } else {
73755 $result[] = Metadata::requiresPhpunitOnMethod($versionRequirement);
73756 }
73757 }
73758 if (!empty($requirements['OSFAMILY'])) {
73759 if ($level === 'class') {
73760 $result[] = Metadata::requiresOperatingSystemFamilyOnClass($requirements['OSFAMILY']);
73761 } else {
73762 $result[] = Metadata::requiresOperatingSystemFamilyOnMethod($requirements['OSFAMILY']);
73763 }
73764 }
73765 if (!empty($requirements['OS'])) {
73766 if ($level === 'class') {
73767 $result[] = Metadata::requiresOperatingSystemOnClass($requirements['OS']);
73768 } else {
73769 $result[] = Metadata::requiresOperatingSystemOnMethod($requirements['OS']);
73770 }
73771 }
73772 if (!empty($requirements['functions'])) {
73773 foreach ($requirements['functions'] as $function) {
73774 $pieces = explode('::', $function);
73775 if (count($pieces) === 2) {
73776 if ($level === 'class') {
73777 $result[] = Metadata::requiresMethodOnClass($pieces[0], $pieces[1]);
73778 } else {
73779 $result[] = Metadata::requiresMethodOnMethod($pieces[0], $pieces[1]);
73780 }
73781 } elseif ($level === 'class') {
73782 $result[] = Metadata::requiresFunctionOnClass($function);
73783 } else {
73784 $result[] = Metadata::requiresFunctionOnMethod($function);
73785 }
73786 }
73787 }
73788 if (!empty($requirements['setting'])) {
73789 foreach ($requirements['setting'] as $setting => $value) {
73790 if ($level === 'class') {
73791 $result[] = Metadata::requiresSettingOnClass($setting, $value);
73792 } else {
73793 $result[] = Metadata::requiresSettingOnMethod($setting, $value);
73794 }
73795 }
73796 }
73797 return $result;
73798 }
73799 }
73800 <?php
73801
73802 declare (strict_types=1);
73803 /*
73804 * This file is part of PHPUnit.
73805 *
73806 * (c) Sebastian Bergmann <sebastian@phpunit.de>
73807 *
73808 * For the full copyright and license information, please view the LICENSE
73809 * file that was distributed with this source code.
73810 */
73811 namespace PHPUnit\Metadata\Parser;
73812
73813 use const JSON_THROW_ON_ERROR;
73814 use function assert;
73815 use function class_exists;
73816 use function json_decode;
73817 use function method_exists;
73818 use function str_starts_with;
73819 use Error;
73820 use PHPUnit\Framework\Attributes\After;
73821 use PHPUnit\Framework\Attributes\AfterClass;
73822 use PHPUnit\Framework\Attributes\BackupGlobals;
73823 use PHPUnit\Framework\Attributes\BackupStaticProperties;
73824 use PHPUnit\Framework\Attributes\Before;
73825 use PHPUnit\Framework\Attributes\BeforeClass;
73826 use PHPUnit\Framework\Attributes\CoversClass;
73827 use PHPUnit\Framework\Attributes\CoversFunction;
73828 use PHPUnit\Framework\Attributes\CoversNothing;
73829 use PHPUnit\Framework\Attributes\DataProvider;
73830 use PHPUnit\Framework\Attributes\DataProviderExternal;
73831 use PHPUnit\Framework\Attributes\Depends;
73832 use PHPUnit\Framework\Attributes\DependsExternal;
73833 use PHPUnit\Framework\Attributes\DependsExternalUsingDeepClone;
73834 use PHPUnit\Framework\Attributes\DependsExternalUsingShallowClone;
73835 use PHPUnit\Framework\Attributes\DependsOnClass;
73836 use PHPUnit\Framework\Attributes\DependsOnClassUsingDeepClone;
73837 use PHPUnit\Framework\Attributes\DependsOnClassUsingShallowClone;
73838 use PHPUnit\Framework\Attributes\DependsUsingDeepClone;
73839 use PHPUnit\Framework\Attributes\DependsUsingShallowClone;
73840 use PHPUnit\Framework\Attributes\DoesNotPerformAssertions;
73841 use PHPUnit\Framework\Attributes\ExcludeGlobalVariableFromBackup;
73842 use PHPUnit\Framework\Attributes\ExcludeStaticPropertyFromBackup;
73843 use PHPUnit\Framework\Attributes\Group;
73844 use PHPUnit\Framework\Attributes\IgnoreClassForCodeCoverage;
73845 use PHPUnit\Framework\Attributes\IgnoreDeprecations;
73846 use PHPUnit\Framework\Attributes\IgnoreFunctionForCodeCoverage;
73847 use PHPUnit\Framework\Attributes\IgnoreMethodForCodeCoverage;
73848 use PHPUnit\Framework\Attributes\Large;
73849 use PHPUnit\Framework\Attributes\Medium;
73850 use PHPUnit\Framework\Attributes\PostCondition;
73851 use PHPUnit\Framework\Attributes\PreCondition;
73852 use PHPUnit\Framework\Attributes\PreserveGlobalState;
73853 use PHPUnit\Framework\Attributes\RequiresFunction;
73854 use PHPUnit\Framework\Attributes\RequiresMethod;
73855 use PHPUnit\Framework\Attributes\RequiresOperatingSystem;
73856 use PHPUnit\Framework\Attributes\RequiresOperatingSystemFamily;
73857 use PHPUnit\Framework\Attributes\RequiresPhp;
73858 use PHPUnit\Framework\Attributes\RequiresPhpExtension;
73859 use PHPUnit\Framework\Attributes\RequiresPhpunit;
73860 use PHPUnit\Framework\Attributes\RequiresSetting;
73861 use PHPUnit\Framework\Attributes\RunClassInSeparateProcess;
73862 use PHPUnit\Framework\Attributes\RunInSeparateProcess;
73863 use PHPUnit\Framework\Attributes\RunTestsInSeparateProcesses;
73864 use PHPUnit\Framework\Attributes\Small;
73865 use PHPUnit\Framework\Attributes\Test;
73866 use PHPUnit\Framework\Attributes\TestDox;
73867 use PHPUnit\Framework\Attributes\TestWith;
73868 use PHPUnit\Framework\Attributes\TestWithJson;
73869 use PHPUnit\Framework\Attributes\Ticket;
73870 use PHPUnit\Framework\Attributes\UsesClass;
73871 use PHPUnit\Framework\Attributes\UsesFunction;
73872 use PHPUnit\Framework\Attributes\WithoutErrorHandler;
73873 use PHPUnit\Metadata\InvalidAttributeException;
73874 use PHPUnit\Metadata\Metadata;
73875 use PHPUnit\Metadata\MetadataCollection;
73876 use PHPUnit\Metadata\Version\Requirement;
73877 use ReflectionClass;
73878 use ReflectionMethod;
73879 /**
73880 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
73881 *
73882 * @internal This class is not covered by the backward compatibility promise for PHPUnit
73883 */
73884 final class AttributeParser implements \PHPUnit\Metadata\Parser\Parser
73885 {
73886 /**
73887 * @psalm-param class-string $className
73888 */
73889 public function forClass(string $className): MetadataCollection
73890 {
73891 assert(class_exists($className));
73892 $reflector = new ReflectionClass($className);
73893 $result = [];
73894 foreach ($reflector->getAttributes() as $attribute) {
73895 if (!str_starts_with($attribute->getName(), 'PHPUnit\Framework\Attributes\\')) {
73896 continue;
73897 }
73898 if (!class_exists($attribute->getName())) {
73899 continue;
73900 }
73901 try {
73902 $attributeInstance = $attribute->newInstance();
73903 } catch (Error $e) {
73904 throw new InvalidAttributeException($attribute->getName(), 'class ' . $className, $reflector->getFileName(), $reflector->getStartLine(), $e->getMessage());
73905 }
73906 switch ($attribute->getName()) {
73907 case BackupGlobals::class:
73908 assert($attributeInstance instanceof BackupGlobals);
73909 $result[] = Metadata::backupGlobalsOnClass($attributeInstance->enabled());
73910 break;
73911 case BackupStaticProperties::class:
73912 assert($attributeInstance instanceof BackupStaticProperties);
73913 $result[] = Metadata::backupStaticPropertiesOnClass($attributeInstance->enabled());
73914 break;
73915 case CoversClass::class:
73916 assert($attributeInstance instanceof CoversClass);
73917 $result[] = Metadata::coversClass($attributeInstance->className());
73918 break;
73919 case CoversFunction::class:
73920 assert($attributeInstance instanceof CoversFunction);
73921 $result[] = Metadata::coversFunction($attributeInstance->functionName());
73922 break;
73923 case CoversNothing::class:
73924 $result[] = Metadata::coversNothingOnClass();
73925 break;
73926 case DoesNotPerformAssertions::class:
73927 $result[] = Metadata::doesNotPerformAssertionsOnClass();
73928 break;
73929 case ExcludeGlobalVariableFromBackup::class:
73930 assert($attributeInstance instanceof ExcludeGlobalVariableFromBackup);
73931 $result[] = Metadata::excludeGlobalVariableFromBackupOnClass($attributeInstance->globalVariableName());
73932 break;
73933 case ExcludeStaticPropertyFromBackup::class:
73934 assert($attributeInstance instanceof ExcludeStaticPropertyFromBackup);
73935 $result[] = Metadata::excludeStaticPropertyFromBackupOnClass($attributeInstance->className(), $attributeInstance->propertyName());
73936 break;
73937 case Group::class:
73938 assert($attributeInstance instanceof Group);
73939 $result[] = Metadata::groupOnClass($attributeInstance->name());
73940 break;
73941 case Large::class:
73942 $result[] = Metadata::groupOnClass('large');
73943 break;
73944 case Medium::class:
73945 $result[] = Metadata::groupOnClass('medium');
73946 break;
73947 case IgnoreClassForCodeCoverage::class:
73948 assert($attributeInstance instanceof IgnoreClassForCodeCoverage);
73949 $result[] = Metadata::ignoreClassForCodeCoverage($attributeInstance->className());
73950 break;
73951 case IgnoreDeprecations::class:
73952 assert($attributeInstance instanceof IgnoreDeprecations);
73953 $result[] = Metadata::ignoreDeprecationsOnClass();
73954 break;
73955 case IgnoreMethodForCodeCoverage::class:
73956 assert($attributeInstance instanceof IgnoreMethodForCodeCoverage);
73957 $result[] = Metadata::ignoreMethodForCodeCoverage($attributeInstance->className(), $attributeInstance->methodName());
73958 break;
73959 case IgnoreFunctionForCodeCoverage::class:
73960 assert($attributeInstance instanceof IgnoreFunctionForCodeCoverage);
73961 $result[] = Metadata::ignoreFunctionForCodeCoverage($attributeInstance->functionName());
73962 break;
73963 case PreserveGlobalState::class:
73964 assert($attributeInstance instanceof PreserveGlobalState);
73965 $result[] = Metadata::preserveGlobalStateOnClass($attributeInstance->enabled());
73966 break;
73967 case RequiresMethod::class:
73968 assert($attributeInstance instanceof RequiresMethod);
73969 $result[] = Metadata::requiresMethodOnClass($attributeInstance->className(), $attributeInstance->methodName());
73970 break;
73971 case RequiresFunction::class:
73972 assert($attributeInstance instanceof RequiresFunction);
73973 $result[] = Metadata::requiresFunctionOnClass($attributeInstance->functionName());
73974 break;
73975 case RequiresOperatingSystem::class:
73976 assert($attributeInstance instanceof RequiresOperatingSystem);
73977 $result[] = Metadata::requiresOperatingSystemOnClass($attributeInstance->regularExpression());
73978 break;
73979 case RequiresOperatingSystemFamily::class:
73980 assert($attributeInstance instanceof RequiresOperatingSystemFamily);
73981 $result[] = Metadata::requiresOperatingSystemFamilyOnClass($attributeInstance->operatingSystemFamily());
73982 break;
73983 case RequiresPhp::class:
73984 assert($attributeInstance instanceof RequiresPhp);
73985 $result[] = Metadata::requiresPhpOnClass(Requirement::from($attributeInstance->versionRequirement()));
73986 break;
73987 case RequiresPhpExtension::class:
73988 assert($attributeInstance instanceof RequiresPhpExtension);
73989 $versionConstraint = null;
73990 $versionRequirement = $attributeInstance->versionRequirement();
73991 if ($versionRequirement !== null) {
73992 $versionConstraint = Requirement::from($versionRequirement);
73993 }
73994 $result[] = Metadata::requiresPhpExtensionOnClass($attributeInstance->extension(), $versionConstraint);
73995 break;
73996 case RequiresPhpunit::class:
73997 assert($attributeInstance instanceof RequiresPhpunit);
73998 $result[] = Metadata::requiresPhpunitOnClass(Requirement::from($attributeInstance->versionRequirement()));
73999 break;
74000 case RequiresSetting::class:
74001 assert($attributeInstance instanceof RequiresSetting);
74002 $result[] = Metadata::requiresSettingOnClass($attributeInstance->setting(), $attributeInstance->value());
74003 break;
74004 case RunClassInSeparateProcess::class:
74005 $result[] = Metadata::runClassInSeparateProcess();
74006 break;
74007 case RunTestsInSeparateProcesses::class:
74008 $result[] = Metadata::runTestsInSeparateProcesses();
74009 break;
74010 case Small::class:
74011 $result[] = Metadata::groupOnClass('small');
74012 break;
74013 case TestDox::class:
74014 assert($attributeInstance instanceof TestDox);
74015 $result[] = Metadata::testDoxOnClass($attributeInstance->text());
74016 break;
74017 case Ticket::class:
74018 assert($attributeInstance instanceof Ticket);
74019 $result[] = Metadata::groupOnClass($attributeInstance->text());
74020 break;
74021 case UsesClass::class:
74022 assert($attributeInstance instanceof UsesClass);
74023 $result[] = Metadata::usesClass($attributeInstance->className());
74024 break;
74025 case UsesFunction::class:
74026 assert($attributeInstance instanceof UsesFunction);
74027 $result[] = Metadata::usesFunction($attributeInstance->functionName());
74028 break;
74029 }
74030 }
74031 return MetadataCollection::fromArray($result);
74032 }
74033 /**
74034 * @psalm-param class-string $className
74035 * @psalm-param non-empty-string $methodName
74036 */
74037 public function forMethod(string $className, string $methodName): MetadataCollection
74038 {
74039 assert(class_exists($className));
74040 assert(method_exists($className, $methodName));
74041 $reflector = new ReflectionMethod($className, $methodName);
74042 $result = [];
74043 foreach ($reflector->getAttributes() as $attribute) {
74044 if (!str_starts_with($attribute->getName(), 'PHPUnit\Framework\Attributes\\')) {
74045 continue;
74046 }
74047 if (!class_exists($attribute->getName())) {
74048 continue;
74049 }
74050 try {
74051 $attributeInstance = $attribute->newInstance();
74052 } catch (Error $e) {
74053 throw new InvalidAttributeException($attribute->getName(), 'method ' . $className . '::' . $methodName . '()', $reflector->getFileName(), $reflector->getStartLine(), $e->getMessage());
74054 }
74055 switch ($attribute->getName()) {
74056 case After::class:
74057 $result[] = Metadata::after();
74058 break;
74059 case AfterClass::class:
74060 $result[] = Metadata::afterClass();
74061 break;
74062 case BackupGlobals::class:
74063 assert($attributeInstance instanceof BackupGlobals);
74064 $result[] = Metadata::backupGlobalsOnMethod($attributeInstance->enabled());
74065 break;
74066 case BackupStaticProperties::class:
74067 assert($attributeInstance instanceof BackupStaticProperties);
74068 $result[] = Metadata::backupStaticPropertiesOnMethod($attributeInstance->enabled());
74069 break;
74070 case Before::class:
74071 $result[] = Metadata::before();
74072 break;
74073 case BeforeClass::class:
74074 $result[] = Metadata::beforeClass();
74075 break;
74076 case CoversNothing::class:
74077 $result[] = Metadata::coversNothingOnMethod();
74078 break;
74079 case DataProvider::class:
74080 assert($attributeInstance instanceof DataProvider);
74081 $result[] = Metadata::dataProvider($className, $attributeInstance->methodName());
74082 break;
74083 case DataProviderExternal::class:
74084 assert($attributeInstance instanceof DataProviderExternal);
74085 $result[] = Metadata::dataProvider($attributeInstance->className(), $attributeInstance->methodName());
74086 break;
74087 case Depends::class:
74088 assert($attributeInstance instanceof Depends);
74089 $result[] = Metadata::dependsOnMethod($className, $attributeInstance->methodName(), \false, \false);
74090 break;
74091 case DependsUsingDeepClone::class:
74092 assert($attributeInstance instanceof DependsUsingDeepClone);
74093 $result[] = Metadata::dependsOnMethod($className, $attributeInstance->methodName(), \true, \false);
74094 break;
74095 case DependsUsingShallowClone::class:
74096 assert($attributeInstance instanceof DependsUsingShallowClone);
74097 $result[] = Metadata::dependsOnMethod($className, $attributeInstance->methodName(), \false, \true);
74098 break;
74099 case DependsExternal::class:
74100 assert($attributeInstance instanceof DependsExternal);
74101 $result[] = Metadata::dependsOnMethod($attributeInstance->className(), $attributeInstance->methodName(), \false, \false);
74102 break;
74103 case DependsExternalUsingDeepClone::class:
74104 assert($attributeInstance instanceof DependsExternalUsingDeepClone);
74105 $result[] = Metadata::dependsOnMethod($attributeInstance->className(), $attributeInstance->methodName(), \true, \false);
74106 break;
74107 case DependsExternalUsingShallowClone::class:
74108 assert($attributeInstance instanceof DependsExternalUsingShallowClone);
74109 $result[] = Metadata::dependsOnMethod($attributeInstance->className(), $attributeInstance->methodName(), \false, \true);
74110 break;
74111 case DependsOnClass::class:
74112 assert($attributeInstance instanceof DependsOnClass);
74113 $result[] = Metadata::dependsOnClass($attributeInstance->className(), \false, \false);
74114 break;
74115 case DependsOnClassUsingDeepClone::class:
74116 assert($attributeInstance instanceof DependsOnClassUsingDeepClone);
74117 $result[] = Metadata::dependsOnClass($attributeInstance->className(), \true, \false);
74118 break;
74119 case DependsOnClassUsingShallowClone::class:
74120 assert($attributeInstance instanceof DependsOnClassUsingShallowClone);
74121 $result[] = Metadata::dependsOnClass($attributeInstance->className(), \false, \true);
74122 break;
74123 case DoesNotPerformAssertions::class:
74124 assert($attributeInstance instanceof DoesNotPerformAssertions);
74125 $result[] = Metadata::doesNotPerformAssertionsOnMethod();
74126 break;
74127 case ExcludeGlobalVariableFromBackup::class:
74128 assert($attributeInstance instanceof ExcludeGlobalVariableFromBackup);
74129 $result[] = Metadata::excludeGlobalVariableFromBackupOnMethod($attributeInstance->globalVariableName());
74130 break;
74131 case ExcludeStaticPropertyFromBackup::class:
74132 assert($attributeInstance instanceof ExcludeStaticPropertyFromBackup);
74133 $result[] = Metadata::excludeStaticPropertyFromBackupOnMethod($attributeInstance->className(), $attributeInstance->propertyName());
74134 break;
74135 case Group::class:
74136 assert($attributeInstance instanceof Group);
74137 $result[] = Metadata::groupOnMethod($attributeInstance->name());
74138 break;
74139 case IgnoreDeprecations::class:
74140 assert($attributeInstance instanceof IgnoreDeprecations);
74141 $result[] = Metadata::ignoreDeprecationsOnMethod();
74142 break;
74143 case PostCondition::class:
74144 $result[] = Metadata::postCondition();
74145 break;
74146 case PreCondition::class:
74147 $result[] = Metadata::preCondition();
74148 break;
74149 case PreserveGlobalState::class:
74150 assert($attributeInstance instanceof PreserveGlobalState);
74151 $result[] = Metadata::preserveGlobalStateOnMethod($attributeInstance->enabled());
74152 break;
74153 case RequiresMethod::class:
74154 assert($attributeInstance instanceof RequiresMethod);
74155 $result[] = Metadata::requiresMethodOnMethod($attributeInstance->className(), $attributeInstance->methodName());
74156 break;
74157 case RequiresFunction::class:
74158 assert($attributeInstance instanceof RequiresFunction);
74159 $result[] = Metadata::requiresFunctionOnMethod($attributeInstance->functionName());
74160 break;
74161 case RequiresOperatingSystem::class:
74162 assert($attributeInstance instanceof RequiresOperatingSystem);
74163 $result[] = Metadata::requiresOperatingSystemOnMethod($attributeInstance->regularExpression());
74164 break;
74165 case RequiresOperatingSystemFamily::class:
74166 assert($attributeInstance instanceof RequiresOperatingSystemFamily);
74167 $result[] = Metadata::requiresOperatingSystemFamilyOnMethod($attributeInstance->operatingSystemFamily());
74168 break;
74169 case RequiresPhp::class:
74170 assert($attributeInstance instanceof RequiresPhp);
74171 $result[] = Metadata::requiresPhpOnMethod(Requirement::from($attributeInstance->versionRequirement()));
74172 break;
74173 case RequiresPhpExtension::class:
74174 assert($attributeInstance instanceof RequiresPhpExtension);
74175 $versionConstraint = null;
74176 $versionRequirement = $attributeInstance->versionRequirement();
74177 if ($versionRequirement !== null) {
74178 $versionConstraint = Requirement::from($versionRequirement);
74179 }
74180 $result[] = Metadata::requiresPhpExtensionOnMethod($attributeInstance->extension(), $versionConstraint);
74181 break;
74182 case RequiresPhpunit::class:
74183 assert($attributeInstance instanceof RequiresPhpunit);
74184 $result[] = Metadata::requiresPhpunitOnMethod(Requirement::from($attributeInstance->versionRequirement()));
74185 break;
74186 case RequiresSetting::class:
74187 assert($attributeInstance instanceof RequiresSetting);
74188 $result[] = Metadata::requiresSettingOnMethod($attributeInstance->setting(), $attributeInstance->value());
74189 break;
74190 case RunInSeparateProcess::class:
74191 $result[] = Metadata::runInSeparateProcess();
74192 break;
74193 case Test::class:
74194 $result[] = Metadata::test();
74195 break;
74196 case TestDox::class:
74197 assert($attributeInstance instanceof TestDox);
74198 $result[] = Metadata::testDoxOnMethod($attributeInstance->text());
74199 break;
74200 case TestWith::class:
74201 assert($attributeInstance instanceof TestWith);
74202 $result[] = Metadata::testWith($attributeInstance->data());
74203 break;
74204 case TestWithJson::class:
74205 assert($attributeInstance instanceof TestWithJson);
74206 $result[] = Metadata::testWith(json_decode($attributeInstance->json(), \true, 512, JSON_THROW_ON_ERROR));
74207 break;
74208 case Ticket::class:
74209 assert($attributeInstance instanceof Ticket);
74210 $result[] = Metadata::groupOnMethod($attributeInstance->text());
74211 break;
74212 case WithoutErrorHandler::class:
74213 assert($attributeInstance instanceof WithoutErrorHandler);
74214 $result[] = Metadata::withoutErrorHandler();
74215 break;
74216 }
74217 }
74218 return MetadataCollection::fromArray($result);
74219 }
74220 /**
74221 * @psalm-param class-string $className
74222 * @psalm-param non-empty-string $methodName
74223 */
74224 public function forClassAndMethod(string $className, string $methodName): MetadataCollection
74225 {
74226 return $this->forClass($className)->mergeWith($this->forMethod($className, $methodName));
74227 }
74228 }
74229 <?php
74230
74231 declare (strict_types=1);
74232 /*
74233 * This file is part of PHPUnit.
74234 *
74235 * (c) Sebastian Bergmann <sebastian@phpunit.de>
74236 *
74237 * For the full copyright and license information, please view the LICENSE
74238 * file that was distributed with this source code.
74239 */
74240 namespace PHPUnit\Metadata\Parser;
74241
74242 use function assert;
74243 use function class_exists;
74244 use function method_exists;
74245 use PHPUnit\Metadata\MetadataCollection;
74246 /**
74247 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
74248 *
74249 * @internal This class is not covered by the backward compatibility promise for PHPUnit
74250 */
74251 final class CachingParser implements \PHPUnit\Metadata\Parser\Parser
74252 {
74253 private readonly \PHPUnit\Metadata\Parser\Parser $reader;
74254 private array $classCache = [];
74255 private array $methodCache = [];
74256 private array $classAndMethodCache = [];
74257 public function __construct(\PHPUnit\Metadata\Parser\Parser $reader)
74258 {
74259 $this->reader = $reader;
74260 }
74261 /**
74262 * @psalm-param class-string $className
74263 */
74264 public function forClass(string $className): MetadataCollection
74265 {
74266 assert(class_exists($className));
74267 if (isset($this->classCache[$className])) {
74268 return $this->classCache[$className];
74269 }
74270 $this->classCache[$className] = $this->reader->forClass($className);
74271 return $this->classCache[$className];
74272 }
74273 /**
74274 * @psalm-param class-string $className
74275 * @psalm-param non-empty-string $methodName
74276 */
74277 public function forMethod(string $className, string $methodName): MetadataCollection
74278 {
74279 assert(class_exists($className));
74280 assert(method_exists($className, $methodName));
74281 $key = $className . '::' . $methodName;
74282 if (isset($this->methodCache[$key])) {
74283 return $this->methodCache[$key];
74284 }
74285 $this->methodCache[$key] = $this->reader->forMethod($className, $methodName);
74286 return $this->methodCache[$key];
74287 }
74288 /**
74289 * @psalm-param class-string $className
74290 * @psalm-param non-empty-string $methodName
74291 */
74292 public function forClassAndMethod(string $className, string $methodName): MetadataCollection
74293 {
74294 $key = $className . '::' . $methodName;
74295 if (isset($this->classAndMethodCache[$key])) {
74296 return $this->classAndMethodCache[$key];
74297 }
74298 $this->classAndMethodCache[$key] = $this->forClass($className)->mergeWith($this->forMethod($className, $methodName));
74299 return $this->classAndMethodCache[$key];
74300 }
74301 }
74302 <?php
74303
74304 declare (strict_types=1);
74305 /*
74306 * This file is part of PHPUnit.
74307 *
74308 * (c) Sebastian Bergmann <sebastian@phpunit.de>
74309 *
74310 * For the full copyright and license information, please view the LICENSE
74311 * file that was distributed with this source code.
74312 */
74313 namespace PHPUnit\Metadata\Parser;
74314
74315 use PHPUnit\Metadata\MetadataCollection;
74316 /**
74317 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
74318 *
74319 * @internal This interface is not covered by the backward compatibility promise for PHPUnit
74320 */
74321 interface Parser
74322 {
74323 /**
74324 * @psalm-param class-string $className
74325 */
74326 public function forClass(string $className): MetadataCollection;
74327 /**
74328 * @psalm-param class-string $className
74329 * @psalm-param non-empty-string $methodName
74330 */
74331 public function forMethod(string $className, string $methodName): MetadataCollection;
74332 /**
74333 * @psalm-param class-string $className
74334 * @psalm-param non-empty-string $methodName
74335 */
74336 public function forClassAndMethod(string $className, string $methodName): MetadataCollection;
74337 }
74338 <?php
74339
74340 declare (strict_types=1);
74341 /*
74342 * This file is part of PHPUnit.
74343 *
74344 * (c) Sebastian Bergmann <sebastian@phpunit.de>
74345 *
74346 * For the full copyright and license information, please view the LICENSE
74347 * file that was distributed with this source code.
74348 */
74349 namespace PHPUnit\Metadata\Parser;
74350
74351 use function assert;
74352 use function class_exists;
74353 use function method_exists;
74354 use PHPUnit\Metadata\MetadataCollection;
74355 /**
74356 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
74357 *
74358 * @internal This class is not covered by the backward compatibility promise for PHPUnit
74359 */
74360 final class ParserChain implements \PHPUnit\Metadata\Parser\Parser
74361 {
74362 private readonly \PHPUnit\Metadata\Parser\Parser $attributeReader;
74363 private readonly \PHPUnit\Metadata\Parser\Parser $annotationReader;
74364 public function __construct(\PHPUnit\Metadata\Parser\Parser $attributeReader, \PHPUnit\Metadata\Parser\Parser $annotationReader)
74365 {
74366 $this->attributeReader = $attributeReader;
74367 $this->annotationReader = $annotationReader;
74368 }
74369 /**
74370 * @psalm-param class-string $className
74371 */
74372 public function forClass(string $className): MetadataCollection
74373 {
74374 assert(class_exists($className));
74375 $metadata = $this->attributeReader->forClass($className);
74376 if (!$metadata->isEmpty()) {
74377 return $metadata;
74378 }
74379 return $this->annotationReader->forClass($className);
74380 }
74381 /**
74382 * @psalm-param class-string $className
74383 * @psalm-param non-empty-string $methodName
74384 */
74385 public function forMethod(string $className, string $methodName): MetadataCollection
74386 {
74387 assert(class_exists($className));
74388 assert(method_exists($className, $methodName));
74389 $metadata = $this->attributeReader->forMethod($className, $methodName);
74390 if (!$metadata->isEmpty()) {
74391 return $metadata;
74392 }
74393 return $this->annotationReader->forMethod($className, $methodName);
74394 }
74395 /**
74396 * @psalm-param class-string $className
74397 * @psalm-param non-empty-string $methodName
74398 */
74399 public function forClassAndMethod(string $className, string $methodName): MetadataCollection
74400 {
74401 return $this->forClass($className)->mergeWith($this->forMethod($className, $methodName));
74402 }
74403 }
74404 <?php
74405
74406 declare (strict_types=1);
74407 /*
74408 * This file is part of PHPUnit.
74409 *
74410 * (c) Sebastian Bergmann <sebastian@phpunit.de>
74411 *
74412 * For the full copyright and license information, please view the LICENSE
74413 * file that was distributed with this source code.
74414 */
74415 namespace PHPUnit\Metadata\Parser;
74416
74417 /**
74418 * Attribute and annotation information is static within a single PHP process.
74419 * It is therefore okay to use a Singleton registry here.
74420 *
74421 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
74422 *
74423 * @internal This class is not covered by the backward compatibility promise for PHPUnit
74424 */
74425 final class Registry
74426 {
74427 private static ?\PHPUnit\Metadata\Parser\Parser $instance = null;
74428 public static function parser(): \PHPUnit\Metadata\Parser\Parser
74429 {
74430 return self::$instance ?? self::$instance = self::build();
74431 }
74432 private static function build(): \PHPUnit\Metadata\Parser\Parser
74433 {
74434 return new \PHPUnit\Metadata\Parser\CachingParser(new \PHPUnit\Metadata\Parser\ParserChain(new \PHPUnit\Metadata\Parser\AttributeParser(), new \PHPUnit\Metadata\Parser\AnnotationParser()));
74435 }
74436 }
74437 <?php
74438
74439 declare (strict_types=1);
74440 /*
74441 * This file is part of PHPUnit.
74442 *
74443 * (c) Sebastian Bergmann <sebastian@phpunit.de>
74444 *
74445 * For the full copyright and license information, please view the LICENSE
74446 * file that was distributed with this source code.
74447 */
74448 namespace PHPUnit\Metadata;
74449
74450 /**
74451 * @psalm-immutable
74452 *
74453 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
74454 */
74455 final class PostCondition extends \PHPUnit\Metadata\Metadata
74456 {
74457 /**
74458 * @psalm-assert-if-true PostCondition $this
74459 */
74460 public function isPostCondition(): bool
74461 {
74462 return \true;
74463 }
74464 }
74465 <?php
74466
74467 declare (strict_types=1);
74468 /*
74469 * This file is part of PHPUnit.
74470 *
74471 * (c) Sebastian Bergmann <sebastian@phpunit.de>
74472 *
74473 * For the full copyright and license information, please view the LICENSE
74474 * file that was distributed with this source code.
74475 */
74476 namespace PHPUnit\Metadata;
74477
74478 /**
74479 * @psalm-immutable
74480 *
74481 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
74482 */
74483 final class PreCondition extends \PHPUnit\Metadata\Metadata
74484 {
74485 /**
74486 * @psalm-assert-if-true PreCondition $this
74487 */
74488 public function isPreCondition(): bool
74489 {
74490 return \true;
74491 }
74492 }
74493 <?php
74494
74495 declare (strict_types=1);
74496 /*
74497 * This file is part of PHPUnit.
74498 *
74499 * (c) Sebastian Bergmann <sebastian@phpunit.de>
74500 *
74501 * For the full copyright and license information, please view the LICENSE
74502 * file that was distributed with this source code.
74503 */
74504 namespace PHPUnit\Metadata;
74505
74506 /**
74507 * @psalm-immutable
74508 *
74509 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
74510 */
74511 final class PreserveGlobalState extends \PHPUnit\Metadata\Metadata
74512 {
74513 private readonly bool $enabled;
74514 /**
74515 * @psalm-param 0|1 $level
74516 */
74517 protected function __construct(int $level, bool $enabled)
74518 {
74519 parent::__construct($level);
74520 $this->enabled = $enabled;
74521 }
74522 /**
74523 * @psalm-assert-if-true PreserveGlobalState $this
74524 */
74525 public function isPreserveGlobalState(): bool
74526 {
74527 return \true;
74528 }
74529 public function enabled(): bool
74530 {
74531 return $this->enabled;
74532 }
74533 }
74534 <?php
74535
74536 declare (strict_types=1);
74537 /*
74538 * This file is part of PHPUnit.
74539 *
74540 * (c) Sebastian Bergmann <sebastian@phpunit.de>
74541 *
74542 * For the full copyright and license information, please view the LICENSE
74543 * file that was distributed with this source code.
74544 */
74545 namespace PHPUnit\Metadata;
74546
74547 /**
74548 * @psalm-immutable
74549 *
74550 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
74551 */
74552 final class RequiresFunction extends \PHPUnit\Metadata\Metadata
74553 {
74554 /**
74555 * @psalm-var non-empty-string
74556 */
74557 private readonly string $functionName;
74558 /**
74559 * @psalm-param 0|1 $level
74560 * @psalm-param non-empty-string $functionName
74561 */
74562 protected function __construct(int $level, string $functionName)
74563 {
74564 parent::__construct($level);
74565 $this->functionName = $functionName;
74566 }
74567 /**
74568 * @psalm-assert-if-true RequiresFunction $this
74569 */
74570 public function isRequiresFunction(): bool
74571 {
74572 return \true;
74573 }
74574 /**
74575 * @psalm-return non-empty-string
74576 */
74577 public function functionName(): string
74578 {
74579 return $this->functionName;
74580 }
74581 }
74582 <?php
74583
74584 declare (strict_types=1);
74585 /*
74586 * This file is part of PHPUnit.
74587 *
74588 * (c) Sebastian Bergmann <sebastian@phpunit.de>
74589 *
74590 * For the full copyright and license information, please view the LICENSE
74591 * file that was distributed with this source code.
74592 */
74593 namespace PHPUnit\Metadata;
74594
74595 /**
74596 * @psalm-immutable
74597 *
74598 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
74599 */
74600 final class RequiresMethod extends \PHPUnit\Metadata\Metadata
74601 {
74602 /**
74603 * @psalm-var class-string
74604 */
74605 private readonly string $className;
74606 /**
74607 * @psalm-var non-empty-string
74608 */
74609 private readonly string $methodName;
74610 /**
74611 * @psalm-param 0|1 $level
74612 * @psalm-param class-string $className
74613 * @psalm-param non-empty-string $methodName
74614 */
74615 protected function __construct(int $level, string $className, string $methodName)
74616 {
74617 parent::__construct($level);
74618 $this->className = $className;
74619 $this->methodName = $methodName;
74620 }
74621 /**
74622 * @psalm-assert-if-true RequiresMethod $this
74623 */
74624 public function isRequiresMethod(): bool
74625 {
74626 return \true;
74627 }
74628 /**
74629 * @psalm-return class-string
74630 */
74631 public function className(): string
74632 {
74633 return $this->className;
74634 }
74635 /**
74636 * @psalm-return non-empty-string
74637 */
74638 public function methodName(): string
74639 {
74640 return $this->methodName;
74641 }
74642 }
74643 <?php
74644
74645 declare (strict_types=1);
74646 /*
74647 * This file is part of PHPUnit.
74648 *
74649 * (c) Sebastian Bergmann <sebastian@phpunit.de>
74650 *
74651 * For the full copyright and license information, please view the LICENSE
74652 * file that was distributed with this source code.
74653 */
74654 namespace PHPUnit\Metadata;
74655
74656 /**
74657 * @psalm-immutable
74658 *
74659 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
74660 */
74661 final class RequiresOperatingSystem extends \PHPUnit\Metadata\Metadata
74662 {
74663 /**
74664 * @psalm-var non-empty-string
74665 */
74666 private readonly string $operatingSystem;
74667 /**
74668 * @psalm-param 0|1 $level
74669 * @psalm-param non-empty-string $operatingSystem
74670 */
74671 protected function __construct(int $level, string $operatingSystem)
74672 {
74673 parent::__construct($level);
74674 $this->operatingSystem = $operatingSystem;
74675 }
74676 /**
74677 * @psalm-assert-if-true RequiresOperatingSystem $this
74678 */
74679 public function isRequiresOperatingSystem(): bool
74680 {
74681 return \true;
74682 }
74683 /**
74684 * @psalm-return non-empty-string
74685 */
74686 public function operatingSystem(): string
74687 {
74688 return $this->operatingSystem;
74689 }
74690 }
74691 <?php
74692
74693 declare (strict_types=1);
74694 /*
74695 * This file is part of PHPUnit.
74696 *
74697 * (c) Sebastian Bergmann <sebastian@phpunit.de>
74698 *
74699 * For the full copyright and license information, please view the LICENSE
74700 * file that was distributed with this source code.
74701 */
74702 namespace PHPUnit\Metadata;
74703
74704 /**
74705 * @psalm-immutable
74706 *
74707 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
74708 */
74709 final class RequiresOperatingSystemFamily extends \PHPUnit\Metadata\Metadata
74710 {
74711 /**
74712 * @psalm-var non-empty-string
74713 */
74714 private readonly string $operatingSystemFamily;
74715 /**
74716 * @psalm-param 0|1 $level
74717 * @psalm-param non-empty-string $operatingSystemFamily
74718 */
74719 protected function __construct(int $level, string $operatingSystemFamily)
74720 {
74721 parent::__construct($level);
74722 $this->operatingSystemFamily = $operatingSystemFamily;
74723 }
74724 /**
74725 * @psalm-assert-if-true RequiresOperatingSystemFamily $this
74726 */
74727 public function isRequiresOperatingSystemFamily(): bool
74728 {
74729 return \true;
74730 }
74731 /**
74732 * @psalm-return non-empty-string
74733 */
74734 public function operatingSystemFamily(): string
74735 {
74736 return $this->operatingSystemFamily;
74737 }
74738 }
74739 <?php
74740
74741 declare (strict_types=1);
74742 /*
74743 * This file is part of PHPUnit.
74744 *
74745 * (c) Sebastian Bergmann <sebastian@phpunit.de>
74746 *
74747 * For the full copyright and license information, please view the LICENSE
74748 * file that was distributed with this source code.
74749 */
74750 namespace PHPUnit\Metadata;
74751
74752 use PHPUnit\Metadata\Version\Requirement;
74753 /**
74754 * @psalm-immutable
74755 *
74756 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
74757 */
74758 final class RequiresPhp extends \PHPUnit\Metadata\Metadata
74759 {
74760 private readonly Requirement $versionRequirement;
74761 /**
74762 * @psalm-param 0|1 $level
74763 */
74764 protected function __construct(int $level, Requirement $versionRequirement)
74765 {
74766 parent::__construct($level);
74767 $this->versionRequirement = $versionRequirement;
74768 }
74769 /**
74770 * @psalm-assert-if-true RequiresPhp $this
74771 */
74772 public function isRequiresPhp(): bool
74773 {
74774 return \true;
74775 }
74776 public function versionRequirement(): Requirement
74777 {
74778 return $this->versionRequirement;
74779 }
74780 }
74781 <?php
74782
74783 declare (strict_types=1);
74784 /*
74785 * This file is part of PHPUnit.
74786 *
74787 * (c) Sebastian Bergmann <sebastian@phpunit.de>
74788 *
74789 * For the full copyright and license information, please view the LICENSE
74790 * file that was distributed with this source code.
74791 */
74792 namespace PHPUnit\Metadata;
74793
74794 use PHPUnit\Metadata\Version\Requirement;
74795 /**
74796 * @psalm-immutable
74797 *
74798 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
74799 */
74800 final class RequiresPhpExtension extends \PHPUnit\Metadata\Metadata
74801 {
74802 /**
74803 * @psalm-var non-empty-string
74804 */
74805 private readonly string $extension;
74806 private readonly ?Requirement $versionRequirement;
74807 /**
74808 * @psalm-param 0|1 $level
74809 * @psalm-param non-empty-string $extension
74810 */
74811 protected function __construct(int $level, string $extension, ?Requirement $versionRequirement)
74812 {
74813 parent::__construct($level);
74814 $this->extension = $extension;
74815 $this->versionRequirement = $versionRequirement;
74816 }
74817 /**
74818 * @psalm-assert-if-true RequiresPhpExtension $this
74819 */
74820 public function isRequiresPhpExtension(): bool
74821 {
74822 return \true;
74823 }
74824 /**
74825 * @psalm-return non-empty-string
74826 */
74827 public function extension(): string
74828 {
74829 return $this->extension;
74830 }
74831 /**
74832 * @psalm-assert-if-true !null $this->versionRequirement
74833 */
74834 public function hasVersionRequirement(): bool
74835 {
74836 return $this->versionRequirement !== null;
74837 }
74838 /**
74839 * @throws NoVersionRequirementException
74840 */
74841 public function versionRequirement(): Requirement
74842 {
74843 if ($this->versionRequirement === null) {
74844 throw new \PHPUnit\Metadata\NoVersionRequirementException();
74845 }
74846 return $this->versionRequirement;
74847 }
74848 }
74849 <?php
74850
74851 declare (strict_types=1);
74852 /*
74853 * This file is part of PHPUnit.
74854 *
74855 * (c) Sebastian Bergmann <sebastian@phpunit.de>
74856 *
74857 * For the full copyright and license information, please view the LICENSE
74858 * file that was distributed with this source code.
74859 */
74860 namespace PHPUnit\Metadata;
74861
74862 use PHPUnit\Metadata\Version\Requirement;
74863 /**
74864 * @psalm-immutable
74865 *
74866 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
74867 */
74868 final class RequiresPhpunit extends \PHPUnit\Metadata\Metadata
74869 {
74870 private readonly Requirement $versionRequirement;
74871 /**
74872 * @psalm-param 0|1 $level
74873 */
74874 protected function __construct(int $level, Requirement $versionRequirement)
74875 {
74876 parent::__construct($level);
74877 $this->versionRequirement = $versionRequirement;
74878 }
74879 /**
74880 * @psalm-assert-if-true RequiresPhpunit $this
74881 */
74882 public function isRequiresPhpunit(): bool
74883 {
74884 return \true;
74885 }
74886 public function versionRequirement(): Requirement
74887 {
74888 return $this->versionRequirement;
74889 }
74890 }
74891 <?php
74892
74893 declare (strict_types=1);
74894 /*
74895 * This file is part of PHPUnit.
74896 *
74897 * (c) Sebastian Bergmann <sebastian@phpunit.de>
74898 *
74899 * For the full copyright and license information, please view the LICENSE
74900 * file that was distributed with this source code.
74901 */
74902 namespace PHPUnit\Metadata;
74903
74904 /**
74905 * @psalm-immutable
74906 *
74907 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
74908 */
74909 final class RequiresSetting extends \PHPUnit\Metadata\Metadata
74910 {
74911 /**
74912 * @psalm-var non-empty-string
74913 */
74914 private readonly string $setting;
74915 /**
74916 * @psalm-var non-empty-string
74917 */
74918 private readonly string $value;
74919 /**
74920 * @psalm-param 0|1 $level
74921 * @psalm-param non-empty-string $setting
74922 * @psalm-param non-empty-string $value
74923 */
74924 protected function __construct(int $level, string $setting, string $value)
74925 {
74926 parent::__construct($level);
74927 $this->setting = $setting;
74928 $this->value = $value;
74929 }
74930 /**
74931 * @psalm-assert-if-true RequiresSetting $this
74932 */
74933 public function isRequiresSetting(): bool
74934 {
74935 return \true;
74936 }
74937 /**
74938 * @psalm-return non-empty-string
74939 */
74940 public function setting(): string
74941 {
74942 return $this->setting;
74943 }
74944 /**
74945 * @psalm-return non-empty-string
74946 */
74947 public function value(): string
74948 {
74949 return $this->value;
74950 }
74951 }
74952 <?php
74953
74954 declare (strict_types=1);
74955 /*
74956 * This file is part of PHPUnit.
74957 *
74958 * (c) Sebastian Bergmann <sebastian@phpunit.de>
74959 *
74960 * For the full copyright and license information, please view the LICENSE
74961 * file that was distributed with this source code.
74962 */
74963 namespace PHPUnit\Metadata;
74964
74965 /**
74966 * @psalm-immutable
74967 *
74968 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
74969 */
74970 final class RunClassInSeparateProcess extends \PHPUnit\Metadata\Metadata
74971 {
74972 /**
74973 * @psalm-assert-if-true RunClassInSeparateProcess $this
74974 */
74975 public function isRunClassInSeparateProcess(): bool
74976 {
74977 return \true;
74978 }
74979 }
74980 <?php
74981
74982 declare (strict_types=1);
74983 /*
74984 * This file is part of PHPUnit.
74985 *
74986 * (c) Sebastian Bergmann <sebastian@phpunit.de>
74987 *
74988 * For the full copyright and license information, please view the LICENSE
74989 * file that was distributed with this source code.
74990 */
74991 namespace PHPUnit\Metadata;
74992
74993 /**
74994 * @psalm-immutable
74995 *
74996 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
74997 */
74998 final class RunInSeparateProcess extends \PHPUnit\Metadata\Metadata
74999 {
75000 /**
75001 * @psalm-assert-if-true RunInSeparateProcess $this
75002 */
75003 public function isRunInSeparateProcess(): bool
75004 {
75005 return \true;
75006 }
75007 }
75008 <?php
75009
75010 declare (strict_types=1);
75011 /*
75012 * This file is part of PHPUnit.
75013 *
75014 * (c) Sebastian Bergmann <sebastian@phpunit.de>
75015 *
75016 * For the full copyright and license information, please view the LICENSE
75017 * file that was distributed with this source code.
75018 */
75019 namespace PHPUnit\Metadata;
75020
75021 /**
75022 * @psalm-immutable
75023 *
75024 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
75025 */
75026 final class RunTestsInSeparateProcesses extends \PHPUnit\Metadata\Metadata
75027 {
75028 /**
75029 * @psalm-assert-if-true RunTestsInSeparateProcesses $this
75030 */
75031 public function isRunTestsInSeparateProcesses(): bool
75032 {
75033 return \true;
75034 }
75035 }
75036 <?php
75037
75038 declare (strict_types=1);
75039 /*
75040 * This file is part of PHPUnit.
75041 *
75042 * (c) Sebastian Bergmann <sebastian@phpunit.de>
75043 *
75044 * For the full copyright and license information, please view the LICENSE
75045 * file that was distributed with this source code.
75046 */
75047 namespace PHPUnit\Metadata;
75048
75049 /**
75050 * @psalm-immutable
75051 *
75052 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
75053 */
75054 final class Test extends \PHPUnit\Metadata\Metadata
75055 {
75056 /**
75057 * @psalm-assert-if-true Test $this
75058 */
75059 public function isTest(): bool
75060 {
75061 return \true;
75062 }
75063 }
75064 <?php
75065
75066 declare (strict_types=1);
75067 /*
75068 * This file is part of PHPUnit.
75069 *
75070 * (c) Sebastian Bergmann <sebastian@phpunit.de>
75071 *
75072 * For the full copyright and license information, please view the LICENSE
75073 * file that was distributed with this source code.
75074 */
75075 namespace PHPUnit\Metadata;
75076
75077 /**
75078 * @psalm-immutable
75079 *
75080 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
75081 */
75082 final class TestDox extends \PHPUnit\Metadata\Metadata
75083 {
75084 /**
75085 * @psalm-var non-empty-string
75086 */
75087 private readonly string $text;
75088 /**
75089 * @psalm-param 0|1 $level
75090 * @psalm-param non-empty-string $text
75091 */
75092 protected function __construct(int $level, string $text)
75093 {
75094 parent::__construct($level);
75095 $this->text = $text;
75096 }
75097 /**
75098 * @psalm-assert-if-true TestDox $this
75099 */
75100 public function isTestDox(): bool
75101 {
75102 return \true;
75103 }
75104 /**
75105 * @psalm-return non-empty-string
75106 */
75107 public function text(): string
75108 {
75109 return $this->text;
75110 }
75111 }
75112 <?php
75113
75114 declare (strict_types=1);
75115 /*
75116 * This file is part of PHPUnit.
75117 *
75118 * (c) Sebastian Bergmann <sebastian@phpunit.de>
75119 *
75120 * For the full copyright and license information, please view the LICENSE
75121 * file that was distributed with this source code.
75122 */
75123 namespace PHPUnit\Metadata;
75124
75125 /**
75126 * @psalm-immutable
75127 *
75128 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
75129 */
75130 final class TestWith extends \PHPUnit\Metadata\Metadata
75131 {
75132 private readonly mixed $data;
75133 /**
75134 * @psalm-param 0|1 $level
75135 */
75136 protected function __construct(int $level, mixed $data)
75137 {
75138 parent::__construct($level);
75139 $this->data = $data;
75140 }
75141 /**
75142 * @psalm-assert-if-true TestWith $this
75143 */
75144 public function isTestWith(): bool
75145 {
75146 return \true;
75147 }
75148 public function data(): mixed
75149 {
75150 return $this->data;
75151 }
75152 }
75153 <?php
75154
75155 declare (strict_types=1);
75156 /*
75157 * This file is part of PHPUnit.
75158 *
75159 * (c) Sebastian Bergmann <sebastian@phpunit.de>
75160 *
75161 * For the full copyright and license information, please view the LICENSE
75162 * file that was distributed with this source code.
75163 */
75164 namespace PHPUnit\Metadata;
75165
75166 /**
75167 * @psalm-immutable
75168 *
75169 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
75170 */
75171 final class Uses extends \PHPUnit\Metadata\Metadata
75172 {
75173 /**
75174 * @psalm-var non-empty-string
75175 */
75176 private readonly string $target;
75177 /**
75178 * @psalm-param 0|1 $level
75179 * @psalm-param non-empty-string $target
75180 */
75181 protected function __construct(int $level, string $target)
75182 {
75183 parent::__construct($level);
75184 $this->target = $target;
75185 }
75186 /**
75187 * @psalm-assert-if-true Uses $this
75188 */
75189 public function isUses(): bool
75190 {
75191 return \true;
75192 }
75193 /**
75194 * @psalm-return non-empty-string
75195 */
75196 public function target(): string
75197 {
75198 return $this->target;
75199 }
75200 }
75201 <?php
75202
75203 declare (strict_types=1);
75204 /*
75205 * This file is part of PHPUnit.
75206 *
75207 * (c) Sebastian Bergmann <sebastian@phpunit.de>
75208 *
75209 * For the full copyright and license information, please view the LICENSE
75210 * file that was distributed with this source code.
75211 */
75212 namespace PHPUnit\Metadata;
75213
75214 /**
75215 * @psalm-immutable
75216 *
75217 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
75218 */
75219 final class UsesClass extends \PHPUnit\Metadata\Metadata
75220 {
75221 /**
75222 * @psalm-var class-string
75223 */
75224 private readonly string $className;
75225 /**
75226 * @psalm-param 0|1 $level
75227 * @psalm-param class-string $className
75228 */
75229 protected function __construct(int $level, string $className)
75230 {
75231 parent::__construct($level);
75232 $this->className = $className;
75233 }
75234 /**
75235 * @psalm-assert-if-true UsesClass $this
75236 */
75237 public function isUsesClass(): bool
75238 {
75239 return \true;
75240 }
75241 /**
75242 * @psalm-return class-string
75243 */
75244 public function className(): string
75245 {
75246 return $this->className;
75247 }
75248 /**
75249 * @psalm-return class-string
75250 *
75251 * @internal This method is not covered by the backward compatibility promise for PHPUnit
75252 */
75253 public function asStringForCodeUnitMapper(): string
75254 {
75255 return $this->className;
75256 }
75257 }
75258 <?php
75259
75260 declare (strict_types=1);
75261 /*
75262 * This file is part of PHPUnit.
75263 *
75264 * (c) Sebastian Bergmann <sebastian@phpunit.de>
75265 *
75266 * For the full copyright and license information, please view the LICENSE
75267 * file that was distributed with this source code.
75268 */
75269 namespace PHPUnit\Metadata;
75270
75271 /**
75272 * @psalm-immutable
75273 *
75274 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
75275 */
75276 final class UsesDefaultClass extends \PHPUnit\Metadata\Metadata
75277 {
75278 /**
75279 * @psalm-var class-string
75280 */
75281 private readonly string $className;
75282 /**
75283 * @psalm-param 0|1 $level
75284 * @psalm-param class-string $className
75285 */
75286 protected function __construct(int $level, string $className)
75287 {
75288 parent::__construct($level);
75289 $this->className = $className;
75290 }
75291 /**
75292 * @psalm-assert-if-true UsesDefaultClass $this
75293 */
75294 public function isUsesDefaultClass(): bool
75295 {
75296 return \true;
75297 }
75298 /**
75299 * @psalm-return class-string
75300 */
75301 public function className(): string
75302 {
75303 return $this->className;
75304 }
75305 }
75306 <?php
75307
75308 declare (strict_types=1);
75309 /*
75310 * This file is part of PHPUnit.
75311 *
75312 * (c) Sebastian Bergmann <sebastian@phpunit.de>
75313 *
75314 * For the full copyright and license information, please view the LICENSE
75315 * file that was distributed with this source code.
75316 */
75317 namespace PHPUnit\Metadata;
75318
75319 /**
75320 * @psalm-immutable
75321 *
75322 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
75323 */
75324 final class UsesFunction extends \PHPUnit\Metadata\Metadata
75325 {
75326 /**
75327 * @psalm-var non-empty-string
75328 */
75329 private readonly string $functionName;
75330 /**
75331 * @psalm-param 0|1 $level
75332 * @psalm-param non-empty-string $functionName
75333 */
75334 protected function __construct(int $level, string $functionName)
75335 {
75336 parent::__construct($level);
75337 $this->functionName = $functionName;
75338 }
75339 /**
75340 * @psalm-assert-if-true UsesFunction $this
75341 */
75342 public function isUsesFunction(): bool
75343 {
75344 return \true;
75345 }
75346 /**
75347 * @psalm-return non-empty-string
75348 */
75349 public function functionName(): string
75350 {
75351 return $this->functionName;
75352 }
75353 /**
75354 * @internal This method is not covered by the backward compatibility promise for PHPUnit
75355 */
75356 public function asStringForCodeUnitMapper(): string
75357 {
75358 return '::' . $this->functionName;
75359 }
75360 }
75361 <?php
75362
75363 declare (strict_types=1);
75364 /*
75365 * This file is part of PHPUnit.
75366 *
75367 * (c) Sebastian Bergmann <sebastian@phpunit.de>
75368 *
75369 * For the full copyright and license information, please view the LICENSE
75370 * file that was distributed with this source code.
75371 */
75372 namespace PHPUnit\Metadata\Version;
75373
75374 use function version_compare;
75375 use PHPUnit\Util\VersionComparisonOperator;
75376 /**
75377 * @psalm-immutable
75378 *
75379 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
75380 */
75381 final class ComparisonRequirement extends \PHPUnit\Metadata\Version\Requirement
75382 {
75383 private readonly string $version;
75384 private readonly VersionComparisonOperator $operator;
75385 public function __construct(string $version, VersionComparisonOperator $operator)
75386 {
75387 $this->version = $version;
75388 $this->operator = $operator;
75389 }
75390 public function isSatisfiedBy(string $version): bool
75391 {
75392 return version_compare($version, $this->version, $this->operator->asString());
75393 }
75394 public function asString(): string
75395 {
75396 return $this->operator->asString() . ' ' . $this->version;
75397 }
75398 }
75399 <?php
75400
75401 declare (strict_types=1);
75402 /*
75403 * This file is part of PHPUnit.
75404 *
75405 * (c) Sebastian Bergmann <sebastian@phpunit.de>
75406 *
75407 * For the full copyright and license information, please view the LICENSE
75408 * file that was distributed with this source code.
75409 */
75410 namespace PHPUnit\Metadata\Version;
75411
75412 use function preg_replace;
75413 use PHPUnitPHAR\PharIo\Version\Version;
75414 use PHPUnitPHAR\PharIo\Version\VersionConstraint;
75415 /**
75416 * @psalm-immutable
75417 *
75418 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
75419 */
75420 final class ConstraintRequirement extends \PHPUnit\Metadata\Version\Requirement
75421 {
75422 private readonly VersionConstraint $constraint;
75423 public function __construct(VersionConstraint $constraint)
75424 {
75425 $this->constraint = $constraint;
75426 }
75427 /**
75428 * @psalm-suppress ImpureMethodCall
75429 */
75430 public function isSatisfiedBy(string $version): bool
75431 {
75432 return $this->constraint->complies(new Version($this->sanitize($version)));
75433 }
75434 /**
75435 * @psalm-suppress ImpureMethodCall
75436 */
75437 public function asString(): string
75438 {
75439 return $this->constraint->asString();
75440 }
75441 private function sanitize(string $version): string
75442 {
75443 return preg_replace('/^(\d+\.\d+(?:.\d+)?).*$/', '$1', $version);
75444 }
75445 }
75446 <?php
75447
75448 declare (strict_types=1);
75449 /*
75450 * This file is part of PHPUnit.
75451 *
75452 * (c) Sebastian Bergmann <sebastian@phpunit.de>
75453 *
75454 * For the full copyright and license information, please view the LICENSE
75455 * file that was distributed with this source code.
75456 */
75457 namespace PHPUnit\Metadata\Version;
75458
75459 use function preg_match;
75460 use PHPUnitPHAR\PharIo\Version\UnsupportedVersionConstraintException;
75461 use PHPUnitPHAR\PharIo\Version\VersionConstraintParser;
75462 use PHPUnit\Metadata\InvalidVersionRequirementException;
75463 use PHPUnit\Util\InvalidVersionOperatorException;
75464 use PHPUnit\Util\VersionComparisonOperator;
75465 /**
75466 * @psalm-immutable
75467 *
75468 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
75469 */
75470 abstract class Requirement
75471 {
75472 private const VERSION_COMPARISON = '/(?P<operator>[<>=!]{0,2})\s*(?P<version>[\d\.-]+(dev|(RC|alpha|beta)[\d\.])?)[ \t]*\r?$/m';
75473 /**
75474 * @throws InvalidVersionOperatorException
75475 * @throws InvalidVersionRequirementException
75476 */
75477 public static function from(string $versionRequirement): self
75478 {
75479 try {
75480 return new \PHPUnit\Metadata\Version\ConstraintRequirement((new VersionConstraintParser())->parse($versionRequirement));
75481 } catch (UnsupportedVersionConstraintException) {
75482 if (preg_match(self::VERSION_COMPARISON, $versionRequirement, $matches)) {
75483 return new \PHPUnit\Metadata\Version\ComparisonRequirement($matches['version'], new VersionComparisonOperator(!empty($matches['operator']) ? $matches['operator'] : '>='));
75484 }
75485 }
75486 throw new InvalidVersionRequirementException();
75487 }
75488 abstract public function isSatisfiedBy(string $version): bool;
75489 abstract public function asString(): string;
75490 }
75491 <?php
75492
75493 declare (strict_types=1);
75494 /*
75495 * This file is part of PHPUnit.
75496 *
75497 * (c) Sebastian Bergmann <sebastian@phpunit.de>
75498 *
75499 * For the full copyright and license information, please view the LICENSE
75500 * file that was distributed with this source code.
75501 */
75502 namespace PHPUnit\Metadata;
75503
75504 /**
75505 * @psalm-immutable
75506 *
75507 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
75508 */
75509 final class WithoutErrorHandler extends \PHPUnit\Metadata\Metadata
75510 {
75511 /**
75512 * @psalm-assert-if-true WithoutErrorHandler $this
75513 */
75514 public function isWithoutErrorHandler(): bool
75515 {
75516 return \true;
75517 }
75518 }
75519 <?php
75520
75521 declare (strict_types=1);
75522 /*
75523 * This file is part of PHPUnit.
75524 *
75525 * (c) Sebastian Bergmann <sebastian@phpunit.de>
75526 *
75527 * For the full copyright and license information, please view the LICENSE
75528 * file that was distributed with this source code.
75529 */
75530 namespace PHPUnit\Runner\Baseline;
75531
75532 /**
75533 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
75534 *
75535 * @internal This class is not covered by the backward compatibility promise for PHPUnit
75536 */
75537 final class Baseline
75538 {
75539 public const VERSION = 1;
75540 /**
75541 * @psalm-var array<non-empty-string, array<positive-int, list<Issue>>>
75542 */
75543 private array $issues = [];
75544 public function add(\PHPUnit\Runner\Baseline\Issue $issue): void
75545 {
75546 if (!isset($this->issues[$issue->file()])) {
75547 $this->issues[$issue->file()] = [];
75548 }
75549 if (!isset($this->issues[$issue->file()][$issue->line()])) {
75550 $this->issues[$issue->file()][$issue->line()] = [];
75551 }
75552 $this->issues[$issue->file()][$issue->line()][] = $issue;
75553 }
75554 public function has(\PHPUnit\Runner\Baseline\Issue $issue): bool
75555 {
75556 if (!isset($this->issues[$issue->file()][$issue->line()])) {
75557 return \false;
75558 }
75559 foreach ($this->issues[$issue->file()][$issue->line()] as $_issue) {
75560 if ($_issue->equals($issue)) {
75561 return \true;
75562 }
75563 }
75564 return \false;
75565 }
75566 /**
75567 * @psalm-return array<string, array<positive-int, list<Issue>>>
75568 */
75569 public function groupedByFileAndLine(): array
75570 {
75571 return $this->issues;
75572 }
75573 }
75574 <?php
75575
75576 declare (strict_types=1);
75577 /*
75578 * This file is part of PHPUnit.
75579 *
75580 * (c) Sebastian Bergmann <sebastian@phpunit.de>
75581 *
75582 * For the full copyright and license information, please view the LICENSE
75583 * file that was distributed with this source code.
75584 */
75585 namespace PHPUnit\Runner\Baseline;
75586
75587 use PHPUnit\Runner\Exception;
75588 use RuntimeException;
75589 /**
75590 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
75591 *
75592 * @internal This class is not covered by the backward compatibility promise for PHPUnit
75593 */
75594 final class CannotLoadBaselineException extends RuntimeException implements Exception
75595 {
75596 }
75597 <?php
75598
75599 declare (strict_types=1);
75600 /*
75601 * This file is part of PHPUnit.
75602 *
75603 * (c) Sebastian Bergmann <sebastian@phpunit.de>
75604 *
75605 * For the full copyright and license information, please view the LICENSE
75606 * file that was distributed with this source code.
75607 */
75608 namespace PHPUnit\Runner\Baseline;
75609
75610 use function sprintf;
75611 use PHPUnit\Runner\Exception;
75612 use RuntimeException;
75613 /**
75614 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
75615 *
75616 * @internal This class is not covered by the backward compatibility promise for PHPUnit
75617 */
75618 final class FileDoesNotHaveLineException extends RuntimeException implements Exception
75619 {
75620 public function __construct(string $file, int $line)
75621 {
75622 parent::__construct(sprintf('File "%s" does not have line %d', $file, $line));
75623 }
75624 }
75625 <?php
75626
75627 declare (strict_types=1);
75628 /*
75629 * This file is part of PHPUnit.
75630 *
75631 * (c) Sebastian Bergmann <sebastian@phpunit.de>
75632 *
75633 * For the full copyright and license information, please view the LICENSE
75634 * file that was distributed with this source code.
75635 */
75636 namespace PHPUnit\Runner\Baseline;
75637
75638 use PHPUnit\Event\EventFacadeIsSealedException;
75639 use PHPUnit\Event\Facade;
75640 use PHPUnit\Event\Test\DeprecationTriggered;
75641 use PHPUnit\Event\Test\NoticeTriggered;
75642 use PHPUnit\Event\Test\PhpDeprecationTriggered;
75643 use PHPUnit\Event\Test\PhpNoticeTriggered;
75644 use PHPUnit\Event\Test\PhpWarningTriggered;
75645 use PHPUnit\Event\Test\WarningTriggered;
75646 use PHPUnit\Event\UnknownSubscriberTypeException;
75647 use PHPUnit\Runner\FileDoesNotExistException;
75648 use PHPUnit\TextUI\Configuration\Source;
75649 use PHPUnit\TextUI\Configuration\SourceFilter;
75650 /**
75651 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
75652 *
75653 * @internal This class is not covered by the backward compatibility promise for PHPUnit
75654 */
75655 final class Generator
75656 {
75657 private \PHPUnit\Runner\Baseline\Baseline $baseline;
75658 private readonly Source $source;
75659 /**
75660 * @throws EventFacadeIsSealedException
75661 * @throws UnknownSubscriberTypeException
75662 */
75663 public function __construct(Facade $facade, Source $source)
75664 {
75665 $facade->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));
75666 $this->baseline = new \PHPUnit\Runner\Baseline\Baseline();
75667 $this->source = $source;
75668 }
75669 public function baseline(): \PHPUnit\Runner\Baseline\Baseline
75670 {
75671 return $this->baseline;
75672 }
75673 /**
75674 * @throws FileDoesNotExistException
75675 * @throws FileDoesNotHaveLineException
75676 */
75677 public function testTriggeredIssue(DeprecationTriggered|NoticeTriggered|PhpDeprecationTriggered|PhpNoticeTriggered|PhpWarningTriggered|WarningTriggered $event): void
75678 {
75679 if ($event->wasSuppressed() && !$this->isSuppressionIgnored($event)) {
75680 return;
75681 }
75682 if ($this->restrict($event) && !SourceFilter::instance()->includes($event->file())) {
75683 return;
75684 }
75685 $this->baseline->add(\PHPUnit\Runner\Baseline\Issue::from($event->file(), $event->line(), null, $event->message()));
75686 }
75687 private function restrict(DeprecationTriggered|NoticeTriggered|PhpDeprecationTriggered|PhpNoticeTriggered|PhpWarningTriggered|WarningTriggered $event): bool
75688 {
75689 if ($event instanceof WarningTriggered || $event instanceof PhpWarningTriggered) {
75690 return $this->source->restrictWarnings();
75691 }
75692 if ($event instanceof NoticeTriggered || $event instanceof PhpNoticeTriggered) {
75693 return $this->source->restrictNotices();
75694 }
75695 return $this->source->restrictDeprecations();
75696 }
75697 private function isSuppressionIgnored(DeprecationTriggered|NoticeTriggered|PhpDeprecationTriggered|PhpNoticeTriggered|PhpWarningTriggered|WarningTriggered $event): bool
75698 {
75699 if ($event instanceof WarningTriggered) {
75700 return $this->source->ignoreSuppressionOfWarnings();
75701 }
75702 if ($event instanceof PhpWarningTriggered) {
75703 return $this->source->ignoreSuppressionOfPhpWarnings();
75704 }
75705 if ($event instanceof PhpNoticeTriggered) {
75706 return $this->source->ignoreSuppressionOfPhpNotices();
75707 }
75708 if ($event instanceof NoticeTriggered) {
75709 return $this->source->ignoreSuppressionOfNotices();
75710 }
75711 if ($event instanceof PhpDeprecationTriggered) {
75712 return $this->source->ignoreSuppressionOfPhpDeprecations();
75713 }
75714 return $this->source->ignoreSuppressionOfDeprecations();
75715 }
75716 }
75717 <?php
75718
75719 declare (strict_types=1);
75720 /*
75721 * This file is part of PHPUnit.
75722 *
75723 * (c) Sebastian Bergmann <sebastian@phpunit.de>
75724 *
75725 * For the full copyright and license information, please view the LICENSE
75726 * file that was distributed with this source code.
75727 */
75728 namespace PHPUnit\Runner\Baseline;
75729
75730 use const FILE_IGNORE_NEW_LINES;
75731 use function assert;
75732 use function file;
75733 use function is_file;
75734 use function sha1;
75735 use PHPUnit\Runner\FileDoesNotExistException;
75736 /**
75737 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
75738 *
75739 * @internal This class is not covered by the backward compatibility promise for PHPUnit
75740 */
75741 final class Issue
75742 {
75743 /**
75744 * @psalm-var non-empty-string
75745 */
75746 private readonly string $file;
75747 /**
75748 * @psalm-var positive-int
75749 */
75750 private readonly int $line;
75751 /**
75752 * @psalm-var non-empty-string
75753 */
75754 private readonly string $hash;
75755 /**
75756 * @psalm-var non-empty-string
75757 */
75758 private readonly string $description;
75759 /**
75760 * @psalm-param non-empty-string $file
75761 * @psalm-param positive-int $line
75762 * @psalm-param ?non-empty-string $hash
75763 * @psalm-param non-empty-string $description
75764 *
75765 * @throws FileDoesNotExistException
75766 * @throws FileDoesNotHaveLineException
75767 */
75768 public static function from(string $file, int $line, ?string $hash, string $description): self
75769 {
75770 if ($hash === null) {
75771 $hash = self::calculateHash($file, $line);
75772 }
75773 return new self($file, $line, $hash, $description);
75774 }
75775 /**
75776 * @psalm-param non-empty-string $file
75777 * @psalm-param positive-int $line
75778 * @psalm-param non-empty-string $hash
75779 * @psalm-param non-empty-string $description
75780 */
75781 private function __construct(string $file, int $line, string $hash, string $description)
75782 {
75783 $this->file = $file;
75784 $this->line = $line;
75785 $this->hash = $hash;
75786 $this->description = $description;
75787 }
75788 /**
75789 * @psalm-return non-empty-string
75790 */
75791 public function file(): string
75792 {
75793 return $this->file;
75794 }
75795 /**
75796 * @psalm-return positive-int
75797 */
75798 public function line(): int
75799 {
75800 return $this->line;
75801 }
75802 /**
75803 * @psalm-return non-empty-string
75804 */
75805 public function hash(): string
75806 {
75807 return $this->hash;
75808 }
75809 /**
75810 * @psalm-return non-empty-string
75811 */
75812 public function description(): string
75813 {
75814 return $this->description;
75815 }
75816 public function equals(self $other): bool
75817 {
75818 return $this->file() === $other->file() && $this->line() === $other->line() && $this->hash() === $other->hash() && $this->description() === $other->description();
75819 }
75820 /**
75821 * @psalm-param non-empty-string $file
75822 * @psalm-param positive-int $line
75823 *
75824 * @throws FileDoesNotExistException
75825 * @throws FileDoesNotHaveLineException
75826 *
75827 * @psalm-return non-empty-string
75828 */
75829 private static function calculateHash(string $file, int $line): string
75830 {
75831 $lines = @file($file, FILE_IGNORE_NEW_LINES);
75832 if ($lines === \false && !is_file($file)) {
75833 throw new FileDoesNotExistException($file);
75834 }
75835 $key = $line - 1;
75836 if (!isset($lines[$key])) {
75837 throw new \PHPUnit\Runner\Baseline\FileDoesNotHaveLineException($file, $line);
75838 }
75839 $hash = sha1($lines[$key]);
75840 assert($hash !== '');
75841 return $hash;
75842 }
75843 }
75844 <?php
75845
75846 declare (strict_types=1);
75847 /*
75848 * This file is part of PHPUnit.
75849 *
75850 * (c) Sebastian Bergmann <sebastian@phpunit.de>
75851 *
75852 * For the full copyright and license information, please view the LICENSE
75853 * file that was distributed with this source code.
75854 */
75855 namespace PHPUnit\Runner\Baseline;
75856
75857 use const DIRECTORY_SEPARATOR;
75858 use function assert;
75859 use function dirname;
75860 use function is_file;
75861 use function realpath;
75862 use function sprintf;
75863 use function str_replace;
75864 use function trim;
75865 use DOMElement;
75866 use DOMXPath;
75867 use PHPUnit\Util\Xml\Loader as XmlLoader;
75868 use PHPUnit\Util\Xml\XmlException;
75869 /**
75870 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
75871 *
75872 * @internal This class is not covered by the backward compatibility promise for PHPUnit
75873 */
75874 final class Reader
75875 {
75876 /**
75877 * @psalm-param non-empty-string $baselineFile
75878 *
75879 * @throws CannotLoadBaselineException
75880 */
75881 public function read(string $baselineFile): \PHPUnit\Runner\Baseline\Baseline
75882 {
75883 if (!is_file($baselineFile)) {
75884 throw new \PHPUnit\Runner\Baseline\CannotLoadBaselineException(sprintf('Cannot read baseline %s, file does not exist', $baselineFile));
75885 }
75886 try {
75887 $document = (new XmlLoader())->loadFile($baselineFile);
75888 } catch (XmlException $e) {
75889 throw new \PHPUnit\Runner\Baseline\CannotLoadBaselineException(sprintf('Cannot read baseline: %s', trim($e->getMessage())));
75890 }
75891 $version = (int) $document->documentElement->getAttribute('version');
75892 if ($version !== \PHPUnit\Runner\Baseline\Baseline::VERSION) {
75893 throw new \PHPUnit\Runner\Baseline\CannotLoadBaselineException(sprintf('Cannot read baseline %s, version %d is not supported', $baselineFile, $version));
75894 }
75895 $baseline = new \PHPUnit\Runner\Baseline\Baseline();
75896 $baselineDirectory = dirname(realpath($baselineFile));
75897 $xpath = new DOMXPath($document);
75898 foreach ($xpath->query('file') as $fileElement) {
75899 assert($fileElement instanceof DOMElement);
75900 $file = $baselineDirectory . DIRECTORY_SEPARATOR . str_replace('/', DIRECTORY_SEPARATOR, $fileElement->getAttribute('path'));
75901 foreach ($xpath->query('line', $fileElement) as $lineElement) {
75902 assert($lineElement instanceof DOMElement);
75903 $line = (int) $lineElement->getAttribute('number');
75904 $hash = $lineElement->getAttribute('hash');
75905 foreach ($xpath->query('issue', $lineElement) as $issueElement) {
75906 assert($issueElement instanceof DOMElement);
75907 $description = $issueElement->textContent;
75908 assert($line > 0);
75909 assert(!empty($hash));
75910 assert(!empty($description));
75911 $baseline->add(\PHPUnit\Runner\Baseline\Issue::from($file, $line, $hash, $description));
75912 }
75913 }
75914 }
75915 return $baseline;
75916 }
75917 }
75918 <?php
75919
75920 declare (strict_types=1);
75921 /*
75922 * This file is part of PHPUnit.
75923 *
75924 * (c) Sebastian Bergmann <sebastian@phpunit.de>
75925 *
75926 * For the full copyright and license information, please view the LICENSE
75927 * file that was distributed with this source code.
75928 */
75929 namespace PHPUnit\Runner\Baseline;
75930
75931 use function array_fill;
75932 use function array_merge;
75933 use function array_slice;
75934 use function assert;
75935 use function count;
75936 use function explode;
75937 use function implode;
75938 use function str_replace;
75939 use function strpos;
75940 use function substr;
75941 use function trim;
75942 /**
75943 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
75944 *
75945 * @internal This class is not covered by the backward compatibility promise for PHPUnit
75946 *
75947 * @see Copied from https://github.com/phpstan/phpstan-src/blob/1.10.33/src/File/ParentDirectoryRelativePathHelper.php
75948 */
75949 final class RelativePathCalculator
75950 {
75951 /**
75952 * @psalm-var non-empty-string $baselineDirectory
75953 */
75954 private readonly string $baselineDirectory;
75955 /**
75956 * @psalm-param non-empty-string $baselineDirectory
75957 */
75958 public function __construct(string $baselineDirectory)
75959 {
75960 $this->baselineDirectory = $baselineDirectory;
75961 }
75962 /**
75963 * @psalm-param non-empty-string $filename
75964 *
75965 * @psalm-return non-empty-string
75966 */
75967 public function calculate(string $filename): string
75968 {
75969 $result = implode('/', $this->parts($filename));
75970 assert($result !== '');
75971 return $result;
75972 }
75973 /**
75974 * @psalm-param non-empty-string $filename
75975 *
75976 * @psalm-return list<non-empty-string>
75977 */
75978 public function parts(string $filename): array
75979 {
75980 $schemePosition = strpos($filename, '://');
75981 if ($schemePosition !== \false) {
75982 $filename = substr($filename, $schemePosition + 3);
75983 assert($filename !== '');
75984 }
75985 $parentParts = explode('/', trim(str_replace('\\', '/', $this->baselineDirectory), '/'));
75986 $parentPartsCount = count($parentParts);
75987 $filenameParts = explode('/', trim(str_replace('\\', '/', $filename), '/'));
75988 $filenamePartsCount = count($filenameParts);
75989 $i = 0;
75990 for (; $i < $filenamePartsCount; $i++) {
75991 if ($parentPartsCount < $i + 1) {
75992 break;
75993 }
75994 $parentPath = implode('/', array_slice($parentParts, 0, $i + 1));
75995 $filenamePath = implode('/', array_slice($filenameParts, 0, $i + 1));
75996 if ($parentPath !== $filenamePath) {
75997 break;
75998 }
75999 }
76000 if ($i === 0) {
76001 return [$filename];
76002 }
76003 $dotsCount = $parentPartsCount - $i;
76004 assert($dotsCount >= 0);
76005 return array_merge(array_fill(0, $dotsCount, '..'), array_slice($filenameParts, $i));
76006 }
76007 }
76008 <?php
76009
76010 declare (strict_types=1);
76011 /*
76012 * This file is part of PHPUnit.
76013 *
76014 * (c) Sebastian Bergmann <sebastian@phpunit.de>
76015 *
76016 * For the full copyright and license information, please view the LICENSE
76017 * file that was distributed with this source code.
76018 */
76019 namespace PHPUnit\Runner\Baseline;
76020
76021 /**
76022 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
76023 *
76024 * @internal This class is not covered by the backward compatibility promise for PHPUnit
76025 */
76026 abstract class Subscriber
76027 {
76028 private readonly \PHPUnit\Runner\Baseline\Generator $generator;
76029 public function __construct(\PHPUnit\Runner\Baseline\Generator $generator)
76030 {
76031 $this->generator = $generator;
76032 }
76033 protected function generator(): \PHPUnit\Runner\Baseline\Generator
76034 {
76035 return $this->generator;
76036 }
76037 }
76038 <?php
76039
76040 declare (strict_types=1);
76041 /*
76042 * This file is part of PHPUnit.
76043 *
76044 * (c) Sebastian Bergmann <sebastian@phpunit.de>
76045 *
76046 * For the full copyright and license information, please view the LICENSE
76047 * file that was distributed with this source code.
76048 */
76049 namespace PHPUnit\Runner\Baseline;
76050
76051 use PHPUnit\Event\Test\DeprecationTriggered;
76052 use PHPUnit\Event\Test\DeprecationTriggeredSubscriber;
76053 use PHPUnit\Runner\FileDoesNotExistException;
76054 /**
76055 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
76056 *
76057 * @internal This class is not covered by the backward compatibility promise for PHPUnit
76058 */
76059 final class TestTriggeredDeprecationSubscriber extends \PHPUnit\Runner\Baseline\Subscriber implements DeprecationTriggeredSubscriber
76060 {
76061 /**
76062 * @throws FileDoesNotExistException
76063 * @throws FileDoesNotHaveLineException
76064 */
76065 public function notify(DeprecationTriggered $event): void
76066 {
76067 $this->generator()->testTriggeredIssue($event);
76068 }
76069 }
76070 <?php
76071
76072 declare (strict_types=1);
76073 /*
76074 * This file is part of PHPUnit.
76075 *
76076 * (c) Sebastian Bergmann <sebastian@phpunit.de>
76077 *
76078 * For the full copyright and license information, please view the LICENSE
76079 * file that was distributed with this source code.
76080 */
76081 namespace PHPUnit\Runner\Baseline;
76082
76083 use PHPUnit\Event\Test\NoticeTriggered;
76084 use PHPUnit\Event\Test\NoticeTriggeredSubscriber;
76085 use PHPUnit\Runner\FileDoesNotExistException;
76086 /**
76087 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
76088 *
76089 * @internal This class is not covered by the backward compatibility promise for PHPUnit
76090 */
76091 final class TestTriggeredNoticeSubscriber extends \PHPUnit\Runner\Baseline\Subscriber implements NoticeTriggeredSubscriber
76092 {
76093 /**
76094 * @throws FileDoesNotExistException
76095 * @throws FileDoesNotHaveLineException
76096 */
76097 public function notify(NoticeTriggered $event): void
76098 {
76099 $this->generator()->testTriggeredIssue($event);
76100 }
76101 }
76102 <?php
76103
76104 declare (strict_types=1);
76105 /*
76106 * This file is part of PHPUnit.
76107 *
76108 * (c) Sebastian Bergmann <sebastian@phpunit.de>
76109 *
76110 * For the full copyright and license information, please view the LICENSE
76111 * file that was distributed with this source code.
76112 */
76113 namespace PHPUnit\Runner\Baseline;
76114
76115 use PHPUnit\Event\Test\PhpDeprecationTriggered;
76116 use PHPUnit\Event\Test\PhpDeprecationTriggeredSubscriber;
76117 use PHPUnit\Runner\FileDoesNotExistException;
76118 /**
76119 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
76120 *
76121 * @internal This class is not covered by the backward compatibility promise for PHPUnit
76122 */
76123 final class TestTriggeredPhpDeprecationSubscriber extends \PHPUnit\Runner\Baseline\Subscriber implements PhpDeprecationTriggeredSubscriber
76124 {
76125 /**
76126 * @throws FileDoesNotExistException
76127 * @throws FileDoesNotHaveLineException
76128 */
76129 public function notify(PhpDeprecationTriggered $event): void
76130 {
76131 $this->generator()->testTriggeredIssue($event);
76132 }
76133 }
76134 <?php
76135
76136 declare (strict_types=1);
76137 /*
76138 * This file is part of PHPUnit.
76139 *
76140 * (c) Sebastian Bergmann <sebastian@phpunit.de>
76141 *
76142 * For the full copyright and license information, please view the LICENSE
76143 * file that was distributed with this source code.
76144 */
76145 namespace PHPUnit\Runner\Baseline;
76146
76147 use PHPUnit\Event\Test\PhpNoticeTriggered;
76148 use PHPUnit\Event\Test\PhpNoticeTriggeredSubscriber;
76149 use PHPUnit\Runner\FileDoesNotExistException;
76150 /**
76151 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
76152 *
76153 * @internal This class is not covered by the backward compatibility promise for PHPUnit
76154 */
76155 final class TestTriggeredPhpNoticeSubscriber extends \PHPUnit\Runner\Baseline\Subscriber implements PhpNoticeTriggeredSubscriber
76156 {
76157 /**
76158 * @throws FileDoesNotExistException
76159 * @throws FileDoesNotHaveLineException
76160 */
76161 public function notify(PhpNoticeTriggered $event): void
76162 {
76163 $this->generator()->testTriggeredIssue($event);
76164 }
76165 }
76166 <?php
76167
76168 declare (strict_types=1);
76169 /*
76170 * This file is part of PHPUnit.
76171 *
76172 * (c) Sebastian Bergmann <sebastian@phpunit.de>
76173 *
76174 * For the full copyright and license information, please view the LICENSE
76175 * file that was distributed with this source code.
76176 */
76177 namespace PHPUnit\Runner\Baseline;
76178
76179 use PHPUnit\Event\Test\PhpWarningTriggered;
76180 use PHPUnit\Event\Test\PhpWarningTriggeredSubscriber;
76181 use PHPUnit\Runner\FileDoesNotExistException;
76182 /**
76183 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
76184 *
76185 * @internal This class is not covered by the backward compatibility promise for PHPUnit
76186 */
76187 final class TestTriggeredPhpWarningSubscriber extends \PHPUnit\Runner\Baseline\Subscriber implements PhpWarningTriggeredSubscriber
76188 {
76189 /**
76190 * @throws FileDoesNotExistException
76191 * @throws FileDoesNotHaveLineException
76192 */
76193 public function notify(PhpWarningTriggered $event): void
76194 {
76195 $this->generator()->testTriggeredIssue($event);
76196 }
76197 }
76198 <?php
76199
76200 declare (strict_types=1);
76201 /*
76202 * This file is part of PHPUnit.
76203 *
76204 * (c) Sebastian Bergmann <sebastian@phpunit.de>
76205 *
76206 * For the full copyright and license information, please view the LICENSE
76207 * file that was distributed with this source code.
76208 */
76209 namespace PHPUnit\Runner\Baseline;
76210
76211 use PHPUnit\Event\Test\WarningTriggered;
76212 use PHPUnit\Event\Test\WarningTriggeredSubscriber;
76213 use PHPUnit\Runner\FileDoesNotExistException;
76214 /**
76215 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
76216 *
76217 * @internal This class is not covered by the backward compatibility promise for PHPUnit
76218 */
76219 final class TestTriggeredWarningSubscriber extends \PHPUnit\Runner\Baseline\Subscriber implements WarningTriggeredSubscriber
76220 {
76221 /**
76222 * @throws FileDoesNotExistException
76223 * @throws FileDoesNotHaveLineException
76224 */
76225 public function notify(WarningTriggered $event): void
76226 {
76227 $this->generator()->testTriggeredIssue($event);
76228 }
76229 }
76230 <?php
76231
76232 declare (strict_types=1);
76233 /*
76234 * This file is part of PHPUnit.
76235 *
76236 * (c) Sebastian Bergmann <sebastian@phpunit.de>
76237 *
76238 * For the full copyright and license information, please view the LICENSE
76239 * file that was distributed with this source code.
76240 */
76241 namespace PHPUnit\Runner\Baseline;
76242
76243 use function assert;
76244 use function dirname;
76245 use function file_put_contents;
76246 use XMLWriter;
76247 /**
76248 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
76249 *
76250 * @internal This class is not covered by the backward compatibility promise for PHPUnit
76251 */
76252 final class Writer
76253 {
76254 /**
76255 * @psalm-param non-empty-string $baselineFile
76256 */
76257 public function write(string $baselineFile, \PHPUnit\Runner\Baseline\Baseline $baseline): void
76258 {
76259 $pathCalculator = new \PHPUnit\Runner\Baseline\RelativePathCalculator(dirname($baselineFile));
76260 $writer = new XMLWriter();
76261 $writer->openMemory();
76262 $writer->setIndent(\true);
76263 $writer->startDocument();
76264 $writer->startElement('files');
76265 $writer->writeAttribute('version', (string) \PHPUnit\Runner\Baseline\Baseline::VERSION);
76266 foreach ($baseline->groupedByFileAndLine() as $file => $lines) {
76267 assert(!empty($file));
76268 $writer->startElement('file');
76269 $writer->writeAttribute('path', $pathCalculator->calculate($file));
76270 foreach ($lines as $line => $issues) {
76271 $writer->startElement('line');
76272 $writer->writeAttribute('number', (string) $line);
76273 $writer->writeAttribute('hash', $issues[0]->hash());
76274 foreach ($issues as $issue) {
76275 $writer->startElement('issue');
76276 $writer->writeCData($issue->description());
76277 $writer->endElement();
76278 }
76279 $writer->endElement();
76280 }
76281 $writer->endElement();
76282 }
76283 $writer->endElement();
76284 file_put_contents($baselineFile, $writer->outputMemory());
76285 }
76286 }
76287 <?php
76288
76289 declare (strict_types=1);
76290 /*
76291 * This file is part of PHPUnit.
76292 *
76293 * (c) Sebastian Bergmann <sebastian@phpunit.de>
76294 *
76295 * For the full copyright and license information, please view the LICENSE
76296 * file that was distributed with this source code.
76297 */
76298 namespace PHPUnit\Runner;
76299
76300 use function file_put_contents;
76301 use function sprintf;
76302 use PHPUnit\Event\Facade as EventFacade;
76303 use PHPUnit\Event\TestData\MoreThanOneDataSetFromDataProviderException;
76304 use PHPUnit\Framework\TestCase;
76305 use PHPUnit\TextUI\Configuration\CodeCoverageFilterRegistry;
76306 use PHPUnit\TextUI\Configuration\Configuration;
76307 use PHPUnit\TextUI\Output\Printer;
76308 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Driver\Driver;
76309 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Driver\Selector;
76310 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Exception as CodeCoverageException;
76311 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Filter;
76312 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Report\Clover as CloverReport;
76313 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Report\Cobertura as CoberturaReport;
76314 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Report\Crap4j as Crap4jReport;
76315 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Report\Html\Colors;
76316 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Report\Html\CustomCssFile;
76317 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Report\Html\Facade as HtmlReport;
76318 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Report\PHP as PhpReport;
76319 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Report\Text as TextReport;
76320 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Report\Thresholds;
76321 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Report\Xml\Facade as XmlReport;
76322 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Test\TestSize\TestSize;
76323 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Test\TestStatus\TestStatus;
76324 use PHPUnitPHAR\SebastianBergmann\Comparator\Comparator;
76325 use PHPUnitPHAR\SebastianBergmann\Timer\NoActiveTimerException;
76326 use PHPUnitPHAR\SebastianBergmann\Timer\Timer;
76327 /**
76328 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
76329 *
76330 * @internal This class is not covered by the backward compatibility promise for PHPUnit
76331 *
76332 * @codeCoverageIgnore
76333 */
76334 final class CodeCoverage
76335 {
76336 private static ?self $instance = null;
76337 private ?\PHPUnitPHAR\SebastianBergmann\CodeCoverage\CodeCoverage $codeCoverage = null;
76338 private ?Driver $driver = null;
76339 private bool $collecting = \false;
76340 private ?TestCase $test = null;
76341 private ?Timer $timer = null;
76342 /**
76343 * @psalm-var array<string,list<int>>
76344 */
76345 private array $linesToBeIgnored = [];
76346 public static function instance(): self
76347 {
76348 if (self::$instance === null) {
76349 self::$instance = new self();
76350 }
76351 return self::$instance;
76352 }
76353 public function init(Configuration $configuration, CodeCoverageFilterRegistry $codeCoverageFilterRegistry, bool $extensionRequiresCodeCoverageCollection): void
76354 {
76355 $codeCoverageFilterRegistry->init($configuration);
76356 if (!$configuration->hasCoverageReport() && !$extensionRequiresCodeCoverageCollection) {
76357 return;
76358 }
76359 $this->activate($codeCoverageFilterRegistry->get(), $configuration->pathCoverage());
76360 if (!$this->isActive()) {
76361 return;
76362 }
76363 if ($configuration->hasCoverageCacheDirectory()) {
76364 $this->codeCoverage()->cacheStaticAnalysis($configuration->coverageCacheDirectory());
76365 }
76366 $this->codeCoverage()->excludeSubclassesOfThisClassFromUnintentionallyCoveredCodeCheck(Comparator::class);
76367 if ($configuration->strictCoverage()) {
76368 $this->codeCoverage()->enableCheckForUnintentionallyCoveredCode();
76369 }
76370 if ($configuration->ignoreDeprecatedCodeUnitsFromCodeCoverage()) {
76371 $this->codeCoverage()->ignoreDeprecatedCode();
76372 } else {
76373 $this->codeCoverage()->doNotIgnoreDeprecatedCode();
76374 }
76375 if ($configuration->disableCodeCoverageIgnore()) {
76376 $this->codeCoverage()->disableAnnotationsForIgnoringCode();
76377 } else {
76378 $this->codeCoverage()->enableAnnotationsForIgnoringCode();
76379 }
76380 if ($configuration->includeUncoveredFiles()) {
76381 $this->codeCoverage()->includeUncoveredFiles();
76382 } else {
76383 $this->codeCoverage()->excludeUncoveredFiles();
76384 }
76385 if ($codeCoverageFilterRegistry->get()->isEmpty()) {
76386 if (!$codeCoverageFilterRegistry->configured()) {
76387 EventFacade::emitter()->testRunnerTriggeredPhpunitWarning('No filter is configured, code coverage will not be processed');
76388 } else {
76389 EventFacade::emitter()->testRunnerTriggeredPhpunitWarning('Incorrect filter configuration, code coverage will not be processed');
76390 }
76391 $this->deactivate();
76392 }
76393 }
76394 /**
76395 * @psalm-assert-if-true !null $this->instance
76396 */
76397 public function isActive(): bool
76398 {
76399 return $this->codeCoverage !== null;
76400 }
76401 public function codeCoverage(): \PHPUnitPHAR\SebastianBergmann\CodeCoverage\CodeCoverage
76402 {
76403 return $this->codeCoverage;
76404 }
76405 public function driver(): Driver
76406 {
76407 return $this->driver;
76408 }
76409 /**
76410 * @throws MoreThanOneDataSetFromDataProviderException
76411 */
76412 public function start(TestCase $test): void
76413 {
76414 if ($this->collecting) {
76415 return;
76416 }
76417 $size = TestSize::unknown();
76418 if ($test->size()->isSmall()) {
76419 $size = TestSize::small();
76420 } elseif ($test->size()->isMedium()) {
76421 $size = TestSize::medium();
76422 } elseif ($test->size()->isLarge()) {
76423 $size = TestSize::large();
76424 }
76425 $this->test = $test;
76426 $this->codeCoverage->start($test->valueObjectForEvents()->id(), $size);
76427 $this->collecting = \true;
76428 }
76429 public function stop(bool $append, array|false $linesToBeCovered = [], array $linesToBeUsed = []): void
76430 {
76431 if (!$this->collecting) {
76432 return;
76433 }
76434 $status = TestStatus::unknown();
76435 if ($this->test !== null) {
76436 if ($this->test->status()->isSuccess()) {
76437 $status = TestStatus::success();
76438 } else {
76439 $status = TestStatus::failure();
76440 }
76441 }
76442 /* @noinspection UnusedFunctionResultInspection */
76443 $this->codeCoverage->stop($append, $status, $linesToBeCovered, $linesToBeUsed, $this->linesToBeIgnored);
76444 $this->test = null;
76445 $this->collecting = \false;
76446 }
76447 public function deactivate(): void
76448 {
76449 $this->driver = null;
76450 $this->codeCoverage = null;
76451 $this->test = null;
76452 }
76453 public function generateReports(Printer $printer, Configuration $configuration): void
76454 {
76455 if (!$this->isActive()) {
76456 return;
76457 }
76458 if ($configuration->hasCoveragePhp()) {
76459 $this->codeCoverageGenerationStart($printer, 'PHP');
76460 try {
76461 $writer = new PhpReport();
76462 $writer->process($this->codeCoverage(), $configuration->coveragePhp());
76463 $this->codeCoverageGenerationSucceeded($printer);
76464 unset($writer);
76465 } catch (CodeCoverageException $e) {
76466 $this->codeCoverageGenerationFailed($printer, $e);
76467 }
76468 }
76469 if ($configuration->hasCoverageClover()) {
76470 $this->codeCoverageGenerationStart($printer, 'Clover XML');
76471 try {
76472 $writer = new CloverReport();
76473 $writer->process($this->codeCoverage(), $configuration->coverageClover());
76474 $this->codeCoverageGenerationSucceeded($printer);
76475 unset($writer);
76476 } catch (CodeCoverageException $e) {
76477 $this->codeCoverageGenerationFailed($printer, $e);
76478 }
76479 }
76480 if ($configuration->hasCoverageCobertura()) {
76481 $this->codeCoverageGenerationStart($printer, 'Cobertura XML');
76482 try {
76483 $writer = new CoberturaReport();
76484 $writer->process($this->codeCoverage(), $configuration->coverageCobertura());
76485 $this->codeCoverageGenerationSucceeded($printer);
76486 unset($writer);
76487 } catch (CodeCoverageException $e) {
76488 $this->codeCoverageGenerationFailed($printer, $e);
76489 }
76490 }
76491 if ($configuration->hasCoverageCrap4j()) {
76492 $this->codeCoverageGenerationStart($printer, 'Crap4J XML');
76493 try {
76494 $writer = new Crap4jReport($configuration->coverageCrap4jThreshold());
76495 $writer->process($this->codeCoverage(), $configuration->coverageCrap4j());
76496 $this->codeCoverageGenerationSucceeded($printer);
76497 unset($writer);
76498 } catch (CodeCoverageException $e) {
76499 $this->codeCoverageGenerationFailed($printer, $e);
76500 }
76501 }
76502 if ($configuration->hasCoverageHtml()) {
76503 $this->codeCoverageGenerationStart($printer, 'HTML');
76504 try {
76505 $customCssFile = CustomCssFile::default();
76506 if ($configuration->hasCoverageHtmlCustomCssFile()) {
76507 $customCssFile = CustomCssFile::from($configuration->coverageHtmlCustomCssFile());
76508 }
76509 $writer = new HtmlReport(sprintf(' and <a href="https://phpunit.de/">PHPUnit %s</a>', \PHPUnit\Runner\Version::id()), Colors::from($configuration->coverageHtmlColorSuccessLow(), $configuration->coverageHtmlColorSuccessMedium(), $configuration->coverageHtmlColorSuccessHigh(), $configuration->coverageHtmlColorWarning(), $configuration->coverageHtmlColorDanger()), Thresholds::from($configuration->coverageHtmlLowUpperBound(), $configuration->coverageHtmlHighLowerBound()), $customCssFile);
76510 $writer->process($this->codeCoverage(), $configuration->coverageHtml());
76511 $this->codeCoverageGenerationSucceeded($printer);
76512 unset($writer);
76513 } catch (CodeCoverageException $e) {
76514 $this->codeCoverageGenerationFailed($printer, $e);
76515 }
76516 }
76517 if ($configuration->hasCoverageText()) {
76518 $processor = new TextReport(Thresholds::default(), $configuration->coverageTextShowUncoveredFiles(), $configuration->coverageTextShowOnlySummary());
76519 $textReport = $processor->process($this->codeCoverage(), $configuration->colors());
76520 if ($configuration->coverageText() === 'php://stdout') {
76521 if (!$configuration->noOutput() && !$configuration->debug()) {
76522 $printer->print($textReport);
76523 }
76524 } else {
76525 file_put_contents($configuration->coverageText(), $textReport);
76526 }
76527 }
76528 if ($configuration->hasCoverageXml()) {
76529 $this->codeCoverageGenerationStart($printer, 'PHPUnit XML');
76530 try {
76531 $writer = new XmlReport(\PHPUnit\Runner\Version::id());
76532 $writer->process($this->codeCoverage(), $configuration->coverageXml());
76533 $this->codeCoverageGenerationSucceeded($printer);
76534 unset($writer);
76535 } catch (CodeCoverageException $e) {
76536 $this->codeCoverageGenerationFailed($printer, $e);
76537 }
76538 }
76539 }
76540 /**
76541 * @psalm-param array<string,list<int>> $linesToBeIgnored
76542 */
76543 public function ignoreLines(array $linesToBeIgnored): void
76544 {
76545 $this->linesToBeIgnored = $linesToBeIgnored;
76546 }
76547 /**
76548 * @psalm-return array<string,list<int>>
76549 */
76550 public function linesToBeIgnored(): array
76551 {
76552 return $this->linesToBeIgnored;
76553 }
76554 private function activate(Filter $filter, bool $pathCoverage): void
76555 {
76556 try {
76557 if ($pathCoverage) {
76558 $this->driver = (new Selector())->forLineAndPathCoverage($filter);
76559 } else {
76560 $this->driver = (new Selector())->forLineCoverage($filter);
76561 }
76562 $this->codeCoverage = new \PHPUnitPHAR\SebastianBergmann\CodeCoverage\CodeCoverage($this->driver, $filter);
76563 } catch (CodeCoverageException $e) {
76564 EventFacade::emitter()->testRunnerTriggeredPhpunitWarning($e->getMessage());
76565 }
76566 }
76567 private function codeCoverageGenerationStart(Printer $printer, string $format): void
76568 {
76569 $printer->print(sprintf("\nGenerating code coverage report in %s format ... ", $format));
76570 $this->timer()->start();
76571 }
76572 /**
76573 * @throws NoActiveTimerException
76574 */
76575 private function codeCoverageGenerationSucceeded(Printer $printer): void
76576 {
76577 $printer->print(sprintf("done [%s]\n", $this->timer()->stop()->asString()));
76578 }
76579 /**
76580 * @throws NoActiveTimerException
76581 */
76582 private function codeCoverageGenerationFailed(Printer $printer, CodeCoverageException $e): void
76583 {
76584 $printer->print(sprintf("failed [%s]\n%s\n", $this->timer()->stop()->asString(), $e->getMessage()));
76585 }
76586 private function timer(): Timer
76587 {
76588 if ($this->timer === null) {
76589 $this->timer = new Timer();
76590 }
76591 return $this->timer;
76592 }
76593 }
76594 <?php
76595
76596 declare (strict_types=1);
76597 /*
76598 * This file is part of PHPUnit.
76599 *
76600 * (c) Sebastian Bergmann <sebastian@phpunit.de>
76601 *
76602 * For the full copyright and license information, please view the LICENSE
76603 * file that was distributed with this source code.
76604 */
76605 namespace PHPUnit\Runner;
76606
76607 use const E_COMPILE_ERROR;
76608 use const E_COMPILE_WARNING;
76609 use const E_CORE_ERROR;
76610 use const E_CORE_WARNING;
76611 use const E_DEPRECATED;
76612 use const E_ERROR;
76613 use const E_NOTICE;
76614 use const E_PARSE;
76615 use const E_RECOVERABLE_ERROR;
76616 use const E_USER_DEPRECATED;
76617 use const E_USER_ERROR;
76618 use const E_USER_NOTICE;
76619 use const E_USER_WARNING;
76620 use const E_WARNING;
76621 use function defined;
76622 use function error_reporting;
76623 use function restore_error_handler;
76624 use function set_error_handler;
76625 use PHPUnit\Event;
76626 use PHPUnit\Event\Code\NoTestCaseObjectOnCallStackException;
76627 use PHPUnit\Runner\Baseline\Baseline;
76628 use PHPUnit\Runner\Baseline\Issue;
76629 use PHPUnit\Util\ExcludeList;
76630 /**
76631 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
76632 *
76633 * @internal This class is not covered by the backward compatibility promise for PHPUnit
76634 */
76635 final class ErrorHandler
76636 {
76637 private const UNHANDLEABLE_LEVELS = E_ERROR | E_PARSE | E_CORE_ERROR | E_CORE_WARNING | E_COMPILE_ERROR | E_COMPILE_WARNING;
76638 private const INSUPPRESSIBLE_LEVELS = E_ERROR | E_PARSE | E_CORE_ERROR | E_COMPILE_ERROR | E_USER_ERROR | E_RECOVERABLE_ERROR;
76639 private static ?self $instance = null;
76640 private ?Baseline $baseline = null;
76641 private bool $enabled = \false;
76642 private ?int $originalErrorReportingLevel = null;
76643 public static function instance(): self
76644 {
76645 return self::$instance ?? self::$instance = new self();
76646 }
76647 /**
76648 * @throws NoTestCaseObjectOnCallStackException
76649 */
76650 public function __invoke(int $errorNumber, string $errorString, string $errorFile, int $errorLine): bool
76651 {
76652 $suppressed = (error_reporting() & ~self::INSUPPRESSIBLE_LEVELS) === 0;
76653 if ($suppressed && (new ExcludeList())->isExcluded($errorFile)) {
76654 return \false;
76655 }
76656 /**
76657 * E_STRICT is deprecated since PHP 8.4.
76658 *
76659 * @see https://github.com/sebastianbergmann/phpunit/issues/5956
76660 */
76661 if (defined('E_STRICT') && $errorNumber === 2048) {
76662 $errorNumber = E_NOTICE;
76663 }
76664 $test = Event\Code\TestMethodBuilder::fromCallStack();
76665 $ignoredByBaseline = $this->ignoredByBaseline($errorFile, $errorLine, $errorString);
76666 $ignoredByTest = $test->metadata()->isIgnoreDeprecations()->isNotEmpty();
76667 switch ($errorNumber) {
76668 case E_NOTICE:
76669 Event\Facade::emitter()->testTriggeredPhpNotice($test, $errorString, $errorFile, $errorLine, $suppressed, $ignoredByBaseline);
76670 break;
76671 case E_USER_NOTICE:
76672 Event\Facade::emitter()->testTriggeredNotice($test, $errorString, $errorFile, $errorLine, $suppressed, $ignoredByBaseline);
76673 break;
76674 case E_WARNING:
76675 Event\Facade::emitter()->testTriggeredPhpWarning($test, $errorString, $errorFile, $errorLine, $suppressed, $ignoredByBaseline);
76676 break;
76677 case E_USER_WARNING:
76678 Event\Facade::emitter()->testTriggeredWarning($test, $errorString, $errorFile, $errorLine, $suppressed, $ignoredByBaseline);
76679 break;
76680 case E_DEPRECATED:
76681 Event\Facade::emitter()->testTriggeredPhpDeprecation($test, $errorString, $errorFile, $errorLine, $suppressed, $ignoredByBaseline, $ignoredByTest);
76682 break;
76683 case E_USER_DEPRECATED:
76684 Event\Facade::emitter()->testTriggeredDeprecation($test, $errorString, $errorFile, $errorLine, $suppressed, $ignoredByBaseline, $ignoredByTest);
76685 break;
76686 case E_USER_ERROR:
76687 Event\Facade::emitter()->testTriggeredError($test, $errorString, $errorFile, $errorLine, $suppressed);
76688 throw new \PHPUnit\Runner\ErrorException('E_USER_ERROR was triggered');
76689 default:
76690 return \false;
76691 }
76692 return \false;
76693 }
76694 public function enable(): void
76695 {
76696 if ($this->enabled) {
76697 return;
76698 }
76699 $oldErrorHandler = set_error_handler($this);
76700 if ($oldErrorHandler !== null) {
76701 restore_error_handler();
76702 return;
76703 }
76704 $this->enabled = \true;
76705 $this->originalErrorReportingLevel = error_reporting();
76706 error_reporting($this->originalErrorReportingLevel & self::UNHANDLEABLE_LEVELS);
76707 }
76708 public function disable(): void
76709 {
76710 if (!$this->enabled) {
76711 return;
76712 }
76713 restore_error_handler();
76714 error_reporting(error_reporting() | $this->originalErrorReportingLevel);
76715 $this->enabled = \false;
76716 $this->originalErrorReportingLevel = null;
76717 }
76718 public function use(Baseline $baseline): void
76719 {
76720 $this->baseline = $baseline;
76721 }
76722 /**
76723 * @psalm-param non-empty-string $file
76724 * @psalm-param positive-int $line
76725 * @psalm-param non-empty-string $description
76726 */
76727 private function ignoredByBaseline(string $file, int $line, string $description): bool
76728 {
76729 if ($this->baseline === null) {
76730 return \false;
76731 }
76732 return $this->baseline->has(Issue::from($file, $line, null, $description));
76733 }
76734 }
76735 <?php
76736
76737 declare (strict_types=1);
76738 /*
76739 * This file is part of PHPUnit.
76740 *
76741 * (c) Sebastian Bergmann <sebastian@phpunit.de>
76742 *
76743 * For the full copyright and license information, please view the LICENSE
76744 * file that was distributed with this source code.
76745 */
76746 namespace PHPUnit\Runner;
76747
76748 use function sprintf;
76749 use RuntimeException;
76750 /**
76751 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
76752 *
76753 * @internal This class is not covered by the backward compatibility promise for PHPUnit
76754 */
76755 final class ClassCannotBeFoundException extends RuntimeException implements \PHPUnit\Runner\Exception
76756 {
76757 public function __construct(string $className, string $file)
76758 {
76759 parent::__construct(sprintf('Class %s cannot be found in %s', $className, $file));
76760 }
76761 }
76762 <?php
76763
76764 declare (strict_types=1);
76765 /*
76766 * This file is part of PHPUnit.
76767 *
76768 * (c) Sebastian Bergmann <sebastian@phpunit.de>
76769 *
76770 * For the full copyright and license information, please view the LICENSE
76771 * file that was distributed with this source code.
76772 */
76773 namespace PHPUnit\Runner;
76774
76775 use function sprintf;
76776 use RuntimeException;
76777 /**
76778 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
76779 *
76780 * @internal This class is not covered by the backward compatibility promise for PHPUnit
76781 */
76782 final class ClassDoesNotExtendTestCaseException extends RuntimeException implements \PHPUnit\Runner\Exception
76783 {
76784 public function __construct(string $className, string $file)
76785 {
76786 parent::__construct(sprintf('Class %s declared in %s does not extend PHPUnit\Framework\TestCase', $className, $file));
76787 }
76788 }
76789 <?php
76790
76791 declare (strict_types=1);
76792 /*
76793 * This file is part of PHPUnit.
76794 *
76795 * (c) Sebastian Bergmann <sebastian@phpunit.de>
76796 *
76797 * For the full copyright and license information, please view the LICENSE
76798 * file that was distributed with this source code.
76799 */
76800 namespace PHPUnit\Runner;
76801
76802 use function sprintf;
76803 use RuntimeException;
76804 /**
76805 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
76806 *
76807 * @internal This class is not covered by the backward compatibility promise for PHPUnit
76808 */
76809 final class ClassIsAbstractException extends RuntimeException implements \PHPUnit\Runner\Exception
76810 {
76811 public function __construct(string $className, string $file)
76812 {
76813 parent::__construct(sprintf('Class %s declared in %s is abstract', $className, $file));
76814 }
76815 }
76816 <?php
76817
76818 declare (strict_types=1);
76819 /*
76820 * This file is part of PHPUnit.
76821 *
76822 * (c) Sebastian Bergmann <sebastian@phpunit.de>
76823 *
76824 * For the full copyright and license information, please view the LICENSE
76825 * file that was distributed with this source code.
76826 */
76827 namespace PHPUnit\Runner;
76828
76829 use RuntimeException;
76830 /**
76831 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
76832 *
76833 * @internal This class is not covered by the backward compatibility promise for PHPUnit
76834 */
76835 final class CodeCoverageFileExistsException extends RuntimeException implements \PHPUnit\Runner\Exception
76836 {
76837 }
76838 <?php
76839
76840 declare (strict_types=1);
76841 /*
76842 * This file is part of PHPUnit.
76843 *
76844 * (c) Sebastian Bergmann <sebastian@phpunit.de>
76845 *
76846 * For the full copyright and license information, please view the LICENSE
76847 * file that was distributed with this source code.
76848 */
76849 namespace PHPUnit\Runner;
76850
76851 use function sprintf;
76852 use RuntimeException;
76853 /**
76854 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
76855 *
76856 * @internal This class is not covered by the backward compatibility promise for PHPUnit
76857 */
76858 final class DirectoryDoesNotExistException extends RuntimeException implements \PHPUnit\Runner\Exception
76859 {
76860 public function __construct(string $directory)
76861 {
76862 parent::__construct(sprintf('Directory "%s" does not exist and could not be created', $directory));
76863 }
76864 }
76865 <?php
76866
76867 declare (strict_types=1);
76868 /*
76869 * This file is part of PHPUnit.
76870 *
76871 * (c) Sebastian Bergmann <sebastian@phpunit.de>
76872 *
76873 * For the full copyright and license information, please view the LICENSE
76874 * file that was distributed with this source code.
76875 */
76876 namespace PHPUnit\Runner;
76877
76878 use Error;
76879 /**
76880 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
76881 *
76882 * @internal This interface is not covered by the backward compatibility promise for PHPUnit
76883 */
76884 final class ErrorException extends Error implements \PHPUnit\Runner\Exception
76885 {
76886 }
76887 <?php
76888
76889 declare (strict_types=1);
76890 /*
76891 * This file is part of PHPUnit.
76892 *
76893 * (c) Sebastian Bergmann <sebastian@phpunit.de>
76894 *
76895 * For the full copyright and license information, please view the LICENSE
76896 * file that was distributed with this source code.
76897 */
76898 namespace PHPUnit\Runner;
76899
76900 /**
76901 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
76902 *
76903 * @internal This interface is not covered by the backward compatibility promise for PHPUnit
76904 */
76905 interface Exception extends \PHPUnit\Exception
76906 {
76907 }
76908 <?php
76909
76910 declare (strict_types=1);
76911 /*
76912 * This file is part of PHPUnit.
76913 *
76914 * (c) Sebastian Bergmann <sebastian@phpunit.de>
76915 *
76916 * For the full copyright and license information, please view the LICENSE
76917 * file that was distributed with this source code.
76918 */
76919 namespace PHPUnit\Runner;
76920
76921 use function sprintf;
76922 use RuntimeException;
76923 /**
76924 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
76925 *
76926 * @internal This class is not covered by the backward compatibility promise for PHPUnit
76927 */
76928 final class FileDoesNotExistException extends RuntimeException implements \PHPUnit\Runner\Exception
76929 {
76930 public function __construct(string $file)
76931 {
76932 parent::__construct(sprintf('File "%s" does not exist', $file));
76933 }
76934 }
76935 <?php
76936
76937 declare (strict_types=1);
76938 /*
76939 * This file is part of PHPUnit.
76940 *
76941 * (c) Sebastian Bergmann <sebastian@phpunit.de>
76942 *
76943 * For the full copyright and license information, please view the LICENSE
76944 * file that was distributed with this source code.
76945 */
76946 namespace PHPUnit\Runner;
76947
76948 use RuntimeException;
76949 /**
76950 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
76951 *
76952 * @internal This class is not covered by the backward compatibility promise for PHPUnit
76953 */
76954 final class InvalidOrderException extends RuntimeException implements \PHPUnit\Runner\Exception
76955 {
76956 }
76957 <?php
76958
76959 declare (strict_types=1);
76960 /*
76961 * This file is part of PHPUnit.
76962 *
76963 * (c) Sebastian Bergmann <sebastian@phpunit.de>
76964 *
76965 * For the full copyright and license information, please view the LICENSE
76966 * file that was distributed with this source code.
76967 */
76968 namespace PHPUnit\Runner;
76969
76970 use RuntimeException;
76971 /**
76972 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
76973 *
76974 * @internal This class is not covered by the backward compatibility promise for PHPUnit
76975 */
76976 final class InvalidPhptFileException extends RuntimeException implements \PHPUnit\Runner\Exception
76977 {
76978 }
76979 <?php
76980
76981 declare (strict_types=1);
76982 /*
76983 * This file is part of PHPUnit.
76984 *
76985 * (c) Sebastian Bergmann <sebastian@phpunit.de>
76986 *
76987 * For the full copyright and license information, please view the LICENSE
76988 * file that was distributed with this source code.
76989 */
76990 namespace PHPUnit\Runner;
76991
76992 use function sprintf;
76993 use RuntimeException;
76994 /**
76995 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
76996 *
76997 * @internal This class is not covered by the backward compatibility promise for PHPUnit
76998 */
76999 final class ParameterDoesNotExistException extends RuntimeException implements \PHPUnit\Runner\Exception
77000 {
77001 public function __construct(string $name)
77002 {
77003 parent::__construct(sprintf('Parameter "%s" does not exist', $name));
77004 }
77005 }
77006 <?php
77007
77008 declare (strict_types=1);
77009 /*
77010 * This file is part of PHPUnit.
77011 *
77012 * (c) Sebastian Bergmann <sebastian@phpunit.de>
77013 *
77014 * For the full copyright and license information, please view the LICENSE
77015 * file that was distributed with this source code.
77016 */
77017 namespace PHPUnit\Runner;
77018
77019 use function sprintf;
77020 use RuntimeException;
77021 /**
77022 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
77023 *
77024 * @internal This class is not covered by the backward compatibility promise for PHPUnit
77025 */
77026 final class PhptExternalFileCannotBeLoadedException extends RuntimeException implements \PHPUnit\Runner\Exception
77027 {
77028 public function __construct(string $section, string $file)
77029 {
77030 parent::__construct(sprintf('Could not load --%s-- %s for PHPT file', $section . '_EXTERNAL', $file));
77031 }
77032 }
77033 <?php
77034
77035 declare (strict_types=1);
77036 /*
77037 * This file is part of PHPUnit.
77038 *
77039 * (c) Sebastian Bergmann <sebastian@phpunit.de>
77040 *
77041 * For the full copyright and license information, please view the LICENSE
77042 * file that was distributed with this source code.
77043 */
77044 namespace PHPUnit\Runner;
77045
77046 use function sprintf;
77047 use RuntimeException;
77048 /**
77049 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
77050 *
77051 * @internal This class is not covered by the backward compatibility promise for PHPUnit
77052 */
77053 final class UnsupportedPhptSectionException extends RuntimeException implements \PHPUnit\Runner\Exception
77054 {
77055 public function __construct(string $section)
77056 {
77057 parent::__construct(sprintf('PHPUnit does not support PHPT %s sections', $section));
77058 }
77059 }
77060 <?php
77061
77062 declare (strict_types=1);
77063 /*
77064 * This file is part of PHPUnit.
77065 *
77066 * (c) Sebastian Bergmann <sebastian@phpunit.de>
77067 *
77068 * For the full copyright and license information, please view the LICENSE
77069 * file that was distributed with this source code.
77070 */
77071 namespace PHPUnit\Runner\Extension;
77072
77073 use PHPUnit\TextUI\Configuration\Configuration;
77074 /**
77075 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
77076 */
77077 interface Extension
77078 {
77079 public function bootstrap(Configuration $configuration, \PHPUnit\Runner\Extension\Facade $facade, \PHPUnit\Runner\Extension\ParameterCollection $parameters): void;
77080 }
77081 <?php
77082
77083 declare (strict_types=1);
77084 /*
77085 * This file is part of PHPUnit.
77086 *
77087 * (c) Sebastian Bergmann <sebastian@phpunit.de>
77088 *
77089 * For the full copyright and license information, please view the LICENSE
77090 * file that was distributed with this source code.
77091 */
77092 namespace PHPUnit\Runner\Extension;
77093
77094 use const PHP_EOL;
77095 use function assert;
77096 use function class_exists;
77097 use function class_implements;
77098 use function in_array;
77099 use function sprintf;
77100 use PHPUnit\Event\Facade as EventFacade;
77101 use PHPUnit\TextUI\Configuration\Configuration;
77102 use ReflectionClass;
77103 use Throwable;
77104 /**
77105 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
77106 *
77107 * @internal This class is not covered by the backward compatibility promise for PHPUnit
77108 */
77109 final class ExtensionBootstrapper
77110 {
77111 private readonly Configuration $configuration;
77112 private readonly \PHPUnit\Runner\Extension\Facade $facade;
77113 public function __construct(Configuration $configuration, \PHPUnit\Runner\Extension\Facade $facade)
77114 {
77115 $this->configuration = $configuration;
77116 $this->facade = $facade;
77117 }
77118 /**
77119 * @psalm-param class-string $className
77120 * @psalm-param array<string, string> $parameters
77121 */
77122 public function bootstrap(string $className, array $parameters): void
77123 {
77124 if (!class_exists($className)) {
77125 EventFacade::emitter()->testRunnerTriggeredPhpunitWarning(sprintf('Cannot bootstrap extension because class %s does not exist', $className));
77126 return;
77127 }
77128 if (!in_array(\PHPUnit\Runner\Extension\Extension::class, class_implements($className), \true)) {
77129 EventFacade::emitter()->testRunnerTriggeredPhpunitWarning(sprintf('Cannot bootstrap extension because class %s does not implement interface %s', $className, \PHPUnit\Runner\Extension\Extension::class));
77130 return;
77131 }
77132 try {
77133 $instance = (new ReflectionClass($className))->newInstance();
77134 assert($instance instanceof \PHPUnit\Runner\Extension\Extension);
77135 $instance->bootstrap($this->configuration, $this->facade, \PHPUnit\Runner\Extension\ParameterCollection::fromArray($parameters));
77136 } catch (Throwable $t) {
77137 EventFacade::emitter()->testRunnerTriggeredPhpunitWarning(sprintf('Bootstrapping of extension %s failed: %s%s%s', $className, $t->getMessage(), PHP_EOL, $t->getTraceAsString()));
77138 return;
77139 }
77140 EventFacade::emitter()->testRunnerBootstrappedExtension($className, $parameters);
77141 }
77142 }
77143 <?php
77144
77145 declare (strict_types=1);
77146 /*
77147 * This file is part of PHPUnit.
77148 *
77149 * (c) Sebastian Bergmann <sebastian@phpunit.de>
77150 *
77151 * For the full copyright and license information, please view the LICENSE
77152 * file that was distributed with this source code.
77153 */
77154 namespace PHPUnit\Runner\Extension;
77155
77156 use PHPUnit\Event\EventFacadeIsSealedException;
77157 use PHPUnit\Event\Facade as EventFacade;
77158 use PHPUnit\Event\Subscriber;
77159 use PHPUnit\Event\Tracer\Tracer;
77160 use PHPUnit\Event\UnknownSubscriberTypeException;
77161 /**
77162 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
77163 */
77164 final class Facade
77165 {
77166 private bool $replacesOutput = \false;
77167 private bool $replacesProgressOutput = \false;
77168 private bool $replacesResultOutput = \false;
77169 private bool $requiresCodeCoverageCollection = \false;
77170 private bool $requiresExportOfObjects = \false;
77171 /**
77172 * @throws EventFacadeIsSealedException
77173 * @throws UnknownSubscriberTypeException
77174 */
77175 public function registerSubscribers(Subscriber ...$subscribers): void
77176 {
77177 EventFacade::instance()->registerSubscribers(...$subscribers);
77178 }
77179 /**
77180 * @throws EventFacadeIsSealedException
77181 * @throws UnknownSubscriberTypeException
77182 */
77183 public function registerSubscriber(Subscriber $subscriber): void
77184 {
77185 EventFacade::instance()->registerSubscriber($subscriber);
77186 }
77187 /**
77188 * @throws EventFacadeIsSealedException
77189 */
77190 public function registerTracer(Tracer $tracer): void
77191 {
77192 EventFacade::instance()->registerTracer($tracer);
77193 }
77194 public function replaceOutput(): void
77195 {
77196 $this->replacesOutput = \true;
77197 }
77198 public function replacesOutput(): bool
77199 {
77200 return $this->replacesOutput;
77201 }
77202 public function replaceProgressOutput(): void
77203 {
77204 $this->replacesProgressOutput = \true;
77205 }
77206 public function replacesProgressOutput(): bool
77207 {
77208 return $this->replacesOutput || $this->replacesProgressOutput;
77209 }
77210 public function replaceResultOutput(): void
77211 {
77212 $this->replacesResultOutput = \true;
77213 }
77214 public function replacesResultOutput(): bool
77215 {
77216 return $this->replacesOutput || $this->replacesResultOutput;
77217 }
77218 public function requireCodeCoverageCollection(): void
77219 {
77220 $this->requiresCodeCoverageCollection = \true;
77221 }
77222 public function requiresCodeCoverageCollection(): bool
77223 {
77224 return $this->requiresCodeCoverageCollection;
77225 }
77226 /**
77227 * @deprecated
77228 */
77229 public function requireExportOfObjects(): void
77230 {
77231 $this->requiresExportOfObjects = \true;
77232 }
77233 /**
77234 * @deprecated
77235 */
77236 public function requiresExportOfObjects(): bool
77237 {
77238 return $this->requiresExportOfObjects;
77239 }
77240 }
77241 <?php
77242
77243 declare (strict_types=1);
77244 /*
77245 * This file is part of PHPUnit.
77246 *
77247 * (c) Sebastian Bergmann <sebastian@phpunit.de>
77248 *
77249 * For the full copyright and license information, please view the LICENSE
77250 * file that was distributed with this source code.
77251 */
77252 namespace PHPUnit\Runner\Extension;
77253
77254 use function array_key_exists;
77255 use PHPUnit\Runner\ParameterDoesNotExistException;
77256 /**
77257 * @psalm-immutable
77258 *
77259 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
77260 */
77261 final class ParameterCollection
77262 {
77263 private readonly array $parameters;
77264 /**
77265 * @psalm-param array<string, string> $parameters
77266 */
77267 public static function fromArray(array $parameters): self
77268 {
77269 return new self($parameters);
77270 }
77271 private function __construct(array $parameters)
77272 {
77273 $this->parameters = $parameters;
77274 }
77275 public function has(string $name): bool
77276 {
77277 return array_key_exists($name, $this->parameters);
77278 }
77279 /**
77280 * @throws ParameterDoesNotExistException
77281 */
77282 public function get(string $name): string
77283 {
77284 if (!$this->has($name)) {
77285 throw new ParameterDoesNotExistException($name);
77286 }
77287 return $this->parameters[$name];
77288 }
77289 }
77290 <?php
77291
77292 declare (strict_types=1);
77293 /*
77294 * This file is part of PHPUnit.
77295 *
77296 * (c) Sebastian Bergmann <sebastian@phpunit.de>
77297 *
77298 * For the full copyright and license information, please view the LICENSE
77299 * file that was distributed with this source code.
77300 */
77301 namespace PHPUnit\Runner\Extension;
77302
77303 use function count;
77304 use function explode;
77305 use function extension_loaded;
77306 use function implode;
77307 use function is_file;
77308 use function sprintf;
77309 use function str_contains;
77310 use PHPUnitPHAR\PharIo\Manifest\ApplicationName;
77311 use PHPUnitPHAR\PharIo\Manifest\Exception as ManifestException;
77312 use PHPUnitPHAR\PharIo\Manifest\ManifestLoader;
77313 use PHPUnitPHAR\PharIo\Version\Version as PharIoVersion;
77314 use PHPUnit\Event;
77315 use PHPUnit\Runner\Version;
77316 use PHPUnitPHAR\SebastianBergmann\FileIterator\Facade as FileIteratorFacade;
77317 use Throwable;
77318 /**
77319 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
77320 *
77321 * @internal This class is not covered by the backward compatibility promise for PHPUnit
77322 */
77323 final class PharLoader
77324 {
77325 /**
77326 * @psalm-param non-empty-string $directory
77327 *
77328 * @psalm-return list<string>
77329 */
77330 public function loadPharExtensionsInDirectory(string $directory): array
77331 {
77332 $pharExtensionLoaded = extension_loaded('phar');
77333 $loadedExtensions = [];
77334 foreach ((new FileIteratorFacade())->getFilesAsArray($directory, '.phar') as $file) {
77335 if (!$pharExtensionLoaded) {
77336 Event\Facade::emitter()->testRunnerTriggeredPhpunitWarning(sprintf('Cannot load extension from %s because the PHAR extension is not available', $file));
77337 continue;
77338 }
77339 if (!is_file('phar://' . $file . '/manifest.xml')) {
77340 Event\Facade::emitter()->testRunnerTriggeredPhpunitWarning(sprintf('%s is not an extension for PHPUnit', $file));
77341 continue;
77342 }
77343 try {
77344 $applicationName = new ApplicationName('phpunit/phpunit');
77345 $version = new PharIoVersion($this->phpunitVersion());
77346 $manifest = ManifestLoader::fromFile('phar://' . $file . '/manifest.xml');
77347 if (!$manifest->isExtensionFor($applicationName)) {
77348 Event\Facade::emitter()->testRunnerTriggeredPhpunitWarning(sprintf('%s is not an extension for PHPUnit', $file));
77349 continue;
77350 }
77351 if (!$manifest->isExtensionFor($applicationName, $version)) {
77352 Event\Facade::emitter()->testRunnerTriggeredPhpunitWarning(sprintf('%s is not compatible with PHPUnit %s', $file, Version::series()));
77353 continue;
77354 }
77355 } catch (ManifestException $e) {
77356 Event\Facade::emitter()->testRunnerTriggeredPhpunitWarning(sprintf('Cannot load extension from %s: %s', $file, $e->getMessage()));
77357 continue;
77358 }
77359 try {
77360 /** @psalm-suppress UnresolvableInclude */
77361 @require $file;
77362 } catch (Throwable $t) {
77363 Event\Facade::emitter()->testRunnerTriggeredPhpunitWarning(sprintf('Cannot load extension from %s: %s', $file, $t->getMessage()));
77364 continue;
77365 }
77366 $loadedExtensions[] = $manifest->getName()->asString() . ' ' . $manifest->getVersion()->getVersionString();
77367 Event\Facade::emitter()->testRunnerLoadedExtensionFromPhar($file, $manifest->getName()->asString(), $manifest->getVersion()->getVersionString());
77368 }
77369 return $loadedExtensions;
77370 }
77371 private function phpunitVersion(): string
77372 {
77373 $version = Version::id();
77374 if (!str_contains($version, '-')) {
77375 return $version;
77376 }
77377 $parts = explode('.', explode('-', $version)[0]);
77378 if (count($parts) === 2) {
77379 $parts[] = 0;
77380 }
77381 return implode('.', $parts);
77382 }
77383 }
77384 <?php
77385
77386 declare (strict_types=1);
77387 /*
77388 * This file is part of PHPUnit.
77389 *
77390 * (c) Sebastian Bergmann <sebastian@phpunit.de>
77391 *
77392 * For the full copyright and license information, please view the LICENSE
77393 * file that was distributed with this source code.
77394 */
77395 namespace PHPUnit\Runner\Filter;
77396
77397 use function in_array;
77398 /**
77399 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
77400 *
77401 * @internal This class is not covered by the backward compatibility promise for PHPUnit
77402 */
77403 final class ExcludeGroupFilterIterator extends \PHPUnit\Runner\Filter\GroupFilterIterator
77404 {
77405 protected function doAccept(int $id): bool
77406 {
77407 return !in_array($id, $this->groupTests, \true);
77408 }
77409 }
77410 <?php
77411
77412 declare (strict_types=1);
77413 /*
77414 * This file is part of PHPUnit.
77415 *
77416 * (c) Sebastian Bergmann <sebastian@phpunit.de>
77417 *
77418 * For the full copyright and license information, please view the LICENSE
77419 * file that was distributed with this source code.
77420 */
77421 namespace PHPUnit\Runner\Filter;
77422
77423 use function assert;
77424 use FilterIterator;
77425 use Iterator;
77426 use PHPUnit\Framework\TestSuite;
77427 use ReflectionClass;
77428 /**
77429 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
77430 *
77431 * @internal This class is not covered by the backward compatibility promise for PHPUnit
77432 */
77433 final class Factory
77434 {
77435 /**
77436 * @psalm-var array<int,array{0: ReflectionClass, 1: array|string}>
77437 */
77438 private array $filters = [];
77439 /**
77440 * @psalm-param list<non-empty-string> $testIds
77441 */
77442 public function addTestIdFilter(array $testIds): void
77443 {
77444 $this->filters[] = [new ReflectionClass(\PHPUnit\Runner\Filter\TestIdFilterIterator::class), $testIds];
77445 }
77446 /**
77447 * @psalm-param list<non-empty-string> $groups
77448 */
77449 public function addExcludeGroupFilter(array $groups): void
77450 {
77451 $this->filters[] = [new ReflectionClass(\PHPUnit\Runner\Filter\ExcludeGroupFilterIterator::class), $groups];
77452 }
77453 /**
77454 * @psalm-param list<non-empty-string> $groups
77455 */
77456 public function addIncludeGroupFilter(array $groups): void
77457 {
77458 $this->filters[] = [new ReflectionClass(\PHPUnit\Runner\Filter\IncludeGroupFilterIterator::class), $groups];
77459 }
77460 /**
77461 * @psalm-param non-empty-string $name
77462 */
77463 public function addNameFilter(string $name): void
77464 {
77465 $this->filters[] = [new ReflectionClass(\PHPUnit\Runner\Filter\NameFilterIterator::class), $name];
77466 }
77467 public function factory(Iterator $iterator, TestSuite $suite): FilterIterator
77468 {
77469 foreach ($this->filters as $filter) {
77470 [$class, $arguments] = $filter;
77471 $iterator = $class->newInstance($iterator, $arguments, $suite);
77472 }
77473 assert($iterator instanceof FilterIterator);
77474 return $iterator;
77475 }
77476 }
77477 <?php
77478
77479 declare (strict_types=1);
77480 /*
77481 * This file is part of PHPUnit.
77482 *
77483 * (c) Sebastian Bergmann <sebastian@phpunit.de>
77484 *
77485 * For the full copyright and license information, please view the LICENSE
77486 * file that was distributed with this source code.
77487 */
77488 namespace PHPUnit\Runner\Filter;
77489
77490 use function array_map;
77491 use function array_push;
77492 use function in_array;
77493 use function spl_object_id;
77494 use PHPUnit\Framework\Test;
77495 use PHPUnit\Framework\TestSuite;
77496 use RecursiveFilterIterator;
77497 use RecursiveIterator;
77498 /**
77499 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
77500 *
77501 * @internal This class is not covered by the backward compatibility promise for PHPUnit
77502 */
77503 abstract class GroupFilterIterator extends RecursiveFilterIterator
77504 {
77505 /**
77506 * @psalm-var list<int>
77507 */
77508 protected array $groupTests = [];
77509 /**
77510 * @psalm-param RecursiveIterator<int, Test> $iterator
77511 * @psalm-param list<non-empty-string> $groups
77512 */
77513 public function __construct(RecursiveIterator $iterator, array $groups, TestSuite $suite)
77514 {
77515 parent::__construct($iterator);
77516 foreach ($suite->groupDetails() as $group => $tests) {
77517 if (in_array((string) $group, $groups, \true)) {
77518 $testHashes = array_map('spl_object_id', $tests);
77519 array_push($this->groupTests, ...$testHashes);
77520 }
77521 }
77522 }
77523 public function accept(): bool
77524 {
77525 $test = $this->getInnerIterator()->current();
77526 if ($test instanceof TestSuite) {
77527 return \true;
77528 }
77529 return $this->doAccept(spl_object_id($test));
77530 }
77531 abstract protected function doAccept(int $id): bool;
77532 }
77533 <?php
77534
77535 declare (strict_types=1);
77536 /*
77537 * This file is part of PHPUnit.
77538 *
77539 * (c) Sebastian Bergmann <sebastian@phpunit.de>
77540 *
77541 * For the full copyright and license information, please view the LICENSE
77542 * file that was distributed with this source code.
77543 */
77544 namespace PHPUnit\Runner\Filter;
77545
77546 use function in_array;
77547 /**
77548 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
77549 *
77550 * @internal This class is not covered by the backward compatibility promise for PHPUnit
77551 */
77552 final class IncludeGroupFilterIterator extends \PHPUnit\Runner\Filter\GroupFilterIterator
77553 {
77554 protected function doAccept(int $id): bool
77555 {
77556 return in_array($id, $this->groupTests, \true);
77557 }
77558 }
77559 <?php
77560
77561 declare (strict_types=1);
77562 /*
77563 * This file is part of PHPUnit.
77564 *
77565 * (c) Sebastian Bergmann <sebastian@phpunit.de>
77566 *
77567 * For the full copyright and license information, please view the LICENSE
77568 * file that was distributed with this source code.
77569 */
77570 namespace PHPUnit\Runner\Filter;
77571
77572 use function end;
77573 use function implode;
77574 use function preg_match;
77575 use function sprintf;
77576 use function str_replace;
77577 use function substr;
77578 use Exception;
77579 use PHPUnit\Framework\SelfDescribing;
77580 use PHPUnit\Framework\Test;
77581 use PHPUnit\Framework\TestCase;
77582 use PHPUnit\Framework\TestSuite;
77583 use RecursiveFilterIterator;
77584 use RecursiveIterator;
77585 /**
77586 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
77587 *
77588 * @internal This class is not covered by the backward compatibility promise for PHPUnit
77589 */
77590 final class NameFilterIterator extends RecursiveFilterIterator
77591 {
77592 private ?string $filter = null;
77593 private ?int $filterMin = null;
77594 private ?int $filterMax = null;
77595 /**
77596 * @psalm-param RecursiveIterator<int, Test> $iterator
77597 * @psalm-param non-empty-string $filter
77598 *
77599 * @throws Exception
77600 */
77601 public function __construct(RecursiveIterator $iterator, string $filter)
77602 {
77603 parent::__construct($iterator);
77604 $this->setFilter($filter);
77605 }
77606 public function accept(): bool
77607 {
77608 $test = $this->getInnerIterator()->current();
77609 if ($test instanceof TestSuite) {
77610 return \true;
77611 }
77612 $tmp = $this->describe($test);
77613 if ($tmp[0] !== '') {
77614 $name = implode('::', $tmp);
77615 } else {
77616 $name = $tmp[1];
77617 }
77618 $accepted = @preg_match($this->filter, $name, $matches);
77619 if ($accepted && isset($this->filterMax)) {
77620 $set = end($matches);
77621 $accepted = $set >= $this->filterMin && $set <= $this->filterMax;
77622 }
77623 return (bool) $accepted;
77624 }
77625 /**
77626 * @throws Exception
77627 */
77628 private function setFilter(string $filter): void
77629 {
77630 if (preg_match('/[a-zA-Z0-9]/', substr($filter, 0, 1)) === 1 || @preg_match($filter, '') === \false) {
77631 // Handles:
77632 // * testAssertEqualsSucceeds#4
77633 // * testAssertEqualsSucceeds#4-8
77634 if (preg_match('/^(.*?)#(\d+)(?:-(\d+))?$/', $filter, $matches)) {
77635 if (isset($matches[3]) && $matches[2] < $matches[3]) {
77636 $filter = sprintf('%s.*with data set #(\d+)$', $matches[1]);
77637 $this->filterMin = (int) $matches[2];
77638 $this->filterMax = (int) $matches[3];
77639 } else {
77640 $filter = sprintf('%s.*with data set #%s$', $matches[1], $matches[2]);
77641 }
77642 } elseif (preg_match('/^(.*?)@(.+)$/', $filter, $matches)) {
77643 $filter = sprintf('%s.*with data set "%s"$', $matches[1], $matches[2]);
77644 }
77645 // Escape delimiters in regular expression. Do NOT use preg_quote,
77646 // to keep magic characters.
77647 $filter = sprintf('/%s/i', str_replace('/', '\/', $filter));
77648 }
77649 $this->filter = $filter;
77650 }
77651 /**
77652 * @psalm-return array{0: string, 1: string}
77653 */
77654 private function describe(Test $test): array
77655 {
77656 if ($test instanceof TestCase) {
77657 return [$test::class, $test->nameWithDataSet()];
77658 }
77659 if ($test instanceof SelfDescribing) {
77660 return ['', $test->toString()];
77661 }
77662 return ['', $test::class];
77663 }
77664 }
77665 <?php
77666
77667 declare (strict_types=1);
77668 /*
77669 * This file is part of PHPUnit.
77670 *
77671 * (c) Sebastian Bergmann <sebastian@phpunit.de>
77672 *
77673 * For the full copyright and license information, please view the LICENSE
77674 * file that was distributed with this source code.
77675 */
77676 namespace PHPUnit\Runner\Filter;
77677
77678 use function in_array;
77679 use PHPUnit\Event\TestData\MoreThanOneDataSetFromDataProviderException;
77680 use PHPUnit\Event\TestData\NoDataSetFromDataProviderException;
77681 use PHPUnit\Framework\Test;
77682 use PHPUnit\Framework\TestCase;
77683 use PHPUnit\Framework\TestSuite;
77684 use PHPUnit\Runner\PhptTestCase;
77685 use RecursiveFilterIterator;
77686 use RecursiveIterator;
77687 /**
77688 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
77689 *
77690 * @internal This class is not covered by the backward compatibility promise for PHPUnit
77691 */
77692 final class TestIdFilterIterator extends RecursiveFilterIterator
77693 {
77694 /**
77695 * @psalm-var non-empty-list<non-empty-string>
77696 */
77697 private readonly array $testIds;
77698 /**
77699 * @psalm-param RecursiveIterator<int, Test> $iterator
77700 * @psalm-param non-empty-list<non-empty-string> $testIds
77701 */
77702 public function __construct(RecursiveIterator $iterator, array $testIds)
77703 {
77704 parent::__construct($iterator);
77705 $this->testIds = $testIds;
77706 }
77707 public function accept(): bool
77708 {
77709 $test = $this->getInnerIterator()->current();
77710 if ($test instanceof TestSuite) {
77711 return \true;
77712 }
77713 if (!$test instanceof TestCase && !$test instanceof PhptTestCase) {
77714 return \false;
77715 }
77716 try {
77717 return in_array($test->valueObjectForEvents()->id(), $this->testIds, \true);
77718 } catch (MoreThanOneDataSetFromDataProviderException|NoDataSetFromDataProviderException) {
77719 return \false;
77720 }
77721 }
77722 }
77723 <?php
77724
77725 declare (strict_types=1);
77726 /*
77727 * This file is part of PHPUnit.
77728 *
77729 * (c) Sebastian Bergmann <sebastian@phpunit.de>
77730 *
77731 * For the full copyright and license information, please view the LICENSE
77732 * file that was distributed with this source code.
77733 */
77734 namespace PHPUnit\Runner\GarbageCollection;
77735
77736 use function gc_collect_cycles;
77737 use function gc_disable;
77738 use function gc_enable;
77739 use PHPUnit\Event\EventFacadeIsSealedException;
77740 use PHPUnit\Event\Facade;
77741 use PHPUnit\Event\UnknownSubscriberTypeException;
77742 /**
77743 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
77744 *
77745 * @internal This class is not covered by the backward compatibility promise for PHPUnit
77746 */
77747 final class GarbageCollectionHandler
77748 {
77749 private readonly Facade $facade;
77750 private readonly int $threshold;
77751 private int $tests = 0;
77752 /**
77753 * @throws EventFacadeIsSealedException
77754 * @throws UnknownSubscriberTypeException
77755 */
77756 public function __construct(Facade $facade, int $threshold)
77757 {
77758 $this->facade = $facade;
77759 $this->threshold = $threshold;
77760 $this->registerSubscribers();
77761 }
77762 public function executionStarted(): void
77763 {
77764 gc_disable();
77765 $this->facade->emitter()->testRunnerDisabledGarbageCollection();
77766 gc_collect_cycles();
77767 $this->facade->emitter()->testRunnerTriggeredGarbageCollection();
77768 }
77769 public function executionFinished(): void
77770 {
77771 gc_collect_cycles();
77772 $this->facade->emitter()->testRunnerTriggeredGarbageCollection();
77773 gc_enable();
77774 $this->facade->emitter()->testRunnerEnabledGarbageCollection();
77775 }
77776 public function testFinished(): void
77777 {
77778 $this->tests++;
77779 if ($this->tests === $this->threshold) {
77780 gc_collect_cycles();
77781 $this->facade->emitter()->testRunnerTriggeredGarbageCollection();
77782 $this->tests = 0;
77783 }
77784 }
77785 /**
77786 * @throws EventFacadeIsSealedException
77787 * @throws UnknownSubscriberTypeException
77788 */
77789 private function registerSubscribers(): void
77790 {
77791 $this->facade->registerSubscribers(new \PHPUnit\Runner\GarbageCollection\ExecutionStartedSubscriber($this), new \PHPUnit\Runner\GarbageCollection\ExecutionFinishedSubscriber($this), new \PHPUnit\Runner\GarbageCollection\TestFinishedSubscriber($this));
77792 }
77793 }
77794 <?php
77795
77796 declare (strict_types=1);
77797 /*
77798 * This file is part of PHPUnit.
77799 *
77800 * (c) Sebastian Bergmann <sebastian@phpunit.de>
77801 *
77802 * For the full copyright and license information, please view the LICENSE
77803 * file that was distributed with this source code.
77804 */
77805 namespace PHPUnit\Runner\GarbageCollection;
77806
77807 use PHPUnit\Event\InvalidArgumentException;
77808 use PHPUnit\Event\TestRunner\ExecutionFinished;
77809 use PHPUnit\Event\TestRunner\ExecutionFinishedSubscriber as TestRunnerExecutionFinishedSubscriber;
77810 /**
77811 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
77812 *
77813 * @internal This class is not covered by the backward compatibility promise for PHPUnit
77814 */
77815 final class ExecutionFinishedSubscriber extends \PHPUnit\Runner\GarbageCollection\Subscriber implements TestRunnerExecutionFinishedSubscriber
77816 {
77817 /**
77818 * @throws \PHPUnit\Framework\InvalidArgumentException
77819 * @throws InvalidArgumentException
77820 */
77821 public function notify(ExecutionFinished $event): void
77822 {
77823 $this->handler()->executionFinished();
77824 }
77825 }
77826 <?php
77827
77828 declare (strict_types=1);
77829 /*
77830 * This file is part of PHPUnit.
77831 *
77832 * (c) Sebastian Bergmann <sebastian@phpunit.de>
77833 *
77834 * For the full copyright and license information, please view the LICENSE
77835 * file that was distributed with this source code.
77836 */
77837 namespace PHPUnit\Runner\GarbageCollection;
77838
77839 use PHPUnit\Event\InvalidArgumentException;
77840 use PHPUnit\Event\TestRunner\ExecutionStarted;
77841 use PHPUnit\Event\TestRunner\ExecutionStartedSubscriber as TestRunnerExecutionStartedSubscriber;
77842 /**
77843 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
77844 *
77845 * @internal This class is not covered by the backward compatibility promise for PHPUnit
77846 */
77847 final class ExecutionStartedSubscriber extends \PHPUnit\Runner\GarbageCollection\Subscriber implements TestRunnerExecutionStartedSubscriber
77848 {
77849 /**
77850 * @throws \PHPUnit\Framework\InvalidArgumentException
77851 * @throws InvalidArgumentException
77852 */
77853 public function notify(ExecutionStarted $event): void
77854 {
77855 $this->handler()->executionStarted();
77856 }
77857 }
77858 <?php
77859
77860 declare (strict_types=1);
77861 /*
77862 * This file is part of PHPUnit.
77863 *
77864 * (c) Sebastian Bergmann <sebastian@phpunit.de>
77865 *
77866 * For the full copyright and license information, please view the LICENSE
77867 * file that was distributed with this source code.
77868 */
77869 namespace PHPUnit\Runner\GarbageCollection;
77870
77871 /**
77872 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
77873 *
77874 * @internal This class is not covered by the backward compatibility promise for PHPUnit
77875 */
77876 abstract class Subscriber
77877 {
77878 private readonly \PHPUnit\Runner\GarbageCollection\GarbageCollectionHandler $handler;
77879 public function __construct(\PHPUnit\Runner\GarbageCollection\GarbageCollectionHandler $handler)
77880 {
77881 $this->handler = $handler;
77882 }
77883 protected function handler(): \PHPUnit\Runner\GarbageCollection\GarbageCollectionHandler
77884 {
77885 return $this->handler;
77886 }
77887 }
77888 <?php
77889
77890 declare (strict_types=1);
77891 /*
77892 * This file is part of PHPUnit.
77893 *
77894 * (c) Sebastian Bergmann <sebastian@phpunit.de>
77895 *
77896 * For the full copyright and license information, please view the LICENSE
77897 * file that was distributed with this source code.
77898 */
77899 namespace PHPUnit\Runner\GarbageCollection;
77900
77901 use PHPUnit\Event\InvalidArgumentException;
77902 use PHPUnit\Event\Test\Finished;
77903 use PHPUnit\Event\Test\FinishedSubscriber;
77904 /**
77905 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
77906 *
77907 * @internal This class is not covered by the backward compatibility promise for PHPUnit
77908 */
77909 final class TestFinishedSubscriber extends \PHPUnit\Runner\GarbageCollection\Subscriber implements FinishedSubscriber
77910 {
77911 /**
77912 * @throws \PHPUnit\Framework\InvalidArgumentException
77913 * @throws InvalidArgumentException
77914 */
77915 public function notify(Finished $event): void
77916 {
77917 $this->handler()->testFinished();
77918 }
77919 }
77920 <?php
77921
77922 declare (strict_types=1);
77923 /*
77924 * This file is part of PHPUnit.
77925 *
77926 * (c) Sebastian Bergmann <sebastian@phpunit.de>
77927 *
77928 * For the full copyright and license information, please view the LICENSE
77929 * file that was distributed with this source code.
77930 */
77931 namespace PHPUnit\Runner;
77932
77933 use const DEBUG_BACKTRACE_IGNORE_ARGS;
77934 use const DIRECTORY_SEPARATOR;
77935 use function array_merge;
77936 use function basename;
77937 use function debug_backtrace;
77938 use function defined;
77939 use function dirname;
77940 use function explode;
77941 use function extension_loaded;
77942 use function file;
77943 use function file_exists;
77944 use function file_get_contents;
77945 use function file_put_contents;
77946 use function is_array;
77947 use function is_file;
77948 use function is_readable;
77949 use function is_string;
77950 use function ltrim;
77951 use function preg_match;
77952 use function preg_replace;
77953 use function preg_split;
77954 use function realpath;
77955 use function rtrim;
77956 use function sprintf;
77957 use function str_contains;
77958 use function str_replace;
77959 use function str_starts_with;
77960 use function strncasecmp;
77961 use function substr;
77962 use function trim;
77963 use function unlink;
77964 use function unserialize;
77965 use function var_export;
77966 use PHPUnit\Event\Code\Phpt;
77967 use PHPUnit\Event\Code\ThrowableBuilder;
77968 use PHPUnit\Event\Facade as EventFacade;
77969 use PHPUnit\Event\NoPreviousThrowableException;
77970 use PHPUnit\Framework\Assert;
77971 use PHPUnit\Framework\AssertionFailedError;
77972 use PHPUnit\Framework\ExecutionOrderDependency;
77973 use PHPUnit\Framework\ExpectationFailedException;
77974 use PHPUnit\Framework\IncompleteTestError;
77975 use PHPUnit\Framework\PhptAssertionFailedError;
77976 use PHPUnit\Framework\Reorderable;
77977 use PHPUnit\Framework\SelfDescribing;
77978 use PHPUnit\Framework\Test;
77979 use PHPUnit\TextUI\Configuration\Registry as ConfigurationRegistry;
77980 use PHPUnit\Util\PHP\AbstractPhpProcess;
77981 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Data\RawCodeCoverageData;
77982 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\InvalidArgumentException;
77983 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\ReflectionException;
77984 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Test\TestSize\TestSize;
77985 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Test\TestStatus\TestStatus;
77986 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\TestIdMissingException;
77987 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\UnintentionallyCoveredCodeException;
77988 use PHPUnitPHAR\SebastianBergmann\Template\Template;
77989 use Throwable;
77990 /**
77991 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
77992 *
77993 * @internal This class is not covered by the backward compatibility promise for PHPUnit
77994 */
77995 final class PhptTestCase implements Reorderable, SelfDescribing, Test
77996 {
77997 /**
77998 * @psalm-var non-empty-string
77999 */
78000 private readonly string $filename;
78001 private readonly AbstractPhpProcess $phpUtil;
78002 private string $output = '';
78003 /**
78004 * Constructs a test case with the given filename.
78005 *
78006 * @psalm-param non-empty-string $filename
78007 *
78008 * @throws Exception
78009 */
78010 public function __construct(string $filename, ?AbstractPhpProcess $phpUtil = null)
78011 {
78012 $this->filename = $filename;
78013 $this->ensureCoverageFileDoesNotExist();
78014 $this->phpUtil = $phpUtil ?: AbstractPhpProcess::factory();
78015 }
78016 /**
78017 * Counts the number of test cases executed by run(TestResult result).
78018 */
78019 public function count(): int
78020 {
78021 return 1;
78022 }
78023 /**
78024 * Runs a test and collects its result in a TestResult instance.
78025 *
78026 * @throws \PHPUnit\Framework\Exception
78027 * @throws \SebastianBergmann\Template\InvalidArgumentException
78028 * @throws Exception
78029 * @throws InvalidArgumentException
78030 * @throws NoPreviousThrowableException
78031 * @throws ReflectionException
78032 * @throws TestIdMissingException
78033 * @throws UnintentionallyCoveredCodeException
78034 *
78035 * @noinspection RepetitiveMethodCallsInspection
78036 */
78037 public function run(): void
78038 {
78039 $emitter = EventFacade::emitter();
78040 $emitter->testPreparationStarted($this->valueObjectForEvents());
78041 try {
78042 $sections = $this->parse();
78043 } catch (\PHPUnit\Runner\Exception $e) {
78044 $emitter->testPrepared($this->valueObjectForEvents());
78045 $emitter->testErrored($this->valueObjectForEvents(), ThrowableBuilder::from($e));
78046 $emitter->testFinished($this->valueObjectForEvents(), 0);
78047 return;
78048 }
78049 $code = $this->render($sections['FILE']);
78050 $xfail = \false;
78051 $settings = $this->parseIniSection($this->settings(\PHPUnit\Runner\CodeCoverage::instance()->isActive()));
78052 $emitter->testPrepared($this->valueObjectForEvents());
78053 if (isset($sections['INI'])) {
78054 $settings = $this->parseIniSection($sections['INI'], $settings);
78055 }
78056 if (isset($sections['ENV'])) {
78057 $env = $this->parseEnvSection($sections['ENV']);
78058 $this->phpUtil->setEnv($env);
78059 }
78060 $this->phpUtil->setUseStderrRedirection(\true);
78061 if ($this->shouldTestBeSkipped($sections, $settings)) {
78062 return;
78063 }
78064 if (isset($sections['XFAIL'])) {
78065 $xfail = trim($sections['XFAIL']);
78066 }
78067 if (isset($sections['STDIN'])) {
78068 $this->phpUtil->setStdin($sections['STDIN']);
78069 }
78070 if (isset($sections['ARGS'])) {
78071 $this->phpUtil->setArgs($sections['ARGS']);
78072 }
78073 if (\PHPUnit\Runner\CodeCoverage::instance()->isActive()) {
78074 $codeCoverageCacheDirectory = null;
78075 if (\PHPUnit\Runner\CodeCoverage::instance()->codeCoverage()->cachesStaticAnalysis()) {
78076 /** @psalm-suppress MissingThrowsDocblock */
78077 $codeCoverageCacheDirectory = \PHPUnit\Runner\CodeCoverage::instance()->codeCoverage()->cacheDirectory();
78078 }
78079 $this->renderForCoverage($code, \PHPUnit\Runner\CodeCoverage::instance()->codeCoverage()->collectsBranchAndPathCoverage(), $codeCoverageCacheDirectory);
78080 }
78081 $jobResult = $this->phpUtil->runJob($code, $this->stringifyIni($settings));
78082 $this->output = $jobResult['stdout'] ?? '';
78083 if (\PHPUnit\Runner\CodeCoverage::instance()->isActive()) {
78084 $coverage = $this->cleanupForCoverage();
78085 \PHPUnit\Runner\CodeCoverage::instance()->codeCoverage()->start($this->filename, TestSize::large());
78086 \PHPUnit\Runner\CodeCoverage::instance()->codeCoverage()->append($coverage, $this->filename, \true, TestStatus::unknown());
78087 }
78088 $passed = \true;
78089 try {
78090 $this->assertPhptExpectation($sections, $this->output);
78091 } catch (AssertionFailedError $e) {
78092 $failure = $e;
78093 if ($xfail !== \false) {
78094 $failure = new IncompleteTestError($xfail, 0, $e);
78095 } elseif ($e instanceof ExpectationFailedException) {
78096 $comparisonFailure = $e->getComparisonFailure();
78097 if ($comparisonFailure) {
78098 $diff = $comparisonFailure->getDiff();
78099 } else {
78100 $diff = $e->getMessage();
78101 }
78102 $hint = $this->getLocationHintFromDiff($diff, $sections);
78103 $trace = array_merge($hint, debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS));
78104 $failure = new PhptAssertionFailedError($e->getMessage(), 0, (string) $trace[0]['file'], (int) $trace[0]['line'], $trace, $comparisonFailure ? $diff : '');
78105 }
78106 if ($failure instanceof IncompleteTestError) {
78107 $emitter->testMarkedAsIncomplete($this->valueObjectForEvents(), ThrowableBuilder::from($failure));
78108 } else {
78109 $emitter->testFailed($this->valueObjectForEvents(), ThrowableBuilder::from($failure), null);
78110 }
78111 $passed = \false;
78112 } catch (Throwable $t) {
78113 $emitter->testErrored($this->valueObjectForEvents(), ThrowableBuilder::from($t));
78114 $passed = \false;
78115 }
78116 if ($passed) {
78117 $emitter->testPassed($this->valueObjectForEvents());
78118 }
78119 $this->runClean($sections, \PHPUnit\Runner\CodeCoverage::instance()->isActive());
78120 $emitter->testFinished($this->valueObjectForEvents(), 1);
78121 }
78122 /**
78123 * Returns the name of the test case.
78124 */
78125 public function getName(): string
78126 {
78127 return $this->toString();
78128 }
78129 /**
78130 * Returns a string representation of the test case.
78131 */
78132 public function toString(): string
78133 {
78134 return $this->filename;
78135 }
78136 public function usesDataProvider(): bool
78137 {
78138 return \false;
78139 }
78140 public function numberOfAssertionsPerformed(): int
78141 {
78142 return 1;
78143 }
78144 public function output(): string
78145 {
78146 return $this->output;
78147 }
78148 public function hasOutput(): bool
78149 {
78150 return !empty($this->output);
78151 }
78152 public function sortId(): string
78153 {
78154 return $this->filename;
78155 }
78156 /**
78157 * @psalm-return list<ExecutionOrderDependency>
78158 */
78159 public function provides(): array
78160 {
78161 return [];
78162 }
78163 /**
78164 * @psalm-return list<ExecutionOrderDependency>
78165 */
78166 public function requires(): array
78167 {
78168 return [];
78169 }
78170 /**
78171 * @internal This method is not covered by the backward compatibility promise for PHPUnit
78172 */
78173 public function valueObjectForEvents(): Phpt
78174 {
78175 return new Phpt($this->filename);
78176 }
78177 /**
78178 * Parse --INI-- section key value pairs and return as array.
78179 */
78180 private function parseIniSection(array|string $content, array $ini = []): array
78181 {
78182 if (is_string($content)) {
78183 $content = explode("\n", trim($content));
78184 }
78185 foreach ($content as $setting) {
78186 if (!str_contains($setting, '=')) {
78187 continue;
78188 }
78189 $setting = explode('=', $setting, 2);
78190 $name = trim($setting[0]);
78191 $value = trim($setting[1]);
78192 if ($name === 'extension' || $name === 'zend_extension') {
78193 if (!isset($ini[$name])) {
78194 $ini[$name] = [];
78195 }
78196 $ini[$name][] = $value;
78197 continue;
78198 }
78199 $ini[$name] = $value;
78200 }
78201 return $ini;
78202 }
78203 private function parseEnvSection(string $content): array
78204 {
78205 $env = [];
78206 foreach (explode("\n", trim($content)) as $e) {
78207 $e = explode('=', trim($e), 2);
78208 if ($e[0] !== '' && isset($e[1])) {
78209 $env[$e[0]] = $e[1];
78210 }
78211 }
78212 return $env;
78213 }
78214 /**
78215 * @throws Exception
78216 * @throws ExpectationFailedException
78217 */
78218 private function assertPhptExpectation(array $sections, string $output): void
78219 {
78220 $assertions = ['EXPECT' => 'assertEquals', 'EXPECTF' => 'assertStringMatchesFormat', 'EXPECTREGEX' => 'assertMatchesRegularExpression'];
78221 $actual = preg_replace('/\r\n/', "\n", trim($output));
78222 foreach ($assertions as $sectionName => $sectionAssertion) {
78223 if (isset($sections[$sectionName])) {
78224 $sectionContent = preg_replace('/\r\n/', "\n", trim($sections[$sectionName]));
78225 $expected = $sectionName === 'EXPECTREGEX' ? "/{$sectionContent}/" : $sectionContent;
78226 Assert::$sectionAssertion($expected, $actual);
78227 return;
78228 }
78229 }
78230 throw new \PHPUnit\Runner\InvalidPhptFileException();
78231 }
78232 private function shouldTestBeSkipped(array $sections, array $settings): bool
78233 {
78234 if (!isset($sections['SKIPIF'])) {
78235 return \false;
78236 }
78237 $skipif = $this->render($sections['SKIPIF']);
78238 $jobResult = $this->phpUtil->runJob($skipif, $this->stringifyIni($settings));
78239 if (!strncasecmp('skip', ltrim($jobResult['stdout']), 4)) {
78240 $message = '';
78241 if (preg_match('/^\s*skip\s*(.+)\s*/i', $jobResult['stdout'], $skipMatch)) {
78242 $message = substr($skipMatch[1], 2);
78243 }
78244 EventFacade::emitter()->testSkipped($this->valueObjectForEvents(), $message);
78245 EventFacade::emitter()->testFinished($this->valueObjectForEvents(), 0);
78246 return \true;
78247 }
78248 return \false;
78249 }
78250 private function runClean(array $sections, bool $collectCoverage): void
78251 {
78252 $this->phpUtil->setStdin('');
78253 $this->phpUtil->setArgs('');
78254 if (isset($sections['CLEAN'])) {
78255 $cleanCode = $this->render($sections['CLEAN']);
78256 $this->phpUtil->runJob($cleanCode, $this->settings($collectCoverage));
78257 }
78258 }
78259 /**
78260 * @throws Exception
78261 */
78262 private function parse(): array
78263 {
78264 $sections = [];
78265 $section = '';
78266 $unsupportedSections = ['CGI', 'COOKIE', 'DEFLATE_POST', 'EXPECTHEADERS', 'EXTENSIONS', 'GET', 'GZIP_POST', 'HEADERS', 'PHPDBG', 'POST', 'POST_RAW', 'PUT', 'REDIRECTTEST', 'REQUEST'];
78267 $lineNr = 0;
78268 foreach (file($this->filename) as $line) {
78269 $lineNr++;
78270 if (preg_match('/^--([_A-Z]+)--/', $line, $result)) {
78271 $section = $result[1];
78272 $sections[$section] = '';
78273 $sections[$section . '_offset'] = $lineNr;
78274 continue;
78275 }
78276 if (empty($section)) {
78277 throw new \PHPUnit\Runner\InvalidPhptFileException();
78278 }
78279 $sections[$section] .= $line;
78280 }
78281 if (isset($sections['FILEEOF'])) {
78282 $sections['FILE'] = rtrim($sections['FILEEOF'], "\r\n");
78283 unset($sections['FILEEOF']);
78284 }
78285 $this->parseExternal($sections);
78286 if (!$this->validate($sections)) {
78287 throw new \PHPUnit\Runner\InvalidPhptFileException();
78288 }
78289 foreach ($unsupportedSections as $section) {
78290 if (isset($sections[$section])) {
78291 throw new \PHPUnit\Runner\UnsupportedPhptSectionException($section);
78292 }
78293 }
78294 return $sections;
78295 }
78296 /**
78297 * @throws Exception
78298 */
78299 private function parseExternal(array &$sections): void
78300 {
78301 $allowSections = ['FILE', 'EXPECT', 'EXPECTF', 'EXPECTREGEX'];
78302 $testDirectory = dirname($this->filename) . DIRECTORY_SEPARATOR;
78303 foreach ($allowSections as $section) {
78304 if (isset($sections[$section . '_EXTERNAL'])) {
78305 $externalFilename = trim($sections[$section . '_EXTERNAL']);
78306 if (!is_file($testDirectory . $externalFilename) || !is_readable($testDirectory . $externalFilename)) {
78307 throw new \PHPUnit\Runner\PhptExternalFileCannotBeLoadedException($section, $testDirectory . $externalFilename);
78308 }
78309 $sections[$section] = file_get_contents($testDirectory . $externalFilename);
78310 }
78311 }
78312 }
78313 private function validate(array $sections): bool
78314 {
78315 $requiredSections = ['FILE', ['EXPECT', 'EXPECTF', 'EXPECTREGEX']];
78316 foreach ($requiredSections as $section) {
78317 if (is_array($section)) {
78318 $foundSection = \false;
78319 foreach ($section as $anySection) {
78320 if (isset($sections[$anySection])) {
78321 $foundSection = \true;
78322 break;
78323 }
78324 }
78325 if (!$foundSection) {
78326 return \false;
78327 }
78328 continue;
78329 }
78330 if (!isset($sections[$section])) {
78331 return \false;
78332 }
78333 }
78334 return \true;
78335 }
78336 private function render(string $code): string
78337 {
78338 return str_replace(['__DIR__', '__FILE__'], ["'" . dirname($this->filename) . "'", "'" . $this->filename . "'"], $code);
78339 }
78340 private function getCoverageFiles(): array
78341 {
78342 $baseDir = dirname(realpath($this->filename)) . DIRECTORY_SEPARATOR;
78343 $basename = basename($this->filename, 'phpt');
78344 return ['coverage' => $baseDir . $basename . 'coverage', 'job' => $baseDir . $basename . 'php'];
78345 }
78346 /**
78347 * @throws \SebastianBergmann\Template\InvalidArgumentException
78348 */
78349 private function renderForCoverage(string &$job, bool $pathCoverage, ?string $codeCoverageCacheDirectory): void
78350 {
78351 $files = $this->getCoverageFiles();
78352 $template = new Template(__DIR__ . '/../Util/PHP/Template/PhptTestCase.tpl');
78353 $composerAutoload = '\'\'';
78354 if (defined('PHPUNIT_COMPOSER_INSTALL')) {
78355 $composerAutoload = var_export(PHPUNIT_COMPOSER_INSTALL, \true);
78356 }
78357 $phar = '\'\'';
78358 if (defined('__PHPUNIT_PHAR__')) {
78359 $phar = var_export(__PHPUNIT_PHAR__, \true);
78360 }
78361 if ($codeCoverageCacheDirectory === null) {
78362 $codeCoverageCacheDirectory = 'null';
78363 } else {
78364 $codeCoverageCacheDirectory = "'" . $codeCoverageCacheDirectory . "'";
78365 }
78366 $bootstrap = '';
78367 if (ConfigurationRegistry::get()->hasBootstrap()) {
78368 $bootstrap = ConfigurationRegistry::get()->bootstrap();
78369 }
78370 $template->setVar(['bootstrap' => $bootstrap, 'composerAutoload' => $composerAutoload, 'phar' => $phar, 'job' => $files['job'], 'coverageFile' => $files['coverage'], 'driverMethod' => $pathCoverage ? 'forLineAndPathCoverage' : 'forLineCoverage', 'codeCoverageCacheDirectory' => $codeCoverageCacheDirectory]);
78371 file_put_contents($files['job'], $job);
78372 $job = $template->render();
78373 }
78374 private function cleanupForCoverage(): RawCodeCoverageData
78375 {
78376 $coverage = RawCodeCoverageData::fromXdebugWithoutPathCoverage([]);
78377 $files = $this->getCoverageFiles();
78378 $buffer = \false;
78379 if (is_file($files['coverage'])) {
78380 $buffer = @file_get_contents($files['coverage']);
78381 }
78382 if ($buffer !== \false) {
78383 $coverage = @unserialize($buffer, ['allowed_classes' => [RawCodeCoverageData::class]]);
78384 if ($coverage === \false) {
78385 $coverage = RawCodeCoverageData::fromXdebugWithoutPathCoverage([]);
78386 }
78387 }
78388 foreach ($files as $file) {
78389 @unlink($file);
78390 }
78391 return $coverage;
78392 }
78393 private function stringifyIni(array $ini): array
78394 {
78395 $settings = [];
78396 foreach ($ini as $key => $value) {
78397 if (is_array($value)) {
78398 foreach ($value as $val) {
78399 $settings[] = $key . '=' . $val;
78400 }
78401 continue;
78402 }
78403 $settings[] = $key . '=' . $value;
78404 }
78405 return $settings;
78406 }
78407 private function getLocationHintFromDiff(string $message, array $sections): array
78408 {
78409 $needle = '';
78410 $previousLine = '';
78411 $block = 'message';
78412 foreach (preg_split('/\r\n|\r|\n/', $message) as $line) {
78413 $line = trim($line);
78414 if ($block === 'message' && $line === '--- Expected') {
78415 $block = 'expected';
78416 }
78417 if ($block === 'expected' && $line === '@@ @@') {
78418 $block = 'diff';
78419 }
78420 if ($block === 'diff') {
78421 if (str_starts_with($line, '+')) {
78422 $needle = $this->getCleanDiffLine($previousLine);
78423 break;
78424 }
78425 if (str_starts_with($line, '-')) {
78426 $needle = $this->getCleanDiffLine($line);
78427 break;
78428 }
78429 }
78430 if (!empty($line)) {
78431 $previousLine = $line;
78432 }
78433 }
78434 return $this->getLocationHint($needle, $sections);
78435 }
78436 private function getCleanDiffLine(string $line): string
78437 {
78438 if (preg_match('/^[\-+]([\'\"]?)(.*)\1$/', $line, $matches)) {
78439 $line = $matches[2];
78440 }
78441 return $line;
78442 }
78443 private function getLocationHint(string $needle, array $sections): array
78444 {
78445 $needle = trim($needle);
78446 if (empty($needle)) {
78447 return [['file' => realpath($this->filename), 'line' => 1]];
78448 }
78449 $search = [
78450 // 'FILE',
78451 'EXPECT',
78452 'EXPECTF',
78453 'EXPECTREGEX',
78454 ];
78455 foreach ($search as $section) {
78456 if (!isset($sections[$section])) {
78457 continue;
78458 }
78459 if (isset($sections[$section . '_EXTERNAL'])) {
78460 $externalFile = trim($sections[$section . '_EXTERNAL']);
78461 return [['file' => realpath(dirname($this->filename) . DIRECTORY_SEPARATOR . $externalFile), 'line' => 1], ['file' => realpath($this->filename), 'line' => ($sections[$section . '_EXTERNAL_offset'] ?? 0) + 1]];
78462 }
78463 $sectionOffset = $sections[$section . '_offset'] ?? 0;
78464 $offset = $sectionOffset + 1;
78465 foreach (preg_split('/\r\n|\r|\n/', $sections[$section]) as $line) {
78466 if (str_contains($line, $needle)) {
78467 return [['file' => realpath($this->filename), 'line' => $offset]];
78468 }
78469 $offset++;
78470 }
78471 }
78472 return [['file' => realpath($this->filename), 'line' => 1]];
78473 }
78474 /**
78475 * @psalm-return list<string>
78476 */
78477 private function settings(bool $collectCoverage): array
78478 {
78479 $settings = ['allow_url_fopen=1', 'auto_append_file=', 'auto_prepend_file=', 'disable_functions=', 'display_errors=1', 'docref_ext=.html', 'docref_root=', 'error_append_string=', 'error_prepend_string=', 'error_reporting=-1', 'html_errors=0', 'log_errors=0', 'open_basedir=', 'output_buffering=Off', 'output_handler=', 'report_zend_debug=0'];
78480 if (extension_loaded('pcov')) {
78481 if ($collectCoverage) {
78482 $settings[] = 'pcov.enabled=1';
78483 } else {
78484 $settings[] = 'pcov.enabled=0';
78485 }
78486 }
78487 if (extension_loaded('xdebug')) {
78488 if ($collectCoverage) {
78489 $settings[] = 'xdebug.mode=coverage';
78490 } else {
78491 $settings[] = 'xdebug.mode=off';
78492 }
78493 }
78494 return $settings;
78495 }
78496 /**
78497 * @throws CodeCoverageFileExistsException
78498 */
78499 private function ensureCoverageFileDoesNotExist(): void
78500 {
78501 $files = $this->getCoverageFiles();
78502 if (file_exists($files['coverage'])) {
78503 throw new \PHPUnit\Runner\CodeCoverageFileExistsException(sprintf('File %s exists, PHPT test %s will not be executed', $files['coverage'], $this->filename));
78504 }
78505 }
78506 }
78507 <?php
78508
78509 declare (strict_types=1);
78510 /*
78511 * This file is part of PHPUnit.
78512 *
78513 * (c) Sebastian Bergmann <sebastian@phpunit.de>
78514 *
78515 * For the full copyright and license information, please view the LICENSE
78516 * file that was distributed with this source code.
78517 */
78518 namespace PHPUnit\Runner\ResultCache;
78519
78520 use const DIRECTORY_SEPARATOR;
78521 use const LOCK_EX;
78522 use function array_keys;
78523 use function assert;
78524 use function dirname;
78525 use function file_get_contents;
78526 use function file_put_contents;
78527 use function is_array;
78528 use function is_dir;
78529 use function is_file;
78530 use function json_decode;
78531 use function json_encode;
78532 use PHPUnit\Framework\TestStatus\TestStatus;
78533 use PHPUnit\Runner\DirectoryDoesNotExistException;
78534 use PHPUnit\Runner\Exception;
78535 use PHPUnit\Util\Filesystem;
78536 /**
78537 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
78538 *
78539 * @internal This class is not covered by the backward compatibility promise for PHPUnit
78540 */
78541 final class DefaultResultCache implements \PHPUnit\Runner\ResultCache\ResultCache
78542 {
78543 /**
78544 * @var int
78545 */
78546 private const VERSION = 2;
78547 /**
78548 * @var string
78549 */
78550 private const DEFAULT_RESULT_CACHE_FILENAME = '.phpunit.result.cache';
78551 private readonly string $cacheFilename;
78552 /**
78553 * @psalm-var array<string, TestStatus>
78554 */
78555 private array $defects = [];
78556 /**
78557 * @psalm-var array<string, float>
78558 */
78559 private array $times = [];
78560 public function __construct(?string $filepath = null)
78561 {
78562 if ($filepath !== null && is_dir($filepath)) {
78563 $filepath .= DIRECTORY_SEPARATOR . self::DEFAULT_RESULT_CACHE_FILENAME;
78564 }
78565 $this->cacheFilename = $filepath ?? $_ENV['PHPUNIT_RESULT_CACHE'] ?? self::DEFAULT_RESULT_CACHE_FILENAME;
78566 }
78567 public function setStatus(string $id, TestStatus $status): void
78568 {
78569 if ($status->isSuccess()) {
78570 return;
78571 }
78572 $this->defects[$id] = $status;
78573 }
78574 public function status(string $id): TestStatus
78575 {
78576 return $this->defects[$id] ?? TestStatus::unknown();
78577 }
78578 public function setTime(string $id, float $time): void
78579 {
78580 $this->times[$id] = $time;
78581 }
78582 public function time(string $id): float
78583 {
78584 return $this->times[$id] ?? 0.0;
78585 }
78586 public function mergeWith(self $other): void
78587 {
78588 foreach ($other->defects as $id => $defect) {
78589 $this->defects[$id] = $defect;
78590 }
78591 foreach ($other->times as $id => $time) {
78592 $this->times[$id] = $time;
78593 }
78594 }
78595 public function load(): void
78596 {
78597 if (!is_file($this->cacheFilename)) {
78598 return;
78599 }
78600 $contents = file_get_contents($this->cacheFilename);
78601 if ($contents === \false) {
78602 return;
78603 }
78604 $data = json_decode($contents, \true);
78605 if ($data === null) {
78606 return;
78607 }
78608 if (!isset($data['version'])) {
78609 return;
78610 }
78611 if ($data['version'] !== self::VERSION) {
78612 return;
78613 }
78614 assert(isset($data['defects']) && is_array($data['defects']));
78615 assert(isset($data['times']) && is_array($data['times']));
78616 foreach (array_keys($data['defects']) as $test) {
78617 $data['defects'][$test] = TestStatus::from($data['defects'][$test]);
78618 }
78619 $this->defects = $data['defects'];
78620 $this->times = $data['times'];
78621 }
78622 /**
78623 * @throws Exception
78624 */
78625 public function persist(): void
78626 {
78627 if (!Filesystem::createDirectory(dirname($this->cacheFilename))) {
78628 throw new DirectoryDoesNotExistException(dirname($this->cacheFilename));
78629 }
78630 $data = ['version' => self::VERSION, 'defects' => [], 'times' => $this->times];
78631 foreach ($this->defects as $test => $status) {
78632 $data['defects'][$test] = $status->asInt();
78633 }
78634 file_put_contents($this->cacheFilename, json_encode($data), LOCK_EX);
78635 }
78636 }
78637 <?php
78638
78639 declare (strict_types=1);
78640 /*
78641 * This file is part of PHPUnit.
78642 *
78643 * (c) Sebastian Bergmann <sebastian@phpunit.de>
78644 *
78645 * For the full copyright and license information, please view the LICENSE
78646 * file that was distributed with this source code.
78647 */
78648 namespace PHPUnit\Runner\ResultCache;
78649
78650 use PHPUnit\Framework\TestStatus\TestStatus;
78651 /**
78652 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
78653 *
78654 * @internal This class is not covered by the backward compatibility promise for PHPUnit
78655 */
78656 final class NullResultCache implements \PHPUnit\Runner\ResultCache\ResultCache
78657 {
78658 public function setStatus(string $id, TestStatus $status): void
78659 {
78660 }
78661 public function status(string $id): TestStatus
78662 {
78663 return TestStatus::unknown();
78664 }
78665 public function setTime(string $id, float $time): void
78666 {
78667 }
78668 public function time(string $id): float
78669 {
78670 return 0;
78671 }
78672 public function load(): void
78673 {
78674 }
78675 public function persist(): void
78676 {
78677 }
78678 }
78679 <?php
78680
78681 declare (strict_types=1);
78682 /*
78683 * This file is part of PHPUnit.
78684 *
78685 * (c) Sebastian Bergmann <sebastian@phpunit.de>
78686 *
78687 * For the full copyright and license information, please view the LICENSE
78688 * file that was distributed with this source code.
78689 */
78690 namespace PHPUnit\Runner\ResultCache;
78691
78692 use PHPUnit\Framework\TestStatus\TestStatus;
78693 /**
78694 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
78695 *
78696 * @internal This interface is not covered by the backward compatibility promise for PHPUnit
78697 */
78698 interface ResultCache
78699 {
78700 public function setStatus(string $id, TestStatus $status): void;
78701 public function status(string $id): TestStatus;
78702 public function setTime(string $id, float $time): void;
78703 public function time(string $id): float;
78704 public function load(): void;
78705 public function persist(): void;
78706 }
78707 <?php
78708
78709 declare (strict_types=1);
78710 /*
78711 * This file is part of PHPUnit.
78712 *
78713 * (c) Sebastian Bergmann <sebastian@phpunit.de>
78714 *
78715 * For the full copyright and license information, please view the LICENSE
78716 * file that was distributed with this source code.
78717 */
78718 namespace PHPUnit\Runner\ResultCache;
78719
78720 use function round;
78721 use PHPUnit\Event\Event;
78722 use PHPUnit\Event\EventFacadeIsSealedException;
78723 use PHPUnit\Event\Facade;
78724 use PHPUnit\Event\Telemetry\HRTime;
78725 use PHPUnit\Event\Test\ConsideredRisky;
78726 use PHPUnit\Event\Test\Errored;
78727 use PHPUnit\Event\Test\Failed;
78728 use PHPUnit\Event\Test\Finished;
78729 use PHPUnit\Event\Test\MarkedIncomplete;
78730 use PHPUnit\Event\Test\Prepared;
78731 use PHPUnit\Event\Test\Skipped;
78732 use PHPUnit\Event\UnknownSubscriberTypeException;
78733 use PHPUnit\Framework\InvalidArgumentException;
78734 use PHPUnit\Framework\TestStatus\TestStatus;
78735 /**
78736 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
78737 *
78738 * @internal This class is not covered by the backward compatibility promise for PHPUnit
78739 */
78740 final class ResultCacheHandler
78741 {
78742 private readonly \PHPUnit\Runner\ResultCache\ResultCache $cache;
78743 private ?HRTime $time = null;
78744 private int $testSuite = 0;
78745 /**
78746 * @throws EventFacadeIsSealedException
78747 * @throws UnknownSubscriberTypeException
78748 */
78749 public function __construct(\PHPUnit\Runner\ResultCache\ResultCache $cache, Facade $facade)
78750 {
78751 $this->cache = $cache;
78752 $this->registerSubscribers($facade);
78753 }
78754 public function testSuiteStarted(): void
78755 {
78756 $this->testSuite++;
78757 }
78758 public function testSuiteFinished(): void
78759 {
78760 $this->testSuite--;
78761 if ($this->testSuite === 0) {
78762 $this->cache->persist();
78763 }
78764 }
78765 public function testPrepared(Prepared $event): void
78766 {
78767 $this->time = $event->telemetryInfo()->time();
78768 }
78769 public function testMarkedIncomplete(MarkedIncomplete $event): void
78770 {
78771 $this->cache->setStatus($event->test()->id(), TestStatus::incomplete($event->throwable()->message()));
78772 }
78773 public function testConsideredRisky(ConsideredRisky $event): void
78774 {
78775 $this->cache->setStatus($event->test()->id(), TestStatus::risky($event->message()));
78776 }
78777 public function testErrored(Errored $event): void
78778 {
78779 $this->cache->setStatus($event->test()->id(), TestStatus::error($event->throwable()->message()));
78780 }
78781 public function testFailed(Failed $event): void
78782 {
78783 $this->cache->setStatus($event->test()->id(), TestStatus::failure($event->throwable()->message()));
78784 }
78785 /**
78786 * @throws \PHPUnit\Event\InvalidArgumentException
78787 * @throws InvalidArgumentException
78788 */
78789 public function testSkipped(Skipped $event): void
78790 {
78791 $this->cache->setStatus($event->test()->id(), TestStatus::skipped($event->message()));
78792 $this->cache->setTime($event->test()->id(), $this->duration($event));
78793 }
78794 /**
78795 * @throws \PHPUnit\Event\InvalidArgumentException
78796 * @throws InvalidArgumentException
78797 */
78798 public function testFinished(Finished $event): void
78799 {
78800 $this->cache->setTime($event->test()->id(), $this->duration($event));
78801 $this->time = null;
78802 }
78803 /**
78804 * @throws \PHPUnit\Event\InvalidArgumentException
78805 * @throws InvalidArgumentException
78806 */
78807 private function duration(Event $event): float
78808 {
78809 if ($this->time === null) {
78810 return 0.0;
78811 }
78812 return round($event->telemetryInfo()->time()->duration($this->time)->asFloat(), 3);
78813 }
78814 /**
78815 * @throws EventFacadeIsSealedException
78816 * @throws UnknownSubscriberTypeException
78817 */
78818 private function registerSubscribers(Facade $facade): void
78819 {
78820 $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));
78821 }
78822 }
78823 <?php
78824
78825 declare (strict_types=1);
78826 /*
78827 * This file is part of PHPUnit.
78828 *
78829 * (c) Sebastian Bergmann <sebastian@phpunit.de>
78830 *
78831 * For the full copyright and license information, please view the LICENSE
78832 * file that was distributed with this source code.
78833 */
78834 namespace PHPUnit\Runner\ResultCache;
78835
78836 /**
78837 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
78838 *
78839 * @internal This class is not covered by the backward compatibility promise for PHPUnit
78840 */
78841 abstract class Subscriber
78842 {
78843 private readonly \PHPUnit\Runner\ResultCache\ResultCacheHandler $handler;
78844 public function __construct(\PHPUnit\Runner\ResultCache\ResultCacheHandler $handler)
78845 {
78846 $this->handler = $handler;
78847 }
78848 protected function handler(): \PHPUnit\Runner\ResultCache\ResultCacheHandler
78849 {
78850 return $this->handler;
78851 }
78852 }
78853 <?php
78854
78855 declare (strict_types=1);
78856 /*
78857 * This file is part of PHPUnit.
78858 *
78859 * (c) Sebastian Bergmann <sebastian@phpunit.de>
78860 *
78861 * For the full copyright and license information, please view the LICENSE
78862 * file that was distributed with this source code.
78863 */
78864 namespace PHPUnit\Runner\ResultCache;
78865
78866 use PHPUnit\Event\Test\ConsideredRisky;
78867 use PHPUnit\Event\Test\ConsideredRiskySubscriber;
78868 /**
78869 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
78870 *
78871 * @internal This class is not covered by the backward compatibility promise for PHPUnit
78872 */
78873 final class TestConsideredRiskySubscriber extends \PHPUnit\Runner\ResultCache\Subscriber implements ConsideredRiskySubscriber
78874 {
78875 public function notify(ConsideredRisky $event): void
78876 {
78877 $this->handler()->testConsideredRisky($event);
78878 }
78879 }
78880 <?php
78881
78882 declare (strict_types=1);
78883 /*
78884 * This file is part of PHPUnit.
78885 *
78886 * (c) Sebastian Bergmann <sebastian@phpunit.de>
78887 *
78888 * For the full copyright and license information, please view the LICENSE
78889 * file that was distributed with this source code.
78890 */
78891 namespace PHPUnit\Runner\ResultCache;
78892
78893 use PHPUnit\Event\Test\Errored;
78894 use PHPUnit\Event\Test\ErroredSubscriber;
78895 /**
78896 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
78897 *
78898 * @internal This class is not covered by the backward compatibility promise for PHPUnit
78899 */
78900 final class TestErroredSubscriber extends \PHPUnit\Runner\ResultCache\Subscriber implements ErroredSubscriber
78901 {
78902 public function notify(Errored $event): void
78903 {
78904 $this->handler()->testErrored($event);
78905 }
78906 }
78907 <?php
78908
78909 declare (strict_types=1);
78910 /*
78911 * This file is part of PHPUnit.
78912 *
78913 * (c) Sebastian Bergmann <sebastian@phpunit.de>
78914 *
78915 * For the full copyright and license information, please view the LICENSE
78916 * file that was distributed with this source code.
78917 */
78918 namespace PHPUnit\Runner\ResultCache;
78919
78920 use PHPUnit\Event\Test\Failed;
78921 use PHPUnit\Event\Test\FailedSubscriber;
78922 /**
78923 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
78924 *
78925 * @internal This class is not covered by the backward compatibility promise for PHPUnit
78926 */
78927 final class TestFailedSubscriber extends \PHPUnit\Runner\ResultCache\Subscriber implements FailedSubscriber
78928 {
78929 public function notify(Failed $event): void
78930 {
78931 $this->handler()->testFailed($event);
78932 }
78933 }
78934 <?php
78935
78936 declare (strict_types=1);
78937 /*
78938 * This file is part of PHPUnit.
78939 *
78940 * (c) Sebastian Bergmann <sebastian@phpunit.de>
78941 *
78942 * For the full copyright and license information, please view the LICENSE
78943 * file that was distributed with this source code.
78944 */
78945 namespace PHPUnit\Runner\ResultCache;
78946
78947 use PHPUnit\Event\InvalidArgumentException;
78948 use PHPUnit\Event\Test\Finished;
78949 use PHPUnit\Event\Test\FinishedSubscriber;
78950 /**
78951 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
78952 *
78953 * @internal This class is not covered by the backward compatibility promise for PHPUnit
78954 */
78955 final class TestFinishedSubscriber extends \PHPUnit\Runner\ResultCache\Subscriber implements FinishedSubscriber
78956 {
78957 /**
78958 * @throws \PHPUnit\Framework\InvalidArgumentException
78959 * @throws InvalidArgumentException
78960 */
78961 public function notify(Finished $event): void
78962 {
78963 $this->handler()->testFinished($event);
78964 }
78965 }
78966 <?php
78967
78968 declare (strict_types=1);
78969 /*
78970 * This file is part of PHPUnit.
78971 *
78972 * (c) Sebastian Bergmann <sebastian@phpunit.de>
78973 *
78974 * For the full copyright and license information, please view the LICENSE
78975 * file that was distributed with this source code.
78976 */
78977 namespace PHPUnit\Runner\ResultCache;
78978
78979 use PHPUnit\Event\Test\MarkedIncomplete;
78980 use PHPUnit\Event\Test\MarkedIncompleteSubscriber;
78981 /**
78982 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
78983 *
78984 * @internal This class is not covered by the backward compatibility promise for PHPUnit
78985 */
78986 final class TestMarkedIncompleteSubscriber extends \PHPUnit\Runner\ResultCache\Subscriber implements MarkedIncompleteSubscriber
78987 {
78988 public function notify(MarkedIncomplete $event): void
78989 {
78990 $this->handler()->testMarkedIncomplete($event);
78991 }
78992 }
78993 <?php
78994
78995 declare (strict_types=1);
78996 /*
78997 * This file is part of PHPUnit.
78998 *
78999 * (c) Sebastian Bergmann <sebastian@phpunit.de>
79000 *
79001 * For the full copyright and license information, please view the LICENSE
79002 * file that was distributed with this source code.
79003 */
79004 namespace PHPUnit\Runner\ResultCache;
79005
79006 use PHPUnit\Event\Test\Prepared;
79007 use PHPUnit\Event\Test\PreparedSubscriber;
79008 /**
79009 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
79010 *
79011 * @internal This class is not covered by the backward compatibility promise for PHPUnit
79012 */
79013 final class TestPreparedSubscriber extends \PHPUnit\Runner\ResultCache\Subscriber implements PreparedSubscriber
79014 {
79015 public function notify(Prepared $event): void
79016 {
79017 $this->handler()->testPrepared($event);
79018 }
79019 }
79020 <?php
79021
79022 declare (strict_types=1);
79023 /*
79024 * This file is part of PHPUnit.
79025 *
79026 * (c) Sebastian Bergmann <sebastian@phpunit.de>
79027 *
79028 * For the full copyright and license information, please view the LICENSE
79029 * file that was distributed with this source code.
79030 */
79031 namespace PHPUnit\Runner\ResultCache;
79032
79033 use PHPUnit\Event\InvalidArgumentException;
79034 use PHPUnit\Event\Test\Skipped;
79035 use PHPUnit\Event\Test\SkippedSubscriber;
79036 /**
79037 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
79038 *
79039 * @internal This class is not covered by the backward compatibility promise for PHPUnit
79040 */
79041 final class TestSkippedSubscriber extends \PHPUnit\Runner\ResultCache\Subscriber implements SkippedSubscriber
79042 {
79043 /**
79044 * @throws \PHPUnit\Framework\InvalidArgumentException
79045 * @throws InvalidArgumentException
79046 */
79047 public function notify(Skipped $event): void
79048 {
79049 $this->handler()->testSkipped($event);
79050 }
79051 }
79052 <?php
79053
79054 declare (strict_types=1);
79055 /*
79056 * This file is part of PHPUnit.
79057 *
79058 * (c) Sebastian Bergmann <sebastian@phpunit.de>
79059 *
79060 * For the full copyright and license information, please view the LICENSE
79061 * file that was distributed with this source code.
79062 */
79063 namespace PHPUnit\Runner\ResultCache;
79064
79065 use PHPUnit\Event\TestSuite\Finished;
79066 use PHPUnit\Event\TestSuite\FinishedSubscriber;
79067 /**
79068 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
79069 *
79070 * @internal This class is not covered by the backward compatibility promise for PHPUnit
79071 */
79072 final class TestSuiteFinishedSubscriber extends \PHPUnit\Runner\ResultCache\Subscriber implements FinishedSubscriber
79073 {
79074 public function notify(Finished $event): void
79075 {
79076 $this->handler()->testSuiteFinished();
79077 }
79078 }
79079 <?php
79080
79081 declare (strict_types=1);
79082 /*
79083 * This file is part of PHPUnit.
79084 *
79085 * (c) Sebastian Bergmann <sebastian@phpunit.de>
79086 *
79087 * For the full copyright and license information, please view the LICENSE
79088 * file that was distributed with this source code.
79089 */
79090 namespace PHPUnit\Runner\ResultCache;
79091
79092 use PHPUnit\Event\TestSuite\Started;
79093 use PHPUnit\Event\TestSuite\StartedSubscriber;
79094 /**
79095 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
79096 *
79097 * @internal This class is not covered by the backward compatibility promise for PHPUnit
79098 */
79099 final class TestSuiteStartedSubscriber extends \PHPUnit\Runner\ResultCache\Subscriber implements StartedSubscriber
79100 {
79101 public function notify(Started $event): void
79102 {
79103 $this->handler()->testSuiteStarted();
79104 }
79105 }
79106 <?php
79107
79108 declare (strict_types=1);
79109 /*
79110 * This file is part of PHPUnit.
79111 *
79112 * (c) Sebastian Bergmann <sebastian@phpunit.de>
79113 *
79114 * For the full copyright and license information, please view the LICENSE
79115 * file that was distributed with this source code.
79116 */
79117 namespace PHPUnit\TestRunner\TestResult;
79118
79119 use function array_values;
79120 use function assert;
79121 use function implode;
79122 use function str_contains;
79123 use PHPUnit\Event\Code\TestMethod;
79124 use PHPUnit\Event\EventFacadeIsSealedException;
79125 use PHPUnit\Event\Facade;
79126 use PHPUnit\Event\Test\AfterLastTestMethodErrored;
79127 use PHPUnit\Event\Test\BeforeFirstTestMethodErrored;
79128 use PHPUnit\Event\Test\ConsideredRisky;
79129 use PHPUnit\Event\Test\DeprecationTriggered;
79130 use PHPUnit\Event\Test\Errored;
79131 use PHPUnit\Event\Test\ErrorTriggered;
79132 use PHPUnit\Event\Test\Failed;
79133 use PHPUnit\Event\Test\Finished;
79134 use PHPUnit\Event\Test\MarkedIncomplete;
79135 use PHPUnit\Event\Test\NoticeTriggered;
79136 use PHPUnit\Event\Test\PhpDeprecationTriggered;
79137 use PHPUnit\Event\Test\PhpNoticeTriggered;
79138 use PHPUnit\Event\Test\PhpunitDeprecationTriggered;
79139 use PHPUnit\Event\Test\PhpunitErrorTriggered;
79140 use PHPUnit\Event\Test\PhpunitWarningTriggered;
79141 use PHPUnit\Event\Test\PhpWarningTriggered;
79142 use PHPUnit\Event\Test\Skipped as TestSkipped;
79143 use PHPUnit\Event\Test\WarningTriggered;
79144 use PHPUnit\Event\TestRunner\DeprecationTriggered as TestRunnerDeprecationTriggered;
79145 use PHPUnit\Event\TestRunner\ExecutionStarted;
79146 use PHPUnit\Event\TestRunner\WarningTriggered as TestRunnerWarningTriggered;
79147 use PHPUnit\Event\TestSuite\Finished as TestSuiteFinished;
79148 use PHPUnit\Event\TestSuite\Skipped as TestSuiteSkipped;
79149 use PHPUnit\Event\TestSuite\Started as TestSuiteStarted;
79150 use PHPUnit\Event\TestSuite\TestSuiteForTestClass;
79151 use PHPUnit\Event\TestSuite\TestSuiteForTestMethodWithDataProvider;
79152 use PHPUnit\Event\UnknownSubscriberTypeException;
79153 use PHPUnit\TestRunner\TestResult\Issues\Issue;
79154 use PHPUnit\TextUI\Configuration\Source;
79155 use PHPUnit\TextUI\Configuration\SourceFilter;
79156 /**
79157 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
79158 *
79159 * @internal This class is not covered by the backward compatibility promise for PHPUnit
79160 */
79161 final class Collector
79162 {
79163 private readonly Source $source;
79164 private int $numberOfTests = 0;
79165 private int $numberOfTestsRun = 0;
79166 private int $numberOfAssertions = 0;
79167 private bool $prepared = \false;
79168 private bool $currentTestSuiteForTestClassFailed = \false;
79169 /**
79170 * @psalm-var non-negative-int
79171 */
79172 private int $numberOfIssuesIgnoredByBaseline = 0;
79173 /**
79174 * @psalm-var list<AfterLastTestMethodErrored|BeforeFirstTestMethodErrored|Errored>
79175 */
79176 private array $testErroredEvents = [];
79177 /**
79178 * @psalm-var list<Failed>
79179 */
79180 private array $testFailedEvents = [];
79181 /**
79182 * @psalm-var list<MarkedIncomplete>
79183 */
79184 private array $testMarkedIncompleteEvents = [];
79185 /**
79186 * @psalm-var list<TestSuiteSkipped>
79187 */
79188 private array $testSuiteSkippedEvents = [];
79189 /**
79190 * @psalm-var list<TestSkipped>
79191 */
79192 private array $testSkippedEvents = [];
79193 /**
79194 * @psalm-var array<string,list<ConsideredRisky>>
79195 */
79196 private array $testConsideredRiskyEvents = [];
79197 /**
79198 * @psalm-var array<string,list<PhpunitDeprecationTriggered>>
79199 */
79200 private array $testTriggeredPhpunitDeprecationEvents = [];
79201 /**
79202 * @psalm-var array<string,list<PhpunitErrorTriggered>>
79203 */
79204 private array $testTriggeredPhpunitErrorEvents = [];
79205 /**
79206 * @psalm-var array<string,list<PhpunitWarningTriggered>>
79207 */
79208 private array $testTriggeredPhpunitWarningEvents = [];
79209 /**
79210 * @psalm-var list<TestRunnerWarningTriggered>
79211 */
79212 private array $testRunnerTriggeredWarningEvents = [];
79213 /**
79214 * @psalm-var list<TestRunnerDeprecationTriggered>
79215 */
79216 private array $testRunnerTriggeredDeprecationEvents = [];
79217 /**
79218 * @psalm-var array<non-empty-string, Issue>
79219 */
79220 private array $errors = [];
79221 /**
79222 * @psalm-var array<non-empty-string, Issue>
79223 */
79224 private array $deprecations = [];
79225 /**
79226 * @psalm-var array<non-empty-string, Issue>
79227 */
79228 private array $notices = [];
79229 /**
79230 * @psalm-var array<non-empty-string, Issue>
79231 */
79232 private array $warnings = [];
79233 /**
79234 * @psalm-var array<non-empty-string, Issue>
79235 */
79236 private array $phpDeprecations = [];
79237 /**
79238 * @psalm-var array<non-empty-string, Issue>
79239 */
79240 private array $phpNotices = [];
79241 /**
79242 * @psalm-var array<non-empty-string, Issue>
79243 */
79244 private array $phpWarnings = [];
79245 /**
79246 * @throws EventFacadeIsSealedException
79247 * @throws UnknownSubscriberTypeException
79248 */
79249 public function __construct(Facade $facade, Source $source)
79250 {
79251 $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\AfterTestClassMethodErroredSubscriber($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));
79252 $this->source = $source;
79253 }
79254 public function result(): \PHPUnit\TestRunner\TestResult\TestResult
79255 {
79256 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);
79257 }
79258 public function executionStarted(ExecutionStarted $event): void
79259 {
79260 $this->numberOfTests = $event->testSuite()->count();
79261 }
79262 public function testSuiteSkipped(TestSuiteSkipped $event): void
79263 {
79264 $testSuite = $event->testSuite();
79265 if (!$testSuite->isForTestClass()) {
79266 return;
79267 }
79268 $this->testSuiteSkippedEvents[] = $event;
79269 }
79270 public function testSuiteStarted(TestSuiteStarted $event): void
79271 {
79272 $testSuite = $event->testSuite();
79273 if (!$testSuite->isForTestClass()) {
79274 return;
79275 }
79276 $this->currentTestSuiteForTestClassFailed = \false;
79277 }
79278 public function testSuiteFinished(TestSuiteFinished $event): void
79279 {
79280 if ($this->currentTestSuiteForTestClassFailed) {
79281 return;
79282 }
79283 $testSuite = $event->testSuite();
79284 if ($testSuite->isWithName()) {
79285 return;
79286 }
79287 if ($testSuite->isForTestMethodWithDataProvider()) {
79288 assert($testSuite instanceof TestSuiteForTestMethodWithDataProvider);
79289 $test = $testSuite->tests()->asArray()[0];
79290 assert($test instanceof TestMethod);
79291 \PHPUnit\TestRunner\TestResult\PassedTests::instance()->testMethodPassed($test, null);
79292 return;
79293 }
79294 assert($testSuite instanceof TestSuiteForTestClass);
79295 \PHPUnit\TestRunner\TestResult\PassedTests::instance()->testClassPassed($testSuite->className());
79296 }
79297 public function testPrepared(): void
79298 {
79299 $this->prepared = \true;
79300 }
79301 public function testFinished(Finished $event): void
79302 {
79303 $this->numberOfAssertions += $event->numberOfAssertionsPerformed();
79304 $this->numberOfTestsRun++;
79305 $this->prepared = \false;
79306 }
79307 public function beforeTestClassMethodErrored(BeforeFirstTestMethodErrored $event): void
79308 {
79309 $this->testErroredEvents[] = $event;
79310 $this->numberOfTestsRun++;
79311 }
79312 public function afterTestClassMethodErrored(AfterLastTestMethodErrored $event): void
79313 {
79314 $this->testErroredEvents[] = $event;
79315 }
79316 public function testErrored(Errored $event): void
79317 {
79318 $this->testErroredEvents[] = $event;
79319 $this->currentTestSuiteForTestClassFailed = \true;
79320 /*
79321 * @todo Eliminate this special case
79322 */
79323 if (str_contains($event->asString(), 'Test was run in child process and ended unexpectedly')) {
79324 return;
79325 }
79326 if (!$this->prepared) {
79327 $this->numberOfTestsRun++;
79328 }
79329 }
79330 public function testFailed(Failed $event): void
79331 {
79332 $this->testFailedEvents[] = $event;
79333 $this->currentTestSuiteForTestClassFailed = \true;
79334 }
79335 public function testMarkedIncomplete(MarkedIncomplete $event): void
79336 {
79337 $this->testMarkedIncompleteEvents[] = $event;
79338 }
79339 public function testSkipped(TestSkipped $event): void
79340 {
79341 $this->testSkippedEvents[] = $event;
79342 if (!$this->prepared) {
79343 $this->numberOfTestsRun++;
79344 }
79345 }
79346 public function testConsideredRisky(ConsideredRisky $event): void
79347 {
79348 if (!isset($this->testConsideredRiskyEvents[$event->test()->id()])) {
79349 $this->testConsideredRiskyEvents[$event->test()->id()] = [];
79350 }
79351 $this->testConsideredRiskyEvents[$event->test()->id()][] = $event;
79352 }
79353 public function testTriggeredDeprecation(DeprecationTriggered $event): void
79354 {
79355 if ($event->ignoredByTest()) {
79356 return;
79357 }
79358 if ($event->ignoredByBaseline()) {
79359 $this->numberOfIssuesIgnoredByBaseline++;
79360 return;
79361 }
79362 if (!$this->source->ignoreSuppressionOfDeprecations() && $event->wasSuppressed()) {
79363 return;
79364 }
79365 if ($this->source->restrictDeprecations() && !SourceFilter::instance()->includes($event->file())) {
79366 return;
79367 }
79368 $id = $this->issueId($event);
79369 if (!isset($this->deprecations[$id])) {
79370 $this->deprecations[$id] = Issue::from($event->file(), $event->line(), $event->message(), $event->test());
79371 return;
79372 }
79373 $this->deprecations[$id]->triggeredBy($event->test());
79374 }
79375 public function testTriggeredPhpDeprecation(PhpDeprecationTriggered $event): void
79376 {
79377 if ($event->ignoredByTest()) {
79378 return;
79379 }
79380 if ($event->ignoredByBaseline()) {
79381 $this->numberOfIssuesIgnoredByBaseline++;
79382 return;
79383 }
79384 if (!$this->source->ignoreSuppressionOfPhpDeprecations() && $event->wasSuppressed()) {
79385 return;
79386 }
79387 if ($this->source->restrictDeprecations() && !SourceFilter::instance()->includes($event->file())) {
79388 return;
79389 }
79390 $id = $this->issueId($event);
79391 if (!isset($this->phpDeprecations[$id])) {
79392 $this->phpDeprecations[$id] = Issue::from($event->file(), $event->line(), $event->message(), $event->test());
79393 return;
79394 }
79395 $this->phpDeprecations[$id]->triggeredBy($event->test());
79396 }
79397 public function testTriggeredPhpunitDeprecation(PhpunitDeprecationTriggered $event): void
79398 {
79399 if (!isset($this->testTriggeredPhpunitDeprecationEvents[$event->test()->id()])) {
79400 $this->testTriggeredPhpunitDeprecationEvents[$event->test()->id()] = [];
79401 }
79402 $this->testTriggeredPhpunitDeprecationEvents[$event->test()->id()][] = $event;
79403 }
79404 public function testTriggeredError(ErrorTriggered $event): void
79405 {
79406 if (!$this->source->ignoreSuppressionOfErrors() && $event->wasSuppressed()) {
79407 return;
79408 }
79409 $id = $this->issueId($event);
79410 if (!isset($this->errors[$id])) {
79411 $this->errors[$id] = Issue::from($event->file(), $event->line(), $event->message(), $event->test());
79412 return;
79413 }
79414 $this->errors[$id]->triggeredBy($event->test());
79415 }
79416 public function testTriggeredNotice(NoticeTriggered $event): void
79417 {
79418 if ($event->ignoredByBaseline()) {
79419 $this->numberOfIssuesIgnoredByBaseline++;
79420 return;
79421 }
79422 if (!$this->source->ignoreSuppressionOfNotices() && $event->wasSuppressed()) {
79423 return;
79424 }
79425 if ($this->source->restrictNotices() && !SourceFilter::instance()->includes($event->file())) {
79426 return;
79427 }
79428 $id = $this->issueId($event);
79429 if (!isset($this->notices[$id])) {
79430 $this->notices[$id] = Issue::from($event->file(), $event->line(), $event->message(), $event->test());
79431 return;
79432 }
79433 $this->notices[$id]->triggeredBy($event->test());
79434 }
79435 public function testTriggeredPhpNotice(PhpNoticeTriggered $event): void
79436 {
79437 if ($event->ignoredByBaseline()) {
79438 $this->numberOfIssuesIgnoredByBaseline++;
79439 return;
79440 }
79441 if (!$this->source->ignoreSuppressionOfPhpNotices() && $event->wasSuppressed()) {
79442 return;
79443 }
79444 if ($this->source->restrictNotices() && !SourceFilter::instance()->includes($event->file())) {
79445 return;
79446 }
79447 $id = $this->issueId($event);
79448 if (!isset($this->phpNotices[$id])) {
79449 $this->phpNotices[$id] = Issue::from($event->file(), $event->line(), $event->message(), $event->test());
79450 return;
79451 }
79452 $this->phpNotices[$id]->triggeredBy($event->test());
79453 }
79454 public function testTriggeredWarning(WarningTriggered $event): void
79455 {
79456 if ($event->ignoredByBaseline()) {
79457 $this->numberOfIssuesIgnoredByBaseline++;
79458 return;
79459 }
79460 if (!$this->source->ignoreSuppressionOfWarnings() && $event->wasSuppressed()) {
79461 return;
79462 }
79463 if ($this->source->restrictWarnings() && !SourceFilter::instance()->includes($event->file())) {
79464 return;
79465 }
79466 $id = $this->issueId($event);
79467 if (!isset($this->warnings[$id])) {
79468 $this->warnings[$id] = Issue::from($event->file(), $event->line(), $event->message(), $event->test());
79469 return;
79470 }
79471 $this->warnings[$id]->triggeredBy($event->test());
79472 }
79473 public function testTriggeredPhpWarning(PhpWarningTriggered $event): void
79474 {
79475 if ($event->ignoredByBaseline()) {
79476 $this->numberOfIssuesIgnoredByBaseline++;
79477 return;
79478 }
79479 if (!$this->source->ignoreSuppressionOfPhpWarnings() && $event->wasSuppressed()) {
79480 return;
79481 }
79482 if ($this->source->restrictWarnings() && !SourceFilter::instance()->includes($event->file())) {
79483 return;
79484 }
79485 $id = $this->issueId($event);
79486 if (!isset($this->phpWarnings[$id])) {
79487 $this->phpWarnings[$id] = Issue::from($event->file(), $event->line(), $event->message(), $event->test());
79488 return;
79489 }
79490 $this->phpWarnings[$id]->triggeredBy($event->test());
79491 }
79492 public function testTriggeredPhpunitError(PhpunitErrorTriggered $event): void
79493 {
79494 if (!isset($this->testTriggeredPhpunitErrorEvents[$event->test()->id()])) {
79495 $this->testTriggeredPhpunitErrorEvents[$event->test()->id()] = [];
79496 }
79497 $this->testTriggeredPhpunitErrorEvents[$event->test()->id()][] = $event;
79498 }
79499 public function testTriggeredPhpunitWarning(PhpunitWarningTriggered $event): void
79500 {
79501 if (!isset($this->testTriggeredPhpunitWarningEvents[$event->test()->id()])) {
79502 $this->testTriggeredPhpunitWarningEvents[$event->test()->id()] = [];
79503 }
79504 $this->testTriggeredPhpunitWarningEvents[$event->test()->id()][] = $event;
79505 }
79506 public function testRunnerTriggeredDeprecation(TestRunnerDeprecationTriggered $event): void
79507 {
79508 $this->testRunnerTriggeredDeprecationEvents[] = $event;
79509 }
79510 public function testRunnerTriggeredWarning(TestRunnerWarningTriggered $event): void
79511 {
79512 $this->testRunnerTriggeredWarningEvents[] = $event;
79513 }
79514 public function hasErroredTests(): bool
79515 {
79516 return !empty($this->testErroredEvents);
79517 }
79518 public function hasFailedTests(): bool
79519 {
79520 return !empty($this->testFailedEvents);
79521 }
79522 public function hasRiskyTests(): bool
79523 {
79524 return !empty($this->testConsideredRiskyEvents);
79525 }
79526 public function hasSkippedTests(): bool
79527 {
79528 return !empty($this->testSkippedEvents);
79529 }
79530 public function hasIncompleteTests(): bool
79531 {
79532 return !empty($this->testMarkedIncompleteEvents);
79533 }
79534 public function hasDeprecations(): bool
79535 {
79536 return !empty($this->deprecations) || !empty($this->phpDeprecations) || !empty($this->testTriggeredPhpunitDeprecationEvents) || !empty($this->testRunnerTriggeredDeprecationEvents);
79537 }
79538 public function hasNotices(): bool
79539 {
79540 return !empty($this->notices) || !empty($this->phpNotices);
79541 }
79542 public function hasWarnings(): bool
79543 {
79544 return !empty($this->warnings) || !empty($this->phpWarnings) || !empty($this->testTriggeredPhpunitWarningEvents) || !empty($this->testRunnerTriggeredWarningEvents);
79545 }
79546 /**
79547 * @psalm-return non-empty-string
79548 */
79549 private function issueId(DeprecationTriggered|ErrorTriggered|NoticeTriggered|PhpDeprecationTriggered|PhpNoticeTriggered|PhpWarningTriggered|WarningTriggered $event): string
79550 {
79551 return implode(':', [$event->file(), $event->line(), $event->message()]);
79552 }
79553 }
79554 <?php
79555
79556 declare (strict_types=1);
79557 /*
79558 * This file is part of PHPUnit.
79559 *
79560 * (c) Sebastian Bergmann <sebastian@phpunit.de>
79561 *
79562 * For the full copyright and license information, please view the LICENSE
79563 * file that was distributed with this source code.
79564 */
79565 namespace PHPUnit\TestRunner\TestResult;
79566
79567 use PHPUnit\Event\EventFacadeIsSealedException;
79568 use PHPUnit\Event\Facade as EventFacade;
79569 use PHPUnit\Event\UnknownSubscriberTypeException;
79570 use PHPUnit\TextUI\Configuration\Registry as ConfigurationRegistry;
79571 /**
79572 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
79573 *
79574 * @internal This class is not covered by the backward compatibility promise for PHPUnit
79575 */
79576 final class Facade
79577 {
79578 private static ?\PHPUnit\TestRunner\TestResult\Collector $collector = null;
79579 /**
79580 * @throws EventFacadeIsSealedException
79581 * @throws UnknownSubscriberTypeException
79582 */
79583 public static function init(): void
79584 {
79585 self::collector();
79586 }
79587 /**
79588 * @throws EventFacadeIsSealedException
79589 * @throws UnknownSubscriberTypeException
79590 */
79591 public static function result(): \PHPUnit\TestRunner\TestResult\TestResult
79592 {
79593 return self::collector()->result();
79594 }
79595 /**
79596 * @throws EventFacadeIsSealedException
79597 * @throws UnknownSubscriberTypeException
79598 */
79599 public static function shouldStop(): bool
79600 {
79601 $configuration = ConfigurationRegistry::get();
79602 $collector = self::collector();
79603 if (($configuration->stopOnDefect() || $configuration->stopOnError()) && $collector->hasErroredTests()) {
79604 return \true;
79605 }
79606 if (($configuration->stopOnDefect() || $configuration->stopOnFailure()) && $collector->hasFailedTests()) {
79607 return \true;
79608 }
79609 if (($configuration->stopOnDefect() || $configuration->stopOnWarning()) && $collector->hasWarnings()) {
79610 return \true;
79611 }
79612 if (($configuration->stopOnDefect() || $configuration->stopOnRisky()) && $collector->hasRiskyTests()) {
79613 return \true;
79614 }
79615 if ($configuration->stopOnDeprecation() && $collector->hasDeprecations()) {
79616 return \true;
79617 }
79618 if ($configuration->stopOnNotice() && $collector->hasNotices()) {
79619 return \true;
79620 }
79621 if ($configuration->stopOnIncomplete() && $collector->hasIncompleteTests()) {
79622 return \true;
79623 }
79624 if ($configuration->stopOnSkipped() && $collector->hasSkippedTests()) {
79625 return \true;
79626 }
79627 return \false;
79628 }
79629 /**
79630 * @throws EventFacadeIsSealedException
79631 * @throws UnknownSubscriberTypeException
79632 */
79633 private static function collector(): \PHPUnit\TestRunner\TestResult\Collector
79634 {
79635 if (self::$collector === null) {
79636 $configuration = ConfigurationRegistry::get();
79637 self::$collector = new \PHPUnit\TestRunner\TestResult\Collector(EventFacade::instance(), $configuration->source());
79638 }
79639 return self::$collector;
79640 }
79641 }
79642 <?php
79643
79644 declare (strict_types=1);
79645 /*
79646 * This file is part of PHPUnit.
79647 *
79648 * (c) Sebastian Bergmann <sebastian@phpunit.de>
79649 *
79650 * For the full copyright and license information, please view the LICENSE
79651 * file that was distributed with this source code.
79652 */
79653 namespace PHPUnit\TestRunner\TestResult\Issues;
79654
79655 use PHPUnit\Event\Code\Test;
79656 /**
79657 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
79658 *
79659 * @internal This class is not covered by the backward compatibility promise for PHPUnit
79660 */
79661 final class Issue
79662 {
79663 /**
79664 * @psalm-var non-empty-string
79665 */
79666 private readonly string $file;
79667 /**
79668 * @psalm-var positive-int
79669 */
79670 private readonly int $line;
79671 /**
79672 * @psalm-var non-empty-string
79673 */
79674 private readonly string $description;
79675 /**
79676 * @psalm-var non-empty-array<non-empty-string, array{test: Test, count: int}>
79677 */
79678 private array $triggeringTests;
79679 /**
79680 * @psalm-param non-empty-string $file
79681 * @psalm-param positive-int $line
79682 * @psalm-param non-empty-string $description
79683 */
79684 public static function from(string $file, int $line, string $description, Test $triggeringTest): self
79685 {
79686 return new self($file, $line, $description, $triggeringTest);
79687 }
79688 /**
79689 * @psalm-param non-empty-string $file
79690 * @psalm-param positive-int $line
79691 * @psalm-param non-empty-string $description
79692 */
79693 private function __construct(string $file, int $line, string $description, Test $triggeringTest)
79694 {
79695 $this->file = $file;
79696 $this->line = $line;
79697 $this->description = $description;
79698 $this->triggeringTests = [$triggeringTest->id() => ['test' => $triggeringTest, 'count' => 1]];
79699 }
79700 public function triggeredBy(Test $test): void
79701 {
79702 if (isset($this->triggeringTests[$test->id()])) {
79703 $this->triggeringTests[$test->id()]['count']++;
79704 return;
79705 }
79706 $this->triggeringTests[$test->id()] = ['test' => $test, 'count' => 1];
79707 }
79708 /**
79709 * @psalm-return non-empty-string
79710 */
79711 public function file(): string
79712 {
79713 return $this->file;
79714 }
79715 /**
79716 * @psalm-return positive-int
79717 */
79718 public function line(): int
79719 {
79720 return $this->line;
79721 }
79722 /**
79723 * @psalm-return non-empty-string
79724 */
79725 public function description(): string
79726 {
79727 return $this->description;
79728 }
79729 /**
79730 * @psalm-return non-empty-array<non-empty-string, array{test: Test, count: int}>
79731 */
79732 public function triggeringTests(): array
79733 {
79734 return $this->triggeringTests;
79735 }
79736 }
79737 <?php
79738
79739 declare (strict_types=1);
79740 /*
79741 * This file is part of PHPUnit.
79742 *
79743 * (c) Sebastian Bergmann <sebastian@phpunit.de>
79744 *
79745 * For the full copyright and license information, please view the LICENSE
79746 * file that was distributed with this source code.
79747 */
79748 namespace PHPUnit\TestRunner\TestResult;
79749
79750 use function array_merge;
79751 use function assert;
79752 use function in_array;
79753 use PHPUnit\Event\Code\TestMethod;
79754 use PHPUnit\Framework\TestSize\Known;
79755 use PHPUnit\Framework\TestSize\TestSize;
79756 use PHPUnit\Metadata\Api\Groups;
79757 /**
79758 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
79759 *
79760 * @internal This class is not covered by the backward compatibility promise for PHPUnit
79761 */
79762 final class PassedTests
79763 {
79764 private static ?self $instance = null;
79765 /**
79766 * @psalm-var list<class-string>
79767 */
79768 private array $passedTestClasses = [];
79769 /**
79770 * @psalm-var array<string,array{returnValue: mixed, size: TestSize}>
79771 */
79772 private array $passedTestMethods = [];
79773 public static function instance(): self
79774 {
79775 if (self::$instance !== null) {
79776 return self::$instance;
79777 }
79778 self::$instance = new self();
79779 return self::$instance;
79780 }
79781 /**
79782 * @psalm-param class-string $className
79783 */
79784 public function testClassPassed(string $className): void
79785 {
79786 $this->passedTestClasses[] = $className;
79787 }
79788 public function testMethodPassed(TestMethod $test, mixed $returnValue): void
79789 {
79790 $size = (new Groups())->size($test->className(), $test->methodName());
79791 $this->passedTestMethods[$test->className() . '::' . $test->methodName()] = ['returnValue' => $returnValue, 'size' => $size];
79792 }
79793 public function import(self $other): void
79794 {
79795 $this->passedTestClasses = array_merge($this->passedTestClasses, $other->passedTestClasses);
79796 $this->passedTestMethods = array_merge($this->passedTestMethods, $other->passedTestMethods);
79797 }
79798 /**
79799 * @psalm-param class-string $className
79800 */
79801 public function hasTestClassPassed(string $className): bool
79802 {
79803 return in_array($className, $this->passedTestClasses, \true);
79804 }
79805 public function hasTestMethodPassed(string $method): bool
79806 {
79807 return isset($this->passedTestMethods[$method]);
79808 }
79809 public function isGreaterThan(string $method, TestSize $other): bool
79810 {
79811 if ($other->isUnknown()) {
79812 return \false;
79813 }
79814 assert($other instanceof Known);
79815 $size = $this->passedTestMethods[$method]['size'];
79816 if ($size->isUnknown()) {
79817 return \false;
79818 }
79819 assert($size instanceof Known);
79820 return $size->isGreaterThan($other);
79821 }
79822 public function returnValue(string $method): mixed
79823 {
79824 if (isset($this->passedTestMethods[$method])) {
79825 return $this->passedTestMethods[$method]['returnValue'];
79826 }
79827 return null;
79828 }
79829 }
79830 <?php
79831
79832 declare (strict_types=1);
79833 /*
79834 * This file is part of PHPUnit.
79835 *
79836 * (c) Sebastian Bergmann <sebastian@phpunit.de>
79837 *
79838 * For the full copyright and license information, please view the LICENSE
79839 * file that was distributed with this source code.
79840 */
79841 namespace PHPUnit\TestRunner\TestResult;
79842
79843 use PHPUnit\Event\Test\AfterLastTestMethodErrored;
79844 use PHPUnit\Event\Test\AfterLastTestMethodErroredSubscriber;
79845 /**
79846 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
79847 *
79848 * @internal This class is not covered by the backward compatibility promise for PHPUnit
79849 */
79850 final class AfterTestClassMethodErroredSubscriber extends \PHPUnit\TestRunner\TestResult\Subscriber implements AfterLastTestMethodErroredSubscriber
79851 {
79852 public function notify(AfterLastTestMethodErrored $event): void
79853 {
79854 $this->collector()->afterTestClassMethodErrored($event);
79855 }
79856 }
79857 <?php
79858
79859 declare (strict_types=1);
79860 /*
79861 * This file is part of PHPUnit.
79862 *
79863 * (c) Sebastian Bergmann <sebastian@phpunit.de>
79864 *
79865 * For the full copyright and license information, please view the LICENSE
79866 * file that was distributed with this source code.
79867 */
79868 namespace PHPUnit\TestRunner\TestResult;
79869
79870 use PHPUnit\Event\Test\BeforeFirstTestMethodErrored;
79871 use PHPUnit\Event\Test\BeforeFirstTestMethodErroredSubscriber;
79872 /**
79873 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
79874 *
79875 * @internal This class is not covered by the backward compatibility promise for PHPUnit
79876 */
79877 final class BeforeTestClassMethodErroredSubscriber extends \PHPUnit\TestRunner\TestResult\Subscriber implements BeforeFirstTestMethodErroredSubscriber
79878 {
79879 public function notify(BeforeFirstTestMethodErrored $event): void
79880 {
79881 $this->collector()->beforeTestClassMethodErrored($event);
79882 }
79883 }
79884 <?php
79885
79886 declare (strict_types=1);
79887 /*
79888 * This file is part of PHPUnit.
79889 *
79890 * (c) Sebastian Bergmann <sebastian@phpunit.de>
79891 *
79892 * For the full copyright and license information, please view the LICENSE
79893 * file that was distributed with this source code.
79894 */
79895 namespace PHPUnit\TestRunner\TestResult;
79896
79897 use PHPUnit\Event\TestRunner\ExecutionStarted;
79898 use PHPUnit\Event\TestRunner\ExecutionStartedSubscriber as TestRunnerExecutionStartedSubscriber;
79899 /**
79900 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
79901 *
79902 * @internal This class is not covered by the backward compatibility promise for PHPUnit
79903 */
79904 final class ExecutionStartedSubscriber extends \PHPUnit\TestRunner\TestResult\Subscriber implements TestRunnerExecutionStartedSubscriber
79905 {
79906 public function notify(ExecutionStarted $event): void
79907 {
79908 $this->collector()->executionStarted($event);
79909 }
79910 }
79911 <?php
79912
79913 declare (strict_types=1);
79914 /*
79915 * This file is part of PHPUnit.
79916 *
79917 * (c) Sebastian Bergmann <sebastian@phpunit.de>
79918 *
79919 * For the full copyright and license information, please view the LICENSE
79920 * file that was distributed with this source code.
79921 */
79922 namespace PHPUnit\TestRunner\TestResult;
79923
79924 /**
79925 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
79926 *
79927 * @internal This class is not covered by the backward compatibility promise for PHPUnit
79928 */
79929 abstract class Subscriber
79930 {
79931 private readonly \PHPUnit\TestRunner\TestResult\Collector $collector;
79932 public function __construct(\PHPUnit\TestRunner\TestResult\Collector $collector)
79933 {
79934 $this->collector = $collector;
79935 }
79936 protected function collector(): \PHPUnit\TestRunner\TestResult\Collector
79937 {
79938 return $this->collector;
79939 }
79940 }
79941 <?php
79942
79943 declare (strict_types=1);
79944 /*
79945 * This file is part of PHPUnit.
79946 *
79947 * (c) Sebastian Bergmann <sebastian@phpunit.de>
79948 *
79949 * For the full copyright and license information, please view the LICENSE
79950 * file that was distributed with this source code.
79951 */
79952 namespace PHPUnit\TestRunner\TestResult;
79953
79954 use PHPUnit\Event\Test\ConsideredRisky;
79955 use PHPUnit\Event\Test\ConsideredRiskySubscriber;
79956 /**
79957 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
79958 *
79959 * @internal This class is not covered by the backward compatibility promise for PHPUnit
79960 */
79961 final class TestConsideredRiskySubscriber extends \PHPUnit\TestRunner\TestResult\Subscriber implements ConsideredRiskySubscriber
79962 {
79963 public function notify(ConsideredRisky $event): void
79964 {
79965 $this->collector()->testConsideredRisky($event);
79966 }
79967 }
79968 <?php
79969
79970 declare (strict_types=1);
79971 /*
79972 * This file is part of PHPUnit.
79973 *
79974 * (c) Sebastian Bergmann <sebastian@phpunit.de>
79975 *
79976 * For the full copyright and license information, please view the LICENSE
79977 * file that was distributed with this source code.
79978 */
79979 namespace PHPUnit\TestRunner\TestResult;
79980
79981 use PHPUnit\Event\Test\Errored;
79982 use PHPUnit\Event\Test\ErroredSubscriber;
79983 /**
79984 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
79985 *
79986 * @internal This class is not covered by the backward compatibility promise for PHPUnit
79987 */
79988 final class TestErroredSubscriber extends \PHPUnit\TestRunner\TestResult\Subscriber implements ErroredSubscriber
79989 {
79990 public function notify(Errored $event): void
79991 {
79992 $this->collector()->testErrored($event);
79993 }
79994 }
79995 <?php
79996
79997 declare (strict_types=1);
79998 /*
79999 * This file is part of PHPUnit.
80000 *
80001 * (c) Sebastian Bergmann <sebastian@phpunit.de>
80002 *
80003 * For the full copyright and license information, please view the LICENSE
80004 * file that was distributed with this source code.
80005 */
80006 namespace PHPUnit\TestRunner\TestResult;
80007
80008 use PHPUnit\Event\Test\Failed;
80009 use PHPUnit\Event\Test\FailedSubscriber;
80010 /**
80011 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
80012 *
80013 * @internal This class is not covered by the backward compatibility promise for PHPUnit
80014 */
80015 final class TestFailedSubscriber extends \PHPUnit\TestRunner\TestResult\Subscriber implements FailedSubscriber
80016 {
80017 public function notify(Failed $event): void
80018 {
80019 $this->collector()->testFailed($event);
80020 }
80021 }
80022 <?php
80023
80024 declare (strict_types=1);
80025 /*
80026 * This file is part of PHPUnit.
80027 *
80028 * (c) Sebastian Bergmann <sebastian@phpunit.de>
80029 *
80030 * For the full copyright and license information, please view the LICENSE
80031 * file that was distributed with this source code.
80032 */
80033 namespace PHPUnit\TestRunner\TestResult;
80034
80035 use PHPUnit\Event\Test\Finished;
80036 use PHPUnit\Event\Test\FinishedSubscriber;
80037 /**
80038 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
80039 *
80040 * @internal This class is not covered by the backward compatibility promise for PHPUnit
80041 */
80042 final class TestFinishedSubscriber extends \PHPUnit\TestRunner\TestResult\Subscriber implements FinishedSubscriber
80043 {
80044 public function notify(Finished $event): void
80045 {
80046 $this->collector()->testFinished($event);
80047 }
80048 }
80049 <?php
80050
80051 declare (strict_types=1);
80052 /*
80053 * This file is part of PHPUnit.
80054 *
80055 * (c) Sebastian Bergmann <sebastian@phpunit.de>
80056 *
80057 * For the full copyright and license information, please view the LICENSE
80058 * file that was distributed with this source code.
80059 */
80060 namespace PHPUnit\TestRunner\TestResult;
80061
80062 use PHPUnit\Event\Test\MarkedIncomplete;
80063 use PHPUnit\Event\Test\MarkedIncompleteSubscriber;
80064 /**
80065 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
80066 *
80067 * @internal This class is not covered by the backward compatibility promise for PHPUnit
80068 */
80069 final class TestMarkedIncompleteSubscriber extends \PHPUnit\TestRunner\TestResult\Subscriber implements MarkedIncompleteSubscriber
80070 {
80071 public function notify(MarkedIncomplete $event): void
80072 {
80073 $this->collector()->testMarkedIncomplete($event);
80074 }
80075 }
80076 <?php
80077
80078 declare (strict_types=1);
80079 /*
80080 * This file is part of PHPUnit.
80081 *
80082 * (c) Sebastian Bergmann <sebastian@phpunit.de>
80083 *
80084 * For the full copyright and license information, please view the LICENSE
80085 * file that was distributed with this source code.
80086 */
80087 namespace PHPUnit\TestRunner\TestResult;
80088
80089 use PHPUnit\Event\Test\Prepared;
80090 use PHPUnit\Event\Test\PreparedSubscriber;
80091 /**
80092 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
80093 *
80094 * @internal This class is not covered by the backward compatibility promise for PHPUnit
80095 */
80096 final class TestPreparedSubscriber extends \PHPUnit\TestRunner\TestResult\Subscriber implements PreparedSubscriber
80097 {
80098 public function notify(Prepared $event): void
80099 {
80100 $this->collector()->testPrepared();
80101 }
80102 }
80103 <?php
80104
80105 declare (strict_types=1);
80106 /*
80107 * This file is part of PHPUnit.
80108 *
80109 * (c) Sebastian Bergmann <sebastian@phpunit.de>
80110 *
80111 * For the full copyright and license information, please view the LICENSE
80112 * file that was distributed with this source code.
80113 */
80114 namespace PHPUnit\TestRunner\TestResult;
80115
80116 use PHPUnit\Event\TestRunner\DeprecationTriggered;
80117 use PHPUnit\Event\TestRunner\DeprecationTriggeredSubscriber;
80118 /**
80119 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
80120 *
80121 * @internal This class is not covered by the backward compatibility promise for PHPUnit
80122 */
80123 final class TestRunnerTriggeredDeprecationSubscriber extends \PHPUnit\TestRunner\TestResult\Subscriber implements DeprecationTriggeredSubscriber
80124 {
80125 public function notify(DeprecationTriggered $event): void
80126 {
80127 $this->collector()->testRunnerTriggeredDeprecation($event);
80128 }
80129 }
80130 <?php
80131
80132 declare (strict_types=1);
80133 /*
80134 * This file is part of PHPUnit.
80135 *
80136 * (c) Sebastian Bergmann <sebastian@phpunit.de>
80137 *
80138 * For the full copyright and license information, please view the LICENSE
80139 * file that was distributed with this source code.
80140 */
80141 namespace PHPUnit\TestRunner\TestResult;
80142
80143 use PHPUnit\Event\TestRunner\WarningTriggered;
80144 use PHPUnit\Event\TestRunner\WarningTriggeredSubscriber;
80145 /**
80146 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
80147 *
80148 * @internal This class is not covered by the backward compatibility promise for PHPUnit
80149 */
80150 final class TestRunnerTriggeredWarningSubscriber extends \PHPUnit\TestRunner\TestResult\Subscriber implements WarningTriggeredSubscriber
80151 {
80152 public function notify(WarningTriggered $event): void
80153 {
80154 $this->collector()->testRunnerTriggeredWarning($event);
80155 }
80156 }
80157 <?php
80158
80159 declare (strict_types=1);
80160 /*
80161 * This file is part of PHPUnit.
80162 *
80163 * (c) Sebastian Bergmann <sebastian@phpunit.de>
80164 *
80165 * For the full copyright and license information, please view the LICENSE
80166 * file that was distributed with this source code.
80167 */
80168 namespace PHPUnit\TestRunner\TestResult;
80169
80170 use PHPUnit\Event\Test\Skipped;
80171 use PHPUnit\Event\Test\SkippedSubscriber;
80172 /**
80173 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
80174 *
80175 * @internal This class is not covered by the backward compatibility promise for PHPUnit
80176 */
80177 final class TestSkippedSubscriber extends \PHPUnit\TestRunner\TestResult\Subscriber implements SkippedSubscriber
80178 {
80179 public function notify(Skipped $event): void
80180 {
80181 $this->collector()->testSkipped($event);
80182 }
80183 }
80184 <?php
80185
80186 declare (strict_types=1);
80187 /*
80188 * This file is part of PHPUnit.
80189 *
80190 * (c) Sebastian Bergmann <sebastian@phpunit.de>
80191 *
80192 * For the full copyright and license information, please view the LICENSE
80193 * file that was distributed with this source code.
80194 */
80195 namespace PHPUnit\TestRunner\TestResult;
80196
80197 use PHPUnit\Event\TestSuite\Finished;
80198 use PHPUnit\Event\TestSuite\FinishedSubscriber;
80199 /**
80200 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
80201 *
80202 * @internal This class is not covered by the backward compatibility promise for PHPUnit
80203 */
80204 final class TestSuiteFinishedSubscriber extends \PHPUnit\TestRunner\TestResult\Subscriber implements FinishedSubscriber
80205 {
80206 public function notify(Finished $event): void
80207 {
80208 $this->collector()->testSuiteFinished($event);
80209 }
80210 }
80211 <?php
80212
80213 declare (strict_types=1);
80214 /*
80215 * This file is part of PHPUnit.
80216 *
80217 * (c) Sebastian Bergmann <sebastian@phpunit.de>
80218 *
80219 * For the full copyright and license information, please view the LICENSE
80220 * file that was distributed with this source code.
80221 */
80222 namespace PHPUnit\TestRunner\TestResult;
80223
80224 use PHPUnit\Event\TestSuite\Skipped;
80225 use PHPUnit\Event\TestSuite\SkippedSubscriber;
80226 /**
80227 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
80228 *
80229 * @internal This class is not covered by the backward compatibility promise for PHPUnit
80230 */
80231 final class TestSuiteSkippedSubscriber extends \PHPUnit\TestRunner\TestResult\Subscriber implements SkippedSubscriber
80232 {
80233 public function notify(Skipped $event): void
80234 {
80235 $this->collector()->testSuiteSkipped($event);
80236 }
80237 }
80238 <?php
80239
80240 declare (strict_types=1);
80241 /*
80242 * This file is part of PHPUnit.
80243 *
80244 * (c) Sebastian Bergmann <sebastian@phpunit.de>
80245 *
80246 * For the full copyright and license information, please view the LICENSE
80247 * file that was distributed with this source code.
80248 */
80249 namespace PHPUnit\TestRunner\TestResult;
80250
80251 use PHPUnit\Event\TestSuite\Started;
80252 use PHPUnit\Event\TestSuite\StartedSubscriber;
80253 /**
80254 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
80255 *
80256 * @internal This class is not covered by the backward compatibility promise for PHPUnit
80257 */
80258 final class TestSuiteStartedSubscriber extends \PHPUnit\TestRunner\TestResult\Subscriber implements StartedSubscriber
80259 {
80260 public function notify(Started $event): void
80261 {
80262 $this->collector()->testSuiteStarted($event);
80263 }
80264 }
80265 <?php
80266
80267 declare (strict_types=1);
80268 /*
80269 * This file is part of PHPUnit.
80270 *
80271 * (c) Sebastian Bergmann <sebastian@phpunit.de>
80272 *
80273 * For the full copyright and license information, please view the LICENSE
80274 * file that was distributed with this source code.
80275 */
80276 namespace PHPUnit\TestRunner\TestResult;
80277
80278 use PHPUnit\Event\Test\DeprecationTriggered;
80279 use PHPUnit\Event\Test\DeprecationTriggeredSubscriber;
80280 /**
80281 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
80282 *
80283 * @internal This class is not covered by the backward compatibility promise for PHPUnit
80284 */
80285 final class TestTriggeredDeprecationSubscriber extends \PHPUnit\TestRunner\TestResult\Subscriber implements DeprecationTriggeredSubscriber
80286 {
80287 public function notify(DeprecationTriggered $event): void
80288 {
80289 $this->collector()->testTriggeredDeprecation($event);
80290 }
80291 }
80292 <?php
80293
80294 declare (strict_types=1);
80295 /*
80296 * This file is part of PHPUnit.
80297 *
80298 * (c) Sebastian Bergmann <sebastian@phpunit.de>
80299 *
80300 * For the full copyright and license information, please view the LICENSE
80301 * file that was distributed with this source code.
80302 */
80303 namespace PHPUnit\TestRunner\TestResult;
80304
80305 use PHPUnit\Event\Test\ErrorTriggered;
80306 use PHPUnit\Event\Test\ErrorTriggeredSubscriber;
80307 /**
80308 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
80309 *
80310 * @internal This class is not covered by the backward compatibility promise for PHPUnit
80311 */
80312 final class TestTriggeredErrorSubscriber extends \PHPUnit\TestRunner\TestResult\Subscriber implements ErrorTriggeredSubscriber
80313 {
80314 public function notify(ErrorTriggered $event): void
80315 {
80316 $this->collector()->testTriggeredError($event);
80317 }
80318 }
80319 <?php
80320
80321 declare (strict_types=1);
80322 /*
80323 * This file is part of PHPUnit.
80324 *
80325 * (c) Sebastian Bergmann <sebastian@phpunit.de>
80326 *
80327 * For the full copyright and license information, please view the LICENSE
80328 * file that was distributed with this source code.
80329 */
80330 namespace PHPUnit\TestRunner\TestResult;
80331
80332 use PHPUnit\Event\Test\NoticeTriggered;
80333 use PHPUnit\Event\Test\NoticeTriggeredSubscriber;
80334 /**
80335 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
80336 *
80337 * @internal This class is not covered by the backward compatibility promise for PHPUnit
80338 */
80339 final class TestTriggeredNoticeSubscriber extends \PHPUnit\TestRunner\TestResult\Subscriber implements NoticeTriggeredSubscriber
80340 {
80341 public function notify(NoticeTriggered $event): void
80342 {
80343 $this->collector()->testTriggeredNotice($event);
80344 }
80345 }
80346 <?php
80347
80348 declare (strict_types=1);
80349 /*
80350 * This file is part of PHPUnit.
80351 *
80352 * (c) Sebastian Bergmann <sebastian@phpunit.de>
80353 *
80354 * For the full copyright and license information, please view the LICENSE
80355 * file that was distributed with this source code.
80356 */
80357 namespace PHPUnit\TestRunner\TestResult;
80358
80359 use PHPUnit\Event\Test\PhpDeprecationTriggered;
80360 use PHPUnit\Event\Test\PhpDeprecationTriggeredSubscriber;
80361 /**
80362 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
80363 *
80364 * @internal This class is not covered by the backward compatibility promise for PHPUnit
80365 */
80366 final class TestTriggeredPhpDeprecationSubscriber extends \PHPUnit\TestRunner\TestResult\Subscriber implements PhpDeprecationTriggeredSubscriber
80367 {
80368 public function notify(PhpDeprecationTriggered $event): void
80369 {
80370 $this->collector()->testTriggeredPhpDeprecation($event);
80371 }
80372 }
80373 <?php
80374
80375 declare (strict_types=1);
80376 /*
80377 * This file is part of PHPUnit.
80378 *
80379 * (c) Sebastian Bergmann <sebastian@phpunit.de>
80380 *
80381 * For the full copyright and license information, please view the LICENSE
80382 * file that was distributed with this source code.
80383 */
80384 namespace PHPUnit\TestRunner\TestResult;
80385
80386 use PHPUnit\Event\Test\PhpNoticeTriggered;
80387 use PHPUnit\Event\Test\PhpNoticeTriggeredSubscriber;
80388 /**
80389 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
80390 *
80391 * @internal This class is not covered by the backward compatibility promise for PHPUnit
80392 */
80393 final class TestTriggeredPhpNoticeSubscriber extends \PHPUnit\TestRunner\TestResult\Subscriber implements PhpNoticeTriggeredSubscriber
80394 {
80395 public function notify(PhpNoticeTriggered $event): void
80396 {
80397 $this->collector()->testTriggeredPhpNotice($event);
80398 }
80399 }
80400 <?php
80401
80402 declare (strict_types=1);
80403 /*
80404 * This file is part of PHPUnit.
80405 *
80406 * (c) Sebastian Bergmann <sebastian@phpunit.de>
80407 *
80408 * For the full copyright and license information, please view the LICENSE
80409 * file that was distributed with this source code.
80410 */
80411 namespace PHPUnit\TestRunner\TestResult;
80412
80413 use PHPUnit\Event\Test\PhpWarningTriggered;
80414 use PHPUnit\Event\Test\PhpWarningTriggeredSubscriber;
80415 /**
80416 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
80417 *
80418 * @internal This class is not covered by the backward compatibility promise for PHPUnit
80419 */
80420 final class TestTriggeredPhpWarningSubscriber extends \PHPUnit\TestRunner\TestResult\Subscriber implements PhpWarningTriggeredSubscriber
80421 {
80422 public function notify(PhpWarningTriggered $event): void
80423 {
80424 $this->collector()->testTriggeredPhpWarning($event);
80425 }
80426 }
80427 <?php
80428
80429 declare (strict_types=1);
80430 /*
80431 * This file is part of PHPUnit.
80432 *
80433 * (c) Sebastian Bergmann <sebastian@phpunit.de>
80434 *
80435 * For the full copyright and license information, please view the LICENSE
80436 * file that was distributed with this source code.
80437 */
80438 namespace PHPUnit\TestRunner\TestResult;
80439
80440 use PHPUnit\Event\Test\PhpunitDeprecationTriggered;
80441 use PHPUnit\Event\Test\PhpunitDeprecationTriggeredSubscriber;
80442 /**
80443 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
80444 *
80445 * @internal This class is not covered by the backward compatibility promise for PHPUnit
80446 */
80447 final class TestTriggeredPhpunitDeprecationSubscriber extends \PHPUnit\TestRunner\TestResult\Subscriber implements PhpunitDeprecationTriggeredSubscriber
80448 {
80449 public function notify(PhpunitDeprecationTriggered $event): void
80450 {
80451 $this->collector()->testTriggeredPhpunitDeprecation($event);
80452 }
80453 }
80454 <?php
80455
80456 declare (strict_types=1);
80457 /*
80458 * This file is part of PHPUnit.
80459 *
80460 * (c) Sebastian Bergmann <sebastian@phpunit.de>
80461 *
80462 * For the full copyright and license information, please view the LICENSE
80463 * file that was distributed with this source code.
80464 */
80465 namespace PHPUnit\TestRunner\TestResult;
80466
80467 use PHPUnit\Event\Test\PhpunitErrorTriggered;
80468 use PHPUnit\Event\Test\PhpunitErrorTriggeredSubscriber;
80469 /**
80470 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
80471 *
80472 * @internal This class is not covered by the backward compatibility promise for PHPUnit
80473 */
80474 final class TestTriggeredPhpunitErrorSubscriber extends \PHPUnit\TestRunner\TestResult\Subscriber implements PhpunitErrorTriggeredSubscriber
80475 {
80476 public function notify(PhpunitErrorTriggered $event): void
80477 {
80478 $this->collector()->testTriggeredPhpunitError($event);
80479 }
80480 }
80481 <?php
80482
80483 declare (strict_types=1);
80484 /*
80485 * This file is part of PHPUnit.
80486 *
80487 * (c) Sebastian Bergmann <sebastian@phpunit.de>
80488 *
80489 * For the full copyright and license information, please view the LICENSE
80490 * file that was distributed with this source code.
80491 */
80492 namespace PHPUnit\TestRunner\TestResult;
80493
80494 use PHPUnit\Event\Test\PhpunitWarningTriggered;
80495 use PHPUnit\Event\Test\PhpunitWarningTriggeredSubscriber;
80496 /**
80497 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
80498 *
80499 * @internal This class is not covered by the backward compatibility promise for PHPUnit
80500 */
80501 final class TestTriggeredPhpunitWarningSubscriber extends \PHPUnit\TestRunner\TestResult\Subscriber implements PhpunitWarningTriggeredSubscriber
80502 {
80503 public function notify(PhpunitWarningTriggered $event): void
80504 {
80505 $this->collector()->testTriggeredPhpunitWarning($event);
80506 }
80507 }
80508 <?php
80509
80510 declare (strict_types=1);
80511 /*
80512 * This file is part of PHPUnit.
80513 *
80514 * (c) Sebastian Bergmann <sebastian@phpunit.de>
80515 *
80516 * For the full copyright and license information, please view the LICENSE
80517 * file that was distributed with this source code.
80518 */
80519 namespace PHPUnit\TestRunner\TestResult;
80520
80521 use PHPUnit\Event\Test\WarningTriggered;
80522 use PHPUnit\Event\Test\WarningTriggeredSubscriber;
80523 /**
80524 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
80525 *
80526 * @internal This class is not covered by the backward compatibility promise for PHPUnit
80527 */
80528 final class TestTriggeredWarningSubscriber extends \PHPUnit\TestRunner\TestResult\Subscriber implements WarningTriggeredSubscriber
80529 {
80530 public function notify(WarningTriggered $event): void
80531 {
80532 $this->collector()->testTriggeredWarning($event);
80533 }
80534 }
80535 <?php
80536
80537 declare (strict_types=1);
80538 /*
80539 * This file is part of PHPUnit.
80540 *
80541 * (c) Sebastian Bergmann <sebastian@phpunit.de>
80542 *
80543 * For the full copyright and license information, please view the LICENSE
80544 * file that was distributed with this source code.
80545 */
80546 namespace PHPUnit\TestRunner\TestResult;
80547
80548 use function count;
80549 use PHPUnit\Event\Test\AfterLastTestMethodErrored;
80550 use PHPUnit\Event\Test\BeforeFirstTestMethodErrored;
80551 use PHPUnit\Event\Test\ConsideredRisky;
80552 use PHPUnit\Event\Test\Errored;
80553 use PHPUnit\Event\Test\Failed;
80554 use PHPUnit\Event\Test\MarkedIncomplete;
80555 use PHPUnit\Event\Test\PhpunitDeprecationTriggered;
80556 use PHPUnit\Event\Test\PhpunitErrorTriggered;
80557 use PHPUnit\Event\Test\PhpunitWarningTriggered;
80558 use PHPUnit\Event\Test\Skipped as TestSkipped;
80559 use PHPUnit\Event\TestRunner\DeprecationTriggered as TestRunnerDeprecationTriggered;
80560 use PHPUnit\Event\TestRunner\WarningTriggered as TestRunnerWarningTriggered;
80561 use PHPUnit\Event\TestSuite\Skipped as TestSuiteSkipped;
80562 use PHPUnit\TestRunner\TestResult\Issues\Issue;
80563 /**
80564 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
80565 *
80566 * @internal This class is not covered by the backward compatibility promise for PHPUnit
80567 */
80568 final class TestResult
80569 {
80570 private readonly int $numberOfTests;
80571 private readonly int $numberOfTestsRun;
80572 private readonly int $numberOfAssertions;
80573 /**
80574 * @psalm-var list<AfterLastTestMethodErrored|BeforeFirstTestMethodErrored|Errored>
80575 */
80576 private readonly array $testErroredEvents;
80577 /**
80578 * @psalm-var list<Failed>
80579 */
80580 private readonly array $testFailedEvents;
80581 /**
80582 * @psalm-var list<MarkedIncomplete>
80583 */
80584 private readonly array $testMarkedIncompleteEvents;
80585 /**
80586 * @psalm-var list<TestSuiteSkipped>
80587 */
80588 private readonly array $testSuiteSkippedEvents;
80589 /**
80590 * @psalm-var list<TestSkipped>
80591 */
80592 private readonly array $testSkippedEvents;
80593 /**
80594 * @psalm-var array<string,list<ConsideredRisky>>
80595 */
80596 private readonly array $testConsideredRiskyEvents;
80597 /**
80598 * @psalm-var array<string,list<PhpunitDeprecationTriggered>>
80599 */
80600 private readonly array $testTriggeredPhpunitDeprecationEvents;
80601 /**
80602 * @psalm-var array<string,list<PhpunitErrorTriggered>>
80603 */
80604 private readonly array $testTriggeredPhpunitErrorEvents;
80605 /**
80606 * @psalm-var array<string,list<PhpunitWarningTriggered>>
80607 */
80608 private readonly array $testTriggeredPhpunitWarningEvents;
80609 /**
80610 * @psalm-var list<TestRunnerDeprecationTriggered>
80611 */
80612 private readonly array $testRunnerTriggeredDeprecationEvents;
80613 /**
80614 * @psalm-var list<TestRunnerWarningTriggered>
80615 */
80616 private readonly array $testRunnerTriggeredWarningEvents;
80617 /**
80618 * @psalm-var list<Issue>
80619 */
80620 private readonly array $errors;
80621 /**
80622 * @psalm-var list<Issue>
80623 */
80624 private readonly array $deprecations;
80625 /**
80626 * @psalm-var list<Issue>
80627 */
80628 private readonly array $notices;
80629 /**
80630 * @psalm-var list<Issue>
80631 */
80632 private readonly array $warnings;
80633 /**
80634 * @psalm-var list<Issue>
80635 */
80636 private readonly array $phpDeprecations;
80637 /**
80638 * @psalm-var list<Issue>
80639 */
80640 private readonly array $phpNotices;
80641 /**
80642 * @psalm-var list<Issue>
80643 */
80644 private readonly array $phpWarnings;
80645 /**
80646 * @psalm-var non-negative-int
80647 */
80648 private readonly int $numberOfIssuesIgnoredByBaseline;
80649 /**
80650 * @psalm-param list<AfterLastTestMethodErrored|BeforeFirstTestMethodErrored|Errored> $testErroredEvents
80651 * @psalm-param list<Failed> $testFailedEvents
80652 * @psalm-param array<string,list<ConsideredRisky>> $testConsideredRiskyEvents
80653 * @psalm-param list<TestSuiteSkipped> $testSuiteSkippedEvents
80654 * @psalm-param list<TestSkipped> $testSkippedEvents
80655 * @psalm-param list<MarkedIncomplete> $testMarkedIncompleteEvents
80656 * @psalm-param array<string,list<PhpunitDeprecationTriggered>> $testTriggeredPhpunitDeprecationEvents
80657 * @psalm-param array<string,list<PhpunitErrorTriggered>> $testTriggeredPhpunitErrorEvents
80658 * @psalm-param array<string,list<PhpunitWarningTriggered>> $testTriggeredPhpunitWarningEvents
80659 * @psalm-param list<TestRunnerDeprecationTriggered> $testRunnerTriggeredDeprecationEvents
80660 * @psalm-param list<TestRunnerWarningTriggered> $testRunnerTriggeredWarningEvents
80661 * @psalm-param list<Issue> $errors
80662 * @psalm-param list<Issue> $deprecations
80663 * @psalm-param list<Issue> $notices
80664 * @psalm-param list<Issue> $warnings
80665 * @psalm-param list<Issue> $phpDeprecations
80666 * @psalm-param list<Issue> $phpNotices
80667 * @psalm-param list<Issue> $phpWarnings
80668 * @psalm-param non-negative-int $numberOfIssuesIgnoredByBaseline
80669 */
80670 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)
80671 {
80672 $this->numberOfTests = $numberOfTests;
80673 $this->numberOfTestsRun = $numberOfTestsRun;
80674 $this->numberOfAssertions = $numberOfAssertions;
80675 $this->testErroredEvents = $testErroredEvents;
80676 $this->testFailedEvents = $testFailedEvents;
80677 $this->testConsideredRiskyEvents = $testConsideredRiskyEvents;
80678 $this->testSuiteSkippedEvents = $testSuiteSkippedEvents;
80679 $this->testSkippedEvents = $testSkippedEvents;
80680 $this->testMarkedIncompleteEvents = $testMarkedIncompleteEvents;
80681 $this->testTriggeredPhpunitDeprecationEvents = $testTriggeredPhpunitDeprecationEvents;
80682 $this->testTriggeredPhpunitErrorEvents = $testTriggeredPhpunitErrorEvents;
80683 $this->testTriggeredPhpunitWarningEvents = $testTriggeredPhpunitWarningEvents;
80684 $this->testRunnerTriggeredDeprecationEvents = $testRunnerTriggeredDeprecationEvents;
80685 $this->testRunnerTriggeredWarningEvents = $testRunnerTriggeredWarningEvents;
80686 $this->errors = $errors;
80687 $this->deprecations = $deprecations;
80688 $this->notices = $notices;
80689 $this->warnings = $warnings;
80690 $this->phpDeprecations = $phpDeprecations;
80691 $this->phpNotices = $phpNotices;
80692 $this->phpWarnings = $phpWarnings;
80693 $this->numberOfIssuesIgnoredByBaseline = $numberOfIssuesIgnoredByBaseline;
80694 }
80695 public function numberOfTestsRun(): int
80696 {
80697 return $this->numberOfTestsRun;
80698 }
80699 public function numberOfAssertions(): int
80700 {
80701 return $this->numberOfAssertions;
80702 }
80703 /**
80704 * @psalm-return list<AfterLastTestMethodErrored|BeforeFirstTestMethodErrored|Errored>
80705 */
80706 public function testErroredEvents(): array
80707 {
80708 return $this->testErroredEvents;
80709 }
80710 public function numberOfTestErroredEvents(): int
80711 {
80712 return count($this->testErroredEvents);
80713 }
80714 public function hasTestErroredEvents(): bool
80715 {
80716 return $this->numberOfTestErroredEvents() > 0;
80717 }
80718 /**
80719 * @psalm-return list<Failed>
80720 */
80721 public function testFailedEvents(): array
80722 {
80723 return $this->testFailedEvents;
80724 }
80725 public function numberOfTestFailedEvents(): int
80726 {
80727 return count($this->testFailedEvents);
80728 }
80729 public function hasTestFailedEvents(): bool
80730 {
80731 return $this->numberOfTestFailedEvents() > 0;
80732 }
80733 /**
80734 * @psalm-return array<string,list<ConsideredRisky>>
80735 */
80736 public function testConsideredRiskyEvents(): array
80737 {
80738 return $this->testConsideredRiskyEvents;
80739 }
80740 public function numberOfTestsWithTestConsideredRiskyEvents(): int
80741 {
80742 return count($this->testConsideredRiskyEvents);
80743 }
80744 public function hasTestConsideredRiskyEvents(): bool
80745 {
80746 return $this->numberOfTestsWithTestConsideredRiskyEvents() > 0;
80747 }
80748 /**
80749 * @psalm-return list<TestSuiteSkipped>
80750 */
80751 public function testSuiteSkippedEvents(): array
80752 {
80753 return $this->testSuiteSkippedEvents;
80754 }
80755 public function numberOfTestSuiteSkippedEvents(): int
80756 {
80757 return count($this->testSuiteSkippedEvents);
80758 }
80759 public function hasTestSuiteSkippedEvents(): bool
80760 {
80761 return $this->numberOfTestSuiteSkippedEvents() > 0;
80762 }
80763 /**
80764 * @psalm-return list<TestSkipped>
80765 */
80766 public function testSkippedEvents(): array
80767 {
80768 return $this->testSkippedEvents;
80769 }
80770 public function numberOfTestSkippedEvents(): int
80771 {
80772 return count($this->testSkippedEvents);
80773 }
80774 public function hasTestSkippedEvents(): bool
80775 {
80776 return $this->numberOfTestSkippedEvents() > 0;
80777 }
80778 /**
80779 * @psalm-return list<MarkedIncomplete>
80780 */
80781 public function testMarkedIncompleteEvents(): array
80782 {
80783 return $this->testMarkedIncompleteEvents;
80784 }
80785 public function numberOfTestMarkedIncompleteEvents(): int
80786 {
80787 return count($this->testMarkedIncompleteEvents);
80788 }
80789 public function hasTestMarkedIncompleteEvents(): bool
80790 {
80791 return $this->numberOfTestMarkedIncompleteEvents() > 0;
80792 }
80793 /**
80794 * @psalm-return array<string,list<PhpunitDeprecationTriggered>>
80795 */
80796 public function testTriggeredPhpunitDeprecationEvents(): array
80797 {
80798 return $this->testTriggeredPhpunitDeprecationEvents;
80799 }
80800 public function numberOfTestsWithTestTriggeredPhpunitDeprecationEvents(): int
80801 {
80802 return count($this->testTriggeredPhpunitDeprecationEvents);
80803 }
80804 public function hasTestTriggeredPhpunitDeprecationEvents(): bool
80805 {
80806 return $this->numberOfTestsWithTestTriggeredPhpunitDeprecationEvents() > 0;
80807 }
80808 /**
80809 * @psalm-return array<string,list<PhpunitErrorTriggered>>
80810 */
80811 public function testTriggeredPhpunitErrorEvents(): array
80812 {
80813 return $this->testTriggeredPhpunitErrorEvents;
80814 }
80815 public function numberOfTestsWithTestTriggeredPhpunitErrorEvents(): int
80816 {
80817 return count($this->testTriggeredPhpunitErrorEvents);
80818 }
80819 public function hasTestTriggeredPhpunitErrorEvents(): bool
80820 {
80821 return $this->numberOfTestsWithTestTriggeredPhpunitErrorEvents() > 0;
80822 }
80823 /**
80824 * @psalm-return array<string,list<PhpunitWarningTriggered>>
80825 */
80826 public function testTriggeredPhpunitWarningEvents(): array
80827 {
80828 return $this->testTriggeredPhpunitWarningEvents;
80829 }
80830 public function numberOfTestsWithTestTriggeredPhpunitWarningEvents(): int
80831 {
80832 return count($this->testTriggeredPhpunitWarningEvents);
80833 }
80834 public function hasTestTriggeredPhpunitWarningEvents(): bool
80835 {
80836 return $this->numberOfTestsWithTestTriggeredPhpunitWarningEvents() > 0;
80837 }
80838 /**
80839 * @psalm-return list<TestRunnerDeprecationTriggered>
80840 */
80841 public function testRunnerTriggeredDeprecationEvents(): array
80842 {
80843 return $this->testRunnerTriggeredDeprecationEvents;
80844 }
80845 public function numberOfTestRunnerTriggeredDeprecationEvents(): int
80846 {
80847 return count($this->testRunnerTriggeredDeprecationEvents);
80848 }
80849 public function hasTestRunnerTriggeredDeprecationEvents(): bool
80850 {
80851 return $this->numberOfTestRunnerTriggeredDeprecationEvents() > 0;
80852 }
80853 /**
80854 * @psalm-return list<TestRunnerWarningTriggered>
80855 */
80856 public function testRunnerTriggeredWarningEvents(): array
80857 {
80858 return $this->testRunnerTriggeredWarningEvents;
80859 }
80860 public function numberOfTestRunnerTriggeredWarningEvents(): int
80861 {
80862 return count($this->testRunnerTriggeredWarningEvents);
80863 }
80864 public function hasTestRunnerTriggeredWarningEvents(): bool
80865 {
80866 return $this->numberOfTestRunnerTriggeredWarningEvents() > 0;
80867 }
80868 public function wasSuccessful(): bool
80869 {
80870 return !$this->hasTestErroredEvents() && !$this->hasTestFailedEvents() && !$this->hasTestTriggeredPhpunitErrorEvents();
80871 }
80872 public function wasSuccessfulAndNoTestHasIssues(): bool
80873 {
80874 return $this->wasSuccessful() && !$this->hasTestsWithIssues();
80875 }
80876 public function hasIssues(): bool
80877 {
80878 return $this->hasTestsWithIssues() || $this->hasTestRunnerTriggeredWarningEvents();
80879 }
80880 public function hasTestsWithIssues(): bool
80881 {
80882 return $this->hasRiskyTests() || $this->hasIncompleteTests() || $this->hasDeprecations() || !empty($this->errors) || $this->hasNotices() || $this->hasWarnings() || $this->hasPhpunitWarnings();
80883 }
80884 /**
80885 * @psalm-return list<Issue>
80886 */
80887 public function errors(): array
80888 {
80889 return $this->errors;
80890 }
80891 /**
80892 * @psalm-return list<Issue>
80893 */
80894 public function deprecations(): array
80895 {
80896 return $this->deprecations;
80897 }
80898 /**
80899 * @psalm-return list<Issue>
80900 */
80901 public function notices(): array
80902 {
80903 return $this->notices;
80904 }
80905 /**
80906 * @psalm-return list<Issue>
80907 */
80908 public function warnings(): array
80909 {
80910 return $this->warnings;
80911 }
80912 /**
80913 * @psalm-return list<Issue>
80914 */
80915 public function phpDeprecations(): array
80916 {
80917 return $this->phpDeprecations;
80918 }
80919 /**
80920 * @psalm-return list<Issue>
80921 */
80922 public function phpNotices(): array
80923 {
80924 return $this->phpNotices;
80925 }
80926 /**
80927 * @psalm-return list<Issue>
80928 */
80929 public function phpWarnings(): array
80930 {
80931 return $this->phpWarnings;
80932 }
80933 public function hasTests(): bool
80934 {
80935 return $this->numberOfTests > 0;
80936 }
80937 public function hasErrors(): bool
80938 {
80939 return $this->numberOfErrors() > 0;
80940 }
80941 public function numberOfErrors(): int
80942 {
80943 return $this->numberOfTestErroredEvents() + count($this->errors) + $this->numberOfTestsWithTestTriggeredPhpunitErrorEvents();
80944 }
80945 public function hasDeprecations(): bool
80946 {
80947 return $this->numberOfDeprecations() > 0;
80948 }
80949 public function hasPhpOrUserDeprecations(): bool
80950 {
80951 return $this->numberOfPhpOrUserDeprecations() > 0;
80952 }
80953 public function numberOfPhpOrUserDeprecations(): int
80954 {
80955 return count($this->deprecations) + count($this->phpDeprecations);
80956 }
80957 public function hasPhpunitDeprecations(): bool
80958 {
80959 return $this->numberOfPhpunitDeprecations() > 0;
80960 }
80961 public function numberOfPhpunitDeprecations(): int
80962 {
80963 return count($this->testTriggeredPhpunitDeprecationEvents) + count($this->testRunnerTriggeredDeprecationEvents);
80964 }
80965 public function hasPhpunitWarnings(): bool
80966 {
80967 return $this->numberOfPhpunitWarnings() > 0;
80968 }
80969 public function numberOfPhpunitWarnings(): int
80970 {
80971 return count($this->testTriggeredPhpunitWarningEvents) + count($this->testRunnerTriggeredWarningEvents);
80972 }
80973 public function numberOfDeprecations(): int
80974 {
80975 return count($this->deprecations) + count($this->phpDeprecations) + count($this->testTriggeredPhpunitDeprecationEvents) + count($this->testRunnerTriggeredDeprecationEvents);
80976 }
80977 public function hasNotices(): bool
80978 {
80979 return $this->numberOfNotices() > 0;
80980 }
80981 public function numberOfNotices(): int
80982 {
80983 return count($this->notices) + count($this->phpNotices);
80984 }
80985 public function hasWarnings(): bool
80986 {
80987 return $this->numberOfWarnings() > 0;
80988 }
80989 public function numberOfWarnings(): int
80990 {
80991 return count($this->warnings) + count($this->phpWarnings);
80992 }
80993 public function hasIncompleteTests(): bool
80994 {
80995 return !empty($this->testMarkedIncompleteEvents);
80996 }
80997 public function hasRiskyTests(): bool
80998 {
80999 return !empty($this->testConsideredRiskyEvents);
81000 }
81001 public function hasSkippedTests(): bool
81002 {
81003 return !empty($this->testSkippedEvents);
81004 }
81005 public function hasIssuesIgnoredByBaseline(): bool
81006 {
81007 return $this->numberOfIssuesIgnoredByBaseline > 0;
81008 }
81009 /**
81010 * @psalm-return non-negative-int
81011 */
81012 public function numberOfIssuesIgnoredByBaseline(): int
81013 {
81014 return $this->numberOfIssuesIgnoredByBaseline;
81015 }
81016 }
81017 <?php
81018
81019 declare (strict_types=1);
81020 /*
81021 * This file is part of PHPUnit.
81022 *
81023 * (c) Sebastian Bergmann <sebastian@phpunit.de>
81024 *
81025 * For the full copyright and license information, please view the LICENSE
81026 * file that was distributed with this source code.
81027 */
81028 namespace PHPUnit\Runner;
81029
81030 use function array_diff;
81031 use function array_values;
81032 use function basename;
81033 use function get_declared_classes;
81034 use function realpath;
81035 use function str_ends_with;
81036 use function strpos;
81037 use function strtolower;
81038 use function substr;
81039 use PHPUnit\Framework\TestCase;
81040 use ReflectionClass;
81041 /**
81042 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
81043 *
81044 * @internal This class is not covered by the backward compatibility promise for PHPUnit
81045 */
81046 final class TestSuiteLoader
81047 {
81048 /**
81049 * @psalm-var list<class-string>
81050 */
81051 private static array $declaredClasses = [];
81052 /**
81053 * @psalm-var array<non-empty-string, list<class-string>>
81054 */
81055 private static array $fileToClassesMap = [];
81056 /**
81057 * @throws Exception
81058 */
81059 public function load(string $suiteClassFile): ReflectionClass
81060 {
81061 $suiteClassFile = realpath($suiteClassFile);
81062 $suiteClassName = $this->classNameFromFileName($suiteClassFile);
81063 $loadedClasses = $this->loadSuiteClassFile($suiteClassFile);
81064 foreach ($loadedClasses as $className) {
81065 /** @noinspection PhpUnhandledExceptionInspection */
81066 $class = new ReflectionClass($className);
81067 if ($class->isAnonymous()) {
81068 continue;
81069 }
81070 if ($class->getFileName() !== $suiteClassFile) {
81071 continue;
81072 }
81073 if (!$class->isSubclassOf(TestCase::class)) {
81074 continue;
81075 }
81076 if (!str_ends_with(strtolower($class->getShortName()), strtolower($suiteClassName))) {
81077 continue;
81078 }
81079 if (!$class->isAbstract()) {
81080 return $class;
81081 }
81082 $e = new \PHPUnit\Runner\ClassIsAbstractException($class->getName(), $suiteClassFile);
81083 }
81084 if (isset($e)) {
81085 throw $e;
81086 }
81087 foreach ($loadedClasses as $className) {
81088 if (str_ends_with(strtolower($className), strtolower($suiteClassName))) {
81089 throw new \PHPUnit\Runner\ClassDoesNotExtendTestCaseException($className, $suiteClassFile);
81090 }
81091 }
81092 throw new \PHPUnit\Runner\ClassCannotBeFoundException($suiteClassName, $suiteClassFile);
81093 }
81094 private function classNameFromFileName(string $suiteClassFile): string
81095 {
81096 $className = basename($suiteClassFile, '.php');
81097 $dotPos = strpos($className, '.');
81098 if ($dotPos !== \false) {
81099 $className = substr($className, 0, $dotPos);
81100 }
81101 return $className;
81102 }
81103 /**
81104 * @psalm-return list<class-string>
81105 */
81106 private function loadSuiteClassFile(string $suiteClassFile): array
81107 {
81108 if (isset(self::$fileToClassesMap[$suiteClassFile])) {
81109 return self::$fileToClassesMap[$suiteClassFile];
81110 }
81111 if (empty(self::$declaredClasses)) {
81112 self::$declaredClasses = get_declared_classes();
81113 }
81114 require_once $suiteClassFile;
81115 $loadedClasses = array_values(array_diff(get_declared_classes(), self::$declaredClasses));
81116 foreach ($loadedClasses as $loadedClass) {
81117 /** @noinspection PhpUnhandledExceptionInspection */
81118 $class = new ReflectionClass($loadedClass);
81119 if (!isset(self::$fileToClassesMap[$class->getFileName()])) {
81120 self::$fileToClassesMap[$class->getFileName()] = [];
81121 }
81122 self::$fileToClassesMap[$class->getFileName()][] = $class->getName();
81123 }
81124 self::$declaredClasses = get_declared_classes();
81125 if (empty($loadedClasses)) {
81126 return self::$declaredClasses;
81127 }
81128 return $loadedClasses;
81129 }
81130 }
81131 <?php
81132
81133 declare (strict_types=1);
81134 /*
81135 * This file is part of PHPUnit.
81136 *
81137 * (c) Sebastian Bergmann <sebastian@phpunit.de>
81138 *
81139 * For the full copyright and license information, please view the LICENSE
81140 * file that was distributed with this source code.
81141 */
81142 namespace PHPUnit\Runner;
81143
81144 use function array_diff;
81145 use function array_merge;
81146 use function array_reverse;
81147 use function array_splice;
81148 use function assert;
81149 use function count;
81150 use function in_array;
81151 use function max;
81152 use function shuffle;
81153 use function usort;
81154 use PHPUnit\Framework\DataProviderTestSuite;
81155 use PHPUnit\Framework\Reorderable;
81156 use PHPUnit\Framework\Test;
81157 use PHPUnit\Framework\TestCase;
81158 use PHPUnit\Framework\TestSuite;
81159 use PHPUnit\Runner\ResultCache\NullResultCache;
81160 use PHPUnit\Runner\ResultCache\ResultCache;
81161 /**
81162 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
81163 *
81164 * @internal This class is not covered by the backward compatibility promise for PHPUnit
81165 */
81166 final class TestSuiteSorter
81167 {
81168 /**
81169 * @var int
81170 */
81171 public const ORDER_DEFAULT = 0;
81172 /**
81173 * @var int
81174 */
81175 public const ORDER_RANDOMIZED = 1;
81176 /**
81177 * @var int
81178 */
81179 public const ORDER_REVERSED = 2;
81180 /**
81181 * @var int
81182 */
81183 public const ORDER_DEFECTS_FIRST = 3;
81184 /**
81185 * @var int
81186 */
81187 public const ORDER_DURATION = 4;
81188 /**
81189 * @var int
81190 */
81191 public const ORDER_SIZE = 5;
81192 private const SIZE_SORT_WEIGHT = ['small' => 1, 'medium' => 2, 'large' => 3, 'unknown' => 4];
81193 /**
81194 * @psalm-var array<string, int> Associative array of (string => DEFECT_SORT_WEIGHT) elements
81195 */
81196 private array $defectSortOrder = [];
81197 private readonly ResultCache $cache;
81198 public function __construct(?ResultCache $cache = null)
81199 {
81200 $this->cache = $cache ?? new NullResultCache();
81201 }
81202 /**
81203 * @throws Exception
81204 */
81205 public function reorderTestsInSuite(Test $suite, int $order, bool $resolveDependencies, int $orderDefects): void
81206 {
81207 $allowedOrders = [self::ORDER_DEFAULT, self::ORDER_REVERSED, self::ORDER_RANDOMIZED, self::ORDER_DURATION, self::ORDER_SIZE];
81208 if (!in_array($order, $allowedOrders, \true)) {
81209 // @codeCoverageIgnoreStart
81210 throw new \PHPUnit\Runner\InvalidOrderException();
81211 // @codeCoverageIgnoreEnd
81212 }
81213 $allowedOrderDefects = [self::ORDER_DEFAULT, self::ORDER_DEFECTS_FIRST];
81214 if (!in_array($orderDefects, $allowedOrderDefects, \true)) {
81215 // @codeCoverageIgnoreStart
81216 throw new \PHPUnit\Runner\InvalidOrderException();
81217 // @codeCoverageIgnoreEnd
81218 }
81219 if ($suite instanceof TestSuite) {
81220 foreach ($suite as $_suite) {
81221 $this->reorderTestsInSuite($_suite, $order, $resolveDependencies, $orderDefects);
81222 }
81223 if ($orderDefects === self::ORDER_DEFECTS_FIRST) {
81224 $this->addSuiteToDefectSortOrder($suite);
81225 }
81226 $this->sort($suite, $order, $resolveDependencies, $orderDefects);
81227 }
81228 }
81229 private function sort(TestSuite $suite, int $order, bool $resolveDependencies, int $orderDefects): void
81230 {
81231 if (empty($suite->tests())) {
81232 return;
81233 }
81234 if ($order === self::ORDER_REVERSED) {
81235 $suite->setTests($this->reverse($suite->tests()));
81236 } elseif ($order === self::ORDER_RANDOMIZED) {
81237 $suite->setTests($this->randomize($suite->tests()));
81238 } elseif ($order === self::ORDER_DURATION) {
81239 $suite->setTests($this->sortByDuration($suite->tests()));
81240 } elseif ($order === self::ORDER_SIZE) {
81241 $suite->setTests($this->sortBySize($suite->tests()));
81242 }
81243 if ($orderDefects === self::ORDER_DEFECTS_FIRST) {
81244 $suite->setTests($this->sortDefectsFirst($suite->tests()));
81245 }
81246 if ($resolveDependencies && !$suite instanceof DataProviderTestSuite) {
81247 $tests = $suite->tests();
81248 $suite->setTests($this->resolveDependencies($tests));
81249 }
81250 }
81251 private function addSuiteToDefectSortOrder(TestSuite $suite): void
81252 {
81253 $max = 0;
81254 foreach ($suite->tests() as $test) {
81255 assert($test instanceof Reorderable);
81256 if (!isset($this->defectSortOrder[$test->sortId()])) {
81257 $this->defectSortOrder[$test->sortId()] = $this->cache->status($test->sortId())->asInt();
81258 $max = max($max, $this->defectSortOrder[$test->sortId()]);
81259 }
81260 }
81261 $this->defectSortOrder[$suite->sortId()] = $max;
81262 }
81263 private function reverse(array $tests): array
81264 {
81265 return array_reverse($tests);
81266 }
81267 private function randomize(array $tests): array
81268 {
81269 shuffle($tests);
81270 return $tests;
81271 }
81272 private function sortDefectsFirst(array $tests): array
81273 {
81274 usort($tests, fn($left, $right) => $this->cmpDefectPriorityAndTime($left, $right));
81275 return $tests;
81276 }
81277 private function sortByDuration(array $tests): array
81278 {
81279 usort($tests, fn($left, $right) => $this->cmpDuration($left, $right));
81280 return $tests;
81281 }
81282 private function sortBySize(array $tests): array
81283 {
81284 usort($tests, fn($left, $right) => $this->cmpSize($left, $right));
81285 return $tests;
81286 }
81287 /**
81288 * Comparator callback function to sort tests for "reach failure as fast as possible".
81289 *
81290 * 1. sort tests by defect weight defined in self::DEFECT_SORT_WEIGHT
81291 * 2. when tests are equally defective, sort the fastest to the front
81292 * 3. do not reorder successful tests
81293 */
81294 private function cmpDefectPriorityAndTime(Test $a, Test $b): int
81295 {
81296 assert($a instanceof Reorderable);
81297 assert($b instanceof Reorderable);
81298 $priorityA = $this->defectSortOrder[$a->sortId()] ?? 0;
81299 $priorityB = $this->defectSortOrder[$b->sortId()] ?? 0;
81300 if ($priorityB <=> $priorityA) {
81301 // Sort defect weight descending
81302 return $priorityB <=> $priorityA;
81303 }
81304 if ($priorityA || $priorityB) {
81305 return $this->cmpDuration($a, $b);
81306 }
81307 // do not change execution order
81308 return 0;
81309 }
81310 /**
81311 * Compares test duration for sorting tests by duration ascending.
81312 */
81313 private function cmpDuration(Test $a, Test $b): int
81314 {
81315 assert($a instanceof Reorderable);
81316 assert($b instanceof Reorderable);
81317 return $this->cache->time($a->sortId()) <=> $this->cache->time($b->sortId());
81318 }
81319 /**
81320 * Compares test size for sorting tests small->medium->large->unknown.
81321 */
81322 private function cmpSize(Test $a, Test $b): int
81323 {
81324 $sizeA = $a instanceof TestCase || $a instanceof DataProviderTestSuite ? $a->size()->asString() : 'unknown';
81325 $sizeB = $b instanceof TestCase || $b instanceof DataProviderTestSuite ? $b->size()->asString() : 'unknown';
81326 return self::SIZE_SORT_WEIGHT[$sizeA] <=> self::SIZE_SORT_WEIGHT[$sizeB];
81327 }
81328 /**
81329 * Reorder Tests within a TestCase in such a way as to resolve as many dependencies as possible.
81330 * The algorithm will leave the tests in original running order when it can.
81331 * For more details see the documentation for test dependencies.
81332 *
81333 * Short description of algorithm:
81334 * 1. Pick the next Test from remaining tests to be checked for dependencies.
81335 * 2. If the test has no dependencies: mark done, start again from the top
81336 * 3. If the test has dependencies but none left to do: mark done, start again from the top
81337 * 4. When we reach the end add any leftover tests to the end. These will be marked 'skipped' during execution.
81338 *
81339 * @psalm-param array<DataProviderTestSuite|TestCase> $tests
81340 *
81341 * @psalm-return array<DataProviderTestSuite|TestCase>
81342 */
81343 private function resolveDependencies(array $tests): array
81344 {
81345 $newTestOrder = [];
81346 $i = 0;
81347 $provided = [];
81348 do {
81349 if ([] === array_diff($tests[$i]->requires(), $provided)) {
81350 $provided = array_merge($provided, $tests[$i]->provides());
81351 $newTestOrder = array_merge($newTestOrder, array_splice($tests, $i, 1));
81352 $i = 0;
81353 } else {
81354 $i++;
81355 }
81356 } while (!empty($tests) && $i < count($tests));
81357 return array_merge($newTestOrder, $tests);
81358 }
81359 }
81360 <?php
81361
81362 declare (strict_types=1);
81363 /*
81364 * This file is part of PHPUnit.
81365 *
81366 * (c) Sebastian Bergmann <sebastian@phpunit.de>
81367 *
81368 * For the full copyright and license information, please view the LICENSE
81369 * file that was distributed with this source code.
81370 */
81371 namespace PHPUnit\Runner;
81372
81373 use function array_slice;
81374 use function dirname;
81375 use function explode;
81376 use function implode;
81377 use function str_contains;
81378 use PHPUnitPHAR\SebastianBergmann\Version as VersionId;
81379 /**
81380 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
81381 */
81382 final class Version
81383 {
81384 private static string $pharVersion = '10.5.63';
81385 private static string $version = '';
81386 /**
81387 * Returns the current version of PHPUnit.
81388 */
81389 public static function id(): string
81390 {
81391 if (self::$pharVersion !== '') {
81392 return self::$pharVersion;
81393 }
81394 if (self::$version === '') {
81395 self::$version = (new VersionId('10.5.63', dirname(__DIR__, 2)))->asString();
81396 }
81397 return self::$version;
81398 }
81399 public static function series(): string
81400 {
81401 if (str_contains(self::id(), '-')) {
81402 $version = explode('-', self::id(), 2)[0];
81403 } else {
81404 $version = self::id();
81405 }
81406 return implode('.', array_slice(explode('.', $version), 0, 2));
81407 }
81408 public static function majorVersionNumber(): int
81409 {
81410 return (int) explode('.', self::series())[0];
81411 }
81412 public static function getVersionString(): string
81413 {
81414 return 'PHPUnit ' . self::id() . ' by Sebastian Bergmann and contributors.';
81415 }
81416 }
81417 <?php
81418
81419 declare (strict_types=1);
81420 /*
81421 * This file is part of PHPUnit.
81422 *
81423 * (c) Sebastian Bergmann <sebastian@phpunit.de>
81424 *
81425 * For the full copyright and license information, please view the LICENSE
81426 * file that was distributed with this source code.
81427 */
81428 namespace PHPUnit\TextUI;
81429
81430 use const PHP_EOL;
81431 use const PHP_VERSION;
81432 use function is_file;
81433 use function is_readable;
81434 use function printf;
81435 use function realpath;
81436 use function sprintf;
81437 use function trim;
81438 use function unlink;
81439 use PHPUnit\Event\EventFacadeIsSealedException;
81440 use PHPUnit\Event\Facade as EventFacade;
81441 use PHPUnit\Event\UnknownSubscriberTypeException;
81442 use PHPUnit\Framework\TestSuite;
81443 use PHPUnit\Logging\EventLogger;
81444 use PHPUnit\Logging\JUnit\JunitXmlLogger;
81445 use PHPUnit\Logging\TeamCity\TeamCityLogger;
81446 use PHPUnit\Logging\TestDox\HtmlRenderer as TestDoxHtmlRenderer;
81447 use PHPUnit\Logging\TestDox\PlainTextRenderer as TestDoxTextRenderer;
81448 use PHPUnit\Logging\TestDox\TestResultCollector as TestDoxResultCollector;
81449 use PHPUnit\Metadata\Api\CodeCoverage as CodeCoverageMetadataApi;
81450 use PHPUnit\Runner\Baseline\CannotLoadBaselineException;
81451 use PHPUnit\Runner\Baseline\Generator as BaselineGenerator;
81452 use PHPUnit\Runner\Baseline\Reader;
81453 use PHPUnit\Runner\Baseline\Writer;
81454 use PHPUnit\Runner\CodeCoverage;
81455 use PHPUnit\Runner\DirectoryDoesNotExistException;
81456 use PHPUnit\Runner\ErrorHandler;
81457 use PHPUnit\Runner\Extension\ExtensionBootstrapper;
81458 use PHPUnit\Runner\Extension\Facade as ExtensionFacade;
81459 use PHPUnit\Runner\Extension\PharLoader;
81460 use PHPUnit\Runner\GarbageCollection\GarbageCollectionHandler;
81461 use PHPUnit\Runner\ResultCache\DefaultResultCache;
81462 use PHPUnit\Runner\ResultCache\NullResultCache;
81463 use PHPUnit\Runner\ResultCache\ResultCache;
81464 use PHPUnit\Runner\ResultCache\ResultCacheHandler;
81465 use PHPUnit\Runner\TestSuiteSorter;
81466 use PHPUnit\Runner\Version;
81467 use PHPUnit\TestRunner\TestResult\Facade as TestResultFacade;
81468 use PHPUnit\TextUI\CliArguments\Builder;
81469 use PHPUnit\TextUI\CliArguments\Configuration as CliConfiguration;
81470 use PHPUnit\TextUI\CliArguments\Exception as ArgumentsException;
81471 use PHPUnit\TextUI\CliArguments\XmlConfigurationFileFinder;
81472 use PHPUnit\TextUI\Command\AtLeastVersionCommand;
81473 use PHPUnit\TextUI\Command\CheckPhpConfigurationCommand;
81474 use PHPUnit\TextUI\Command\GenerateConfigurationCommand;
81475 use PHPUnit\TextUI\Command\ListGroupsCommand;
81476 use PHPUnit\TextUI\Command\ListTestsAsTextCommand;
81477 use PHPUnit\TextUI\Command\ListTestsAsXmlCommand;
81478 use PHPUnit\TextUI\Command\ListTestSuitesCommand;
81479 use PHPUnit\TextUI\Command\MigrateConfigurationCommand;
81480 use PHPUnit\TextUI\Command\Result;
81481 use PHPUnit\TextUI\Command\ShowHelpCommand;
81482 use PHPUnit\TextUI\Command\ShowVersionCommand;
81483 use PHPUnit\TextUI\Command\VersionCheckCommand;
81484 use PHPUnit\TextUI\Command\WarmCodeCoverageCacheCommand;
81485 use PHPUnit\TextUI\Configuration\CodeCoverageFilterRegistry;
81486 use PHPUnit\TextUI\Configuration\Configuration;
81487 use PHPUnit\TextUI\Configuration\PhpHandler;
81488 use PHPUnit\TextUI\Configuration\Registry;
81489 use PHPUnit\TextUI\Configuration\TestSuiteBuilder;
81490 use PHPUnit\TextUI\Output\DefaultPrinter;
81491 use PHPUnit\TextUI\Output\Facade as OutputFacade;
81492 use PHPUnit\TextUI\Output\Printer;
81493 use PHPUnit\TextUI\XmlConfiguration\Configuration as XmlConfiguration;
81494 use PHPUnit\TextUI\XmlConfiguration\DefaultConfiguration;
81495 use PHPUnit\TextUI\XmlConfiguration\Loader;
81496 use PHPUnit\Util\Http\PhpDownloader;
81497 use PHPUnitPHAR\SebastianBergmann\Timer\Timer;
81498 use Throwable;
81499 /**
81500 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
81501 *
81502 * @internal This class is not covered by the backward compatibility promise for PHPUnit
81503 */
81504 final class Application
81505 {
81506 public function run(array $argv): int
81507 {
81508 try {
81509 EventFacade::emitter()->applicationStarted();
81510 $cliConfiguration = $this->buildCliConfiguration($argv);
81511 $pathToXmlConfigurationFile = (new XmlConfigurationFileFinder())->find($cliConfiguration);
81512 $this->executeCommandsThatOnlyRequireCliConfiguration($cliConfiguration, $pathToXmlConfigurationFile);
81513 $xmlConfiguration = $this->loadXmlConfiguration($pathToXmlConfigurationFile);
81514 $configuration = Registry::init($cliConfiguration, $xmlConfiguration);
81515 (new PhpHandler())->handle($configuration->php());
81516 if ($configuration->hasBootstrap()) {
81517 $this->loadBootstrapScript($configuration->bootstrap());
81518 }
81519 $this->executeCommandsThatRequireCompleteConfiguration($configuration, $cliConfiguration);
81520 $testSuite = $this->buildTestSuite($configuration);
81521 $this->executeCommandsThatRequireCliConfigurationAndTestSuite($cliConfiguration, $testSuite);
81522 $this->executeHelpCommandWhenThereIsNothingElseToDo($configuration, $testSuite);
81523 $pharExtensions = null;
81524 $extensionRequiresCodeCoverageCollection = \false;
81525 $extensionReplacesOutput = \false;
81526 $extensionReplacesProgressOutput = \false;
81527 $extensionReplacesResultOutput = \false;
81528 $extensionRequiresExportOfObjects = \false;
81529 if (!$configuration->noExtensions()) {
81530 if ($configuration->hasPharExtensionDirectory()) {
81531 $pharExtensions = (new PharLoader())->loadPharExtensionsInDirectory($configuration->pharExtensionDirectory());
81532 }
81533 $bootstrappedExtensions = $this->bootstrapExtensions($configuration);
81534 $extensionRequiresCodeCoverageCollection = $bootstrappedExtensions['requiresCodeCoverageCollection'];
81535 $extensionReplacesOutput = $bootstrappedExtensions['replacesOutput'];
81536 $extensionReplacesProgressOutput = $bootstrappedExtensions['replacesProgressOutput'];
81537 $extensionReplacesResultOutput = $bootstrappedExtensions['replacesResultOutput'];
81538 $extensionRequiresExportOfObjects = $bootstrappedExtensions['requiresExportOfObjects'];
81539 }
81540 if ($extensionRequiresExportOfObjects) {
81541 EventFacade::emitter()->exportObjects();
81542 }
81543 CodeCoverage::instance()->init($configuration, CodeCoverageFilterRegistry::instance(), $extensionRequiresCodeCoverageCollection);
81544 if (CodeCoverage::instance()->isActive()) {
81545 CodeCoverage::instance()->ignoreLines((new CodeCoverageMetadataApi())->linesToBeIgnored($testSuite));
81546 }
81547 $printer = OutputFacade::init($configuration, $extensionReplacesProgressOutput, $extensionReplacesResultOutput);
81548 if (!$configuration->debug() && !$extensionReplacesOutput) {
81549 $this->writeRuntimeInformation($printer, $configuration);
81550 $this->writePharExtensionInformation($printer, $pharExtensions);
81551 $this->writeRandomSeedInformation($printer, $configuration);
81552 $printer->print(PHP_EOL);
81553 }
81554 if ($configuration->debug()) {
81555 EventFacade::instance()->registerTracer(new EventLogger('php://stdout', \false));
81556 }
81557 $this->registerLogfileWriters($configuration);
81558 $testDoxResultCollector = $this->testDoxResultCollector($configuration);
81559 TestResultFacade::init();
81560 $resultCache = $this->initializeTestResultCache($configuration);
81561 if ($configuration->controlGarbageCollector()) {
81562 new GarbageCollectionHandler(EventFacade::instance(), $configuration->numberOfTestsBeforeGarbageCollection());
81563 }
81564 $baselineGenerator = $this->configureBaseline($configuration);
81565 EventFacade::instance()->seal();
81566 $timer = new Timer();
81567 $timer->start();
81568 $runner = new \PHPUnit\TextUI\TestRunner();
81569 $runner->run($configuration, $resultCache, $testSuite);
81570 $duration = $timer->stop();
81571 $testDoxResult = null;
81572 if (isset($testDoxResultCollector)) {
81573 $testDoxResult = $testDoxResultCollector->testMethodsGroupedByClass();
81574 }
81575 if ($testDoxResult !== null && $configuration->hasLogfileTestdoxHtml()) {
81576 try {
81577 OutputFacade::printerFor($configuration->logfileTestdoxHtml())->print((new TestDoxHtmlRenderer())->render($testDoxResult));
81578 } catch (DirectoryDoesNotExistException|\PHPUnit\TextUI\InvalidSocketException $e) {
81579 EventFacade::emitter()->testRunnerTriggeredPhpunitWarning(sprintf('Cannot log test results in TestDox HTML format to "%s": %s', $configuration->logfileTestdoxHtml(), $e->getMessage()));
81580 }
81581 }
81582 if ($testDoxResult !== null && $configuration->hasLogfileTestdoxText()) {
81583 try {
81584 OutputFacade::printerFor($configuration->logfileTestdoxText())->print((new TestDoxTextRenderer())->render($testDoxResult));
81585 } catch (DirectoryDoesNotExistException|\PHPUnit\TextUI\InvalidSocketException $e) {
81586 EventFacade::emitter()->testRunnerTriggeredPhpunitWarning(sprintf('Cannot log test results in TestDox plain text format to "%s": %s', $configuration->logfileTestdoxText(), $e->getMessage()));
81587 }
81588 }
81589 $result = TestResultFacade::result();
81590 if (!$extensionReplacesResultOutput && !$configuration->debug()) {
81591 OutputFacade::printResult($result, $testDoxResult, $duration);
81592 }
81593 CodeCoverage::instance()->generateReports($printer, $configuration);
81594 if (isset($baselineGenerator)) {
81595 (new Writer())->write($configuration->generateBaseline(), $baselineGenerator->baseline());
81596 $printer->print(sprintf(PHP_EOL . 'Baseline written to %s.' . PHP_EOL, realpath($configuration->generateBaseline())));
81597 }
81598 $shellExitCode = (new \PHPUnit\TextUI\ShellExitCodeCalculator())->calculate($configuration, $result);
81599 EventFacade::emitter()->applicationFinished($shellExitCode);
81600 return $shellExitCode;
81601 // @codeCoverageIgnoreStart
81602 } catch (Throwable $t) {
81603 $this->exitWithCrashMessage($t);
81604 }
81605 // @codeCoverageIgnoreEnd
81606 }
81607 private function execute(\PHPUnit\TextUI\Command\Command $command, bool $requiresResultCollectedFromEvents = \false): never
81608 {
81609 if ($requiresResultCollectedFromEvents) {
81610 try {
81611 TestResultFacade::init();
81612 EventFacade::instance()->seal();
81613 $resultCollectedFromEvents = TestResultFacade::result();
81614 } catch (EventFacadeIsSealedException|UnknownSubscriberTypeException) {
81615 }
81616 }
81617 print Version::getVersionString() . PHP_EOL . PHP_EOL;
81618 $result = $command->execute();
81619 print $result->output();
81620 $shellExitCode = $result->shellExitCode();
81621 if (isset($resultCollectedFromEvents) && $resultCollectedFromEvents->hasTestTriggeredPhpunitErrorEvents()) {
81622 $shellExitCode = Result::EXCEPTION;
81623 print PHP_EOL . PHP_EOL . 'There were errors:' . PHP_EOL;
81624 foreach ($resultCollectedFromEvents->testTriggeredPhpunitErrorEvents() as $events) {
81625 foreach ($events as $event) {
81626 print PHP_EOL . trim($event->message()) . PHP_EOL;
81627 }
81628 }
81629 }
81630 exit($shellExitCode);
81631 }
81632 private function loadBootstrapScript(string $filename): void
81633 {
81634 if (!is_readable($filename)) {
81635 $this->exitWithErrorMessage(sprintf('Cannot open bootstrap script "%s"', $filename));
81636 }
81637 try {
81638 include_once $filename;
81639 } catch (Throwable $t) {
81640 $message = sprintf('Error in bootstrap script: %s:%s%s%s%s', $t::class, PHP_EOL, $t->getMessage(), PHP_EOL, $t->getTraceAsString());
81641 while ($t = $t->getPrevious()) {
81642 $message .= sprintf('%s%sPrevious error: %s:%s%s%s%s', PHP_EOL, PHP_EOL, $t::class, PHP_EOL, $t->getMessage(), PHP_EOL, $t->getTraceAsString());
81643 }
81644 $this->exitWithErrorMessage($message);
81645 }
81646 EventFacade::emitter()->testRunnerBootstrapFinished($filename);
81647 }
81648 private function buildCliConfiguration(array $argv): CliConfiguration
81649 {
81650 try {
81651 $cliConfiguration = (new Builder())->fromParameters($argv);
81652 } catch (ArgumentsException $e) {
81653 $this->exitWithErrorMessage($e->getMessage());
81654 }
81655 return $cliConfiguration;
81656 }
81657 private function loadXmlConfiguration(false|string $configurationFile): XmlConfiguration
81658 {
81659 if ($configurationFile === \false) {
81660 return DefaultConfiguration::create();
81661 }
81662 try {
81663 return (new Loader())->load($configurationFile);
81664 } catch (Throwable $e) {
81665 $this->exitWithErrorMessage($e->getMessage());
81666 }
81667 }
81668 private function buildTestSuite(Configuration $configuration): TestSuite
81669 {
81670 try {
81671 return (new TestSuiteBuilder())->build($configuration);
81672 } catch (\PHPUnit\TextUI\Exception $e) {
81673 $this->exitWithErrorMessage($e->getMessage());
81674 }
81675 }
81676 /**
81677 * @psalm-return array{requiresCodeCoverageCollection: bool, replacesOutput: bool, replacesProgressOutput: bool, replacesResultOutput: bool, requiresExportOfObjects: bool}
81678 */
81679 private function bootstrapExtensions(Configuration $configuration): array
81680 {
81681 $facade = new ExtensionFacade();
81682 $extensionBootstrapper = new ExtensionBootstrapper($configuration, $facade);
81683 foreach ($configuration->extensionBootstrappers() as $bootstrapper) {
81684 $extensionBootstrapper->bootstrap($bootstrapper['className'], $bootstrapper['parameters']);
81685 }
81686 return ['requiresCodeCoverageCollection' => $facade->requiresCodeCoverageCollection(), 'replacesOutput' => $facade->replacesOutput(), 'replacesProgressOutput' => $facade->replacesProgressOutput(), 'replacesResultOutput' => $facade->replacesResultOutput(), 'requiresExportOfObjects' => $facade->requiresExportOfObjects()];
81687 }
81688 private function executeCommandsThatOnlyRequireCliConfiguration(CliConfiguration $cliConfiguration, false|string $configurationFile): void
81689 {
81690 if ($cliConfiguration->generateConfiguration()) {
81691 $this->execute(new GenerateConfigurationCommand());
81692 }
81693 if ($cliConfiguration->migrateConfiguration()) {
81694 if ($configurationFile === \false) {
81695 $this->exitWithErrorMessage('No configuration file found to migrate');
81696 }
81697 $this->execute(new MigrateConfigurationCommand(realpath($configurationFile)));
81698 }
81699 if ($cliConfiguration->hasAtLeastVersion()) {
81700 $this->execute(new AtLeastVersionCommand($cliConfiguration->atLeastVersion()));
81701 }
81702 if ($cliConfiguration->version()) {
81703 $this->execute(new ShowVersionCommand());
81704 }
81705 if ($cliConfiguration->checkPhpConfiguration()) {
81706 $this->execute(new CheckPhpConfigurationCommand());
81707 }
81708 if ($cliConfiguration->checkVersion()) {
81709 $this->execute(new VersionCheckCommand(new PhpDownloader(), Version::majorVersionNumber(), Version::id()));
81710 }
81711 if ($cliConfiguration->help()) {
81712 $this->execute(new ShowHelpCommand(Result::SUCCESS));
81713 }
81714 }
81715 private function executeCommandsThatRequireCliConfigurationAndTestSuite(CliConfiguration $cliConfiguration, TestSuite $testSuite): void
81716 {
81717 if ($cliConfiguration->listGroups()) {
81718 $this->execute(new ListGroupsCommand($testSuite), \true);
81719 }
81720 if ($cliConfiguration->listTests()) {
81721 $this->execute(new ListTestsAsTextCommand($testSuite), \true);
81722 }
81723 if ($cliConfiguration->hasListTestsXml()) {
81724 $this->execute(new ListTestsAsXmlCommand($cliConfiguration->listTestsXml(), $testSuite), \true);
81725 }
81726 }
81727 private function executeCommandsThatRequireCompleteConfiguration(Configuration $configuration, CliConfiguration $cliConfiguration): void
81728 {
81729 if ($cliConfiguration->listSuites()) {
81730 $this->execute(new ListTestSuitesCommand($configuration->testSuite()));
81731 }
81732 if ($cliConfiguration->warmCoverageCache()) {
81733 $this->execute(new WarmCodeCoverageCacheCommand($configuration, CodeCoverageFilterRegistry::instance()));
81734 }
81735 }
81736 private function executeHelpCommandWhenThereIsNothingElseToDo(Configuration $configuration, TestSuite $testSuite): void
81737 {
81738 if ($testSuite->isEmpty() && !$configuration->hasCliArguments() && $configuration->testSuite()->isEmpty()) {
81739 $this->execute(new ShowHelpCommand(Result::FAILURE));
81740 }
81741 }
81742 private function writeRuntimeInformation(Printer $printer, Configuration $configuration): void
81743 {
81744 $printer->print(Version::getVersionString() . PHP_EOL . PHP_EOL);
81745 $runtime = 'PHP ' . PHP_VERSION;
81746 if (CodeCoverage::instance()->isActive()) {
81747 $runtime .= ' with ' . CodeCoverage::instance()->driver()->nameAndVersion();
81748 }
81749 $this->writeMessage($printer, 'Runtime', $runtime);
81750 if ($configuration->hasConfigurationFile()) {
81751 $this->writeMessage($printer, 'Configuration', $configuration->configurationFile());
81752 }
81753 }
81754 /**
81755 * @psalm-param ?list<string> $pharExtensions
81756 */
81757 private function writePharExtensionInformation(Printer $printer, ?array $pharExtensions): void
81758 {
81759 if ($pharExtensions === null) {
81760 return;
81761 }
81762 foreach ($pharExtensions as $extension) {
81763 $this->writeMessage($printer, 'Extension', $extension);
81764 }
81765 }
81766 private function writeMessage(Printer $printer, string $type, string $message): void
81767 {
81768 $printer->print(sprintf("%-15s%s\n", $type . ':', $message));
81769 }
81770 private function writeRandomSeedInformation(Printer $printer, Configuration $configuration): void
81771 {
81772 if ($configuration->executionOrder() === TestSuiteSorter::ORDER_RANDOMIZED) {
81773 $this->writeMessage($printer, 'Random Seed', (string) $configuration->randomOrderSeed());
81774 }
81775 }
81776 /**
81777 * @throws EventFacadeIsSealedException
81778 * @throws UnknownSubscriberTypeException
81779 */
81780 private function registerLogfileWriters(Configuration $configuration): void
81781 {
81782 if ($configuration->hasLogEventsText()) {
81783 if (is_file($configuration->logEventsText())) {
81784 unlink($configuration->logEventsText());
81785 }
81786 EventFacade::instance()->registerTracer(new EventLogger($configuration->logEventsText(), \false));
81787 }
81788 if ($configuration->hasLogEventsVerboseText()) {
81789 if (is_file($configuration->logEventsVerboseText())) {
81790 unlink($configuration->logEventsVerboseText());
81791 }
81792 EventFacade::instance()->registerTracer(new EventLogger($configuration->logEventsVerboseText(), \true));
81793 EventFacade::emitter()->exportObjects();
81794 }
81795 if ($configuration->hasLogfileJunit()) {
81796 try {
81797 new JunitXmlLogger(OutputFacade::printerFor($configuration->logfileJunit()), EventFacade::instance());
81798 } catch (DirectoryDoesNotExistException|\PHPUnit\TextUI\InvalidSocketException $e) {
81799 EventFacade::emitter()->testRunnerTriggeredPhpunitWarning(sprintf('Cannot log test results in JUnit XML format to "%s": %s', $configuration->logfileJunit(), $e->getMessage()));
81800 }
81801 }
81802 if ($configuration->hasLogfileTeamcity()) {
81803 try {
81804 new TeamCityLogger(DefaultPrinter::from($configuration->logfileTeamcity()), EventFacade::instance());
81805 } catch (DirectoryDoesNotExistException|\PHPUnit\TextUI\InvalidSocketException $e) {
81806 EventFacade::emitter()->testRunnerTriggeredPhpunitWarning(sprintf('Cannot log test results in TeamCity format to "%s": %s', $configuration->logfileTeamcity(), $e->getMessage()));
81807 }
81808 }
81809 }
81810 /**
81811 * @throws EventFacadeIsSealedException
81812 * @throws UnknownSubscriberTypeException
81813 */
81814 private function testDoxResultCollector(Configuration $configuration): ?TestDoxResultCollector
81815 {
81816 if ($configuration->hasLogfileTestdoxHtml() || $configuration->hasLogfileTestdoxText() || $configuration->outputIsTestDox()) {
81817 return new TestDoxResultCollector(EventFacade::instance(), $configuration->source());
81818 }
81819 return null;
81820 }
81821 /**
81822 * @throws EventFacadeIsSealedException
81823 * @throws UnknownSubscriberTypeException
81824 */
81825 private function initializeTestResultCache(Configuration $configuration): ResultCache
81826 {
81827 if ($configuration->cacheResult()) {
81828 $cache = new DefaultResultCache($configuration->testResultCacheFile());
81829 new ResultCacheHandler($cache, EventFacade::instance());
81830 return $cache;
81831 }
81832 return new NullResultCache();
81833 }
81834 /**
81835 * @throws EventFacadeIsSealedException
81836 * @throws UnknownSubscriberTypeException
81837 */
81838 private function configureBaseline(Configuration $configuration): ?BaselineGenerator
81839 {
81840 if ($configuration->hasGenerateBaseline()) {
81841 return new BaselineGenerator(EventFacade::instance(), $configuration->source());
81842 }
81843 if ($configuration->source()->useBaseline()) {
81844 /** @psalm-suppress MissingThrowsDocblock */
81845 $baselineFile = $configuration->source()->baseline();
81846 $baseline = null;
81847 try {
81848 $baseline = (new Reader())->read($baselineFile);
81849 } catch (CannotLoadBaselineException $e) {
81850 EventFacade::emitter()->testRunnerTriggeredPhpunitWarning($e->getMessage());
81851 }
81852 if ($baseline !== null) {
81853 ErrorHandler::instance()->use($baseline);
81854 }
81855 }
81856 return null;
81857 }
81858 /**
81859 * @codeCoverageIgnore
81860 */
81861 private function exitWithCrashMessage(Throwable $t): never
81862 {
81863 $message = $t->getMessage();
81864 if (empty(trim($message))) {
81865 $message = '(no message)';
81866 }
81867 printf('%s%sAn error occurred inside PHPUnit.%s%sMessage: %s', PHP_EOL, PHP_EOL, PHP_EOL, PHP_EOL, $message);
81868 $first = \true;
81869 if ($t->getPrevious()) {
81870 $t = $t->getPrevious();
81871 }
81872 do {
81873 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);
81874 $first = \false;
81875 } while ($t = $t->getPrevious());
81876 exit(Result::CRASH);
81877 }
81878 private function exitWithErrorMessage(string $message): never
81879 {
81880 print Version::getVersionString() . PHP_EOL . PHP_EOL . $message . PHP_EOL;
81881 exit(Result::EXCEPTION);
81882 }
81883 }
81884 <?php
81885
81886 declare (strict_types=1);
81887 /*
81888 * This file is part of PHPUnit.
81889 *
81890 * (c) Sebastian Bergmann <sebastian@phpunit.de>
81891 *
81892 * For the full copyright and license information, please view the LICENSE
81893 * file that was distributed with this source code.
81894 */
81895 namespace PHPUnit\TextUI\Command;
81896
81897 /**
81898 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
81899 *
81900 * @internal This interface is not covered by the backward compatibility promise for PHPUnit
81901 */
81902 interface Command
81903 {
81904 public function execute(): \PHPUnit\TextUI\Command\Result;
81905 }
81906 <?php
81907
81908 declare (strict_types=1);
81909 /*
81910 * This file is part of PHPUnit.
81911 *
81912 * (c) Sebastian Bergmann <sebastian@phpunit.de>
81913 *
81914 * For the full copyright and license information, please view the LICENSE
81915 * file that was distributed with this source code.
81916 */
81917 namespace PHPUnit\TextUI\Command;
81918
81919 use function version_compare;
81920 use PHPUnit\Runner\Version;
81921 /**
81922 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
81923 *
81924 * @internal This class is not covered by the backward compatibility promise for PHPUnit
81925 */
81926 final class AtLeastVersionCommand implements \PHPUnit\TextUI\Command\Command
81927 {
81928 private readonly string $version;
81929 public function __construct(string $version)
81930 {
81931 $this->version = $version;
81932 }
81933 public function execute(): \PHPUnit\TextUI\Command\Result
81934 {
81935 if (version_compare(Version::id(), $this->version, '>=')) {
81936 return \PHPUnit\TextUI\Command\Result::from();
81937 }
81938 return \PHPUnit\TextUI\Command\Result::from('', \PHPUnit\TextUI\Command\Result::FAILURE);
81939 }
81940 }
81941 <?php
81942
81943 declare (strict_types=1);
81944 /*
81945 * This file is part of PHPUnit.
81946 *
81947 * (c) Sebastian Bergmann <sebastian@phpunit.de>
81948 *
81949 * For the full copyright and license information, please view the LICENSE
81950 * file that was distributed with this source code.
81951 */
81952 namespace PHPUnit\TextUI\Command;
81953
81954 use const E_ALL;
81955 use const PHP_EOL;
81956 use function extension_loaded;
81957 use function in_array;
81958 use function ini_get;
81959 use function max;
81960 use function sprintf;
81961 use function strlen;
81962 use PHPUnit\Runner\Version;
81963 use PHPUnit\Util\Color;
81964 use PHPUnitPHAR\SebastianBergmann\Environment\Console;
81965 /**
81966 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
81967 *
81968 * @internal This class is not covered by the backward compatibility promise for PHPUnit
81969 */
81970 final class CheckPhpConfigurationCommand implements \PHPUnit\TextUI\Command\Command
81971 {
81972 private readonly bool $colorize;
81973 public function __construct()
81974 {
81975 $this->colorize = (new Console())->hasColorSupport();
81976 }
81977 public function execute(): \PHPUnit\TextUI\Command\Result
81978 {
81979 $lines = [];
81980 $shellExitCode = 0;
81981 foreach ($this->settings() as $name => $setting) {
81982 foreach ($setting['requiredExtensions'] as $extension) {
81983 if (!extension_loaded($extension)) {
81984 // @codeCoverageIgnoreStart
81985 continue 2;
81986 // @codeCoverageIgnoreEnd
81987 }
81988 }
81989 $actualValue = ini_get($name);
81990 if (in_array($actualValue, $setting['expectedValues'], \true)) {
81991 $check = $this->ok();
81992 } else {
81993 $check = $this->notOk($actualValue);
81994 $shellExitCode = 1;
81995 }
81996 $lines[] = [sprintf('%s = %s', $name, $setting['valueForConfiguration']), $check];
81997 }
81998 $maxLength = 0;
81999 foreach ($lines as $line) {
82000 $maxLength = max($maxLength, strlen($line[0]));
82001 }
82002 $buffer = sprintf('Checking whether PHP is configured according to https://docs.phpunit.de/en/%s/installation.html#configuring-php-for-development' . PHP_EOL . PHP_EOL, Version::series());
82003 foreach ($lines as $line) {
82004 $buffer .= sprintf('%-' . $maxLength . 's ... %s' . PHP_EOL, $line[0], $line[1]);
82005 }
82006 return \PHPUnit\TextUI\Command\Result::from($buffer, $shellExitCode);
82007 }
82008 /**
82009 * @return non-empty-string
82010 */
82011 private function ok(): string
82012 {
82013 if (!$this->colorize) {
82014 return 'ok';
82015 }
82016 // @codeCoverageIgnoreStart
82017 return Color::colorizeTextBox('fg-green, bold', 'ok');
82018 // @codeCoverageIgnoreEnd
82019 }
82020 /**
82021 * @return non-empty-string
82022 */
82023 private function notOk(string $actualValue): string
82024 {
82025 $message = sprintf('not ok (%s)', $actualValue);
82026 if (!$this->colorize) {
82027 return $message;
82028 }
82029 // @codeCoverageIgnoreStart
82030 return Color::colorizeTextBox('fg-red, bold', $message);
82031 // @codeCoverageIgnoreEnd
82032 }
82033 /**
82034 * @return non-empty-array<non-empty-string, array{expectedValues: non-empty-list<non-empty-string>, valueForConfiguration: non-empty-string, requiredExtensions: list<non-empty-string>}>
82035 */
82036 private function settings(): array
82037 {
82038 return ['display_errors' => ['expectedValues' => ['1'], 'valueForConfiguration' => 'On', 'requiredExtensions' => []], 'display_startup_errors' => ['expectedValues' => ['1'], 'valueForConfiguration' => 'On', 'requiredExtensions' => []], 'error_reporting' => ['expectedValues' => ['-1', (string) E_ALL], 'valueForConfiguration' => '-1', 'requiredExtensions' => []], 'xdebug.show_exception_trace' => ['expectedValues' => ['0'], 'valueForConfiguration' => '0', 'requiredExtensions' => ['xdebug']], 'zend.assertions' => ['expectedValues' => ['1'], 'valueForConfiguration' => '1', 'requiredExtensions' => []], 'assert.exception' => ['expectedValues' => ['1'], 'valueForConfiguration' => '1', 'requiredExtensions' => []], 'memory_limit' => ['expectedValues' => ['-1'], 'valueForConfiguration' => '-1', 'requiredExtensions' => []]];
82039 }
82040 }
82041 <?php
82042
82043 declare (strict_types=1);
82044 /*
82045 * This file is part of PHPUnit.
82046 *
82047 * (c) Sebastian Bergmann <sebastian@phpunit.de>
82048 *
82049 * For the full copyright and license information, please view the LICENSE
82050 * file that was distributed with this source code.
82051 */
82052 namespace PHPUnit\TextUI\Command;
82053
82054 use const PHP_EOL;
82055 use const STDIN;
82056 use function fgets;
82057 use function file_put_contents;
82058 use function getcwd;
82059 use function sprintf;
82060 use function trim;
82061 use PHPUnit\Runner\Version;
82062 use PHPUnit\TextUI\XmlConfiguration\Generator;
82063 /**
82064 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
82065 *
82066 * @internal This class is not covered by the backward compatibility promise for PHPUnit
82067 */
82068 final class GenerateConfigurationCommand implements \PHPUnit\TextUI\Command\Command
82069 {
82070 public function execute(): \PHPUnit\TextUI\Command\Result
82071 {
82072 print 'Generating phpunit.xml in ' . getcwd() . PHP_EOL . PHP_EOL;
82073 print 'Bootstrap script (relative to path shown above; default: vendor/autoload.php): ';
82074 $bootstrapScript = $this->read();
82075 print 'Tests directory (relative to path shown above; default: tests): ';
82076 $testsDirectory = $this->read();
82077 print 'Source directory (relative to path shown above; default: src): ';
82078 $src = $this->read();
82079 print 'Cache directory (relative to path shown above; default: .phpunit.cache): ';
82080 $cacheDirectory = $this->read();
82081 if ($bootstrapScript === '') {
82082 $bootstrapScript = 'vendor/autoload.php';
82083 }
82084 if ($testsDirectory === '') {
82085 $testsDirectory = 'tests';
82086 }
82087 if ($src === '') {
82088 $src = 'src';
82089 }
82090 if ($cacheDirectory === '') {
82091 $cacheDirectory = '.phpunit.cache';
82092 }
82093 $generator = new Generator();
82094 $result = @file_put_contents('phpunit.xml', $generator->generateDefaultConfiguration(Version::series(), $bootstrapScript, $testsDirectory, $src, $cacheDirectory));
82095 if ($result !== \false) {
82096 return \PHPUnit\TextUI\Command\Result::from(sprintf(PHP_EOL . 'Generated phpunit.xml in %s.' . PHP_EOL . 'Make sure to exclude the %s directory from version control.' . PHP_EOL, getcwd(), $cacheDirectory));
82097 }
82098 // @codeCoverageIgnoreStart
82099 return \PHPUnit\TextUI\Command\Result::from(sprintf(PHP_EOL . 'Could not write phpunit.xml in %s.' . PHP_EOL, getcwd()), \PHPUnit\TextUI\Command\Result::EXCEPTION);
82100 // @codeCoverageIgnoreEnd
82101 }
82102 private function read(): string
82103 {
82104 return trim(fgets(STDIN));
82105 }
82106 }
82107 <?php
82108
82109 declare (strict_types=1);
82110 /*
82111 * This file is part of PHPUnit.
82112 *
82113 * (c) Sebastian Bergmann <sebastian@phpunit.de>
82114 *
82115 * For the full copyright and license information, please view the LICENSE
82116 * file that was distributed with this source code.
82117 */
82118 namespace PHPUnit\TextUI\Command;
82119
82120 use const PHP_EOL;
82121 use function sort;
82122 use function sprintf;
82123 use function str_starts_with;
82124 use PHPUnit\Framework\TestSuite;
82125 use PHPUnit\TextUI\Configuration\Registry;
82126 /**
82127 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
82128 *
82129 * @internal This class is not covered by the backward compatibility promise for PHPUnit
82130 */
82131 final class ListGroupsCommand implements \PHPUnit\TextUI\Command\Command
82132 {
82133 private readonly TestSuite $suite;
82134 public function __construct(TestSuite $suite)
82135 {
82136 $this->suite = $suite;
82137 }
82138 public function execute(): \PHPUnit\TextUI\Command\Result
82139 {
82140 $buffer = $this->warnAboutConflictingOptions();
82141 $buffer .= 'Available test group(s):' . PHP_EOL;
82142 $groups = $this->suite->groups();
82143 sort($groups);
82144 foreach ($groups as $group) {
82145 if (str_starts_with($group, '__phpunit_')) {
82146 continue;
82147 }
82148 $buffer .= sprintf(' - %s' . PHP_EOL, $group);
82149 }
82150 return \PHPUnit\TextUI\Command\Result::from($buffer);
82151 }
82152 private function warnAboutConflictingOptions(): string
82153 {
82154 $buffer = '';
82155 $configuration = Registry::get();
82156 if ($configuration->hasFilter()) {
82157 $buffer .= 'The --filter and --list-groups options cannot be combined, --filter is ignored' . PHP_EOL;
82158 }
82159 if ($configuration->hasGroups()) {
82160 $buffer .= 'The --group and --list-groups options cannot be combined, --group is ignored' . PHP_EOL;
82161 }
82162 if ($configuration->hasExcludeGroups()) {
82163 $buffer .= 'The --exclude-group and --list-groups options cannot be combined, --exclude-group is ignored' . PHP_EOL;
82164 }
82165 if ($configuration->includeTestSuite() !== '') {
82166 $buffer .= 'The --testsuite and --list-groups options cannot be combined, --exclude-group is ignored' . PHP_EOL;
82167 }
82168 if (!empty($buffer)) {
82169 $buffer .= PHP_EOL;
82170 }
82171 return $buffer;
82172 }
82173 }
82174 <?php
82175
82176 declare (strict_types=1);
82177 /*
82178 * This file is part of PHPUnit.
82179 *
82180 * (c) Sebastian Bergmann <sebastian@phpunit.de>
82181 *
82182 * For the full copyright and license information, please view the LICENSE
82183 * file that was distributed with this source code.
82184 */
82185 namespace PHPUnit\TextUI\Command;
82186
82187 use const PHP_EOL;
82188 use function sprintf;
82189 use PHPUnit\TextUI\Configuration\Registry;
82190 use PHPUnit\TextUI\Configuration\TestSuiteCollection;
82191 /**
82192 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
82193 *
82194 * @internal This class is not covered by the backward compatibility promise for PHPUnit
82195 */
82196 final class ListTestSuitesCommand implements \PHPUnit\TextUI\Command\Command
82197 {
82198 private readonly TestSuiteCollection $suites;
82199 public function __construct(TestSuiteCollection $suites)
82200 {
82201 $this->suites = $suites;
82202 }
82203 public function execute(): \PHPUnit\TextUI\Command\Result
82204 {
82205 $buffer = $this->warnAboutConflictingOptions();
82206 $buffer .= 'Available test suite(s):' . PHP_EOL;
82207 foreach ($this->suites as $suite) {
82208 $buffer .= sprintf(' - %s' . PHP_EOL, $suite->name());
82209 }
82210 return \PHPUnit\TextUI\Command\Result::from($buffer);
82211 }
82212 private function warnAboutConflictingOptions(): string
82213 {
82214 $buffer = '';
82215 $configuration = Registry::get();
82216 if ($configuration->hasFilter()) {
82217 $buffer .= 'The --filter and --list-suites options cannot be combined, --filter is ignored' . PHP_EOL;
82218 }
82219 if ($configuration->hasGroups()) {
82220 $buffer .= 'The --group and --list-suites options cannot be combined, --group is ignored' . PHP_EOL;
82221 }
82222 if ($configuration->hasExcludeGroups()) {
82223 $buffer .= 'The --exclude-group and --list-suites options cannot be combined, --exclude-group is ignored' . PHP_EOL;
82224 }
82225 if ($configuration->includeTestSuite() !== '') {
82226 $buffer .= 'The --testsuite and --list-suites options cannot be combined, --testsuite is ignored' . PHP_EOL;
82227 }
82228 if (!empty($buffer)) {
82229 $buffer .= PHP_EOL;
82230 }
82231 return $buffer;
82232 }
82233 }
82234 <?php
82235
82236 declare (strict_types=1);
82237 /*
82238 * This file is part of PHPUnit.
82239 *
82240 * (c) Sebastian Bergmann <sebastian@phpunit.de>
82241 *
82242 * For the full copyright and license information, please view the LICENSE
82243 * file that was distributed with this source code.
82244 */
82245 namespace PHPUnit\TextUI\Command;
82246
82247 use const PHP_EOL;
82248 use function sprintf;
82249 use function str_replace;
82250 use PHPUnit\Framework\TestCase;
82251 use PHPUnit\Framework\TestSuite;
82252 use PHPUnit\Runner\PhptTestCase;
82253 use PHPUnit\TextUI\Configuration\Registry;
82254 use RecursiveIteratorIterator;
82255 /**
82256 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
82257 *
82258 * @internal This class is not covered by the backward compatibility promise for PHPUnit
82259 */
82260 final class ListTestsAsTextCommand implements \PHPUnit\TextUI\Command\Command
82261 {
82262 private readonly TestSuite $suite;
82263 public function __construct(TestSuite $suite)
82264 {
82265 $this->suite = $suite;
82266 }
82267 public function execute(): \PHPUnit\TextUI\Command\Result
82268 {
82269 $buffer = $this->warnAboutConflictingOptions();
82270 $buffer .= 'Available test(s):' . PHP_EOL;
82271 foreach (new RecursiveIteratorIterator($this->suite) as $test) {
82272 if ($test instanceof TestCase) {
82273 $name = sprintf('%s::%s', $test::class, str_replace(' with data set ', '', $test->nameWithDataSet()));
82274 } elseif ($test instanceof PhptTestCase) {
82275 $name = $test->getName();
82276 } else {
82277 continue;
82278 }
82279 $buffer .= sprintf(' - %s' . PHP_EOL, $name);
82280 }
82281 return \PHPUnit\TextUI\Command\Result::from($buffer);
82282 }
82283 private function warnAboutConflictingOptions(): string
82284 {
82285 $buffer = '';
82286 $configuration = Registry::get();
82287 if ($configuration->hasFilter()) {
82288 $buffer .= 'The --filter and --list-tests options cannot be combined, --filter is ignored' . PHP_EOL;
82289 }
82290 if ($configuration->hasGroups()) {
82291 $buffer .= 'The --group and --list-tests options cannot be combined, --group is ignored' . PHP_EOL;
82292 }
82293 if ($configuration->hasExcludeGroups()) {
82294 $buffer .= 'The --exclude-group and --list-tests options cannot be combined, --exclude-group is ignored' . PHP_EOL;
82295 }
82296 if (!empty($buffer)) {
82297 $buffer .= PHP_EOL;
82298 }
82299 return $buffer;
82300 }
82301 }
82302 <?php
82303
82304 declare (strict_types=1);
82305 /*
82306 * This file is part of PHPUnit.
82307 *
82308 * (c) Sebastian Bergmann <sebastian@phpunit.de>
82309 *
82310 * For the full copyright and license information, please view the LICENSE
82311 * file that was distributed with this source code.
82312 */
82313 namespace PHPUnit\TextUI\Command;
82314
82315 use const PHP_EOL;
82316 use function file_put_contents;
82317 use function implode;
82318 use function sprintf;
82319 use function str_replace;
82320 use PHPUnit\Framework\TestCase;
82321 use PHPUnit\Framework\TestSuite;
82322 use PHPUnit\Runner\PhptTestCase;
82323 use PHPUnit\TextUI\Configuration\Registry;
82324 use RecursiveIteratorIterator;
82325 use XMLWriter;
82326 /**
82327 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
82328 *
82329 * @internal This class is not covered by the backward compatibility promise for PHPUnit
82330 */
82331 final class ListTestsAsXmlCommand implements \PHPUnit\TextUI\Command\Command
82332 {
82333 private readonly string $filename;
82334 private readonly TestSuite $suite;
82335 public function __construct(string $filename, TestSuite $suite)
82336 {
82337 $this->filename = $filename;
82338 $this->suite = $suite;
82339 }
82340 public function execute(): \PHPUnit\TextUI\Command\Result
82341 {
82342 $buffer = $this->warnAboutConflictingOptions();
82343 $writer = new XMLWriter();
82344 $writer->openMemory();
82345 $writer->setIndent(\true);
82346 $writer->startDocument();
82347 $writer->startElement('tests');
82348 $currentTestCase = null;
82349 foreach (new RecursiveIteratorIterator($this->suite) as $test) {
82350 if ($test instanceof TestCase) {
82351 if ($test::class !== $currentTestCase) {
82352 if ($currentTestCase !== null) {
82353 $writer->endElement();
82354 }
82355 $writer->startElement('testCaseClass');
82356 $writer->writeAttribute('name', $test::class);
82357 $currentTestCase = $test::class;
82358 }
82359 $writer->startElement('testCaseMethod');
82360 $writer->writeAttribute('id', $test->valueObjectForEvents()->id());
82361 $writer->writeAttribute('name', $test->name());
82362 $writer->writeAttribute('groups', implode(',', $test->groups()));
82363 /**
82364 * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5481
82365 */
82366 if (!empty($test->dataSetAsString())) {
82367 $writer->writeAttribute('dataSet', str_replace(' with data set ', '', $test->dataSetAsString()));
82368 }
82369 $writer->endElement();
82370 continue;
82371 }
82372 if ($test instanceof PhptTestCase) {
82373 if ($currentTestCase !== null) {
82374 $writer->endElement();
82375 $currentTestCase = null;
82376 }
82377 $writer->startElement('phptFile');
82378 $writer->writeAttribute('path', $test->getName());
82379 $writer->endElement();
82380 }
82381 }
82382 if ($currentTestCase !== null) {
82383 $writer->endElement();
82384 }
82385 $writer->endElement();
82386 file_put_contents($this->filename, $writer->outputMemory());
82387 $buffer .= sprintf('Wrote list of tests that would have been run to %s' . PHP_EOL, $this->filename);
82388 return \PHPUnit\TextUI\Command\Result::from($buffer);
82389 }
82390 private function warnAboutConflictingOptions(): string
82391 {
82392 $buffer = '';
82393 $configuration = Registry::get();
82394 if ($configuration->hasFilter()) {
82395 $buffer .= 'The --filter and --list-tests-xml options cannot be combined, --filter is ignored' . PHP_EOL;
82396 }
82397 if ($configuration->hasGroups()) {
82398 $buffer .= 'The --group and --list-tests-xml options cannot be combined, --group is ignored' . PHP_EOL;
82399 }
82400 if ($configuration->hasExcludeGroups()) {
82401 $buffer .= 'The --exclude-group and --list-tests-xml options cannot be combined, --exclude-group is ignored' . PHP_EOL;
82402 }
82403 if (!empty($buffer)) {
82404 $buffer .= PHP_EOL;
82405 }
82406 return $buffer;
82407 }
82408 }
82409 <?php
82410
82411 declare (strict_types=1);
82412 /*
82413 * This file is part of PHPUnit.
82414 *
82415 * (c) Sebastian Bergmann <sebastian@phpunit.de>
82416 *
82417 * For the full copyright and license information, please view the LICENSE
82418 * file that was distributed with this source code.
82419 */
82420 namespace PHPUnit\TextUI\Command;
82421
82422 use const PHP_EOL;
82423 use function copy;
82424 use function file_put_contents;
82425 use function sprintf;
82426 use PHPUnit\TextUI\XmlConfiguration\Migrator;
82427 use Throwable;
82428 /**
82429 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
82430 *
82431 * @internal This class is not covered by the backward compatibility promise for PHPUnit
82432 */
82433 final class MigrateConfigurationCommand implements \PHPUnit\TextUI\Command\Command
82434 {
82435 private readonly string $filename;
82436 public function __construct(string $filename)
82437 {
82438 $this->filename = $filename;
82439 }
82440 public function execute(): \PHPUnit\TextUI\Command\Result
82441 {
82442 try {
82443 $migrated = (new Migrator())->migrate($this->filename);
82444 copy($this->filename, $this->filename . '.bak');
82445 file_put_contents($this->filename, $migrated);
82446 return \PHPUnit\TextUI\Command\Result::from(sprintf('Created backup: %s.bak%sMigrated configuration: %s%s', $this->filename, PHP_EOL, $this->filename, PHP_EOL));
82447 } catch (Throwable $t) {
82448 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);
82449 }
82450 }
82451 }
82452 <?php
82453
82454 declare (strict_types=1);
82455 /*
82456 * This file is part of PHPUnit.
82457 *
82458 * (c) Sebastian Bergmann <sebastian@phpunit.de>
82459 *
82460 * For the full copyright and license information, please view the LICENSE
82461 * file that was distributed with this source code.
82462 */
82463 namespace PHPUnit\TextUI\Command;
82464
82465 use PHPUnit\TextUI\Help;
82466 /**
82467 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
82468 *
82469 * @internal This class is not covered by the backward compatibility promise for PHPUnit
82470 */
82471 final class ShowHelpCommand implements \PHPUnit\TextUI\Command\Command
82472 {
82473 private readonly int $shellExitCode;
82474 public function __construct(int $shellExitCode)
82475 {
82476 $this->shellExitCode = $shellExitCode;
82477 }
82478 public function execute(): \PHPUnit\TextUI\Command\Result
82479 {
82480 return \PHPUnit\TextUI\Command\Result::from((new Help())->generate(), $this->shellExitCode);
82481 }
82482 }
82483 <?php
82484
82485 declare (strict_types=1);
82486 /*
82487 * This file is part of PHPUnit.
82488 *
82489 * (c) Sebastian Bergmann <sebastian@phpunit.de>
82490 *
82491 * For the full copyright and license information, please view the LICENSE
82492 * file that was distributed with this source code.
82493 */
82494 namespace PHPUnit\TextUI\Command;
82495
82496 /**
82497 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
82498 *
82499 * @internal This class is not covered by the backward compatibility promise for PHPUnit
82500 */
82501 final class ShowVersionCommand implements \PHPUnit\TextUI\Command\Command
82502 {
82503 public function execute(): \PHPUnit\TextUI\Command\Result
82504 {
82505 return \PHPUnit\TextUI\Command\Result::from();
82506 }
82507 }
82508 <?php
82509
82510 declare (strict_types=1);
82511 /*
82512 * This file is part of PHPUnit.
82513 *
82514 * (c) Sebastian Bergmann <sebastian@phpunit.de>
82515 *
82516 * For the full copyright and license information, please view the LICENSE
82517 * file that was distributed with this source code.
82518 */
82519 namespace PHPUnit\TextUI\Command;
82520
82521 use const PHP_EOL;
82522 use function assert;
82523 use function sprintf;
82524 use function version_compare;
82525 use PHPUnit\Util\Http\Downloader;
82526 /**
82527 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
82528 *
82529 * @internal This class is not covered by the backward compatibility promise for PHPUnit
82530 */
82531 final class VersionCheckCommand implements \PHPUnit\TextUI\Command\Command
82532 {
82533 private readonly Downloader $downloader;
82534 private readonly int $majorVersionNumber;
82535 private readonly string $versionId;
82536 public function __construct(Downloader $downloader, int $majorVersionNumber, string $versionId)
82537 {
82538 $this->downloader = $downloader;
82539 $this->majorVersionNumber = $majorVersionNumber;
82540 $this->versionId = $versionId;
82541 }
82542 public function execute(): \PHPUnit\TextUI\Command\Result
82543 {
82544 $latestVersion = $this->downloader->download('https://phar.phpunit.de/latest-version-of/phpunit');
82545 assert($latestVersion !== \false);
82546 $latestCompatibleVersion = $this->downloader->download('https://phar.phpunit.de/latest-version-of/phpunit-' . $this->majorVersionNumber);
82547 assert($latestCompatibleVersion !== \false);
82548 $notLatest = version_compare($latestVersion, $this->versionId, '>');
82549 $notLatestCompatible = version_compare($latestCompatibleVersion, $this->versionId, '>');
82550 if (!$notLatest && !$notLatestCompatible) {
82551 return \PHPUnit\TextUI\Command\Result::from('You are using the latest version of PHPUnit.' . PHP_EOL);
82552 }
82553 $buffer = 'You are not using the latest version of PHPUnit.' . PHP_EOL;
82554 if ($notLatestCompatible) {
82555 $buffer .= sprintf('The latest version compatible with PHPUnit %s is PHPUnit %s.' . PHP_EOL, $this->versionId, $latestCompatibleVersion);
82556 }
82557 if ($notLatest) {
82558 $buffer .= sprintf('The latest version is PHPUnit %s.' . PHP_EOL, $latestVersion);
82559 }
82560 return \PHPUnit\TextUI\Command\Result::from($buffer);
82561 }
82562 }
82563 <?php
82564
82565 declare (strict_types=1);
82566 /*
82567 * This file is part of PHPUnit.
82568 *
82569 * (c) Sebastian Bergmann <sebastian@phpunit.de>
82570 *
82571 * For the full copyright and license information, please view the LICENSE
82572 * file that was distributed with this source code.
82573 */
82574 namespace PHPUnit\TextUI\Command;
82575
82576 use const PHP_EOL;
82577 use function printf;
82578 use PHPUnit\TextUI\Configuration\CodeCoverageFilterRegistry;
82579 use PHPUnit\TextUI\Configuration\Configuration;
82580 use PHPUnit\TextUI\Configuration\NoCoverageCacheDirectoryException;
82581 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\StaticAnalysis\CacheWarmer;
82582 use PHPUnitPHAR\SebastianBergmann\Timer\NoActiveTimerException;
82583 use PHPUnitPHAR\SebastianBergmann\Timer\Timer;
82584 /**
82585 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
82586 *
82587 * @internal This class is not covered by the backward compatibility promise for PHPUnit
82588 *
82589 * @codeCoverageIgnore
82590 */
82591 final class WarmCodeCoverageCacheCommand implements \PHPUnit\TextUI\Command\Command
82592 {
82593 private readonly Configuration $configuration;
82594 private readonly CodeCoverageFilterRegistry $codeCoverageFilterRegistry;
82595 public function __construct(Configuration $configuration, CodeCoverageFilterRegistry $codeCoverageFilterRegistry)
82596 {
82597 $this->configuration = $configuration;
82598 $this->codeCoverageFilterRegistry = $codeCoverageFilterRegistry;
82599 }
82600 /**
82601 * @throws NoActiveTimerException
82602 * @throws NoCoverageCacheDirectoryException
82603 */
82604 public function execute(): \PHPUnit\TextUI\Command\Result
82605 {
82606 if (!$this->configuration->hasCoverageCacheDirectory()) {
82607 return \PHPUnit\TextUI\Command\Result::from('Cache for static analysis has not been configured' . PHP_EOL, \PHPUnit\TextUI\Command\Result::FAILURE);
82608 }
82609 $this->codeCoverageFilterRegistry->init($this->configuration, \true);
82610 if (!$this->codeCoverageFilterRegistry->configured()) {
82611 return \PHPUnit\TextUI\Command\Result::from('Filter for code coverage has not been configured' . PHP_EOL, \PHPUnit\TextUI\Command\Result::FAILURE);
82612 }
82613 $timer = new Timer();
82614 $timer->start();
82615 print 'Warming cache for static analysis ... ';
82616 (new CacheWarmer())->warmCache($this->configuration->coverageCacheDirectory(), !$this->configuration->disableCodeCoverageIgnore(), $this->configuration->ignoreDeprecatedCodeUnitsFromCodeCoverage(), $this->codeCoverageFilterRegistry->get());
82617 printf('[%s]%s', $timer->stop()->asString(), PHP_EOL);
82618 return \PHPUnit\TextUI\Command\Result::from();
82619 }
82620 }
82621 <?php
82622
82623 declare (strict_types=1);
82624 /*
82625 * This file is part of PHPUnit.
82626 *
82627 * (c) Sebastian Bergmann <sebastian@phpunit.de>
82628 *
82629 * For the full copyright and license information, please view the LICENSE
82630 * file that was distributed with this source code.
82631 */
82632 namespace PHPUnit\TextUI\Command;
82633
82634 /**
82635 * @psalm-immutable
82636 *
82637 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
82638 *
82639 * @internal This class is not covered by the backward compatibility promise for PHPUnit
82640 */
82641 final class Result
82642 {
82643 public const SUCCESS = 0;
82644 public const FAILURE = 1;
82645 public const EXCEPTION = 2;
82646 public const CRASH = 255;
82647 private readonly string $output;
82648 private readonly int $shellExitCode;
82649 public static function from(string $output = '', int $shellExitCode = self::SUCCESS): self
82650 {
82651 return new self($output, $shellExitCode);
82652 }
82653 private function __construct(string $output, int $shellExitCode)
82654 {
82655 $this->output = $output;
82656 $this->shellExitCode = $shellExitCode;
82657 }
82658 public function output(): string
82659 {
82660 return $this->output;
82661 }
82662 public function shellExitCode(): int
82663 {
82664 return $this->shellExitCode;
82665 }
82666 }
82667 <?php
82668
82669 declare (strict_types=1);
82670 /*
82671 * This file is part of PHPUnit.
82672 *
82673 * (c) Sebastian Bergmann <sebastian@phpunit.de>
82674 *
82675 * For the full copyright and license information, please view the LICENSE
82676 * file that was distributed with this source code.
82677 */
82678 namespace PHPUnit\TextUI\Configuration;
82679
82680 use PHPUnit\TextUI\CliArguments\Builder as CliConfigurationBuilder;
82681 use PHPUnit\TextUI\CliArguments\Exception as CliConfigurationException;
82682 use PHPUnit\TextUI\CliArguments\XmlConfigurationFileFinder;
82683 use PHPUnit\TextUI\XmlConfiguration\DefaultConfiguration;
82684 use PHPUnit\TextUI\XmlConfiguration\Exception as XmlConfigurationException;
82685 use PHPUnit\TextUI\XmlConfiguration\Loader;
82686 /**
82687 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
82688 *
82689 * @codeCoverageIgnore
82690 */
82691 final class Builder
82692 {
82693 /**
82694 * @throws ConfigurationCannotBeBuiltException
82695 */
82696 public function build(array $argv): \PHPUnit\TextUI\Configuration\Configuration
82697 {
82698 try {
82699 $cliConfiguration = (new CliConfigurationBuilder())->fromParameters($argv);
82700 $configurationFile = (new XmlConfigurationFileFinder())->find($cliConfiguration);
82701 $xmlConfiguration = DefaultConfiguration::create();
82702 if ($configurationFile !== \false) {
82703 $xmlConfiguration = (new Loader())->load($configurationFile);
82704 }
82705 return \PHPUnit\TextUI\Configuration\Registry::init($cliConfiguration, $xmlConfiguration);
82706 } catch (CliConfigurationException|XmlConfigurationException $e) {
82707 throw new \PHPUnit\TextUI\Configuration\ConfigurationCannotBeBuiltException($e->getMessage(), $e->getCode(), $e);
82708 }
82709 }
82710 }
82711 <?php
82712
82713 declare (strict_types=1);
82714 /*
82715 * This file is part of PHPUnit.
82716 *
82717 * (c) Sebastian Bergmann <sebastian@phpunit.de>
82718 *
82719 * For the full copyright and license information, please view the LICENSE
82720 * file that was distributed with this source code.
82721 */
82722 namespace PHPUnit\TextUI\CliArguments;
82723
82724 use const DIRECTORY_SEPARATOR;
82725 use function array_map;
82726 use function basename;
82727 use function explode;
82728 use function getcwd;
82729 use function is_file;
82730 use function is_numeric;
82731 use function sprintf;
82732 use PHPUnit\Event\Facade as EventFacade;
82733 use PHPUnit\Runner\TestSuiteSorter;
82734 use PHPUnit\Util\Filesystem;
82735 use PHPUnitPHAR\SebastianBergmann\CliParser\Exception as CliParserException;
82736 use PHPUnitPHAR\SebastianBergmann\CliParser\Parser as CliParser;
82737 /**
82738 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
82739 *
82740 * @internal This class is not covered by the backward compatibility promise for PHPUnit
82741 */
82742 final class Builder
82743 {
82744 private const LONG_OPTIONS = ['atleast-version=', 'bootstrap=', 'cache-result', 'do-not-cache-result', 'cache-directory=', 'cache-result-file=', 'check-version', 'check-php-configuration', 'colors==', 'columns=', 'configuration=', 'coverage-cache=', 'warm-coverage-cache', 'coverage-filter=', 'coverage-clover=', 'coverage-cobertura=', 'coverage-crap4j=', 'coverage-html=', 'coverage-php=', 'coverage-text==', 'only-summary-for-coverage-text', 'show-uncovered-for-coverage-text', 'coverage-xml=', 'path-coverage', 'disallow-test-output', 'display-all-issues', 'display-incomplete', 'display-skipped', 'display-deprecations', 'display-phpunit-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', 'do-not-report-useless-tests', 'dont-report-useless-tests', 'random-order', 'random-order-seed=', 'reverse-order', 'reverse-list', 'static-backup', 'stderr', 'fail-on-all-issues', 'fail-on-deprecation', 'fail-on-phpunit-deprecation', 'fail-on-phpunit-warning', 'fail-on-empty-test-suite', 'fail-on-incomplete', 'fail-on-notice', 'fail-on-risky', 'fail-on-skipped', 'fail-on-warning', 'do-not-fail-on-deprecation', 'do-not-fail-on-phpunit-deprecation', 'do-not-fail-on-phpunit-warning', 'do-not-fail-on-empty-test-suite', 'do-not-fail-on-incomplete', 'do-not-fail-on-notice', 'do-not-fail-on-risky', 'do-not-fail-on-skipped', 'do-not-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'];
82745 private const SHORT_OPTIONS = 'd:c:h';
82746 /**
82747 * @psalm-var array<string, non-negative-int>
82748 */
82749 private array $processed = [];
82750 /**
82751 * @throws Exception
82752 */
82753 public function fromParameters(array $parameters): \PHPUnit\TextUI\CliArguments\Configuration
82754 {
82755 try {
82756 $options = (new CliParser())->parse($parameters, self::SHORT_OPTIONS, self::LONG_OPTIONS);
82757 } catch (CliParserException $e) {
82758 throw new \PHPUnit\TextUI\CliArguments\Exception($e->getMessage(), $e->getCode(), $e);
82759 }
82760 $atLeastVersion = null;
82761 $backupGlobals = null;
82762 $backupStaticProperties = null;
82763 $beStrictAboutChangesToGlobalState = null;
82764 $bootstrap = null;
82765 $cacheDirectory = null;
82766 $cacheResult = null;
82767 $cacheResultFile = null;
82768 $checkPhpConfiguration = \false;
82769 $checkVersion = \false;
82770 $colors = null;
82771 $columns = null;
82772 $configuration = null;
82773 $coverageCacheDirectory = null;
82774 $warmCoverageCache = \false;
82775 $coverageFilter = null;
82776 $coverageClover = null;
82777 $coverageCobertura = null;
82778 $coverageCrap4J = null;
82779 $coverageHtml = null;
82780 $coveragePhp = null;
82781 $coverageText = null;
82782 $coverageTextShowUncoveredFiles = null;
82783 $coverageTextShowOnlySummary = null;
82784 $coverageXml = null;
82785 $pathCoverage = null;
82786 $defaultTimeLimit = null;
82787 $disableCodeCoverageIgnore = null;
82788 $disallowTestOutput = null;
82789 $displayAllIssues = null;
82790 $displayIncomplete = null;
82791 $displaySkipped = null;
82792 $displayDeprecations = null;
82793 $displayPhpunitDeprecations = null;
82794 $displayErrors = null;
82795 $displayNotices = null;
82796 $displayWarnings = null;
82797 $enforceTimeLimit = null;
82798 $excludeGroups = null;
82799 $executionOrder = null;
82800 $executionOrderDefects = null;
82801 $failOnAllIssues = null;
82802 $failOnDeprecation = null;
82803 $failOnPhpunitDeprecation = null;
82804 $failOnPhpunitWarning = null;
82805 $failOnEmptyTestSuite = null;
82806 $failOnIncomplete = null;
82807 $failOnNotice = null;
82808 $failOnRisky = null;
82809 $failOnSkipped = null;
82810 $failOnWarning = null;
82811 $doNotFailOnDeprecation = null;
82812 $doNotFailOnPhpunitDeprecation = null;
82813 $doNotFailOnPhpunitWarning = null;
82814 $doNotFailOnEmptyTestSuite = null;
82815 $doNotFailOnIncomplete = null;
82816 $doNotFailOnNotice = null;
82817 $doNotFailOnRisky = null;
82818 $doNotFailOnSkipped = null;
82819 $doNotFailOnWarning = null;
82820 $stopOnDefect = null;
82821 $stopOnDeprecation = null;
82822 $stopOnError = null;
82823 $stopOnFailure = null;
82824 $stopOnIncomplete = null;
82825 $stopOnNotice = null;
82826 $stopOnRisky = null;
82827 $stopOnSkipped = null;
82828 $stopOnWarning = null;
82829 $filter = null;
82830 $generateBaseline = null;
82831 $useBaseline = null;
82832 $ignoreBaseline = \false;
82833 $generateConfiguration = \false;
82834 $migrateConfiguration = \false;
82835 $groups = null;
82836 $testsCovering = null;
82837 $testsUsing = null;
82838 $help = \false;
82839 $includePath = null;
82840 $iniSettings = [];
82841 $junitLogfile = null;
82842 $listGroups = \false;
82843 $listSuites = \false;
82844 $listTests = \false;
82845 $listTestsXml = null;
82846 $noCoverage = null;
82847 $noExtensions = null;
82848 $noOutput = null;
82849 $noProgress = null;
82850 $noResults = null;
82851 $noLogging = null;
82852 $processIsolation = null;
82853 $randomOrderSeed = null;
82854 $reportUselessTests = null;
82855 $resolveDependencies = null;
82856 $reverseList = null;
82857 $stderr = null;
82858 $strictCoverage = null;
82859 $teamcityLogfile = null;
82860 $testdoxHtmlFile = null;
82861 $testdoxTextFile = null;
82862 $testSuffixes = null;
82863 $testSuite = null;
82864 $excludeTestSuite = null;
82865 $useDefaultConfiguration = \true;
82866 $version = \false;
82867 $logEventsText = null;
82868 $logEventsVerboseText = null;
82869 $printerTeamCity = null;
82870 $printerTestDox = null;
82871 $debug = \false;
82872 foreach ($options[0] as $option) {
82873 $optionAllowedMultipleTimes = \false;
82874 switch ($option[0]) {
82875 case '--colors':
82876 $colors = $option[1] ?: \PHPUnit\TextUI\Configuration\Configuration::COLOR_AUTO;
82877 break;
82878 case '--bootstrap':
82879 $bootstrap = $option[1];
82880 break;
82881 case '--cache-directory':
82882 $cacheDirectory = $option[1];
82883 break;
82884 case '--cache-result':
82885 $cacheResult = \true;
82886 break;
82887 case '--do-not-cache-result':
82888 $cacheResult = \false;
82889 break;
82890 case '--cache-result-file':
82891 $cacheResultFile = $option[1];
82892 break;
82893 case '--columns':
82894 if (is_numeric($option[1])) {
82895 $columns = (int) $option[1];
82896 } elseif ($option[1] === 'max') {
82897 $columns = 'max';
82898 }
82899 break;
82900 case 'c':
82901 case '--configuration':
82902 $configuration = $option[1];
82903 break;
82904 case '--coverage-cache':
82905 $coverageCacheDirectory = $option[1];
82906 break;
82907 case '--warm-coverage-cache':
82908 $warmCoverageCache = \true;
82909 break;
82910 case '--coverage-clover':
82911 $coverageClover = $option[1];
82912 break;
82913 case '--coverage-cobertura':
82914 $coverageCobertura = $option[1];
82915 break;
82916 case '--coverage-crap4j':
82917 $coverageCrap4J = $option[1];
82918 break;
82919 case '--coverage-html':
82920 $coverageHtml = $option[1];
82921 break;
82922 case '--coverage-php':
82923 $coveragePhp = $option[1];
82924 break;
82925 case '--coverage-text':
82926 if ($option[1] === null) {
82927 $option[1] = 'php://stdout';
82928 }
82929 $coverageText = $option[1];
82930 break;
82931 case '--only-summary-for-coverage-text':
82932 $coverageTextShowOnlySummary = \true;
82933 break;
82934 case '--show-uncovered-for-coverage-text':
82935 $coverageTextShowUncoveredFiles = \true;
82936 break;
82937 case '--coverage-xml':
82938 $coverageXml = $option[1];
82939 break;
82940 case '--path-coverage':
82941 $pathCoverage = \true;
82942 break;
82943 case 'd':
82944 $tmp = explode('=', $option[1]);
82945 if (isset($tmp[0])) {
82946 if (isset($tmp[1])) {
82947 $iniSettings[$tmp[0]] = $tmp[1];
82948 } else {
82949 $iniSettings[$tmp[0]] = '1';
82950 }
82951 }
82952 $optionAllowedMultipleTimes = \true;
82953 break;
82954 case 'h':
82955 case '--help':
82956 $help = \true;
82957 break;
82958 case '--filter':
82959 $filter = $option[1];
82960 break;
82961 case '--testsuite':
82962 $testSuite = $option[1];
82963 break;
82964 case '--exclude-testsuite':
82965 $excludeTestSuite = $option[1];
82966 break;
82967 case '--generate-baseline':
82968 $generateBaseline = $option[1];
82969 if (basename($generateBaseline) === $generateBaseline) {
82970 $generateBaseline = getcwd() . DIRECTORY_SEPARATOR . $generateBaseline;
82971 }
82972 break;
82973 case '--use-baseline':
82974 $useBaseline = $option[1];
82975 if (basename($useBaseline) === $useBaseline && !is_file($useBaseline)) {
82976 $useBaseline = getcwd() . DIRECTORY_SEPARATOR . $useBaseline;
82977 }
82978 break;
82979 case '--ignore-baseline':
82980 $ignoreBaseline = \true;
82981 break;
82982 case '--generate-configuration':
82983 $generateConfiguration = \true;
82984 break;
82985 case '--migrate-configuration':
82986 $migrateConfiguration = \true;
82987 break;
82988 case '--group':
82989 $groups = explode(',', $option[1]);
82990 break;
82991 case '--exclude-group':
82992 $excludeGroups = explode(',', $option[1]);
82993 break;
82994 case '--covers':
82995 $testsCovering = array_map('strtolower', explode(',', $option[1]));
82996 break;
82997 case '--uses':
82998 $testsUsing = array_map('strtolower', explode(',', $option[1]));
82999 break;
83000 case '--test-suffix':
83001 $testSuffixes = explode(',', $option[1]);
83002 break;
83003 case '--include-path':
83004 $includePath = $option[1];
83005 break;
83006 case '--list-groups':
83007 $listGroups = \true;
83008 break;
83009 case '--list-suites':
83010 $listSuites = \true;
83011 break;
83012 case '--list-tests':
83013 $listTests = \true;
83014 break;
83015 case '--list-tests-xml':
83016 $listTestsXml = $option[1];
83017 break;
83018 case '--log-junit':
83019 $junitLogfile = $option[1];
83020 break;
83021 case '--log-teamcity':
83022 $teamcityLogfile = $option[1];
83023 break;
83024 case '--order-by':
83025 foreach (explode(',', $option[1]) as $order) {
83026 switch ($order) {
83027 case 'default':
83028 $executionOrder = TestSuiteSorter::ORDER_DEFAULT;
83029 $executionOrderDefects = TestSuiteSorter::ORDER_DEFAULT;
83030 $resolveDependencies = \true;
83031 break;
83032 case 'defects':
83033 $executionOrderDefects = TestSuiteSorter::ORDER_DEFECTS_FIRST;
83034 break;
83035 case 'depends':
83036 $resolveDependencies = \true;
83037 break;
83038 case 'duration':
83039 $executionOrder = TestSuiteSorter::ORDER_DURATION;
83040 break;
83041 case 'no-depends':
83042 $resolveDependencies = \false;
83043 break;
83044 case 'random':
83045 $executionOrder = TestSuiteSorter::ORDER_RANDOMIZED;
83046 break;
83047 case 'reverse':
83048 $executionOrder = TestSuiteSorter::ORDER_REVERSED;
83049 break;
83050 case 'size':
83051 $executionOrder = TestSuiteSorter::ORDER_SIZE;
83052 break;
83053 default:
83054 throw new \PHPUnit\TextUI\CliArguments\Exception(sprintf('unrecognized --order-by option: %s', $order));
83055 }
83056 }
83057 break;
83058 case '--process-isolation':
83059 $processIsolation = \true;
83060 break;
83061 case '--stderr':
83062 $stderr = \true;
83063 break;
83064 case '--fail-on-all-issues':
83065 $failOnAllIssues = \true;
83066 break;
83067 case '--fail-on-deprecation':
83068 $this->warnWhenOptionsConflict($doNotFailOnDeprecation, '--fail-on-deprecation', '--do-not-fail-on-deprecation');
83069 $failOnDeprecation = \true;
83070 break;
83071 case '--fail-on-phpunit-deprecation':
83072 $this->warnWhenOptionsConflict($doNotFailOnPhpunitDeprecation, '--fail-on-phpunit-deprecation', '--do-not-fail-on-phpunit-deprecation');
83073 $failOnPhpunitDeprecation = \true;
83074 break;
83075 case '--fail-on-phpunit-warning':
83076 $this->warnWhenOptionsConflict($doNotFailOnPhpunitWarning, '--fail-on-phpunit-warning', '--do-not-fail-on-phpunit-warning');
83077 $failOnPhpunitWarning = \true;
83078 break;
83079 case '--fail-on-empty-test-suite':
83080 $this->warnWhenOptionsConflict($doNotFailOnEmptyTestSuite, '--fail-on-empty-test-suite', '--do-not-fail-on-empty-test-suite');
83081 $failOnEmptyTestSuite = \true;
83082 break;
83083 case '--fail-on-incomplete':
83084 $this->warnWhenOptionsConflict($doNotFailOnIncomplete, '--fail-on-incomplete', '--do-not-fail-on-incomplete');
83085 $failOnIncomplete = \true;
83086 break;
83087 case '--fail-on-notice':
83088 $this->warnWhenOptionsConflict($doNotFailOnNotice, '--fail-on-notice', '--do-not-fail-on-notice');
83089 $failOnNotice = \true;
83090 break;
83091 case '--fail-on-risky':
83092 $this->warnWhenOptionsConflict($doNotFailOnRisky, '--fail-on-risky', '--do-not-fail-on-risky');
83093 $failOnRisky = \true;
83094 break;
83095 case '--fail-on-skipped':
83096 $this->warnWhenOptionsConflict($doNotFailOnSkipped, '--fail-on-skipped', '--do-not-fail-on-skipped');
83097 $failOnSkipped = \true;
83098 break;
83099 case '--fail-on-warning':
83100 $this->warnWhenOptionsConflict($doNotFailOnWarning, '--fail-on-warning', '--do-not-fail-on-warning');
83101 $failOnWarning = \true;
83102 break;
83103 case '--do-not-fail-on-deprecation':
83104 $this->warnWhenOptionsConflict($failOnDeprecation, '--do-not-fail-on-deprecation', '--fail-on-deprecation');
83105 $doNotFailOnDeprecation = \true;
83106 break;
83107 case '--do-not-fail-on-phpunit-deprecation':
83108 $this->warnWhenOptionsConflict($failOnPhpunitDeprecation, '--do-not-fail-on-phpunit-deprecation', '--fail-on-phpunit-deprecation');
83109 $doNotFailOnPhpunitDeprecation = \true;
83110 break;
83111 case '--do-not-fail-on-phpunit-warning':
83112 $this->warnWhenOptionsConflict($failOnPhpunitWarning, '--do-not-fail-on-phpunit-warning', '--fail-on-phpunit-warning');
83113 $doNotFailOnPhpunitWarning = \true;
83114 break;
83115 case '--do-not-fail-on-empty-test-suite':
83116 $this->warnWhenOptionsConflict($failOnEmptyTestSuite, '--do-not-fail-on-empty-test-suite', '--fail-on-empty-test-suite');
83117 $doNotFailOnEmptyTestSuite = \true;
83118 break;
83119 case '--do-not-fail-on-incomplete':
83120 $this->warnWhenOptionsConflict($failOnIncomplete, '--do-not-fail-on-incomplete', '--fail-on-incomplete');
83121 $doNotFailOnIncomplete = \true;
83122 break;
83123 case '--do-not-fail-on-notice':
83124 $this->warnWhenOptionsConflict($failOnNotice, '--do-not-fail-on-notice', '--fail-on-notice');
83125 $doNotFailOnNotice = \true;
83126 break;
83127 case '--do-not-fail-on-risky':
83128 $this->warnWhenOptionsConflict($failOnRisky, '--do-not-fail-on-risky', '--fail-on-risky');
83129 $doNotFailOnRisky = \true;
83130 break;
83131 case '--do-not-fail-on-skipped':
83132 $this->warnWhenOptionsConflict($failOnSkipped, '--do-not-fail-on-skipped', '--fail-on-skipped');
83133 $doNotFailOnSkipped = \true;
83134 break;
83135 case '--do-not-fail-on-warning':
83136 $this->warnWhenOptionsConflict($failOnWarning, '--do-not-fail-on-warning', '--fail-on-warning');
83137 $doNotFailOnWarning = \true;
83138 break;
83139 case '--stop-on-defect':
83140 $stopOnDefect = \true;
83141 break;
83142 case '--stop-on-deprecation':
83143 $stopOnDeprecation = \true;
83144 break;
83145 case '--stop-on-error':
83146 $stopOnError = \true;
83147 break;
83148 case '--stop-on-failure':
83149 $stopOnFailure = \true;
83150 break;
83151 case '--stop-on-incomplete':
83152 $stopOnIncomplete = \true;
83153 break;
83154 case '--stop-on-notice':
83155 $stopOnNotice = \true;
83156 break;
83157 case '--stop-on-risky':
83158 $stopOnRisky = \true;
83159 break;
83160 case '--stop-on-skipped':
83161 $stopOnSkipped = \true;
83162 break;
83163 case '--stop-on-warning':
83164 $stopOnWarning = \true;
83165 break;
83166 case '--teamcity':
83167 $printerTeamCity = \true;
83168 break;
83169 case '--testdox':
83170 $printerTestDox = \true;
83171 break;
83172 case '--testdox-html':
83173 $testdoxHtmlFile = $option[1];
83174 break;
83175 case '--testdox-text':
83176 $testdoxTextFile = $option[1];
83177 break;
83178 case '--no-configuration':
83179 $useDefaultConfiguration = \false;
83180 break;
83181 case '--no-extensions':
83182 $noExtensions = \true;
83183 break;
83184 case '--no-coverage':
83185 $noCoverage = \true;
83186 break;
83187 case '--no-logging':
83188 $noLogging = \true;
83189 break;
83190 case '--no-output':
83191 $noOutput = \true;
83192 break;
83193 case '--no-progress':
83194 $noProgress = \true;
83195 break;
83196 case '--no-results':
83197 $noResults = \true;
83198 break;
83199 case '--globals-backup':
83200 $backupGlobals = \true;
83201 break;
83202 case '--static-backup':
83203 $backupStaticProperties = \true;
83204 break;
83205 case '--atleast-version':
83206 $atLeastVersion = $option[1];
83207 break;
83208 case '--version':
83209 $version = \true;
83210 break;
83211 case '--do-not-report-useless-tests':
83212 case '--dont-report-useless-tests':
83213 $reportUselessTests = \false;
83214 break;
83215 case '--strict-coverage':
83216 $strictCoverage = \true;
83217 break;
83218 case '--disable-coverage-ignore':
83219 $disableCodeCoverageIgnore = \true;
83220 break;
83221 case '--strict-global-state':
83222 $beStrictAboutChangesToGlobalState = \true;
83223 break;
83224 case '--disallow-test-output':
83225 $disallowTestOutput = \true;
83226 break;
83227 case '--display-all-issues':
83228 $displayAllIssues = \true;
83229 break;
83230 case '--display-incomplete':
83231 $displayIncomplete = \true;
83232 break;
83233 case '--display-skipped':
83234 $displaySkipped = \true;
83235 break;
83236 case '--display-deprecations':
83237 $displayDeprecations = \true;
83238 break;
83239 case '--display-phpunit-deprecations':
83240 $displayPhpunitDeprecations = \true;
83241 break;
83242 case '--display-errors':
83243 $displayErrors = \true;
83244 break;
83245 case '--display-notices':
83246 $displayNotices = \true;
83247 break;
83248 case '--display-warnings':
83249 $displayWarnings = \true;
83250 break;
83251 case '--default-time-limit':
83252 $defaultTimeLimit = (int) $option[1];
83253 break;
83254 case '--enforce-time-limit':
83255 $enforceTimeLimit = \true;
83256 break;
83257 case '--reverse-list':
83258 $reverseList = \true;
83259 break;
83260 case '--check-php-configuration':
83261 $checkPhpConfiguration = \true;
83262 break;
83263 case '--check-version':
83264 $checkVersion = \true;
83265 break;
83266 case '--coverage-filter':
83267 if ($coverageFilter === null) {
83268 $coverageFilter = [];
83269 }
83270 $coverageFilter[] = $option[1];
83271 $optionAllowedMultipleTimes = \true;
83272 break;
83273 case '--random-order':
83274 $executionOrder = TestSuiteSorter::ORDER_RANDOMIZED;
83275 break;
83276 case '--random-order-seed':
83277 $randomOrderSeed = (int) $option[1];
83278 break;
83279 case '--resolve-dependencies':
83280 $resolveDependencies = \true;
83281 break;
83282 case '--ignore-dependencies':
83283 $resolveDependencies = \false;
83284 break;
83285 case '--reverse-order':
83286 $executionOrder = TestSuiteSorter::ORDER_REVERSED;
83287 break;
83288 case '--log-events-text':
83289 $logEventsText = Filesystem::resolveStreamOrFile($option[1]);
83290 if ($logEventsText === \false) {
83291 throw new \PHPUnit\TextUI\CliArguments\Exception(sprintf('The path "%s" specified for the --log-events-text option could not be resolved', $option[1]));
83292 }
83293 break;
83294 case '--log-events-verbose-text':
83295 $logEventsVerboseText = Filesystem::resolveStreamOrFile($option[1]);
83296 if ($logEventsVerboseText === \false) {
83297 throw new \PHPUnit\TextUI\CliArguments\Exception(sprintf('The path "%s" specified for the --log-events-verbose-text option could not be resolved', $option[1]));
83298 }
83299 break;
83300 case '--debug':
83301 $debug = \true;
83302 break;
83303 }
83304 if (!$optionAllowedMultipleTimes) {
83305 $this->markProcessed($option[0]);
83306 }
83307 }
83308 if (empty($iniSettings)) {
83309 $iniSettings = null;
83310 }
83311 if (empty($coverageFilter)) {
83312 $coverageFilter = null;
83313 }
83314 return new \PHPUnit\TextUI\CliArguments\Configuration($options[1], $atLeastVersion, $backupGlobals, $backupStaticProperties, $beStrictAboutChangesToGlobalState, $bootstrap, $cacheDirectory, $cacheResult, $cacheResultFile, $checkPhpConfiguration, $checkVersion, $colors, $columns, $configuration, $coverageClover, $coverageCobertura, $coverageCrap4J, $coverageHtml, $coveragePhp, $coverageText, $coverageTextShowUncoveredFiles, $coverageTextShowOnlySummary, $coverageXml, $pathCoverage, $coverageCacheDirectory, $warmCoverageCache, $defaultTimeLimit, $disableCodeCoverageIgnore, $disallowTestOutput, $enforceTimeLimit, $excludeGroups, $executionOrder, $executionOrderDefects, $failOnAllIssues, $failOnDeprecation, $failOnPhpunitDeprecation, $failOnPhpunitWarning, $failOnEmptyTestSuite, $failOnIncomplete, $failOnNotice, $failOnRisky, $failOnSkipped, $failOnWarning, $doNotFailOnDeprecation, $doNotFailOnPhpunitDeprecation, $doNotFailOnPhpunitWarning, $doNotFailOnEmptyTestSuite, $doNotFailOnIncomplete, $doNotFailOnNotice, $doNotFailOnRisky, $doNotFailOnSkipped, $doNotFailOnWarning, $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, $displayAllIssues, $displayIncomplete, $displaySkipped, $displayDeprecations, $displayPhpunitDeprecations, $displayErrors, $displayNotices, $displayWarnings, $version, $coverageFilter, $logEventsText, $logEventsVerboseText, $printerTeamCity, $printerTestDox, $debug);
83315 }
83316 /**
83317 * @psalm-param non-empty-string $option
83318 */
83319 private function markProcessed(string $option): void
83320 {
83321 if (!isset($this->processed[$option])) {
83322 $this->processed[$option] = 1;
83323 return;
83324 }
83325 $this->processed[$option]++;
83326 if ($this->processed[$option] === 2) {
83327 EventFacade::emitter()->testRunnerTriggeredPhpunitWarning(sprintf('Option %s cannot be used more than once', $option));
83328 }
83329 }
83330 /**
83331 * @psalm-param non-empty-string $option
83332 */
83333 private function warnWhenOptionsConflict(?bool $current, string $option, string $opposite): void
83334 {
83335 if ($current === null) {
83336 return;
83337 }
83338 EventFacade::emitter()->testRunnerTriggeredPhpunitWarning(sprintf('Options %s and %s cannot be used together', $option, $opposite));
83339 }
83340 }
83341 <?php
83342
83343 declare (strict_types=1);
83344 /*
83345 * This file is part of PHPUnit.
83346 *
83347 * (c) Sebastian Bergmann <sebastian@phpunit.de>
83348 *
83349 * For the full copyright and license information, please view the LICENSE
83350 * file that was distributed with this source code.
83351 */
83352 namespace PHPUnit\TextUI\CliArguments;
83353
83354 /**
83355 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
83356 *
83357 * @internal This class is not covered by the backward compatibility promise for PHPUnit
83358 *
83359 * @psalm-immutable
83360 */
83361 final class Configuration
83362 {
83363 /**
83364 * @psalm-var list<non-empty-string>
83365 */
83366 private readonly array $arguments;
83367 private readonly ?string $atLeastVersion;
83368 private readonly ?bool $backupGlobals;
83369 private readonly ?bool $backupStaticProperties;
83370 private readonly ?bool $beStrictAboutChangesToGlobalState;
83371 private readonly ?string $bootstrap;
83372 private readonly ?string $cacheDirectory;
83373 private readonly ?bool $cacheResult;
83374 private readonly ?string $cacheResultFile;
83375 private readonly bool $checkPhpConfiguration;
83376 private readonly bool $checkVersion;
83377 private readonly ?string $colors;
83378 private readonly null|int|string $columns;
83379 private readonly ?string $configurationFile;
83380 private readonly ?array $coverageFilter;
83381 private readonly ?string $coverageClover;
83382 private readonly ?string $coverageCobertura;
83383 private readonly ?string $coverageCrap4J;
83384 private readonly ?string $coverageHtml;
83385 private readonly ?string $coveragePhp;
83386 private readonly ?string $coverageText;
83387 private readonly ?bool $coverageTextShowUncoveredFiles;
83388 private readonly ?bool $coverageTextShowOnlySummary;
83389 private readonly ?string $coverageXml;
83390 private readonly ?bool $pathCoverage;
83391 private readonly ?string $coverageCacheDirectory;
83392 private readonly bool $warmCoverageCache;
83393 private readonly ?int $defaultTimeLimit;
83394 private readonly ?bool $disableCodeCoverageIgnore;
83395 private readonly ?bool $disallowTestOutput;
83396 private readonly ?bool $enforceTimeLimit;
83397 private readonly ?array $excludeGroups;
83398 private readonly ?int $executionOrder;
83399 private readonly ?int $executionOrderDefects;
83400 private readonly ?bool $failOnAllIssues;
83401 private readonly ?bool $failOnDeprecation;
83402 private readonly ?bool $failOnPhpunitDeprecation;
83403 private readonly ?bool $failOnPhpunitWarning;
83404 private readonly ?bool $failOnEmptyTestSuite;
83405 private readonly ?bool $failOnIncomplete;
83406 private readonly ?bool $failOnNotice;
83407 private readonly ?bool $failOnRisky;
83408 private readonly ?bool $failOnSkipped;
83409 private readonly ?bool $failOnWarning;
83410 private readonly ?bool $doNotFailOnDeprecation;
83411 private readonly ?bool $doNotFailOnPhpunitDeprecation;
83412 private readonly ?bool $doNotFailOnPhpunitWarning;
83413 private readonly ?bool $doNotFailOnEmptyTestSuite;
83414 private readonly ?bool $doNotFailOnIncomplete;
83415 private readonly ?bool $doNotFailOnNotice;
83416 private readonly ?bool $doNotFailOnRisky;
83417 private readonly ?bool $doNotFailOnSkipped;
83418 private readonly ?bool $doNotFailOnWarning;
83419 private readonly ?bool $stopOnDefect;
83420 private readonly ?bool $stopOnDeprecation;
83421 private readonly ?bool $stopOnError;
83422 private readonly ?bool $stopOnFailure;
83423 private readonly ?bool $stopOnIncomplete;
83424 private readonly ?bool $stopOnNotice;
83425 private readonly ?bool $stopOnRisky;
83426 private readonly ?bool $stopOnSkipped;
83427 private readonly ?bool $stopOnWarning;
83428 private readonly ?string $filter;
83429 private readonly ?string $generateBaseline;
83430 private readonly ?string $useBaseline;
83431 private readonly bool $ignoreBaseline;
83432 private readonly bool $generateConfiguration;
83433 private readonly bool $migrateConfiguration;
83434 private readonly ?array $groups;
83435 private readonly ?array $testsCovering;
83436 private readonly ?array $testsUsing;
83437 private readonly bool $help;
83438 private readonly ?string $includePath;
83439 private readonly ?array $iniSettings;
83440 private readonly ?string $junitLogfile;
83441 private readonly bool $listGroups;
83442 private readonly bool $listSuites;
83443 private readonly bool $listTests;
83444 private readonly ?string $listTestsXml;
83445 private readonly ?bool $noCoverage;
83446 private readonly ?bool $noExtensions;
83447 private readonly ?bool $noOutput;
83448 private readonly ?bool $noProgress;
83449 private readonly ?bool $noResults;
83450 private readonly ?bool $noLogging;
83451 private readonly ?bool $processIsolation;
83452 private readonly ?int $randomOrderSeed;
83453 private readonly ?bool $reportUselessTests;
83454 private readonly ?bool $resolveDependencies;
83455 private readonly ?bool $reverseList;
83456 private readonly ?bool $stderr;
83457 private readonly ?bool $strictCoverage;
83458 private readonly ?string $teamcityLogfile;
83459 private readonly ?bool $teamCityPrinter;
83460 private readonly ?string $testdoxHtmlFile;
83461 private readonly ?string $testdoxTextFile;
83462 private readonly ?bool $testdoxPrinter;
83463 /**
83464 * @psalm-var ?non-empty-list<non-empty-string>
83465 */
83466 private readonly ?array $testSuffixes;
83467 private readonly ?string $testSuite;
83468 private readonly ?string $excludeTestSuite;
83469 private readonly bool $useDefaultConfiguration;
83470 private readonly ?bool $displayDetailsOnAllIssues;
83471 private readonly ?bool $displayDetailsOnIncompleteTests;
83472 private readonly ?bool $displayDetailsOnSkippedTests;
83473 private readonly ?bool $displayDetailsOnTestsThatTriggerDeprecations;
83474 private readonly ?bool $displayDetailsOnPhpunitDeprecations;
83475 private readonly ?bool $displayDetailsOnTestsThatTriggerErrors;
83476 private readonly ?bool $displayDetailsOnTestsThatTriggerNotices;
83477 private readonly ?bool $displayDetailsOnTestsThatTriggerWarnings;
83478 private readonly bool $version;
83479 private readonly ?string $logEventsText;
83480 private readonly ?string $logEventsVerboseText;
83481 private readonly bool $debug;
83482 /**
83483 * @psalm-param list<non-empty-string> $arguments
83484 * @psalm-param ?non-empty-list<non-empty-string> $testSuffixes
83485 */
83486 public function __construct(array $arguments, ?string $atLeastVersion, ?bool $backupGlobals, ?bool $backupStaticProperties, ?bool $beStrictAboutChangesToGlobalState, ?string $bootstrap, ?string $cacheDirectory, ?bool $cacheResult, ?string $cacheResultFile, bool $checkPhpConfiguration, 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 $failOnAllIssues, ?bool $failOnDeprecation, ?bool $failOnPhpunitDeprecation, ?bool $failOnPhpunitWarning, ?bool $failOnEmptyTestSuite, ?bool $failOnIncomplete, ?bool $failOnNotice, ?bool $failOnRisky, ?bool $failOnSkipped, ?bool $failOnWarning, ?bool $doNotFailOnDeprecation, ?bool $doNotFailOnPhpunitDeprecation, ?bool $doNotFailOnPhpunitWarning, ?bool $doNotFailOnEmptyTestSuite, ?bool $doNotFailOnIncomplete, ?bool $doNotFailOnNotice, ?bool $doNotFailOnRisky, ?bool $doNotFailOnSkipped, ?bool $doNotFailOnWarning, ?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 $displayDetailsOnAllIssues, ?bool $displayDetailsOnIncompleteTests, ?bool $displayDetailsOnSkippedTests, ?bool $displayDetailsOnTestsThatTriggerDeprecations, ?bool $displayDetailsOnPhpunitDeprecations, ?bool $displayDetailsOnTestsThatTriggerErrors, ?bool $displayDetailsOnTestsThatTriggerNotices, ?bool $displayDetailsOnTestsThatTriggerWarnings, bool $version, ?array $coverageFilter, ?string $logEventsText, ?string $logEventsVerboseText, ?bool $printerTeamCity, ?bool $printerTestDox, bool $debug)
83487 {
83488 $this->arguments = $arguments;
83489 $this->atLeastVersion = $atLeastVersion;
83490 $this->backupGlobals = $backupGlobals;
83491 $this->backupStaticProperties = $backupStaticProperties;
83492 $this->beStrictAboutChangesToGlobalState = $beStrictAboutChangesToGlobalState;
83493 $this->bootstrap = $bootstrap;
83494 $this->cacheDirectory = $cacheDirectory;
83495 $this->cacheResult = $cacheResult;
83496 $this->cacheResultFile = $cacheResultFile;
83497 $this->checkPhpConfiguration = $checkPhpConfiguration;
83498 $this->checkVersion = $checkVersion;
83499 $this->colors = $colors;
83500 $this->columns = $columns;
83501 $this->configurationFile = $configurationFile;
83502 $this->coverageFilter = $coverageFilter;
83503 $this->coverageClover = $coverageClover;
83504 $this->coverageCobertura = $coverageCobertura;
83505 $this->coverageCrap4J = $coverageCrap4J;
83506 $this->coverageHtml = $coverageHtml;
83507 $this->coveragePhp = $coveragePhp;
83508 $this->coverageText = $coverageText;
83509 $this->coverageTextShowUncoveredFiles = $coverageTextShowUncoveredFiles;
83510 $this->coverageTextShowOnlySummary = $coverageTextShowOnlySummary;
83511 $this->coverageXml = $coverageXml;
83512 $this->pathCoverage = $pathCoverage;
83513 $this->coverageCacheDirectory = $coverageCacheDirectory;
83514 $this->warmCoverageCache = $warmCoverageCache;
83515 $this->defaultTimeLimit = $defaultTimeLimit;
83516 $this->disableCodeCoverageIgnore = $disableCodeCoverageIgnore;
83517 $this->disallowTestOutput = $disallowTestOutput;
83518 $this->enforceTimeLimit = $enforceTimeLimit;
83519 $this->excludeGroups = $excludeGroups;
83520 $this->executionOrder = $executionOrder;
83521 $this->executionOrderDefects = $executionOrderDefects;
83522 $this->failOnAllIssues = $failOnAllIssues;
83523 $this->failOnDeprecation = $failOnDeprecation;
83524 $this->failOnPhpunitDeprecation = $failOnPhpunitDeprecation;
83525 $this->failOnPhpunitWarning = $failOnPhpunitWarning;
83526 $this->failOnEmptyTestSuite = $failOnEmptyTestSuite;
83527 $this->failOnIncomplete = $failOnIncomplete;
83528 $this->failOnNotice = $failOnNotice;
83529 $this->failOnRisky = $failOnRisky;
83530 $this->failOnSkipped = $failOnSkipped;
83531 $this->failOnWarning = $failOnWarning;
83532 $this->doNotFailOnDeprecation = $doNotFailOnDeprecation;
83533 $this->doNotFailOnPhpunitDeprecation = $doNotFailOnPhpunitDeprecation;
83534 $this->doNotFailOnPhpunitWarning = $doNotFailOnPhpunitWarning;
83535 $this->doNotFailOnEmptyTestSuite = $doNotFailOnEmptyTestSuite;
83536 $this->doNotFailOnIncomplete = $doNotFailOnIncomplete;
83537 $this->doNotFailOnNotice = $doNotFailOnNotice;
83538 $this->doNotFailOnRisky = $doNotFailOnRisky;
83539 $this->doNotFailOnSkipped = $doNotFailOnSkipped;
83540 $this->doNotFailOnWarning = $doNotFailOnWarning;
83541 $this->stopOnDefect = $stopOnDefect;
83542 $this->stopOnDeprecation = $stopOnDeprecation;
83543 $this->stopOnError = $stopOnError;
83544 $this->stopOnFailure = $stopOnFailure;
83545 $this->stopOnIncomplete = $stopOnIncomplete;
83546 $this->stopOnNotice = $stopOnNotice;
83547 $this->stopOnRisky = $stopOnRisky;
83548 $this->stopOnSkipped = $stopOnSkipped;
83549 $this->stopOnWarning = $stopOnWarning;
83550 $this->filter = $filter;
83551 $this->generateBaseline = $generateBaseline;
83552 $this->useBaseline = $useBaseline;
83553 $this->ignoreBaseline = $ignoreBaseline;
83554 $this->generateConfiguration = $generateConfiguration;
83555 $this->migrateConfiguration = $migrateConfiguration;
83556 $this->groups = $groups;
83557 $this->testsCovering = $testsCovering;
83558 $this->testsUsing = $testsUsing;
83559 $this->help = $help;
83560 $this->includePath = $includePath;
83561 $this->iniSettings = $iniSettings;
83562 $this->junitLogfile = $junitLogfile;
83563 $this->listGroups = $listGroups;
83564 $this->listSuites = $listSuites;
83565 $this->listTests = $listTests;
83566 $this->listTestsXml = $listTestsXml;
83567 $this->noCoverage = $noCoverage;
83568 $this->noExtensions = $noExtensions;
83569 $this->noOutput = $noOutput;
83570 $this->noProgress = $noProgress;
83571 $this->noResults = $noResults;
83572 $this->noLogging = $noLogging;
83573 $this->processIsolation = $processIsolation;
83574 $this->randomOrderSeed = $randomOrderSeed;
83575 $this->reportUselessTests = $reportUselessTests;
83576 $this->resolveDependencies = $resolveDependencies;
83577 $this->reverseList = $reverseList;
83578 $this->stderr = $stderr;
83579 $this->strictCoverage = $strictCoverage;
83580 $this->teamcityLogfile = $teamcityLogfile;
83581 $this->testdoxHtmlFile = $testdoxHtmlFile;
83582 $this->testdoxTextFile = $testdoxTextFile;
83583 $this->testSuffixes = $testSuffixes;
83584 $this->testSuite = $testSuite;
83585 $this->excludeTestSuite = $excludeTestSuite;
83586 $this->useDefaultConfiguration = $useDefaultConfiguration;
83587 $this->displayDetailsOnAllIssues = $displayDetailsOnAllIssues;
83588 $this->displayDetailsOnIncompleteTests = $displayDetailsOnIncompleteTests;
83589 $this->displayDetailsOnSkippedTests = $displayDetailsOnSkippedTests;
83590 $this->displayDetailsOnTestsThatTriggerDeprecations = $displayDetailsOnTestsThatTriggerDeprecations;
83591 $this->displayDetailsOnPhpunitDeprecations = $displayDetailsOnPhpunitDeprecations;
83592 $this->displayDetailsOnTestsThatTriggerErrors = $displayDetailsOnTestsThatTriggerErrors;
83593 $this->displayDetailsOnTestsThatTriggerNotices = $displayDetailsOnTestsThatTriggerNotices;
83594 $this->displayDetailsOnTestsThatTriggerWarnings = $displayDetailsOnTestsThatTriggerWarnings;
83595 $this->version = $version;
83596 $this->logEventsText = $logEventsText;
83597 $this->logEventsVerboseText = $logEventsVerboseText;
83598 $this->teamCityPrinter = $printerTeamCity;
83599 $this->testdoxPrinter = $printerTestDox;
83600 $this->debug = $debug;
83601 }
83602 /**
83603 * @psalm-return list<non-empty-string>
83604 */
83605 public function arguments(): array
83606 {
83607 return $this->arguments;
83608 }
83609 /**
83610 * @psalm-assert-if-true !null $this->atLeastVersion
83611 */
83612 public function hasAtLeastVersion(): bool
83613 {
83614 return $this->atLeastVersion !== null;
83615 }
83616 /**
83617 * @throws Exception
83618 */
83619 public function atLeastVersion(): string
83620 {
83621 if (!$this->hasAtLeastVersion()) {
83622 throw new \PHPUnit\TextUI\CliArguments\Exception();
83623 }
83624 return $this->atLeastVersion;
83625 }
83626 /**
83627 * @psalm-assert-if-true !null $this->backupGlobals
83628 */
83629 public function hasBackupGlobals(): bool
83630 {
83631 return $this->backupGlobals !== null;
83632 }
83633 /**
83634 * @throws Exception
83635 */
83636 public function backupGlobals(): bool
83637 {
83638 if (!$this->hasBackupGlobals()) {
83639 throw new \PHPUnit\TextUI\CliArguments\Exception();
83640 }
83641 return $this->backupGlobals;
83642 }
83643 /**
83644 * @psalm-assert-if-true !null $this->backupStaticProperties
83645 */
83646 public function hasBackupStaticProperties(): bool
83647 {
83648 return $this->backupStaticProperties !== null;
83649 }
83650 /**
83651 * @throws Exception
83652 */
83653 public function backupStaticProperties(): bool
83654 {
83655 if (!$this->hasBackupStaticProperties()) {
83656 throw new \PHPUnit\TextUI\CliArguments\Exception();
83657 }
83658 return $this->backupStaticProperties;
83659 }
83660 /**
83661 * @psalm-assert-if-true !null $this->beStrictAboutChangesToGlobalState
83662 */
83663 public function hasBeStrictAboutChangesToGlobalState(): bool
83664 {
83665 return $this->beStrictAboutChangesToGlobalState !== null;
83666 }
83667 /**
83668 * @throws Exception
83669 */
83670 public function beStrictAboutChangesToGlobalState(): bool
83671 {
83672 if (!$this->hasBeStrictAboutChangesToGlobalState()) {
83673 throw new \PHPUnit\TextUI\CliArguments\Exception();
83674 }
83675 return $this->beStrictAboutChangesToGlobalState;
83676 }
83677 /**
83678 * @psalm-assert-if-true !null $this->bootstrap
83679 */
83680 public function hasBootstrap(): bool
83681 {
83682 return $this->bootstrap !== null;
83683 }
83684 /**
83685 * @throws Exception
83686 */
83687 public function bootstrap(): string
83688 {
83689 if (!$this->hasBootstrap()) {
83690 throw new \PHPUnit\TextUI\CliArguments\Exception();
83691 }
83692 return $this->bootstrap;
83693 }
83694 /**
83695 * @psalm-assert-if-true !null $this->cacheDirectory
83696 */
83697 public function hasCacheDirectory(): bool
83698 {
83699 return $this->cacheDirectory !== null;
83700 }
83701 /**
83702 * @throws Exception
83703 */
83704 public function cacheDirectory(): string
83705 {
83706 if (!$this->hasCacheDirectory()) {
83707 throw new \PHPUnit\TextUI\CliArguments\Exception();
83708 }
83709 return $this->cacheDirectory;
83710 }
83711 /**
83712 * @psalm-assert-if-true !null $this->cacheResult
83713 */
83714 public function hasCacheResult(): bool
83715 {
83716 return $this->cacheResult !== null;
83717 }
83718 /**
83719 * @throws Exception
83720 */
83721 public function cacheResult(): bool
83722 {
83723 if (!$this->hasCacheResult()) {
83724 throw new \PHPUnit\TextUI\CliArguments\Exception();
83725 }
83726 return $this->cacheResult;
83727 }
83728 /**
83729 * @psalm-assert-if-true !null $this->cacheResultFile
83730 *
83731 * @deprecated
83732 */
83733 public function hasCacheResultFile(): bool
83734 {
83735 return $this->cacheResultFile !== null;
83736 }
83737 /**
83738 * @throws Exception
83739 *
83740 * @deprecated
83741 */
83742 public function cacheResultFile(): string
83743 {
83744 if (!$this->hasCacheResultFile()) {
83745 throw new \PHPUnit\TextUI\CliArguments\Exception();
83746 }
83747 return $this->cacheResultFile;
83748 }
83749 public function checkPhpConfiguration(): bool
83750 {
83751 return $this->checkPhpConfiguration;
83752 }
83753 public function checkVersion(): bool
83754 {
83755 return $this->checkVersion;
83756 }
83757 /**
83758 * @psalm-assert-if-true !null $this->colors
83759 */
83760 public function hasColors(): bool
83761 {
83762 return $this->colors !== null;
83763 }
83764 /**
83765 * @throws Exception
83766 */
83767 public function colors(): string
83768 {
83769 if (!$this->hasColors()) {
83770 throw new \PHPUnit\TextUI\CliArguments\Exception();
83771 }
83772 return $this->colors;
83773 }
83774 /**
83775 * @psalm-assert-if-true !null $this->columns
83776 */
83777 public function hasColumns(): bool
83778 {
83779 return $this->columns !== null;
83780 }
83781 /**
83782 * @throws Exception
83783 */
83784 public function columns(): int|string
83785 {
83786 if (!$this->hasColumns()) {
83787 throw new \PHPUnit\TextUI\CliArguments\Exception();
83788 }
83789 return $this->columns;
83790 }
83791 /**
83792 * @psalm-assert-if-true !null $this->configurationFile
83793 */
83794 public function hasConfigurationFile(): bool
83795 {
83796 return $this->configurationFile !== null;
83797 }
83798 /**
83799 * @throws Exception
83800 */
83801 public function configurationFile(): string
83802 {
83803 if (!$this->hasConfigurationFile()) {
83804 throw new \PHPUnit\TextUI\CliArguments\Exception();
83805 }
83806 return $this->configurationFile;
83807 }
83808 /**
83809 * @psalm-assert-if-true !null $this->coverageFilter
83810 */
83811 public function hasCoverageFilter(): bool
83812 {
83813 return $this->coverageFilter !== null;
83814 }
83815 /**
83816 * @throws Exception
83817 */
83818 public function coverageFilter(): array
83819 {
83820 if (!$this->hasCoverageFilter()) {
83821 throw new \PHPUnit\TextUI\CliArguments\Exception();
83822 }
83823 return $this->coverageFilter;
83824 }
83825 /**
83826 * @psalm-assert-if-true !null $this->coverageClover
83827 */
83828 public function hasCoverageClover(): bool
83829 {
83830 return $this->coverageClover !== null;
83831 }
83832 /**
83833 * @throws Exception
83834 */
83835 public function coverageClover(): string
83836 {
83837 if (!$this->hasCoverageClover()) {
83838 throw new \PHPUnit\TextUI\CliArguments\Exception();
83839 }
83840 return $this->coverageClover;
83841 }
83842 /**
83843 * @psalm-assert-if-true !null $this->coverageCobertura
83844 */
83845 public function hasCoverageCobertura(): bool
83846 {
83847 return $this->coverageCobertura !== null;
83848 }
83849 /**
83850 * @throws Exception
83851 */
83852 public function coverageCobertura(): string
83853 {
83854 if (!$this->hasCoverageCobertura()) {
83855 throw new \PHPUnit\TextUI\CliArguments\Exception();
83856 }
83857 return $this->coverageCobertura;
83858 }
83859 /**
83860 * @psalm-assert-if-true !null $this->coverageCrap4J
83861 */
83862 public function hasCoverageCrap4J(): bool
83863 {
83864 return $this->coverageCrap4J !== null;
83865 }
83866 /**
83867 * @throws Exception
83868 */
83869 public function coverageCrap4J(): string
83870 {
83871 if (!$this->hasCoverageCrap4J()) {
83872 throw new \PHPUnit\TextUI\CliArguments\Exception();
83873 }
83874 return $this->coverageCrap4J;
83875 }
83876 /**
83877 * @psalm-assert-if-true !null $this->coverageHtml
83878 */
83879 public function hasCoverageHtml(): bool
83880 {
83881 return $this->coverageHtml !== null;
83882 }
83883 /**
83884 * @throws Exception
83885 */
83886 public function coverageHtml(): string
83887 {
83888 if (!$this->hasCoverageHtml()) {
83889 throw new \PHPUnit\TextUI\CliArguments\Exception();
83890 }
83891 return $this->coverageHtml;
83892 }
83893 /**
83894 * @psalm-assert-if-true !null $this->coveragePhp
83895 */
83896 public function hasCoveragePhp(): bool
83897 {
83898 return $this->coveragePhp !== null;
83899 }
83900 /**
83901 * @throws Exception
83902 */
83903 public function coveragePhp(): string
83904 {
83905 if (!$this->hasCoveragePhp()) {
83906 throw new \PHPUnit\TextUI\CliArguments\Exception();
83907 }
83908 return $this->coveragePhp;
83909 }
83910 /**
83911 * @psalm-assert-if-true !null $this->coverageText
83912 */
83913 public function hasCoverageText(): bool
83914 {
83915 return $this->coverageText !== null;
83916 }
83917 /**
83918 * @throws Exception
83919 */
83920 public function coverageText(): string
83921 {
83922 if (!$this->hasCoverageText()) {
83923 throw new \PHPUnit\TextUI\CliArguments\Exception();
83924 }
83925 return $this->coverageText;
83926 }
83927 /**
83928 * @psalm-assert-if-true !null $this->coverageTextShowUncoveredFiles
83929 */
83930 public function hasCoverageTextShowUncoveredFiles(): bool
83931 {
83932 return $this->coverageTextShowUncoveredFiles !== null;
83933 }
83934 /**
83935 * @throws Exception
83936 */
83937 public function coverageTextShowUncoveredFiles(): bool
83938 {
83939 if (!$this->hasCoverageTextShowUncoveredFiles()) {
83940 throw new \PHPUnit\TextUI\CliArguments\Exception();
83941 }
83942 return $this->coverageTextShowUncoveredFiles;
83943 }
83944 /**
83945 * @psalm-assert-if-true !null $this->coverageTextShowOnlySummary
83946 */
83947 public function hasCoverageTextShowOnlySummary(): bool
83948 {
83949 return $this->coverageTextShowOnlySummary !== null;
83950 }
83951 /**
83952 * @throws Exception
83953 */
83954 public function coverageTextShowOnlySummary(): bool
83955 {
83956 if (!$this->hasCoverageTextShowOnlySummary()) {
83957 throw new \PHPUnit\TextUI\CliArguments\Exception();
83958 }
83959 return $this->coverageTextShowOnlySummary;
83960 }
83961 /**
83962 * @psalm-assert-if-true !null $this->coverageXml
83963 */
83964 public function hasCoverageXml(): bool
83965 {
83966 return $this->coverageXml !== null;
83967 }
83968 /**
83969 * @throws Exception
83970 */
83971 public function coverageXml(): string
83972 {
83973 if (!$this->hasCoverageXml()) {
83974 throw new \PHPUnit\TextUI\CliArguments\Exception();
83975 }
83976 return $this->coverageXml;
83977 }
83978 /**
83979 * @psalm-assert-if-true !null $this->pathCoverage
83980 */
83981 public function hasPathCoverage(): bool
83982 {
83983 return $this->pathCoverage !== null;
83984 }
83985 /**
83986 * @throws Exception
83987 */
83988 public function pathCoverage(): bool
83989 {
83990 if (!$this->hasPathCoverage()) {
83991 throw new \PHPUnit\TextUI\CliArguments\Exception();
83992 }
83993 return $this->pathCoverage;
83994 }
83995 /**
83996 * @psalm-assert-if-true !null $this->coverageCacheDirectory
83997 *
83998 * @deprecated
83999 */
84000 public function hasCoverageCacheDirectory(): bool
84001 {
84002 return $this->coverageCacheDirectory !== null;
84003 }
84004 /**
84005 * @throws Exception
84006 *
84007 * @deprecated
84008 */
84009 public function coverageCacheDirectory(): string
84010 {
84011 if (!$this->hasCoverageCacheDirectory()) {
84012 throw new \PHPUnit\TextUI\CliArguments\Exception();
84013 }
84014 return $this->coverageCacheDirectory;
84015 }
84016 public function warmCoverageCache(): bool
84017 {
84018 return $this->warmCoverageCache;
84019 }
84020 /**
84021 * @psalm-assert-if-true !null $this->defaultTimeLimit
84022 */
84023 public function hasDefaultTimeLimit(): bool
84024 {
84025 return $this->defaultTimeLimit !== null;
84026 }
84027 /**
84028 * @throws Exception
84029 */
84030 public function defaultTimeLimit(): int
84031 {
84032 if (!$this->hasDefaultTimeLimit()) {
84033 throw new \PHPUnit\TextUI\CliArguments\Exception();
84034 }
84035 return $this->defaultTimeLimit;
84036 }
84037 /**
84038 * @psalm-assert-if-true !null $this->disableCodeCoverageIgnore
84039 */
84040 public function hasDisableCodeCoverageIgnore(): bool
84041 {
84042 return $this->disableCodeCoverageIgnore !== null;
84043 }
84044 /**
84045 * @throws Exception
84046 */
84047 public function disableCodeCoverageIgnore(): bool
84048 {
84049 if (!$this->hasDisableCodeCoverageIgnore()) {
84050 throw new \PHPUnit\TextUI\CliArguments\Exception();
84051 }
84052 return $this->disableCodeCoverageIgnore;
84053 }
84054 /**
84055 * @psalm-assert-if-true !null $this->disallowTestOutput
84056 */
84057 public function hasDisallowTestOutput(): bool
84058 {
84059 return $this->disallowTestOutput !== null;
84060 }
84061 /**
84062 * @throws Exception
84063 */
84064 public function disallowTestOutput(): bool
84065 {
84066 if (!$this->hasDisallowTestOutput()) {
84067 throw new \PHPUnit\TextUI\CliArguments\Exception();
84068 }
84069 return $this->disallowTestOutput;
84070 }
84071 /**
84072 * @psalm-assert-if-true !null $this->enforceTimeLimit
84073 */
84074 public function hasEnforceTimeLimit(): bool
84075 {
84076 return $this->enforceTimeLimit !== null;
84077 }
84078 /**
84079 * @throws Exception
84080 */
84081 public function enforceTimeLimit(): bool
84082 {
84083 if (!$this->hasEnforceTimeLimit()) {
84084 throw new \PHPUnit\TextUI\CliArguments\Exception();
84085 }
84086 return $this->enforceTimeLimit;
84087 }
84088 /**
84089 * @psalm-assert-if-true !null $this->excludeGroups
84090 */
84091 public function hasExcludeGroups(): bool
84092 {
84093 return $this->excludeGroups !== null;
84094 }
84095 /**
84096 * @throws Exception
84097 */
84098 public function excludeGroups(): array
84099 {
84100 if (!$this->hasExcludeGroups()) {
84101 throw new \PHPUnit\TextUI\CliArguments\Exception();
84102 }
84103 return $this->excludeGroups;
84104 }
84105 /**
84106 * @psalm-assert-if-true !null $this->executionOrder
84107 */
84108 public function hasExecutionOrder(): bool
84109 {
84110 return $this->executionOrder !== null;
84111 }
84112 /**
84113 * @throws Exception
84114 */
84115 public function executionOrder(): int
84116 {
84117 if (!$this->hasExecutionOrder()) {
84118 throw new \PHPUnit\TextUI\CliArguments\Exception();
84119 }
84120 return $this->executionOrder;
84121 }
84122 /**
84123 * @psalm-assert-if-true !null $this->executionOrderDefects
84124 */
84125 public function hasExecutionOrderDefects(): bool
84126 {
84127 return $this->executionOrderDefects !== null;
84128 }
84129 /**
84130 * @throws Exception
84131 */
84132 public function executionOrderDefects(): int
84133 {
84134 if (!$this->hasExecutionOrderDefects()) {
84135 throw new \PHPUnit\TextUI\CliArguments\Exception();
84136 }
84137 return $this->executionOrderDefects;
84138 }
84139 /**
84140 * @psalm-assert-if-true !null $this->failOnAllIssues
84141 */
84142 public function hasFailOnAllIssues(): bool
84143 {
84144 return $this->failOnAllIssues !== null;
84145 }
84146 /**
84147 * @throws Exception
84148 */
84149 public function failOnAllIssues(): bool
84150 {
84151 if (!$this->hasFailOnAllIssues()) {
84152 throw new \PHPUnit\TextUI\CliArguments\Exception();
84153 }
84154 return $this->failOnAllIssues;
84155 }
84156 /**
84157 * @psalm-assert-if-true !null $this->failOnDeprecation
84158 */
84159 public function hasFailOnDeprecation(): bool
84160 {
84161 return $this->failOnDeprecation !== null;
84162 }
84163 /**
84164 * @throws Exception
84165 */
84166 public function failOnDeprecation(): bool
84167 {
84168 if (!$this->hasFailOnDeprecation()) {
84169 throw new \PHPUnit\TextUI\CliArguments\Exception();
84170 }
84171 return $this->failOnDeprecation;
84172 }
84173 /**
84174 * @psalm-assert-if-true !null $this->failOnPhpunitDeprecation
84175 */
84176 public function hasFailOnPhpunitDeprecation(): bool
84177 {
84178 return $this->failOnPhpunitDeprecation !== null;
84179 }
84180 /**
84181 * @throws Exception
84182 */
84183 public function failOnPhpunitDeprecation(): bool
84184 {
84185 if (!$this->hasFailOnPhpunitDeprecation()) {
84186 throw new \PHPUnit\TextUI\CliArguments\Exception();
84187 }
84188 return $this->failOnPhpunitDeprecation;
84189 }
84190 /**
84191 * @psalm-assert-if-true !null $this->failOnPhpunitWarning
84192 */
84193 public function hasFailOnPhpunitWarning(): bool
84194 {
84195 return $this->failOnPhpunitWarning !== null;
84196 }
84197 /**
84198 * @throws Exception
84199 */
84200 public function failOnPhpunitWarning(): bool
84201 {
84202 if (!$this->hasFailOnPhpunitWarning()) {
84203 throw new \PHPUnit\TextUI\CliArguments\Exception();
84204 }
84205 return $this->failOnPhpunitWarning;
84206 }
84207 /**
84208 * @psalm-assert-if-true !null $this->failOnEmptyTestSuite
84209 */
84210 public function hasFailOnEmptyTestSuite(): bool
84211 {
84212 return $this->failOnEmptyTestSuite !== null;
84213 }
84214 /**
84215 * @throws Exception
84216 */
84217 public function failOnEmptyTestSuite(): bool
84218 {
84219 if (!$this->hasFailOnEmptyTestSuite()) {
84220 throw new \PHPUnit\TextUI\CliArguments\Exception();
84221 }
84222 return $this->failOnEmptyTestSuite;
84223 }
84224 /**
84225 * @psalm-assert-if-true !null $this->failOnIncomplete
84226 */
84227 public function hasFailOnIncomplete(): bool
84228 {
84229 return $this->failOnIncomplete !== null;
84230 }
84231 /**
84232 * @throws Exception
84233 */
84234 public function failOnIncomplete(): bool
84235 {
84236 if (!$this->hasFailOnIncomplete()) {
84237 throw new \PHPUnit\TextUI\CliArguments\Exception();
84238 }
84239 return $this->failOnIncomplete;
84240 }
84241 /**
84242 * @psalm-assert-if-true !null $this->failOnNotice
84243 */
84244 public function hasFailOnNotice(): bool
84245 {
84246 return $this->failOnNotice !== null;
84247 }
84248 /**
84249 * @throws Exception
84250 */
84251 public function failOnNotice(): bool
84252 {
84253 if (!$this->hasFailOnNotice()) {
84254 throw new \PHPUnit\TextUI\CliArguments\Exception();
84255 }
84256 return $this->failOnNotice;
84257 }
84258 /**
84259 * @psalm-assert-if-true !null $this->failOnRisky
84260 */
84261 public function hasFailOnRisky(): bool
84262 {
84263 return $this->failOnRisky !== null;
84264 }
84265 /**
84266 * @throws Exception
84267 */
84268 public function failOnRisky(): bool
84269 {
84270 if (!$this->hasFailOnRisky()) {
84271 throw new \PHPUnit\TextUI\CliArguments\Exception();
84272 }
84273 return $this->failOnRisky;
84274 }
84275 /**
84276 * @psalm-assert-if-true !null $this->failOnSkipped
84277 */
84278 public function hasFailOnSkipped(): bool
84279 {
84280 return $this->failOnSkipped !== null;
84281 }
84282 /**
84283 * @throws Exception
84284 */
84285 public function failOnSkipped(): bool
84286 {
84287 if (!$this->hasFailOnSkipped()) {
84288 throw new \PHPUnit\TextUI\CliArguments\Exception();
84289 }
84290 return $this->failOnSkipped;
84291 }
84292 /**
84293 * @psalm-assert-if-true !null $this->failOnWarning
84294 */
84295 public function hasFailOnWarning(): bool
84296 {
84297 return $this->failOnWarning !== null;
84298 }
84299 /**
84300 * @throws Exception
84301 */
84302 public function failOnWarning(): bool
84303 {
84304 if (!$this->hasFailOnWarning()) {
84305 throw new \PHPUnit\TextUI\CliArguments\Exception();
84306 }
84307 return $this->failOnWarning;
84308 }
84309 /**
84310 * @psalm-assert-if-true !null $this->doNotFailOnDeprecation
84311 */
84312 public function hasDoNotFailOnDeprecation(): bool
84313 {
84314 return $this->doNotFailOnDeprecation !== null;
84315 }
84316 /**
84317 * @throws Exception
84318 */
84319 public function doNotFailOnDeprecation(): bool
84320 {
84321 if (!$this->hasDoNotFailOnDeprecation()) {
84322 throw new \PHPUnit\TextUI\CliArguments\Exception();
84323 }
84324 return $this->doNotFailOnDeprecation;
84325 }
84326 /**
84327 * @psalm-assert-if-true !null $this->doNotFailOnPhpunitDeprecation
84328 */
84329 public function hasDoNotFailOnPhpunitDeprecation(): bool
84330 {
84331 return $this->doNotFailOnPhpunitDeprecation !== null;
84332 }
84333 /**
84334 * @throws Exception
84335 */
84336 public function doNotFailOnPhpunitDeprecation(): bool
84337 {
84338 if (!$this->hasDoNotFailOnPhpunitDeprecation()) {
84339 throw new \PHPUnit\TextUI\CliArguments\Exception();
84340 }
84341 return $this->doNotFailOnPhpunitDeprecation;
84342 }
84343 /**
84344 * @psalm-assert-if-true !null $this->doNotFailOnPhpunitWarning
84345 */
84346 public function hasDoNotFailOnPhpunitWarning(): bool
84347 {
84348 return $this->doNotFailOnPhpunitWarning !== null;
84349 }
84350 /**
84351 * @throws Exception
84352 */
84353 public function doNotFailOnPhpunitWarning(): bool
84354 {
84355 if (!$this->hasDoNotFailOnPhpunitWarning()) {
84356 throw new \PHPUnit\TextUI\CliArguments\Exception();
84357 }
84358 return $this->doNotFailOnPhpunitWarning;
84359 }
84360 /**
84361 * @psalm-assert-if-true !null $this->doNotFailOnEmptyTestSuite
84362 */
84363 public function hasDoNotFailOnEmptyTestSuite(): bool
84364 {
84365 return $this->doNotFailOnEmptyTestSuite !== null;
84366 }
84367 /**
84368 * @throws Exception
84369 */
84370 public function doNotFailOnEmptyTestSuite(): bool
84371 {
84372 if (!$this->hasDoNotFailOnEmptyTestSuite()) {
84373 throw new \PHPUnit\TextUI\CliArguments\Exception();
84374 }
84375 return $this->doNotFailOnEmptyTestSuite;
84376 }
84377 /**
84378 * @psalm-assert-if-true !null $this->doNotFailOnIncomplete
84379 */
84380 public function hasDoNotFailOnIncomplete(): bool
84381 {
84382 return $this->doNotFailOnIncomplete !== null;
84383 }
84384 /**
84385 * @throws Exception
84386 */
84387 public function doNotFailOnIncomplete(): bool
84388 {
84389 if (!$this->hasDoNotFailOnIncomplete()) {
84390 throw new \PHPUnit\TextUI\CliArguments\Exception();
84391 }
84392 return $this->doNotFailOnIncomplete;
84393 }
84394 /**
84395 * @psalm-assert-if-true !null $this->doNotFailOnNotice
84396 */
84397 public function hasDoNotFailOnNotice(): bool
84398 {
84399 return $this->doNotFailOnNotice !== null;
84400 }
84401 /**
84402 * @throws Exception
84403 */
84404 public function doNotFailOnNotice(): bool
84405 {
84406 if (!$this->hasDoNotFailOnNotice()) {
84407 throw new \PHPUnit\TextUI\CliArguments\Exception();
84408 }
84409 return $this->doNotFailOnNotice;
84410 }
84411 /**
84412 * @psalm-assert-if-true !null $this->doNotFailOnRisky
84413 */
84414 public function hasDoNotFailOnRisky(): bool
84415 {
84416 return $this->doNotFailOnRisky !== null;
84417 }
84418 /**
84419 * @throws Exception
84420 */
84421 public function doNotFailOnRisky(): bool
84422 {
84423 if (!$this->hasDoNotFailOnRisky()) {
84424 throw new \PHPUnit\TextUI\CliArguments\Exception();
84425 }
84426 return $this->doNotFailOnRisky;
84427 }
84428 /**
84429 * @psalm-assert-if-true !null $this->doNotFailOnSkipped
84430 */
84431 public function hasDoNotFailOnSkipped(): bool
84432 {
84433 return $this->doNotFailOnSkipped !== null;
84434 }
84435 /**
84436 * @throws Exception
84437 */
84438 public function doNotFailOnSkipped(): bool
84439 {
84440 if (!$this->hasDoNotFailOnSkipped()) {
84441 throw new \PHPUnit\TextUI\CliArguments\Exception();
84442 }
84443 return $this->doNotFailOnSkipped;
84444 }
84445 /**
84446 * @psalm-assert-if-true !null $this->doNotFailOnWarning
84447 */
84448 public function hasDoNotFailOnWarning(): bool
84449 {
84450 return $this->doNotFailOnWarning !== null;
84451 }
84452 /**
84453 * @throws Exception
84454 */
84455 public function doNotFailOnWarning(): bool
84456 {
84457 if (!$this->hasDoNotFailOnWarning()) {
84458 throw new \PHPUnit\TextUI\CliArguments\Exception();
84459 }
84460 return $this->doNotFailOnWarning;
84461 }
84462 /**
84463 * @psalm-assert-if-true !null $this->stopOnDefect
84464 */
84465 public function hasStopOnDefect(): bool
84466 {
84467 return $this->stopOnDefect !== null;
84468 }
84469 /**
84470 * @throws Exception
84471 */
84472 public function stopOnDefect(): bool
84473 {
84474 if (!$this->hasStopOnDefect()) {
84475 throw new \PHPUnit\TextUI\CliArguments\Exception();
84476 }
84477 return $this->stopOnDefect;
84478 }
84479 /**
84480 * @psalm-assert-if-true !null $this->stopOnDeprecation
84481 */
84482 public function hasStopOnDeprecation(): bool
84483 {
84484 return $this->stopOnDeprecation !== null;
84485 }
84486 /**
84487 * @throws Exception
84488 */
84489 public function stopOnDeprecation(): bool
84490 {
84491 if (!$this->hasStopOnDeprecation()) {
84492 throw new \PHPUnit\TextUI\CliArguments\Exception();
84493 }
84494 return $this->stopOnDeprecation;
84495 }
84496 /**
84497 * @psalm-assert-if-true !null $this->stopOnError
84498 */
84499 public function hasStopOnError(): bool
84500 {
84501 return $this->stopOnError !== null;
84502 }
84503 /**
84504 * @throws Exception
84505 */
84506 public function stopOnError(): bool
84507 {
84508 if (!$this->hasStopOnError()) {
84509 throw new \PHPUnit\TextUI\CliArguments\Exception();
84510 }
84511 return $this->stopOnError;
84512 }
84513 /**
84514 * @psalm-assert-if-true !null $this->stopOnFailure
84515 */
84516 public function hasStopOnFailure(): bool
84517 {
84518 return $this->stopOnFailure !== null;
84519 }
84520 /**
84521 * @throws Exception
84522 */
84523 public function stopOnFailure(): bool
84524 {
84525 if (!$this->hasStopOnFailure()) {
84526 throw new \PHPUnit\TextUI\CliArguments\Exception();
84527 }
84528 return $this->stopOnFailure;
84529 }
84530 /**
84531 * @psalm-assert-if-true !null $this->stopOnIncomplete
84532 */
84533 public function hasStopOnIncomplete(): bool
84534 {
84535 return $this->stopOnIncomplete !== null;
84536 }
84537 /**
84538 * @throws Exception
84539 */
84540 public function stopOnIncomplete(): bool
84541 {
84542 if (!$this->hasStopOnIncomplete()) {
84543 throw new \PHPUnit\TextUI\CliArguments\Exception();
84544 }
84545 return $this->stopOnIncomplete;
84546 }
84547 /**
84548 * @psalm-assert-if-true !null $this->stopOnNotice
84549 */
84550 public function hasStopOnNotice(): bool
84551 {
84552 return $this->stopOnNotice !== null;
84553 }
84554 /**
84555 * @throws Exception
84556 */
84557 public function stopOnNotice(): bool
84558 {
84559 if (!$this->hasStopOnNotice()) {
84560 throw new \PHPUnit\TextUI\CliArguments\Exception();
84561 }
84562 return $this->stopOnNotice;
84563 }
84564 /**
84565 * @psalm-assert-if-true !null $this->stopOnRisky
84566 */
84567 public function hasStopOnRisky(): bool
84568 {
84569 return $this->stopOnRisky !== null;
84570 }
84571 /**
84572 * @throws Exception
84573 */
84574 public function stopOnRisky(): bool
84575 {
84576 if (!$this->hasStopOnRisky()) {
84577 throw new \PHPUnit\TextUI\CliArguments\Exception();
84578 }
84579 return $this->stopOnRisky;
84580 }
84581 /**
84582 * @psalm-assert-if-true !null $this->stopOnSkipped
84583 */
84584 public function hasStopOnSkipped(): bool
84585 {
84586 return $this->stopOnSkipped !== null;
84587 }
84588 /**
84589 * @throws Exception
84590 */
84591 public function stopOnSkipped(): bool
84592 {
84593 if (!$this->hasStopOnSkipped()) {
84594 throw new \PHPUnit\TextUI\CliArguments\Exception();
84595 }
84596 return $this->stopOnSkipped;
84597 }
84598 /**
84599 * @psalm-assert-if-true !null $this->stopOnWarning
84600 */
84601 public function hasStopOnWarning(): bool
84602 {
84603 return $this->stopOnWarning !== null;
84604 }
84605 /**
84606 * @throws Exception
84607 */
84608 public function stopOnWarning(): bool
84609 {
84610 if (!$this->hasStopOnWarning()) {
84611 throw new \PHPUnit\TextUI\CliArguments\Exception();
84612 }
84613 return $this->stopOnWarning;
84614 }
84615 /**
84616 * @psalm-assert-if-true !null $this->filter
84617 */
84618 public function hasFilter(): bool
84619 {
84620 return $this->filter !== null;
84621 }
84622 /**
84623 * @throws Exception
84624 */
84625 public function filter(): string
84626 {
84627 if (!$this->hasFilter()) {
84628 throw new \PHPUnit\TextUI\CliArguments\Exception();
84629 }
84630 return $this->filter;
84631 }
84632 /**
84633 * @psalm-assert-if-true !null $this->generateBaseline
84634 */
84635 public function hasGenerateBaseline(): bool
84636 {
84637 return $this->generateBaseline !== null;
84638 }
84639 /**
84640 * @throws Exception
84641 */
84642 public function generateBaseline(): string
84643 {
84644 if (!$this->hasGenerateBaseline()) {
84645 throw new \PHPUnit\TextUI\CliArguments\Exception();
84646 }
84647 return $this->generateBaseline;
84648 }
84649 /**
84650 * @psalm-assert-if-true !null $this->useBaseline
84651 */
84652 public function hasUseBaseline(): bool
84653 {
84654 return $this->useBaseline !== null;
84655 }
84656 /**
84657 * @throws Exception
84658 */
84659 public function useBaseline(): string
84660 {
84661 if (!$this->hasUseBaseline()) {
84662 throw new \PHPUnit\TextUI\CliArguments\Exception();
84663 }
84664 return $this->useBaseline;
84665 }
84666 public function ignoreBaseline(): bool
84667 {
84668 return $this->ignoreBaseline;
84669 }
84670 public function generateConfiguration(): bool
84671 {
84672 return $this->generateConfiguration;
84673 }
84674 public function migrateConfiguration(): bool
84675 {
84676 return $this->migrateConfiguration;
84677 }
84678 /**
84679 * @psalm-assert-if-true !null $this->groups
84680 */
84681 public function hasGroups(): bool
84682 {
84683 return $this->groups !== null;
84684 }
84685 /**
84686 * @throws Exception
84687 */
84688 public function groups(): array
84689 {
84690 if (!$this->hasGroups()) {
84691 throw new \PHPUnit\TextUI\CliArguments\Exception();
84692 }
84693 return $this->groups;
84694 }
84695 /**
84696 * @psalm-assert-if-true !null $this->testsCovering
84697 */
84698 public function hasTestsCovering(): bool
84699 {
84700 return $this->testsCovering !== null;
84701 }
84702 /**
84703 * @throws Exception
84704 */
84705 public function testsCovering(): array
84706 {
84707 if (!$this->hasTestsCovering()) {
84708 throw new \PHPUnit\TextUI\CliArguments\Exception();
84709 }
84710 return $this->testsCovering;
84711 }
84712 /**
84713 * @psalm-assert-if-true !null $this->testsUsing
84714 */
84715 public function hasTestsUsing(): bool
84716 {
84717 return $this->testsUsing !== null;
84718 }
84719 /**
84720 * @throws Exception
84721 */
84722 public function testsUsing(): array
84723 {
84724 if (!$this->hasTestsUsing()) {
84725 throw new \PHPUnit\TextUI\CliArguments\Exception();
84726 }
84727 return $this->testsUsing;
84728 }
84729 public function help(): bool
84730 {
84731 return $this->help;
84732 }
84733 /**
84734 * @psalm-assert-if-true !null $this->includePath
84735 */
84736 public function hasIncludePath(): bool
84737 {
84738 return $this->includePath !== null;
84739 }
84740 /**
84741 * @throws Exception
84742 */
84743 public function includePath(): string
84744 {
84745 if (!$this->hasIncludePath()) {
84746 throw new \PHPUnit\TextUI\CliArguments\Exception();
84747 }
84748 return $this->includePath;
84749 }
84750 /**
84751 * @psalm-assert-if-true !null $this->iniSettings
84752 */
84753 public function hasIniSettings(): bool
84754 {
84755 return $this->iniSettings !== null;
84756 }
84757 /**
84758 * @throws Exception
84759 */
84760 public function iniSettings(): array
84761 {
84762 if (!$this->hasIniSettings()) {
84763 throw new \PHPUnit\TextUI\CliArguments\Exception();
84764 }
84765 return $this->iniSettings;
84766 }
84767 /**
84768 * @psalm-assert-if-true !null $this->junitLogfile
84769 */
84770 public function hasJunitLogfile(): bool
84771 {
84772 return $this->junitLogfile !== null;
84773 }
84774 /**
84775 * @throws Exception
84776 */
84777 public function junitLogfile(): string
84778 {
84779 if (!$this->hasJunitLogfile()) {
84780 throw new \PHPUnit\TextUI\CliArguments\Exception();
84781 }
84782 return $this->junitLogfile;
84783 }
84784 public function listGroups(): bool
84785 {
84786 return $this->listGroups;
84787 }
84788 public function listSuites(): bool
84789 {
84790 return $this->listSuites;
84791 }
84792 public function listTests(): bool
84793 {
84794 return $this->listTests;
84795 }
84796 /**
84797 * @psalm-assert-if-true !null $this->listTestsXml
84798 */
84799 public function hasListTestsXml(): bool
84800 {
84801 return $this->listTestsXml !== null;
84802 }
84803 /**
84804 * @throws Exception
84805 */
84806 public function listTestsXml(): string
84807 {
84808 if (!$this->hasListTestsXml()) {
84809 throw new \PHPUnit\TextUI\CliArguments\Exception();
84810 }
84811 return $this->listTestsXml;
84812 }
84813 /**
84814 * @psalm-assert-if-true !null $this->noCoverage
84815 */
84816 public function hasNoCoverage(): bool
84817 {
84818 return $this->noCoverage !== null;
84819 }
84820 /**
84821 * @throws Exception
84822 */
84823 public function noCoverage(): bool
84824 {
84825 if (!$this->hasNoCoverage()) {
84826 throw new \PHPUnit\TextUI\CliArguments\Exception();
84827 }
84828 return $this->noCoverage;
84829 }
84830 /**
84831 * @psalm-assert-if-true !null $this->noExtensions
84832 */
84833 public function hasNoExtensions(): bool
84834 {
84835 return $this->noExtensions !== null;
84836 }
84837 /**
84838 * @throws Exception
84839 */
84840 public function noExtensions(): bool
84841 {
84842 if (!$this->hasNoExtensions()) {
84843 throw new \PHPUnit\TextUI\CliArguments\Exception();
84844 }
84845 return $this->noExtensions;
84846 }
84847 /**
84848 * @psalm-assert-if-true !null $this->noOutput
84849 */
84850 public function hasNoOutput(): bool
84851 {
84852 return $this->noOutput !== null;
84853 }
84854 /**
84855 * @throws Exception
84856 */
84857 public function noOutput(): bool
84858 {
84859 if ($this->noOutput === null) {
84860 throw new \PHPUnit\TextUI\CliArguments\Exception();
84861 }
84862 return $this->noOutput;
84863 }
84864 /**
84865 * @psalm-assert-if-true !null $this->noProgress
84866 */
84867 public function hasNoProgress(): bool
84868 {
84869 return $this->noProgress !== null;
84870 }
84871 /**
84872 * @throws Exception
84873 */
84874 public function noProgress(): bool
84875 {
84876 if ($this->noProgress === null) {
84877 throw new \PHPUnit\TextUI\CliArguments\Exception();
84878 }
84879 return $this->noProgress;
84880 }
84881 /**
84882 * @psalm-assert-if-true !null $this->noResults
84883 */
84884 public function hasNoResults(): bool
84885 {
84886 return $this->noResults !== null;
84887 }
84888 /**
84889 * @throws Exception
84890 */
84891 public function noResults(): bool
84892 {
84893 if ($this->noResults === null) {
84894 throw new \PHPUnit\TextUI\CliArguments\Exception();
84895 }
84896 return $this->noResults;
84897 }
84898 /**
84899 * @psalm-assert-if-true !null $this->noLogging
84900 */
84901 public function hasNoLogging(): bool
84902 {
84903 return $this->noLogging !== null;
84904 }
84905 /**
84906 * @throws Exception
84907 */
84908 public function noLogging(): bool
84909 {
84910 if (!$this->hasNoLogging()) {
84911 throw new \PHPUnit\TextUI\CliArguments\Exception();
84912 }
84913 return $this->noLogging;
84914 }
84915 /**
84916 * @psalm-assert-if-true !null $this->processIsolation
84917 */
84918 public function hasProcessIsolation(): bool
84919 {
84920 return $this->processIsolation !== null;
84921 }
84922 /**
84923 * @throws Exception
84924 */
84925 public function processIsolation(): bool
84926 {
84927 if (!$this->hasProcessIsolation()) {
84928 throw new \PHPUnit\TextUI\CliArguments\Exception();
84929 }
84930 return $this->processIsolation;
84931 }
84932 /**
84933 * @psalm-assert-if-true !null $this->randomOrderSeed
84934 */
84935 public function hasRandomOrderSeed(): bool
84936 {
84937 return $this->randomOrderSeed !== null;
84938 }
84939 /**
84940 * @throws Exception
84941 */
84942 public function randomOrderSeed(): int
84943 {
84944 if (!$this->hasRandomOrderSeed()) {
84945 throw new \PHPUnit\TextUI\CliArguments\Exception();
84946 }
84947 return $this->randomOrderSeed;
84948 }
84949 /**
84950 * @psalm-assert-if-true !null $this->reportUselessTests
84951 */
84952 public function hasReportUselessTests(): bool
84953 {
84954 return $this->reportUselessTests !== null;
84955 }
84956 /**
84957 * @throws Exception
84958 */
84959 public function reportUselessTests(): bool
84960 {
84961 if (!$this->hasReportUselessTests()) {
84962 throw new \PHPUnit\TextUI\CliArguments\Exception();
84963 }
84964 return $this->reportUselessTests;
84965 }
84966 /**
84967 * @psalm-assert-if-true !null $this->resolveDependencies
84968 */
84969 public function hasResolveDependencies(): bool
84970 {
84971 return $this->resolveDependencies !== null;
84972 }
84973 /**
84974 * @throws Exception
84975 */
84976 public function resolveDependencies(): bool
84977 {
84978 if (!$this->hasResolveDependencies()) {
84979 throw new \PHPUnit\TextUI\CliArguments\Exception();
84980 }
84981 return $this->resolveDependencies;
84982 }
84983 /**
84984 * @psalm-assert-if-true !null $this->reverseList
84985 */
84986 public function hasReverseList(): bool
84987 {
84988 return $this->reverseList !== null;
84989 }
84990 /**
84991 * @throws Exception
84992 */
84993 public function reverseList(): bool
84994 {
84995 if (!$this->hasReverseList()) {
84996 throw new \PHPUnit\TextUI\CliArguments\Exception();
84997 }
84998 return $this->reverseList;
84999 }
85000 /**
85001 * @psalm-assert-if-true !null $this->stderr
85002 */
85003 public function hasStderr(): bool
85004 {
85005 return $this->stderr !== null;
85006 }
85007 /**
85008 * @throws Exception
85009 */
85010 public function stderr(): bool
85011 {
85012 if (!$this->hasStderr()) {
85013 throw new \PHPUnit\TextUI\CliArguments\Exception();
85014 }
85015 return $this->stderr;
85016 }
85017 /**
85018 * @psalm-assert-if-true !null $this->strictCoverage
85019 */
85020 public function hasStrictCoverage(): bool
85021 {
85022 return $this->strictCoverage !== null;
85023 }
85024 /**
85025 * @throws Exception
85026 */
85027 public function strictCoverage(): bool
85028 {
85029 if (!$this->hasStrictCoverage()) {
85030 throw new \PHPUnit\TextUI\CliArguments\Exception();
85031 }
85032 return $this->strictCoverage;
85033 }
85034 /**
85035 * @psalm-assert-if-true !null $this->teamcityLogfile
85036 */
85037 public function hasTeamcityLogfile(): bool
85038 {
85039 return $this->teamcityLogfile !== null;
85040 }
85041 /**
85042 * @throws Exception
85043 */
85044 public function teamcityLogfile(): string
85045 {
85046 if (!$this->hasTeamcityLogfile()) {
85047 throw new \PHPUnit\TextUI\CliArguments\Exception();
85048 }
85049 return $this->teamcityLogfile;
85050 }
85051 /**
85052 * @psalm-assert-if-true !null $this->teamcityPrinter
85053 */
85054 public function hasTeamCityPrinter(): bool
85055 {
85056 return $this->teamCityPrinter !== null;
85057 }
85058 /**
85059 * @throws Exception
85060 */
85061 public function teamCityPrinter(): bool
85062 {
85063 if (!$this->hasTeamCityPrinter()) {
85064 throw new \PHPUnit\TextUI\CliArguments\Exception();
85065 }
85066 return $this->teamCityPrinter;
85067 }
85068 /**
85069 * @psalm-assert-if-true !null $this->testdoxHtmlFile
85070 */
85071 public function hasTestdoxHtmlFile(): bool
85072 {
85073 return $this->testdoxHtmlFile !== null;
85074 }
85075 /**
85076 * @throws Exception
85077 */
85078 public function testdoxHtmlFile(): string
85079 {
85080 if (!$this->hasTestdoxHtmlFile()) {
85081 throw new \PHPUnit\TextUI\CliArguments\Exception();
85082 }
85083 return $this->testdoxHtmlFile;
85084 }
85085 /**
85086 * @psalm-assert-if-true !null $this->testdoxTextFile
85087 */
85088 public function hasTestdoxTextFile(): bool
85089 {
85090 return $this->testdoxTextFile !== null;
85091 }
85092 /**
85093 * @throws Exception
85094 */
85095 public function testdoxTextFile(): string
85096 {
85097 if (!$this->hasTestdoxTextFile()) {
85098 throw new \PHPUnit\TextUI\CliArguments\Exception();
85099 }
85100 return $this->testdoxTextFile;
85101 }
85102 /**
85103 * @psalm-assert-if-true !null $this->testdoxPrinter
85104 */
85105 public function hasTestDoxPrinter(): bool
85106 {
85107 return $this->testdoxPrinter !== null;
85108 }
85109 /**
85110 * @throws Exception
85111 */
85112 public function testdoxPrinter(): bool
85113 {
85114 if (!$this->hasTestdoxPrinter()) {
85115 throw new \PHPUnit\TextUI\CliArguments\Exception();
85116 }
85117 return $this->testdoxPrinter;
85118 }
85119 /**
85120 * @psalm-assert-if-true !null $this->testSuffixes
85121 */
85122 public function hasTestSuffixes(): bool
85123 {
85124 return $this->testSuffixes !== null;
85125 }
85126 /**
85127 * @throws Exception
85128 *
85129 * @psalm-return non-empty-list<non-empty-string>
85130 */
85131 public function testSuffixes(): array
85132 {
85133 if (!$this->hasTestSuffixes()) {
85134 throw new \PHPUnit\TextUI\CliArguments\Exception();
85135 }
85136 return $this->testSuffixes;
85137 }
85138 /**
85139 * @psalm-assert-if-true !null $this->testSuite
85140 */
85141 public function hasTestSuite(): bool
85142 {
85143 return $this->testSuite !== null;
85144 }
85145 /**
85146 * @throws Exception
85147 */
85148 public function testSuite(): string
85149 {
85150 if (!$this->hasTestSuite()) {
85151 throw new \PHPUnit\TextUI\CliArguments\Exception();
85152 }
85153 return $this->testSuite;
85154 }
85155 /**
85156 * @psalm-assert-if-true !null $this->excludedTestSuite
85157 */
85158 public function hasExcludedTestSuite(): bool
85159 {
85160 return $this->excludeTestSuite !== null;
85161 }
85162 /**
85163 * @throws Exception
85164 */
85165 public function excludedTestSuite(): string
85166 {
85167 if (!$this->hasExcludedTestSuite()) {
85168 throw new \PHPUnit\TextUI\CliArguments\Exception();
85169 }
85170 return $this->excludeTestSuite;
85171 }
85172 public function useDefaultConfiguration(): bool
85173 {
85174 return $this->useDefaultConfiguration;
85175 }
85176 /**
85177 * @psalm-assert-if-true !null $this->displayDetailsOnAllIssues
85178 */
85179 public function hasDisplayDetailsOnAllIssues(): bool
85180 {
85181 return $this->displayDetailsOnAllIssues !== null;
85182 }
85183 /**
85184 * @throws Exception
85185 */
85186 public function displayDetailsOnAllIssues(): bool
85187 {
85188 if (!$this->hasDisplayDetailsOnAllIssues()) {
85189 throw new \PHPUnit\TextUI\CliArguments\Exception();
85190 }
85191 return $this->displayDetailsOnAllIssues;
85192 }
85193 /**
85194 * @psalm-assert-if-true !null $this->displayDetailsOnIncompleteTests
85195 */
85196 public function hasDisplayDetailsOnIncompleteTests(): bool
85197 {
85198 return $this->displayDetailsOnIncompleteTests !== null;
85199 }
85200 /**
85201 * @throws Exception
85202 */
85203 public function displayDetailsOnIncompleteTests(): bool
85204 {
85205 if (!$this->hasDisplayDetailsOnIncompleteTests()) {
85206 throw new \PHPUnit\TextUI\CliArguments\Exception();
85207 }
85208 return $this->displayDetailsOnIncompleteTests;
85209 }
85210 /**
85211 * @psalm-assert-if-true !null $this->displayDetailsOnSkippedTests
85212 */
85213 public function hasDisplayDetailsOnSkippedTests(): bool
85214 {
85215 return $this->displayDetailsOnSkippedTests !== null;
85216 }
85217 /**
85218 * @throws Exception
85219 */
85220 public function displayDetailsOnSkippedTests(): bool
85221 {
85222 if (!$this->hasDisplayDetailsOnSkippedTests()) {
85223 throw new \PHPUnit\TextUI\CliArguments\Exception();
85224 }
85225 return $this->displayDetailsOnSkippedTests;
85226 }
85227 /**
85228 * @psalm-assert-if-true !null $this->displayDetailsOnTestsThatTriggerDeprecations
85229 */
85230 public function hasDisplayDetailsOnTestsThatTriggerDeprecations(): bool
85231 {
85232 return $this->displayDetailsOnTestsThatTriggerDeprecations !== null;
85233 }
85234 /**
85235 * @throws Exception
85236 */
85237 public function displayDetailsOnTestsThatTriggerDeprecations(): bool
85238 {
85239 if (!$this->hasDisplayDetailsOnTestsThatTriggerDeprecations()) {
85240 throw new \PHPUnit\TextUI\CliArguments\Exception();
85241 }
85242 return $this->displayDetailsOnTestsThatTriggerDeprecations;
85243 }
85244 /**
85245 * @psalm-assert-if-true !null $this->displayDetailsOnPhpunitDeprecations
85246 */
85247 public function hasDisplayDetailsOnPhpunitDeprecations(): bool
85248 {
85249 return $this->displayDetailsOnPhpunitDeprecations !== null;
85250 }
85251 /**
85252 * @throws Exception
85253 */
85254 public function displayDetailsOnPhpunitDeprecations(): bool
85255 {
85256 if (!$this->hasDisplayDetailsOnPhpunitDeprecations()) {
85257 throw new \PHPUnit\TextUI\CliArguments\Exception();
85258 }
85259 return $this->displayDetailsOnPhpunitDeprecations;
85260 }
85261 /**
85262 * @psalm-assert-if-true !null $this->displayDetailsOnTestsThatTriggerErrors
85263 */
85264 public function hasDisplayDetailsOnTestsThatTriggerErrors(): bool
85265 {
85266 return $this->displayDetailsOnTestsThatTriggerErrors !== null;
85267 }
85268 /**
85269 * @throws Exception
85270 */
85271 public function displayDetailsOnTestsThatTriggerErrors(): bool
85272 {
85273 if (!$this->hasDisplayDetailsOnTestsThatTriggerErrors()) {
85274 throw new \PHPUnit\TextUI\CliArguments\Exception();
85275 }
85276 return $this->displayDetailsOnTestsThatTriggerErrors;
85277 }
85278 /**
85279 * @psalm-assert-if-true !null $this->displayDetailsOnTestsThatTriggerNotices
85280 */
85281 public function hasDisplayDetailsOnTestsThatTriggerNotices(): bool
85282 {
85283 return $this->displayDetailsOnTestsThatTriggerNotices !== null;
85284 }
85285 /**
85286 * @throws Exception
85287 */
85288 public function displayDetailsOnTestsThatTriggerNotices(): bool
85289 {
85290 if (!$this->hasDisplayDetailsOnTestsThatTriggerNotices()) {
85291 throw new \PHPUnit\TextUI\CliArguments\Exception();
85292 }
85293 return $this->displayDetailsOnTestsThatTriggerNotices;
85294 }
85295 /**
85296 * @psalm-assert-if-true !null $this->displayDetailsOnTestsThatTriggerWarnings
85297 */
85298 public function hasDisplayDetailsOnTestsThatTriggerWarnings(): bool
85299 {
85300 return $this->displayDetailsOnTestsThatTriggerWarnings !== null;
85301 }
85302 /**
85303 * @throws Exception
85304 */
85305 public function displayDetailsOnTestsThatTriggerWarnings(): bool
85306 {
85307 if (!$this->hasDisplayDetailsOnTestsThatTriggerWarnings()) {
85308 throw new \PHPUnit\TextUI\CliArguments\Exception();
85309 }
85310 return $this->displayDetailsOnTestsThatTriggerWarnings;
85311 }
85312 public function version(): bool
85313 {
85314 return $this->version;
85315 }
85316 /**
85317 * @psalm-assert-if-true !null $this->logEventsText
85318 */
85319 public function hasLogEventsText(): bool
85320 {
85321 return $this->logEventsText !== null;
85322 }
85323 /**
85324 * @throws Exception
85325 */
85326 public function logEventsText(): string
85327 {
85328 if (!$this->hasLogEventsText()) {
85329 throw new \PHPUnit\TextUI\CliArguments\Exception();
85330 }
85331 return $this->logEventsText;
85332 }
85333 /**
85334 * @psalm-assert-if-true !null $this->logEventsVerboseText
85335 */
85336 public function hasLogEventsVerboseText(): bool
85337 {
85338 return $this->logEventsVerboseText !== null;
85339 }
85340 /**
85341 * @throws Exception
85342 */
85343 public function logEventsVerboseText(): string
85344 {
85345 if (!$this->hasLogEventsVerboseText()) {
85346 throw new \PHPUnit\TextUI\CliArguments\Exception();
85347 }
85348 return $this->logEventsVerboseText;
85349 }
85350 public function debug(): bool
85351 {
85352 return $this->debug;
85353 }
85354 }
85355 <?php
85356
85357 declare (strict_types=1);
85358 /*
85359 * This file is part of PHPUnit.
85360 *
85361 * (c) Sebastian Bergmann <sebastian@phpunit.de>
85362 *
85363 * For the full copyright and license information, please view the LICENSE
85364 * file that was distributed with this source code.
85365 */
85366 namespace PHPUnit\TextUI\CliArguments;
85367
85368 use RuntimeException;
85369 /**
85370 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
85371 *
85372 * @internal This class is not covered by the backward compatibility promise for PHPUnit
85373 */
85374 final class Exception extends RuntimeException implements \PHPUnit\Exception
85375 {
85376 }
85377 <?php
85378
85379 declare (strict_types=1);
85380 /*
85381 * This file is part of PHPUnit.
85382 *
85383 * (c) Sebastian Bergmann <sebastian@phpunit.de>
85384 *
85385 * For the full copyright and license information, please view the LICENSE
85386 * file that was distributed with this source code.
85387 */
85388 namespace PHPUnit\TextUI\CliArguments;
85389
85390 use function getcwd;
85391 use function is_dir;
85392 use function is_file;
85393 use function realpath;
85394 /**
85395 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
85396 *
85397 * @internal This class is not covered by the backward compatibility promise for PHPUnit
85398 */
85399 final class XmlConfigurationFileFinder
85400 {
85401 public function find(\PHPUnit\TextUI\CliArguments\Configuration $configuration): false|string
85402 {
85403 $useDefaultConfiguration = $configuration->useDefaultConfiguration();
85404 if ($configuration->hasConfigurationFile()) {
85405 if (is_dir($configuration->configurationFile())) {
85406 $candidate = $this->configurationFileInDirectory($configuration->configurationFile());
85407 if ($candidate !== \false) {
85408 return $candidate;
85409 }
85410 return \false;
85411 }
85412 return $configuration->configurationFile();
85413 }
85414 if ($useDefaultConfiguration) {
85415 $candidate = $this->configurationFileInDirectory(getcwd());
85416 if ($candidate !== \false) {
85417 return $candidate;
85418 }
85419 }
85420 return \false;
85421 }
85422 private function configurationFileInDirectory(string $directory): false|string
85423 {
85424 $candidates = [$directory . '/phpunit.xml', $directory . '/phpunit.dist.xml', $directory . '/phpunit.xml.dist'];
85425 foreach ($candidates as $candidate) {
85426 if (is_file($candidate)) {
85427 return realpath($candidate);
85428 }
85429 }
85430 return \false;
85431 }
85432 }
85433 <?php
85434
85435 declare (strict_types=1);
85436 /*
85437 * This file is part of PHPUnit.
85438 *
85439 * (c) Sebastian Bergmann <sebastian@phpunit.de>
85440 *
85441 * For the full copyright and license information, please view the LICENSE
85442 * file that was distributed with this source code.
85443 */
85444 namespace PHPUnit\TextUI\Configuration;
85445
85446 use function array_keys;
85447 use function assert;
85448 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Filter;
85449 /**
85450 * CLI options and XML configuration are static within a single PHPUnit process.
85451 * It is therefore okay to use a Singleton registry here.
85452 *
85453 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
85454 *
85455 * @internal This class is not covered by the backward compatibility promise for PHPUnit
85456 */
85457 final class CodeCoverageFilterRegistry
85458 {
85459 private static ?self $instance = null;
85460 private ?Filter $filter = null;
85461 private bool $configured = \false;
85462 public static function instance(): self
85463 {
85464 if (self::$instance === null) {
85465 self::$instance = new self();
85466 }
85467 return self::$instance;
85468 }
85469 /**
85470 * @codeCoverageIgnore
85471 */
85472 public function get(): Filter
85473 {
85474 assert($this->filter !== null);
85475 return $this->filter;
85476 }
85477 /**
85478 * @codeCoverageIgnore
85479 */
85480 public function init(\PHPUnit\TextUI\Configuration\Configuration $configuration, bool $force = \false): void
85481 {
85482 if (!$configuration->hasCoverageReport() && !$force) {
85483 return;
85484 }
85485 if ($this->configured && !$force) {
85486 return;
85487 }
85488 $this->filter = new Filter();
85489 if ($configuration->source()->notEmpty()) {
85490 $this->filter->includeFiles(array_keys((new \PHPUnit\TextUI\Configuration\SourceMapper())->map($configuration->source())));
85491 $this->configured = \true;
85492 }
85493 }
85494 /**
85495 * @codeCoverageIgnore
85496 */
85497 public function configured(): bool
85498 {
85499 return $this->configured;
85500 }
85501 }
85502 <?php
85503
85504 declare (strict_types=1);
85505 /*
85506 * This file is part of PHPUnit.
85507 *
85508 * (c) Sebastian Bergmann <sebastian@phpunit.de>
85509 *
85510 * For the full copyright and license information, please view the LICENSE
85511 * file that was distributed with this source code.
85512 */
85513 namespace PHPUnit\TextUI\Configuration;
85514
85515 /**
85516 * @psalm-immutable
85517 *
85518 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
85519 */
85520 final class Configuration
85521 {
85522 public const COLOR_NEVER = 'never';
85523 public const COLOR_AUTO = 'auto';
85524 public const COLOR_ALWAYS = 'always';
85525 public const COLOR_DEFAULT = self::COLOR_NEVER;
85526 /**
85527 * @psalm-var list<non-empty-string>
85528 */
85529 private readonly array $cliArguments;
85530 private readonly ?string $configurationFile;
85531 private readonly ?string $bootstrap;
85532 private readonly bool $cacheResult;
85533 private readonly ?string $cacheDirectory;
85534 private readonly ?string $coverageCacheDirectory;
85535 private readonly \PHPUnit\TextUI\Configuration\Source $source;
85536 private readonly bool $pathCoverage;
85537 private readonly ?string $coverageClover;
85538 private readonly ?string $coverageCobertura;
85539 private readonly ?string $coverageCrap4j;
85540 private readonly int $coverageCrap4jThreshold;
85541 private readonly ?string $coverageHtml;
85542 private readonly int $coverageHtmlLowUpperBound;
85543 private readonly int $coverageHtmlHighLowerBound;
85544 private readonly string $coverageHtmlColorSuccessLow;
85545 private readonly string $coverageHtmlColorSuccessMedium;
85546 private readonly string $coverageHtmlColorSuccessHigh;
85547 private readonly string $coverageHtmlColorWarning;
85548 private readonly string $coverageHtmlColorDanger;
85549 private readonly ?string $coverageHtmlCustomCssFile;
85550 private readonly ?string $coveragePhp;
85551 private readonly ?string $coverageText;
85552 private readonly bool $coverageTextShowUncoveredFiles;
85553 private readonly bool $coverageTextShowOnlySummary;
85554 private readonly ?string $coverageXml;
85555 private readonly string $testResultCacheFile;
85556 private readonly bool $ignoreDeprecatedCodeUnitsFromCodeCoverage;
85557 private readonly bool $disableCodeCoverageIgnore;
85558 private readonly bool $failOnAllIssues;
85559 private readonly bool $failOnDeprecation;
85560 private readonly bool $failOnPhpunitDeprecation;
85561 private readonly bool $failOnPhpunitWarning;
85562 private readonly bool $failOnEmptyTestSuite;
85563 private readonly bool $failOnIncomplete;
85564 private readonly bool $failOnNotice;
85565 private readonly bool $failOnRisky;
85566 private readonly bool $failOnSkipped;
85567 private readonly bool $failOnWarning;
85568 private readonly bool $doNotFailOnDeprecation;
85569 private readonly bool $doNotFailOnPhpunitDeprecation;
85570 private readonly bool $doNotFailOnPhpunitWarning;
85571 private readonly bool $doNotFailOnEmptyTestSuite;
85572 private readonly bool $doNotFailOnIncomplete;
85573 private readonly bool $doNotFailOnNotice;
85574 private readonly bool $doNotFailOnRisky;
85575 private readonly bool $doNotFailOnSkipped;
85576 private readonly bool $doNotFailOnWarning;
85577 private readonly bool $stopOnDefect;
85578 private readonly bool $stopOnDeprecation;
85579 private readonly bool $stopOnError;
85580 private readonly bool $stopOnFailure;
85581 private readonly bool $stopOnIncomplete;
85582 private readonly bool $stopOnNotice;
85583 private readonly bool $stopOnRisky;
85584 private readonly bool $stopOnSkipped;
85585 private readonly bool $stopOnWarning;
85586 private readonly bool $outputToStandardErrorStream;
85587 private readonly int $columns;
85588 private readonly bool $noExtensions;
85589 /**
85590 * @psalm-var ?non-empty-string
85591 */
85592 private readonly ?string $pharExtensionDirectory;
85593 /**
85594 * @psalm-var list<array{className: class-string, parameters: array<string, string>}>
85595 */
85596 private readonly array $extensionBootstrappers;
85597 private readonly bool $backupGlobals;
85598 private readonly bool $backupStaticProperties;
85599 private readonly bool $beStrictAboutChangesToGlobalState;
85600 private readonly bool $colors;
85601 private readonly bool $processIsolation;
85602 private readonly bool $enforceTimeLimit;
85603 private readonly int $defaultTimeLimit;
85604 private readonly int $timeoutForSmallTests;
85605 private readonly int $timeoutForMediumTests;
85606 private readonly int $timeoutForLargeTests;
85607 private readonly bool $reportUselessTests;
85608 private readonly bool $strictCoverage;
85609 private readonly bool $disallowTestOutput;
85610 private readonly bool $displayDetailsOnAllIssues;
85611 private readonly bool $displayDetailsOnIncompleteTests;
85612 private readonly bool $displayDetailsOnSkippedTests;
85613 private readonly bool $displayDetailsOnTestsThatTriggerDeprecations;
85614 private readonly bool $displayDetailsOnPhpunitDeprecations;
85615 private readonly bool $displayDetailsOnTestsThatTriggerErrors;
85616 private readonly bool $displayDetailsOnTestsThatTriggerNotices;
85617 private readonly bool $displayDetailsOnTestsThatTriggerWarnings;
85618 private readonly bool $reverseDefectList;
85619 private readonly bool $requireCoverageMetadata;
85620 private readonly bool $registerMockObjectsFromTestArgumentsRecursively;
85621 private readonly bool $noProgress;
85622 private readonly bool $noResults;
85623 private readonly bool $noOutput;
85624 private readonly int $executionOrder;
85625 private readonly int $executionOrderDefects;
85626 private readonly bool $resolveDependencies;
85627 private readonly ?string $logfileTeamcity;
85628 private readonly ?string $logfileJunit;
85629 private readonly ?string $logfileTestdoxHtml;
85630 private readonly ?string $logfileTestdoxText;
85631 private readonly ?string $logEventsText;
85632 private readonly ?string $logEventsVerboseText;
85633 private readonly ?array $testsCovering;
85634 private readonly ?array $testsUsing;
85635 private readonly bool $teamCityOutput;
85636 private readonly bool $testDoxOutput;
85637 private readonly ?string $filter;
85638 private readonly ?array $groups;
85639 private readonly ?array $excludeGroups;
85640 private readonly int $randomOrderSeed;
85641 private readonly bool $includeUncoveredFiles;
85642 private readonly \PHPUnit\TextUI\Configuration\TestSuiteCollection $testSuite;
85643 private readonly string $includeTestSuite;
85644 private readonly string $excludeTestSuite;
85645 private readonly ?string $defaultTestSuite;
85646 /**
85647 * @psalm-var non-empty-list<non-empty-string>
85648 */
85649 private readonly array $testSuffixes;
85650 private readonly \PHPUnit\TextUI\Configuration\Php $php;
85651 private readonly bool $controlGarbageCollector;
85652 private readonly int $numberOfTestsBeforeGarbageCollection;
85653 private readonly ?string $generateBaseline;
85654 private readonly bool $debug;
85655 /**
85656 * @psalm-param list<non-empty-string> $cliArguments
85657 * @psalm-param ?non-empty-string $pharExtensionDirectory
85658 * @psalm-param non-empty-list<non-empty-string> $testSuffixes
85659 * @psalm-param list<array{className: class-string, parameters: array<string, string>}> $extensionBootstrappers
85660 */
85661 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 $failOnAllIssues, bool $failOnDeprecation, bool $failOnPhpunitDeprecation, bool $failOnPhpunitWarning, bool $failOnEmptyTestSuite, bool $failOnIncomplete, bool $failOnNotice, bool $failOnRisky, bool $failOnSkipped, bool $failOnWarning, bool $doNotFailOnDeprecation, bool $doNotFailOnPhpunitDeprecation, bool $doNotFailOnPhpunitWarning, bool $doNotFailOnEmptyTestSuite, bool $doNotFailOnIncomplete, bool $doNotFailOnNotice, bool $doNotFailOnRisky, bool $doNotFailOnSkipped, bool $doNotFailOnWarning, 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 $displayDetailsOnAllIssues, bool $displayDetailsOnIncompleteTests, bool $displayDetailsOnSkippedTests, bool $displayDetailsOnTestsThatTriggerDeprecations, bool $displayDetailsOnPhpunitDeprecations, 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)
85662 {
85663 $this->cliArguments = $cliArguments;
85664 $this->configurationFile = $configurationFile;
85665 $this->bootstrap = $bootstrap;
85666 $this->cacheResult = $cacheResult;
85667 $this->cacheDirectory = $cacheDirectory;
85668 $this->coverageCacheDirectory = $coverageCacheDirectory;
85669 $this->source = $source;
85670 $this->testResultCacheFile = $testResultCacheFile;
85671 $this->coverageClover = $coverageClover;
85672 $this->coverageCobertura = $coverageCobertura;
85673 $this->coverageCrap4j = $coverageCrap4j;
85674 $this->coverageCrap4jThreshold = $coverageCrap4jThreshold;
85675 $this->coverageHtml = $coverageHtml;
85676 $this->coverageHtmlLowUpperBound = $coverageHtmlLowUpperBound;
85677 $this->coverageHtmlHighLowerBound = $coverageHtmlHighLowerBound;
85678 $this->coverageHtmlColorSuccessLow = $coverageHtmlColorSuccessLow;
85679 $this->coverageHtmlColorSuccessMedium = $coverageHtmlColorSuccessMedium;
85680 $this->coverageHtmlColorSuccessHigh = $coverageHtmlColorSuccessHigh;
85681 $this->coverageHtmlColorWarning = $coverageHtmlColorWarning;
85682 $this->coverageHtmlColorDanger = $coverageHtmlColorDanger;
85683 $this->coverageHtmlCustomCssFile = $coverageHtmlCustomCssFile;
85684 $this->coveragePhp = $coveragePhp;
85685 $this->coverageText = $coverageText;
85686 $this->coverageTextShowUncoveredFiles = $coverageTextShowUncoveredFiles;
85687 $this->coverageTextShowOnlySummary = $coverageTextShowOnlySummary;
85688 $this->coverageXml = $coverageXml;
85689 $this->pathCoverage = $pathCoverage;
85690 $this->ignoreDeprecatedCodeUnitsFromCodeCoverage = $ignoreDeprecatedCodeUnitsFromCodeCoverage;
85691 $this->disableCodeCoverageIgnore = $disableCodeCoverageIgnore;
85692 $this->failOnAllIssues = $failOnAllIssues;
85693 $this->failOnDeprecation = $failOnDeprecation;
85694 $this->failOnPhpunitDeprecation = $failOnPhpunitDeprecation;
85695 $this->failOnPhpunitWarning = $failOnPhpunitWarning;
85696 $this->failOnEmptyTestSuite = $failOnEmptyTestSuite;
85697 $this->failOnIncomplete = $failOnIncomplete;
85698 $this->failOnNotice = $failOnNotice;
85699 $this->failOnRisky = $failOnRisky;
85700 $this->failOnSkipped = $failOnSkipped;
85701 $this->failOnWarning = $failOnWarning;
85702 $this->doNotFailOnDeprecation = $doNotFailOnDeprecation;
85703 $this->doNotFailOnPhpunitDeprecation = $doNotFailOnPhpunitDeprecation;
85704 $this->doNotFailOnPhpunitWarning = $doNotFailOnPhpunitWarning;
85705 $this->doNotFailOnEmptyTestSuite = $doNotFailOnEmptyTestSuite;
85706 $this->doNotFailOnIncomplete = $doNotFailOnIncomplete;
85707 $this->doNotFailOnNotice = $doNotFailOnNotice;
85708 $this->doNotFailOnRisky = $doNotFailOnRisky;
85709 $this->doNotFailOnSkipped = $doNotFailOnSkipped;
85710 $this->doNotFailOnWarning = $doNotFailOnWarning;
85711 $this->stopOnDefect = $stopOnDefect;
85712 $this->stopOnDeprecation = $stopOnDeprecation;
85713 $this->stopOnError = $stopOnError;
85714 $this->stopOnFailure = $stopOnFailure;
85715 $this->stopOnIncomplete = $stopOnIncomplete;
85716 $this->stopOnNotice = $stopOnNotice;
85717 $this->stopOnRisky = $stopOnRisky;
85718 $this->stopOnSkipped = $stopOnSkipped;
85719 $this->stopOnWarning = $stopOnWarning;
85720 $this->outputToStandardErrorStream = $outputToStandardErrorStream;
85721 $this->columns = $columns;
85722 $this->noExtensions = $noExtensions;
85723 $this->pharExtensionDirectory = $pharExtensionDirectory;
85724 $this->extensionBootstrappers = $extensionBootstrappers;
85725 $this->backupGlobals = $backupGlobals;
85726 $this->backupStaticProperties = $backupStaticProperties;
85727 $this->beStrictAboutChangesToGlobalState = $beStrictAboutChangesToGlobalState;
85728 $this->colors = $colors;
85729 $this->processIsolation = $processIsolation;
85730 $this->enforceTimeLimit = $enforceTimeLimit;
85731 $this->defaultTimeLimit = $defaultTimeLimit;
85732 $this->timeoutForSmallTests = $timeoutForSmallTests;
85733 $this->timeoutForMediumTests = $timeoutForMediumTests;
85734 $this->timeoutForLargeTests = $timeoutForLargeTests;
85735 $this->reportUselessTests = $reportUselessTests;
85736 $this->strictCoverage = $strictCoverage;
85737 $this->disallowTestOutput = $disallowTestOutput;
85738 $this->displayDetailsOnAllIssues = $displayDetailsOnAllIssues;
85739 $this->displayDetailsOnIncompleteTests = $displayDetailsOnIncompleteTests;
85740 $this->displayDetailsOnSkippedTests = $displayDetailsOnSkippedTests;
85741 $this->displayDetailsOnTestsThatTriggerDeprecations = $displayDetailsOnTestsThatTriggerDeprecations;
85742 $this->displayDetailsOnPhpunitDeprecations = $displayDetailsOnPhpunitDeprecations;
85743 $this->displayDetailsOnTestsThatTriggerErrors = $displayDetailsOnTestsThatTriggerErrors;
85744 $this->displayDetailsOnTestsThatTriggerNotices = $displayDetailsOnTestsThatTriggerNotices;
85745 $this->displayDetailsOnTestsThatTriggerWarnings = $displayDetailsOnTestsThatTriggerWarnings;
85746 $this->reverseDefectList = $reverseDefectList;
85747 $this->requireCoverageMetadata = $requireCoverageMetadata;
85748 $this->registerMockObjectsFromTestArgumentsRecursively = $registerMockObjectsFromTestArgumentsRecursively;
85749 $this->noProgress = $noProgress;
85750 $this->noResults = $noResults;
85751 $this->noOutput = $noOutput;
85752 $this->executionOrder = $executionOrder;
85753 $this->executionOrderDefects = $executionOrderDefects;
85754 $this->resolveDependencies = $resolveDependencies;
85755 $this->logfileTeamcity = $logfileTeamcity;
85756 $this->logfileJunit = $logfileJunit;
85757 $this->logfileTestdoxHtml = $logfileTestdoxHtml;
85758 $this->logfileTestdoxText = $logfileTestdoxText;
85759 $this->logEventsText = $logEventsText;
85760 $this->logEventsVerboseText = $logEventsVerboseText;
85761 $this->teamCityOutput = $teamCityOutput;
85762 $this->testDoxOutput = $testDoxOutput;
85763 $this->testsCovering = $testsCovering;
85764 $this->testsUsing = $testsUsing;
85765 $this->filter = $filter;
85766 $this->groups = $groups;
85767 $this->excludeGroups = $excludeGroups;
85768 $this->randomOrderSeed = $randomOrderSeed;
85769 $this->includeUncoveredFiles = $includeUncoveredFiles;
85770 $this->testSuite = $testSuite;
85771 $this->includeTestSuite = $includeTestSuite;
85772 $this->excludeTestSuite = $excludeTestSuite;
85773 $this->defaultTestSuite = $defaultTestSuite;
85774 $this->testSuffixes = $testSuffixes;
85775 $this->php = $php;
85776 $this->controlGarbageCollector = $controlGarbageCollector;
85777 $this->numberOfTestsBeforeGarbageCollection = $numberOfTestsBeforeGarbageCollection;
85778 $this->generateBaseline = $generateBaseline;
85779 $this->debug = $debug;
85780 }
85781 /**
85782 * @psalm-assert-if-true !empty $this->cliArguments
85783 */
85784 public function hasCliArguments(): bool
85785 {
85786 return !empty($this->cliArguments);
85787 }
85788 /**
85789 * @psalm-return list<non-empty-string>
85790 */
85791 public function cliArguments(): array
85792 {
85793 return $this->cliArguments;
85794 }
85795 /**
85796 * @psalm-assert-if-true !empty $this->cliArguments
85797 *
85798 * @deprecated Use hasCliArguments() instead
85799 */
85800 public function hasCliArgument(): bool
85801 {
85802 return !empty($this->cliArguments);
85803 }
85804 /**
85805 * @throws NoCliArgumentException
85806 *
85807 * @return non-empty-string
85808 *
85809 * @deprecated Use cliArguments()[0] instead
85810 */
85811 public function cliArgument(): string
85812 {
85813 if (!$this->hasCliArguments()) {
85814 throw new \PHPUnit\TextUI\Configuration\NoCliArgumentException();
85815 }
85816 return $this->cliArguments[0];
85817 }
85818 /**
85819 * @psalm-assert-if-true !null $this->configurationFile
85820 */
85821 public function hasConfigurationFile(): bool
85822 {
85823 return $this->configurationFile !== null;
85824 }
85825 /**
85826 * @throws NoConfigurationFileException
85827 */
85828 public function configurationFile(): string
85829 {
85830 if (!$this->hasConfigurationFile()) {
85831 throw new \PHPUnit\TextUI\Configuration\NoConfigurationFileException();
85832 }
85833 return $this->configurationFile;
85834 }
85835 /**
85836 * @psalm-assert-if-true !null $this->bootstrap
85837 */
85838 public function hasBootstrap(): bool
85839 {
85840 return $this->bootstrap !== null;
85841 }
85842 /**
85843 * @throws NoBootstrapException
85844 */
85845 public function bootstrap(): string
85846 {
85847 if (!$this->hasBootstrap()) {
85848 throw new \PHPUnit\TextUI\Configuration\NoBootstrapException();
85849 }
85850 return $this->bootstrap;
85851 }
85852 public function cacheResult(): bool
85853 {
85854 return $this->cacheResult;
85855 }
85856 /**
85857 * @psalm-assert-if-true !null $this->cacheDirectory
85858 */
85859 public function hasCacheDirectory(): bool
85860 {
85861 return $this->cacheDirectory !== null;
85862 }
85863 /**
85864 * @throws NoCacheDirectoryException
85865 */
85866 public function cacheDirectory(): string
85867 {
85868 if (!$this->hasCacheDirectory()) {
85869 throw new \PHPUnit\TextUI\Configuration\NoCacheDirectoryException();
85870 }
85871 return $this->cacheDirectory;
85872 }
85873 /**
85874 * @psalm-assert-if-true !null $this->coverageCacheDirectory
85875 */
85876 public function hasCoverageCacheDirectory(): bool
85877 {
85878 return $this->coverageCacheDirectory !== null;
85879 }
85880 /**
85881 * @throws NoCoverageCacheDirectoryException
85882 */
85883 public function coverageCacheDirectory(): string
85884 {
85885 if (!$this->hasCoverageCacheDirectory()) {
85886 throw new \PHPUnit\TextUI\Configuration\NoCoverageCacheDirectoryException();
85887 }
85888 return $this->coverageCacheDirectory;
85889 }
85890 public function source(): \PHPUnit\TextUI\Configuration\Source
85891 {
85892 return $this->source;
85893 }
85894 /**
85895 * @deprecated Use source()->restrictDeprecations() instead
85896 */
85897 public function restrictDeprecations(): bool
85898 {
85899 return $this->source()->restrictDeprecations();
85900 }
85901 /**
85902 * @deprecated Use source()->restrictNotices() instead
85903 */
85904 public function restrictNotices(): bool
85905 {
85906 return $this->source()->restrictNotices();
85907 }
85908 /**
85909 * @deprecated Use source()->restrictWarnings() instead
85910 */
85911 public function restrictWarnings(): bool
85912 {
85913 return $this->source()->restrictWarnings();
85914 }
85915 /**
85916 * @deprecated Use source()->notEmpty() instead
85917 */
85918 public function hasNonEmptyListOfFilesToBeIncludedInCodeCoverageReport(): bool
85919 {
85920 return $this->source->notEmpty();
85921 }
85922 /**
85923 * @deprecated Use source()->includeDirectories() instead
85924 */
85925 public function coverageIncludeDirectories(): \PHPUnit\TextUI\Configuration\FilterDirectoryCollection
85926 {
85927 return $this->source()->includeDirectories();
85928 }
85929 /**
85930 * @deprecated Use source()->includeFiles() instead
85931 */
85932 public function coverageIncludeFiles(): \PHPUnit\TextUI\Configuration\FileCollection
85933 {
85934 return $this->source()->includeFiles();
85935 }
85936 /**
85937 * @deprecated Use source()->excludeDirectories() instead
85938 */
85939 public function coverageExcludeDirectories(): \PHPUnit\TextUI\Configuration\FilterDirectoryCollection
85940 {
85941 return $this->source()->excludeDirectories();
85942 }
85943 /**
85944 * @deprecated Use source()->excludeFiles() instead
85945 */
85946 public function coverageExcludeFiles(): \PHPUnit\TextUI\Configuration\FileCollection
85947 {
85948 return $this->source()->excludeFiles();
85949 }
85950 public function testResultCacheFile(): string
85951 {
85952 return $this->testResultCacheFile;
85953 }
85954 public function ignoreDeprecatedCodeUnitsFromCodeCoverage(): bool
85955 {
85956 return $this->ignoreDeprecatedCodeUnitsFromCodeCoverage;
85957 }
85958 public function disableCodeCoverageIgnore(): bool
85959 {
85960 return $this->disableCodeCoverageIgnore;
85961 }
85962 public function pathCoverage(): bool
85963 {
85964 return $this->pathCoverage;
85965 }
85966 public function hasCoverageReport(): bool
85967 {
85968 return $this->hasCoverageClover() || $this->hasCoverageCobertura() || $this->hasCoverageCrap4j() || $this->hasCoverageHtml() || $this->hasCoveragePhp() || $this->hasCoverageText() || $this->hasCoverageXml();
85969 }
85970 /**
85971 * @psalm-assert-if-true !null $this->coverageClover
85972 */
85973 public function hasCoverageClover(): bool
85974 {
85975 return $this->coverageClover !== null;
85976 }
85977 /**
85978 * @throws CodeCoverageReportNotConfiguredException
85979 */
85980 public function coverageClover(): string
85981 {
85982 if (!$this->hasCoverageClover()) {
85983 throw new \PHPUnit\TextUI\Configuration\CodeCoverageReportNotConfiguredException();
85984 }
85985 return $this->coverageClover;
85986 }
85987 /**
85988 * @psalm-assert-if-true !null $this->coverageCobertura
85989 */
85990 public function hasCoverageCobertura(): bool
85991 {
85992 return $this->coverageCobertura !== null;
85993 }
85994 /**
85995 * @throws CodeCoverageReportNotConfiguredException
85996 */
85997 public function coverageCobertura(): string
85998 {
85999 if (!$this->hasCoverageCobertura()) {
86000 throw new \PHPUnit\TextUI\Configuration\CodeCoverageReportNotConfiguredException();
86001 }
86002 return $this->coverageCobertura;
86003 }
86004 /**
86005 * @psalm-assert-if-true !null $this->coverageCrap4j
86006 */
86007 public function hasCoverageCrap4j(): bool
86008 {
86009 return $this->coverageCrap4j !== null;
86010 }
86011 /**
86012 * @throws CodeCoverageReportNotConfiguredException
86013 */
86014 public function coverageCrap4j(): string
86015 {
86016 if (!$this->hasCoverageCrap4j()) {
86017 throw new \PHPUnit\TextUI\Configuration\CodeCoverageReportNotConfiguredException();
86018 }
86019 return $this->coverageCrap4j;
86020 }
86021 public function coverageCrap4jThreshold(): int
86022 {
86023 return $this->coverageCrap4jThreshold;
86024 }
86025 /**
86026 * @psalm-assert-if-true !null $this->coverageHtml
86027 */
86028 public function hasCoverageHtml(): bool
86029 {
86030 return $this->coverageHtml !== null;
86031 }
86032 /**
86033 * @throws CodeCoverageReportNotConfiguredException
86034 */
86035 public function coverageHtml(): string
86036 {
86037 if (!$this->hasCoverageHtml()) {
86038 throw new \PHPUnit\TextUI\Configuration\CodeCoverageReportNotConfiguredException();
86039 }
86040 return $this->coverageHtml;
86041 }
86042 public function coverageHtmlLowUpperBound(): int
86043 {
86044 return $this->coverageHtmlLowUpperBound;
86045 }
86046 public function coverageHtmlHighLowerBound(): int
86047 {
86048 return $this->coverageHtmlHighLowerBound;
86049 }
86050 public function coverageHtmlColorSuccessLow(): string
86051 {
86052 return $this->coverageHtmlColorSuccessLow;
86053 }
86054 public function coverageHtmlColorSuccessMedium(): string
86055 {
86056 return $this->coverageHtmlColorSuccessMedium;
86057 }
86058 public function coverageHtmlColorSuccessHigh(): string
86059 {
86060 return $this->coverageHtmlColorSuccessHigh;
86061 }
86062 public function coverageHtmlColorWarning(): string
86063 {
86064 return $this->coverageHtmlColorWarning;
86065 }
86066 public function coverageHtmlColorDanger(): string
86067 {
86068 return $this->coverageHtmlColorDanger;
86069 }
86070 /**
86071 * @psalm-assert-if-true !null $this->coverageHtmlCustomCssFile
86072 */
86073 public function hasCoverageHtmlCustomCssFile(): bool
86074 {
86075 return $this->coverageHtmlCustomCssFile !== null;
86076 }
86077 /**
86078 * @throws NoCustomCssFileException
86079 */
86080 public function coverageHtmlCustomCssFile(): string
86081 {
86082 if (!$this->hasCoverageHtmlCustomCssFile()) {
86083 throw new \PHPUnit\TextUI\Configuration\NoCustomCssFileException();
86084 }
86085 return $this->coverageHtmlCustomCssFile;
86086 }
86087 /**
86088 * @psalm-assert-if-true !null $this->coveragePhp
86089 */
86090 public function hasCoveragePhp(): bool
86091 {
86092 return $this->coveragePhp !== null;
86093 }
86094 /**
86095 * @throws CodeCoverageReportNotConfiguredException
86096 */
86097 public function coveragePhp(): string
86098 {
86099 if (!$this->hasCoveragePhp()) {
86100 throw new \PHPUnit\TextUI\Configuration\CodeCoverageReportNotConfiguredException();
86101 }
86102 return $this->coveragePhp;
86103 }
86104 /**
86105 * @psalm-assert-if-true !null $this->coverageText
86106 */
86107 public function hasCoverageText(): bool
86108 {
86109 return $this->coverageText !== null;
86110 }
86111 /**
86112 * @throws CodeCoverageReportNotConfiguredException
86113 */
86114 public function coverageText(): string
86115 {
86116 if (!$this->hasCoverageText()) {
86117 throw new \PHPUnit\TextUI\Configuration\CodeCoverageReportNotConfiguredException();
86118 }
86119 return $this->coverageText;
86120 }
86121 public function coverageTextShowUncoveredFiles(): bool
86122 {
86123 return $this->coverageTextShowUncoveredFiles;
86124 }
86125 public function coverageTextShowOnlySummary(): bool
86126 {
86127 return $this->coverageTextShowOnlySummary;
86128 }
86129 /**
86130 * @psalm-assert-if-true !null $this->coverageXml
86131 */
86132 public function hasCoverageXml(): bool
86133 {
86134 return $this->coverageXml !== null;
86135 }
86136 /**
86137 * @throws CodeCoverageReportNotConfiguredException
86138 */
86139 public function coverageXml(): string
86140 {
86141 if (!$this->hasCoverageXml()) {
86142 throw new \PHPUnit\TextUI\Configuration\CodeCoverageReportNotConfiguredException();
86143 }
86144 return $this->coverageXml;
86145 }
86146 public function failOnAllIssues(): bool
86147 {
86148 return $this->failOnAllIssues;
86149 }
86150 public function failOnDeprecation(): bool
86151 {
86152 return $this->failOnDeprecation;
86153 }
86154 public function failOnPhpunitDeprecation(): bool
86155 {
86156 return $this->failOnPhpunitDeprecation;
86157 }
86158 public function failOnPhpunitWarning(): bool
86159 {
86160 return $this->failOnPhpunitWarning;
86161 }
86162 public function failOnEmptyTestSuite(): bool
86163 {
86164 return $this->failOnEmptyTestSuite;
86165 }
86166 public function failOnIncomplete(): bool
86167 {
86168 return $this->failOnIncomplete;
86169 }
86170 public function failOnNotice(): bool
86171 {
86172 return $this->failOnNotice;
86173 }
86174 public function failOnRisky(): bool
86175 {
86176 return $this->failOnRisky;
86177 }
86178 public function failOnSkipped(): bool
86179 {
86180 return $this->failOnSkipped;
86181 }
86182 public function failOnWarning(): bool
86183 {
86184 return $this->failOnWarning;
86185 }
86186 public function doNotFailOnDeprecation(): bool
86187 {
86188 return $this->doNotFailOnDeprecation;
86189 }
86190 public function doNotFailOnPhpunitDeprecation(): bool
86191 {
86192 return $this->doNotFailOnPhpunitDeprecation;
86193 }
86194 public function doNotFailOnPhpunitWarning(): bool
86195 {
86196 return $this->doNotFailOnPhpunitWarning;
86197 }
86198 public function doNotFailOnEmptyTestSuite(): bool
86199 {
86200 return $this->doNotFailOnEmptyTestSuite;
86201 }
86202 public function doNotFailOnIncomplete(): bool
86203 {
86204 return $this->doNotFailOnIncomplete;
86205 }
86206 public function doNotFailOnNotice(): bool
86207 {
86208 return $this->doNotFailOnNotice;
86209 }
86210 public function doNotFailOnRisky(): bool
86211 {
86212 return $this->doNotFailOnRisky;
86213 }
86214 public function doNotFailOnSkipped(): bool
86215 {
86216 return $this->doNotFailOnSkipped;
86217 }
86218 public function doNotFailOnWarning(): bool
86219 {
86220 return $this->doNotFailOnWarning;
86221 }
86222 public function stopOnDefect(): bool
86223 {
86224 return $this->stopOnDefect;
86225 }
86226 public function stopOnDeprecation(): bool
86227 {
86228 return $this->stopOnDeprecation;
86229 }
86230 public function stopOnError(): bool
86231 {
86232 return $this->stopOnError;
86233 }
86234 public function stopOnFailure(): bool
86235 {
86236 return $this->stopOnFailure;
86237 }
86238 public function stopOnIncomplete(): bool
86239 {
86240 return $this->stopOnIncomplete;
86241 }
86242 public function stopOnNotice(): bool
86243 {
86244 return $this->stopOnNotice;
86245 }
86246 public function stopOnRisky(): bool
86247 {
86248 return $this->stopOnRisky;
86249 }
86250 public function stopOnSkipped(): bool
86251 {
86252 return $this->stopOnSkipped;
86253 }
86254 public function stopOnWarning(): bool
86255 {
86256 return $this->stopOnWarning;
86257 }
86258 public function outputToStandardErrorStream(): bool
86259 {
86260 return $this->outputToStandardErrorStream;
86261 }
86262 public function columns(): int
86263 {
86264 return $this->columns;
86265 }
86266 /**
86267 * @deprecated Use noExtensions() instead
86268 */
86269 public function loadPharExtensions(): bool
86270 {
86271 return $this->noExtensions;
86272 }
86273 public function noExtensions(): bool
86274 {
86275 return $this->noExtensions;
86276 }
86277 /**
86278 * @psalm-assert-if-true !null $this->pharExtensionDirectory
86279 */
86280 public function hasPharExtensionDirectory(): bool
86281 {
86282 return $this->pharExtensionDirectory !== null;
86283 }
86284 /**
86285 * @throws NoPharExtensionDirectoryException
86286 *
86287 * @psalm-return non-empty-string
86288 */
86289 public function pharExtensionDirectory(): string
86290 {
86291 if (!$this->hasPharExtensionDirectory()) {
86292 throw new \PHPUnit\TextUI\Configuration\NoPharExtensionDirectoryException();
86293 }
86294 return $this->pharExtensionDirectory;
86295 }
86296 /**
86297 * @psalm-return list<array{className: class-string, parameters: array<string, string>}>
86298 */
86299 public function extensionBootstrappers(): array
86300 {
86301 return $this->extensionBootstrappers;
86302 }
86303 public function backupGlobals(): bool
86304 {
86305 return $this->backupGlobals;
86306 }
86307 public function backupStaticProperties(): bool
86308 {
86309 return $this->backupStaticProperties;
86310 }
86311 public function beStrictAboutChangesToGlobalState(): bool
86312 {
86313 return $this->beStrictAboutChangesToGlobalState;
86314 }
86315 public function colors(): bool
86316 {
86317 return $this->colors;
86318 }
86319 public function processIsolation(): bool
86320 {
86321 return $this->processIsolation;
86322 }
86323 public function enforceTimeLimit(): bool
86324 {
86325 return $this->enforceTimeLimit;
86326 }
86327 public function defaultTimeLimit(): int
86328 {
86329 return $this->defaultTimeLimit;
86330 }
86331 public function timeoutForSmallTests(): int
86332 {
86333 return $this->timeoutForSmallTests;
86334 }
86335 public function timeoutForMediumTests(): int
86336 {
86337 return $this->timeoutForMediumTests;
86338 }
86339 public function timeoutForLargeTests(): int
86340 {
86341 return $this->timeoutForLargeTests;
86342 }
86343 public function reportUselessTests(): bool
86344 {
86345 return $this->reportUselessTests;
86346 }
86347 public function strictCoverage(): bool
86348 {
86349 return $this->strictCoverage;
86350 }
86351 public function disallowTestOutput(): bool
86352 {
86353 return $this->disallowTestOutput;
86354 }
86355 public function displayDetailsOnAllIssues(): bool
86356 {
86357 return $this->displayDetailsOnAllIssues;
86358 }
86359 public function displayDetailsOnIncompleteTests(): bool
86360 {
86361 return $this->displayDetailsOnIncompleteTests;
86362 }
86363 public function displayDetailsOnSkippedTests(): bool
86364 {
86365 return $this->displayDetailsOnSkippedTests;
86366 }
86367 public function displayDetailsOnTestsThatTriggerDeprecations(): bool
86368 {
86369 return $this->displayDetailsOnTestsThatTriggerDeprecations;
86370 }
86371 public function displayDetailsOnPhpunitDeprecations(): bool
86372 {
86373 return $this->displayDetailsOnPhpunitDeprecations;
86374 }
86375 public function displayDetailsOnTestsThatTriggerErrors(): bool
86376 {
86377 return $this->displayDetailsOnTestsThatTriggerErrors;
86378 }
86379 public function displayDetailsOnTestsThatTriggerNotices(): bool
86380 {
86381 return $this->displayDetailsOnTestsThatTriggerNotices;
86382 }
86383 public function displayDetailsOnTestsThatTriggerWarnings(): bool
86384 {
86385 return $this->displayDetailsOnTestsThatTriggerWarnings;
86386 }
86387 public function reverseDefectList(): bool
86388 {
86389 return $this->reverseDefectList;
86390 }
86391 public function requireCoverageMetadata(): bool
86392 {
86393 return $this->requireCoverageMetadata;
86394 }
86395 /**
86396 * @deprecated
86397 */
86398 public function registerMockObjectsFromTestArgumentsRecursively(): bool
86399 {
86400 return $this->registerMockObjectsFromTestArgumentsRecursively;
86401 }
86402 public function noProgress(): bool
86403 {
86404 return $this->noProgress;
86405 }
86406 public function noResults(): bool
86407 {
86408 return $this->noResults;
86409 }
86410 public function noOutput(): bool
86411 {
86412 return $this->noOutput;
86413 }
86414 public function executionOrder(): int
86415 {
86416 return $this->executionOrder;
86417 }
86418 public function executionOrderDefects(): int
86419 {
86420 return $this->executionOrderDefects;
86421 }
86422 public function resolveDependencies(): bool
86423 {
86424 return $this->resolveDependencies;
86425 }
86426 /**
86427 * @psalm-assert-if-true !null $this->logfileTeamcity
86428 */
86429 public function hasLogfileTeamcity(): bool
86430 {
86431 return $this->logfileTeamcity !== null;
86432 }
86433 /**
86434 * @throws LoggingNotConfiguredException
86435 */
86436 public function logfileTeamcity(): string
86437 {
86438 if (!$this->hasLogfileTeamcity()) {
86439 throw new \PHPUnit\TextUI\Configuration\LoggingNotConfiguredException();
86440 }
86441 return $this->logfileTeamcity;
86442 }
86443 /**
86444 * @psalm-assert-if-true !null $this->logfileJunit
86445 */
86446 public function hasLogfileJunit(): bool
86447 {
86448 return $this->logfileJunit !== null;
86449 }
86450 /**
86451 * @throws LoggingNotConfiguredException
86452 */
86453 public function logfileJunit(): string
86454 {
86455 if (!$this->hasLogfileJunit()) {
86456 throw new \PHPUnit\TextUI\Configuration\LoggingNotConfiguredException();
86457 }
86458 return $this->logfileJunit;
86459 }
86460 /**
86461 * @psalm-assert-if-true !null $this->logfileTestdoxHtml
86462 */
86463 public function hasLogfileTestdoxHtml(): bool
86464 {
86465 return $this->logfileTestdoxHtml !== null;
86466 }
86467 /**
86468 * @throws LoggingNotConfiguredException
86469 */
86470 public function logfileTestdoxHtml(): string
86471 {
86472 if (!$this->hasLogfileTestdoxHtml()) {
86473 throw new \PHPUnit\TextUI\Configuration\LoggingNotConfiguredException();
86474 }
86475 return $this->logfileTestdoxHtml;
86476 }
86477 /**
86478 * @psalm-assert-if-true !null $this->logfileTestdoxText
86479 */
86480 public function hasLogfileTestdoxText(): bool
86481 {
86482 return $this->logfileTestdoxText !== null;
86483 }
86484 /**
86485 * @throws LoggingNotConfiguredException
86486 */
86487 public function logfileTestdoxText(): string
86488 {
86489 if (!$this->hasLogfileTestdoxText()) {
86490 throw new \PHPUnit\TextUI\Configuration\LoggingNotConfiguredException();
86491 }
86492 return $this->logfileTestdoxText;
86493 }
86494 /**
86495 * @psalm-assert-if-true !null $this->logEventsText
86496 */
86497 public function hasLogEventsText(): bool
86498 {
86499 return $this->logEventsText !== null;
86500 }
86501 /**
86502 * @throws LoggingNotConfiguredException
86503 */
86504 public function logEventsText(): string
86505 {
86506 if (!$this->hasLogEventsText()) {
86507 throw new \PHPUnit\TextUI\Configuration\LoggingNotConfiguredException();
86508 }
86509 return $this->logEventsText;
86510 }
86511 /**
86512 * @psalm-assert-if-true !null $this->logEventsVerboseText
86513 */
86514 public function hasLogEventsVerboseText(): bool
86515 {
86516 return $this->logEventsVerboseText !== null;
86517 }
86518 /**
86519 * @throws LoggingNotConfiguredException
86520 */
86521 public function logEventsVerboseText(): string
86522 {
86523 if (!$this->hasLogEventsVerboseText()) {
86524 throw new \PHPUnit\TextUI\Configuration\LoggingNotConfiguredException();
86525 }
86526 return $this->logEventsVerboseText;
86527 }
86528 public function outputIsTeamCity(): bool
86529 {
86530 return $this->teamCityOutput;
86531 }
86532 public function outputIsTestDox(): bool
86533 {
86534 return $this->testDoxOutput;
86535 }
86536 /**
86537 * @psalm-assert-if-true !empty $this->testsCovering
86538 */
86539 public function hasTestsCovering(): bool
86540 {
86541 return !empty($this->testsCovering);
86542 }
86543 /**
86544 * @throws FilterNotConfiguredException
86545 *
86546 * @psalm-return list<string>
86547 */
86548 public function testsCovering(): array
86549 {
86550 if (!$this->hasTestsCovering()) {
86551 throw new \PHPUnit\TextUI\Configuration\FilterNotConfiguredException();
86552 }
86553 return $this->testsCovering;
86554 }
86555 /**
86556 * @psalm-assert-if-true !empty $this->testsUsing
86557 */
86558 public function hasTestsUsing(): bool
86559 {
86560 return !empty($this->testsUsing);
86561 }
86562 /**
86563 * @throws FilterNotConfiguredException
86564 *
86565 * @psalm-return list<string>
86566 */
86567 public function testsUsing(): array
86568 {
86569 if (!$this->hasTestsUsing()) {
86570 throw new \PHPUnit\TextUI\Configuration\FilterNotConfiguredException();
86571 }
86572 return $this->testsUsing;
86573 }
86574 /**
86575 * @psalm-assert-if-true !null $this->filter
86576 */
86577 public function hasFilter(): bool
86578 {
86579 return $this->filter !== null;
86580 }
86581 /**
86582 * @throws FilterNotConfiguredException
86583 */
86584 public function filter(): string
86585 {
86586 if (!$this->hasFilter()) {
86587 throw new \PHPUnit\TextUI\Configuration\FilterNotConfiguredException();
86588 }
86589 return $this->filter;
86590 }
86591 /**
86592 * @psalm-assert-if-true !empty $this->groups
86593 */
86594 public function hasGroups(): bool
86595 {
86596 return !empty($this->groups);
86597 }
86598 /**
86599 * @throws FilterNotConfiguredException
86600 */
86601 public function groups(): array
86602 {
86603 if (!$this->hasGroups()) {
86604 throw new \PHPUnit\TextUI\Configuration\FilterNotConfiguredException();
86605 }
86606 return $this->groups;
86607 }
86608 /**
86609 * @psalm-assert-if-true !empty $this->excludeGroups
86610 */
86611 public function hasExcludeGroups(): bool
86612 {
86613 return !empty($this->excludeGroups);
86614 }
86615 /**
86616 * @throws FilterNotConfiguredException
86617 */
86618 public function excludeGroups(): array
86619 {
86620 if (!$this->hasExcludeGroups()) {
86621 throw new \PHPUnit\TextUI\Configuration\FilterNotConfiguredException();
86622 }
86623 return $this->excludeGroups;
86624 }
86625 public function randomOrderSeed(): int
86626 {
86627 return $this->randomOrderSeed;
86628 }
86629 public function includeUncoveredFiles(): bool
86630 {
86631 return $this->includeUncoveredFiles;
86632 }
86633 public function testSuite(): \PHPUnit\TextUI\Configuration\TestSuiteCollection
86634 {
86635 return $this->testSuite;
86636 }
86637 public function includeTestSuite(): string
86638 {
86639 return $this->includeTestSuite;
86640 }
86641 public function excludeTestSuite(): string
86642 {
86643 return $this->excludeTestSuite;
86644 }
86645 /**
86646 * @psalm-assert-if-true !null $this->defaultTestSuite
86647 */
86648 public function hasDefaultTestSuite(): bool
86649 {
86650 return $this->defaultTestSuite !== null;
86651 }
86652 /**
86653 * @throws NoDefaultTestSuiteException
86654 */
86655 public function defaultTestSuite(): string
86656 {
86657 if (!$this->hasDefaultTestSuite()) {
86658 throw new \PHPUnit\TextUI\Configuration\NoDefaultTestSuiteException();
86659 }
86660 return $this->defaultTestSuite;
86661 }
86662 /**
86663 * @psalm-return non-empty-list<non-empty-string>
86664 */
86665 public function testSuffixes(): array
86666 {
86667 return $this->testSuffixes;
86668 }
86669 public function php(): \PHPUnit\TextUI\Configuration\Php
86670 {
86671 return $this->php;
86672 }
86673 public function controlGarbageCollector(): bool
86674 {
86675 return $this->controlGarbageCollector;
86676 }
86677 public function numberOfTestsBeforeGarbageCollection(): int
86678 {
86679 return $this->numberOfTestsBeforeGarbageCollection;
86680 }
86681 /**
86682 * @psalm-assert-if-true !null $this->generateBaseline
86683 */
86684 public function hasGenerateBaseline(): bool
86685 {
86686 return $this->generateBaseline !== null;
86687 }
86688 /**
86689 * @throws NoBaselineException
86690 */
86691 public function generateBaseline(): string
86692 {
86693 if (!$this->hasGenerateBaseline()) {
86694 throw new \PHPUnit\TextUI\Configuration\NoBaselineException();
86695 }
86696 return $this->generateBaseline;
86697 }
86698 public function debug(): bool
86699 {
86700 return $this->debug;
86701 }
86702 }
86703 <?php
86704
86705 declare (strict_types=1);
86706 /*
86707 * This file is part of PHPUnit.
86708 *
86709 * (c) Sebastian Bergmann <sebastian@phpunit.de>
86710 *
86711 * For the full copyright and license information, please view the LICENSE
86712 * file that was distributed with this source code.
86713 */
86714 namespace PHPUnit\TextUI\XmlConfiguration;
86715
86716 use PHPUnit\TextUI\Configuration\Exception;
86717 use RuntimeException;
86718 /**
86719 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
86720 *
86721 * @internal This class is not covered by the backward compatibility promise for PHPUnit
86722 */
86723 final class CannotFindSchemaException extends RuntimeException implements Exception
86724 {
86725 }
86726 <?php
86727
86728 declare (strict_types=1);
86729 /*
86730 * This file is part of PHPUnit.
86731 *
86732 * (c) Sebastian Bergmann <sebastian@phpunit.de>
86733 *
86734 * For the full copyright and license information, please view the LICENSE
86735 * file that was distributed with this source code.
86736 */
86737 namespace PHPUnit\TextUI\Configuration;
86738
86739 use RuntimeException;
86740 /**
86741 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
86742 *
86743 * @internal This class is not covered by the backward compatibility promise for PHPUnit
86744 */
86745 final class CodeCoverageReportNotConfiguredException extends RuntimeException implements \PHPUnit\TextUI\Configuration\Exception
86746 {
86747 }
86748 <?php
86749
86750 declare (strict_types=1);
86751 /*
86752 * This file is part of PHPUnit.
86753 *
86754 * (c) Sebastian Bergmann <sebastian@phpunit.de>
86755 *
86756 * For the full copyright and license information, please view the LICENSE
86757 * file that was distributed with this source code.
86758 */
86759 namespace PHPUnit\TextUI\Configuration;
86760
86761 use RuntimeException;
86762 /**
86763 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
86764 *
86765 * @internal This class is not covered by the backward compatibility promise for PHPUnit
86766 */
86767 final class ConfigurationCannotBeBuiltException extends RuntimeException implements \PHPUnit\TextUI\Configuration\Exception
86768 {
86769 }
86770 <?php
86771
86772 declare (strict_types=1);
86773 /*
86774 * This file is part of PHPUnit.
86775 *
86776 * (c) Sebastian Bergmann <sebastian@phpunit.de>
86777 *
86778 * For the full copyright and license information, please view the LICENSE
86779 * file that was distributed with this source code.
86780 */
86781 namespace PHPUnit\TextUI\Configuration;
86782
86783 /**
86784 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
86785 *
86786 * @internal This interface is not covered by the backward compatibility promise for PHPUnit
86787 */
86788 interface Exception extends \PHPUnit\TextUI\Exception
86789 {
86790 }
86791 <?php
86792
86793 declare (strict_types=1);
86794 /*
86795 * This file is part of PHPUnit.
86796 *
86797 * (c) Sebastian Bergmann <sebastian@phpunit.de>
86798 *
86799 * For the full copyright and license information, please view the LICENSE
86800 * file that was distributed with this source code.
86801 */
86802 namespace PHPUnit\TextUI\Configuration;
86803
86804 use RuntimeException;
86805 /**
86806 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
86807 *
86808 * @internal This class is not covered by the backward compatibility promise for PHPUnit
86809 */
86810 final class FilterNotConfiguredException extends RuntimeException implements \PHPUnit\TextUI\Configuration\Exception
86811 {
86812 }
86813 <?php
86814
86815 declare (strict_types=1);
86816 /*
86817 * This file is part of PHPUnit.
86818 *
86819 * (c) Sebastian Bergmann <sebastian@phpunit.de>
86820 *
86821 * For the full copyright and license information, please view the LICENSE
86822 * file that was distributed with this source code.
86823 */
86824 namespace PHPUnit\TextUI\Configuration;
86825
86826 use RuntimeException;
86827 /**
86828 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
86829 *
86830 * @internal This class is not covered by the backward compatibility promise for PHPUnit
86831 */
86832 final class LoggingNotConfiguredException extends RuntimeException implements \PHPUnit\TextUI\Configuration\Exception
86833 {
86834 }
86835 <?php
86836
86837 declare (strict_types=1);
86838 /*
86839 * This file is part of PHPUnit.
86840 *
86841 * (c) Sebastian Bergmann <sebastian@phpunit.de>
86842 *
86843 * For the full copyright and license information, please view the LICENSE
86844 * file that was distributed with this source code.
86845 */
86846 namespace PHPUnit\TextUI\Configuration;
86847
86848 use RuntimeException;
86849 /**
86850 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
86851 *
86852 * @internal This class is not covered by the backward compatibility promise for PHPUnit
86853 */
86854 final class NoBaselineException extends RuntimeException implements \PHPUnit\TextUI\Configuration\Exception
86855 {
86856 }
86857 <?php
86858
86859 declare (strict_types=1);
86860 /*
86861 * This file is part of PHPUnit.
86862 *
86863 * (c) Sebastian Bergmann <sebastian@phpunit.de>
86864 *
86865 * For the full copyright and license information, please view the LICENSE
86866 * file that was distributed with this source code.
86867 */
86868 namespace PHPUnit\TextUI\Configuration;
86869
86870 use RuntimeException;
86871 /**
86872 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
86873 *
86874 * @internal This class is not covered by the backward compatibility promise for PHPUnit
86875 */
86876 final class NoBootstrapException extends RuntimeException implements \PHPUnit\TextUI\Configuration\Exception
86877 {
86878 }
86879 <?php
86880
86881 declare (strict_types=1);
86882 /*
86883 * This file is part of PHPUnit.
86884 *
86885 * (c) Sebastian Bergmann <sebastian@phpunit.de>
86886 *
86887 * For the full copyright and license information, please view the LICENSE
86888 * file that was distributed with this source code.
86889 */
86890 namespace PHPUnit\TextUI\Configuration;
86891
86892 use RuntimeException;
86893 /**
86894 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
86895 *
86896 * @internal This class is not covered by the backward compatibility promise for PHPUnit
86897 */
86898 final class NoCacheDirectoryException extends RuntimeException implements \PHPUnit\TextUI\Configuration\Exception
86899 {
86900 }
86901 <?php
86902
86903 declare (strict_types=1);
86904 /*
86905 * This file is part of PHPUnit.
86906 *
86907 * (c) Sebastian Bergmann <sebastian@phpunit.de>
86908 *
86909 * For the full copyright and license information, please view the LICENSE
86910 * file that was distributed with this source code.
86911 */
86912 namespace PHPUnit\TextUI\Configuration;
86913
86914 use RuntimeException;
86915 /**
86916 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
86917 *
86918 * @internal This class is not covered by the backward compatibility promise for PHPUnit
86919 */
86920 final class NoCliArgumentException extends RuntimeException implements \PHPUnit\TextUI\Configuration\Exception
86921 {
86922 }
86923 <?php
86924
86925 declare (strict_types=1);
86926 /*
86927 * This file is part of PHPUnit.
86928 *
86929 * (c) Sebastian Bergmann <sebastian@phpunit.de>
86930 *
86931 * For the full copyright and license information, please view the LICENSE
86932 * file that was distributed with this source code.
86933 */
86934 namespace PHPUnit\TextUI\Configuration;
86935
86936 use RuntimeException;
86937 /**
86938 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
86939 *
86940 * @internal This class is not covered by the backward compatibility promise for PHPUnit
86941 */
86942 final class NoConfigurationFileException extends RuntimeException implements \PHPUnit\TextUI\Configuration\Exception
86943 {
86944 }
86945 <?php
86946
86947 declare (strict_types=1);
86948 /*
86949 * This file is part of PHPUnit.
86950 *
86951 * (c) Sebastian Bergmann <sebastian@phpunit.de>
86952 *
86953 * For the full copyright and license information, please view the LICENSE
86954 * file that was distributed with this source code.
86955 */
86956 namespace PHPUnit\TextUI\Configuration;
86957
86958 use RuntimeException;
86959 /**
86960 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
86961 *
86962 * @internal This class is not covered by the backward compatibility promise for PHPUnit
86963 */
86964 final class NoCoverageCacheDirectoryException extends RuntimeException implements \PHPUnit\TextUI\Configuration\Exception
86965 {
86966 }
86967 <?php
86968
86969 declare (strict_types=1);
86970 /*
86971 * This file is part of PHPUnit.
86972 *
86973 * (c) Sebastian Bergmann <sebastian@phpunit.de>
86974 *
86975 * For the full copyright and license information, please view the LICENSE
86976 * file that was distributed with this source code.
86977 */
86978 namespace PHPUnit\TextUI\Configuration;
86979
86980 use RuntimeException;
86981 /**
86982 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
86983 *
86984 * @internal This class is not covered by the backward compatibility promise for PHPUnit
86985 */
86986 final class NoCustomCssFileException extends RuntimeException implements \PHPUnit\TextUI\Configuration\Exception
86987 {
86988 }
86989 <?php
86990
86991 declare (strict_types=1);
86992 /*
86993 * This file is part of PHPUnit.
86994 *
86995 * (c) Sebastian Bergmann <sebastian@phpunit.de>
86996 *
86997 * For the full copyright and license information, please view the LICENSE
86998 * file that was distributed with this source code.
86999 */
87000 namespace PHPUnit\TextUI\Configuration;
87001
87002 use RuntimeException;
87003 /**
87004 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
87005 *
87006 * @internal This class is not covered by the backward compatibility promise for PHPUnit
87007 */
87008 final class NoDefaultTestSuiteException extends RuntimeException implements \PHPUnit\TextUI\Configuration\Exception
87009 {
87010 }
87011 <?php
87012
87013 declare (strict_types=1);
87014 /*
87015 * This file is part of PHPUnit.
87016 *
87017 * (c) Sebastian Bergmann <sebastian@phpunit.de>
87018 *
87019 * For the full copyright and license information, please view the LICENSE
87020 * file that was distributed with this source code.
87021 */
87022 namespace PHPUnit\TextUI\Configuration;
87023
87024 use RuntimeException;
87025 /**
87026 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
87027 *
87028 * @internal This class is not covered by the backward compatibility promise for PHPUnit
87029 */
87030 final class NoPharExtensionDirectoryException extends RuntimeException implements \PHPUnit\TextUI\Configuration\Exception
87031 {
87032 }
87033 <?php
87034
87035 declare (strict_types=1);
87036 /*
87037 * This file is part of PHPUnit.
87038 *
87039 * (c) Sebastian Bergmann <sebastian@phpunit.de>
87040 *
87041 * For the full copyright and license information, please view the LICENSE
87042 * file that was distributed with this source code.
87043 */
87044 namespace PHPUnit\TextUI\Configuration;
87045
87046 use const DIRECTORY_SEPARATOR;
87047 use const PATH_SEPARATOR;
87048 use function array_diff;
87049 use function assert;
87050 use function dirname;
87051 use function explode;
87052 use function is_int;
87053 use function realpath;
87054 use function time;
87055 use PHPUnit\Event\Facade as EventFacade;
87056 use PHPUnit\Runner\TestSuiteSorter;
87057 use PHPUnit\TextUI\CliArguments\Configuration as CliConfiguration;
87058 use PHPUnit\TextUI\CliArguments\Exception;
87059 use PHPUnit\TextUI\XmlConfiguration\Configuration as XmlConfiguration;
87060 use PHPUnit\TextUI\XmlConfiguration\LoadedFromFileConfiguration;
87061 use PHPUnit\TextUI\XmlConfiguration\SchemaDetector;
87062 use PHPUnit\Util\Filesystem;
87063 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Report\Html\Colors;
87064 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Report\Thresholds;
87065 use PHPUnitPHAR\SebastianBergmann\Environment\Console;
87066 use PHPUnitPHAR\SebastianBergmann\Invoker\Invoker;
87067 /**
87068 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
87069 *
87070 * @internal This class is not covered by the backward compatibility promise for PHPUnit
87071 */
87072 final class Merger
87073 {
87074 /**
87075 * @throws \PHPUnit\TextUI\XmlConfiguration\Exception
87076 * @throws Exception
87077 * @throws NoCustomCssFileException
87078 */
87079 public function merge(CliConfiguration $cliConfiguration, XmlConfiguration $xmlConfiguration): \PHPUnit\TextUI\Configuration\Configuration
87080 {
87081 $configurationFile = null;
87082 if ($xmlConfiguration->wasLoadedFromFile()) {
87083 assert($xmlConfiguration instanceof LoadedFromFileConfiguration);
87084 $configurationFile = $xmlConfiguration->filename();
87085 }
87086 $bootstrap = null;
87087 if ($cliConfiguration->hasBootstrap()) {
87088 $bootstrap = $cliConfiguration->bootstrap();
87089 } elseif ($xmlConfiguration->phpunit()->hasBootstrap()) {
87090 $bootstrap = $xmlConfiguration->phpunit()->bootstrap();
87091 }
87092 if ($cliConfiguration->hasCacheResult()) {
87093 $cacheResult = $cliConfiguration->cacheResult();
87094 } else {
87095 $cacheResult = $xmlConfiguration->phpunit()->cacheResult();
87096 }
87097 $cacheDirectory = null;
87098 $coverageCacheDirectory = null;
87099 if ($cliConfiguration->hasCacheDirectory() && Filesystem::createDirectory($cliConfiguration->cacheDirectory())) {
87100 $cacheDirectory = realpath($cliConfiguration->cacheDirectory());
87101 } elseif ($xmlConfiguration->phpunit()->hasCacheDirectory() && Filesystem::createDirectory($xmlConfiguration->phpunit()->cacheDirectory())) {
87102 $cacheDirectory = realpath($xmlConfiguration->phpunit()->cacheDirectory());
87103 }
87104 if ($cacheDirectory !== null) {
87105 $coverageCacheDirectory = $cacheDirectory . DIRECTORY_SEPARATOR . 'code-coverage';
87106 $testResultCacheFile = $cacheDirectory . DIRECTORY_SEPARATOR . 'test-results';
87107 }
87108 if ($coverageCacheDirectory === null) {
87109 if ($cliConfiguration->hasCoverageCacheDirectory() && Filesystem::createDirectory($cliConfiguration->coverageCacheDirectory())) {
87110 $coverageCacheDirectory = realpath($cliConfiguration->coverageCacheDirectory());
87111 } elseif ($xmlConfiguration->codeCoverage()->hasCacheDirectory()) {
87112 $coverageCacheDirectory = $xmlConfiguration->codeCoverage()->cacheDirectory()->path();
87113 }
87114 }
87115 if (!isset($testResultCacheFile)) {
87116 if ($cliConfiguration->hasCacheResultFile()) {
87117 $testResultCacheFile = $cliConfiguration->cacheResultFile();
87118 } elseif ($xmlConfiguration->phpunit()->hasCacheResultFile()) {
87119 $testResultCacheFile = $xmlConfiguration->phpunit()->cacheResultFile();
87120 } elseif ($xmlConfiguration->wasLoadedFromFile()) {
87121 $testResultCacheFile = dirname(realpath($xmlConfiguration->filename())) . DIRECTORY_SEPARATOR . '.phpunit.result.cache';
87122 } else {
87123 $candidate = realpath($_SERVER['PHP_SELF']);
87124 if ($candidate) {
87125 $testResultCacheFile = dirname($candidate) . DIRECTORY_SEPARATOR . '.phpunit.result.cache';
87126 } else {
87127 $testResultCacheFile = '.phpunit.result.cache';
87128 }
87129 }
87130 }
87131 if ($cliConfiguration->hasDisableCodeCoverageIgnore()) {
87132 $disableCodeCoverageIgnore = $cliConfiguration->disableCodeCoverageIgnore();
87133 } else {
87134 $disableCodeCoverageIgnore = $xmlConfiguration->codeCoverage()->disableCodeCoverageIgnore();
87135 }
87136 if ($cliConfiguration->hasFailOnAllIssues()) {
87137 $failOnAllIssues = $cliConfiguration->failOnAllIssues();
87138 } else {
87139 $failOnAllIssues = $xmlConfiguration->phpunit()->failOnAllIssues();
87140 }
87141 if ($cliConfiguration->hasFailOnDeprecation()) {
87142 $failOnDeprecation = $cliConfiguration->failOnDeprecation();
87143 } else {
87144 $failOnDeprecation = $xmlConfiguration->phpunit()->failOnDeprecation();
87145 }
87146 if ($cliConfiguration->hasFailOnPhpunitDeprecation()) {
87147 $failOnPhpunitDeprecation = $cliConfiguration->failOnPhpunitDeprecation();
87148 } else {
87149 $failOnPhpunitDeprecation = $xmlConfiguration->phpunit()->failOnPhpunitDeprecation();
87150 }
87151 if ($cliConfiguration->hasFailOnPhpunitWarning()) {
87152 $failOnPhpunitWarning = $cliConfiguration->failOnPhpunitWarning();
87153 } else {
87154 $failOnPhpunitWarning = $xmlConfiguration->phpunit()->failOnPhpunitWarning();
87155 }
87156 if ($cliConfiguration->hasFailOnEmptyTestSuite()) {
87157 $failOnEmptyTestSuite = $cliConfiguration->failOnEmptyTestSuite();
87158 } else {
87159 $failOnEmptyTestSuite = $xmlConfiguration->phpunit()->failOnEmptyTestSuite();
87160 }
87161 if ($cliConfiguration->hasFailOnIncomplete()) {
87162 $failOnIncomplete = $cliConfiguration->failOnIncomplete();
87163 } else {
87164 $failOnIncomplete = $xmlConfiguration->phpunit()->failOnIncomplete();
87165 }
87166 if ($cliConfiguration->hasFailOnNotice()) {
87167 $failOnNotice = $cliConfiguration->failOnNotice();
87168 } else {
87169 $failOnNotice = $xmlConfiguration->phpunit()->failOnNotice();
87170 }
87171 if ($cliConfiguration->hasFailOnRisky()) {
87172 $failOnRisky = $cliConfiguration->failOnRisky();
87173 } else {
87174 $failOnRisky = $xmlConfiguration->phpunit()->failOnRisky();
87175 }
87176 if ($cliConfiguration->hasFailOnSkipped()) {
87177 $failOnSkipped = $cliConfiguration->failOnSkipped();
87178 } else {
87179 $failOnSkipped = $xmlConfiguration->phpunit()->failOnSkipped();
87180 }
87181 if ($cliConfiguration->hasFailOnWarning()) {
87182 $failOnWarning = $cliConfiguration->failOnWarning();
87183 } else {
87184 $failOnWarning = $xmlConfiguration->phpunit()->failOnWarning();
87185 }
87186 $doNotFailOnDeprecation = \false;
87187 if ($cliConfiguration->hasDoNotFailOnDeprecation()) {
87188 $doNotFailOnDeprecation = $cliConfiguration->doNotFailOnDeprecation();
87189 }
87190 $doNotFailOnPhpunitDeprecation = \false;
87191 if ($cliConfiguration->hasDoNotFailOnPhpunitDeprecation()) {
87192 $doNotFailOnPhpunitDeprecation = $cliConfiguration->doNotFailOnPhpunitDeprecation();
87193 }
87194 $doNotFailOnPhpunitWarning = \false;
87195 if ($cliConfiguration->hasDoNotFailOnPhpunitWarning()) {
87196 $doNotFailOnPhpunitWarning = $cliConfiguration->doNotFailOnPhpunitWarning();
87197 }
87198 $doNotFailOnEmptyTestSuite = \false;
87199 if ($cliConfiguration->hasDoNotFailOnEmptyTestSuite()) {
87200 $doNotFailOnEmptyTestSuite = $cliConfiguration->doNotFailOnEmptyTestSuite();
87201 }
87202 $doNotFailOnIncomplete = \false;
87203 if ($cliConfiguration->hasDoNotFailOnIncomplete()) {
87204 $doNotFailOnIncomplete = $cliConfiguration->doNotFailOnIncomplete();
87205 }
87206 $doNotFailOnNotice = \false;
87207 if ($cliConfiguration->hasDoNotFailOnNotice()) {
87208 $doNotFailOnNotice = $cliConfiguration->doNotFailOnNotice();
87209 }
87210 $doNotFailOnRisky = \false;
87211 if ($cliConfiguration->hasDoNotFailOnRisky()) {
87212 $doNotFailOnRisky = $cliConfiguration->doNotFailOnRisky();
87213 }
87214 $doNotFailOnSkipped = \false;
87215 if ($cliConfiguration->hasDoNotFailOnSkipped()) {
87216 $doNotFailOnSkipped = $cliConfiguration->doNotFailOnSkipped();
87217 }
87218 $doNotFailOnWarning = \false;
87219 if ($cliConfiguration->hasDoNotFailOnWarning()) {
87220 $doNotFailOnWarning = $cliConfiguration->doNotFailOnWarning();
87221 }
87222 if ($cliConfiguration->hasStopOnDefect()) {
87223 $stopOnDefect = $cliConfiguration->stopOnDefect();
87224 } else {
87225 $stopOnDefect = $xmlConfiguration->phpunit()->stopOnDefect();
87226 }
87227 if ($cliConfiguration->hasStopOnDeprecation()) {
87228 $stopOnDeprecation = $cliConfiguration->stopOnDeprecation();
87229 } else {
87230 $stopOnDeprecation = $xmlConfiguration->phpunit()->stopOnDeprecation();
87231 }
87232 if ($cliConfiguration->hasStopOnError()) {
87233 $stopOnError = $cliConfiguration->stopOnError();
87234 } else {
87235 $stopOnError = $xmlConfiguration->phpunit()->stopOnError();
87236 }
87237 if ($cliConfiguration->hasStopOnFailure()) {
87238 $stopOnFailure = $cliConfiguration->stopOnFailure();
87239 } else {
87240 $stopOnFailure = $xmlConfiguration->phpunit()->stopOnFailure();
87241 }
87242 if ($cliConfiguration->hasStopOnIncomplete()) {
87243 $stopOnIncomplete = $cliConfiguration->stopOnIncomplete();
87244 } else {
87245 $stopOnIncomplete = $xmlConfiguration->phpunit()->stopOnIncomplete();
87246 }
87247 if ($cliConfiguration->hasStopOnNotice()) {
87248 $stopOnNotice = $cliConfiguration->stopOnNotice();
87249 } else {
87250 $stopOnNotice = $xmlConfiguration->phpunit()->stopOnNotice();
87251 }
87252 if ($cliConfiguration->hasStopOnRisky()) {
87253 $stopOnRisky = $cliConfiguration->stopOnRisky();
87254 } else {
87255 $stopOnRisky = $xmlConfiguration->phpunit()->stopOnRisky();
87256 }
87257 if ($cliConfiguration->hasStopOnSkipped()) {
87258 $stopOnSkipped = $cliConfiguration->stopOnSkipped();
87259 } else {
87260 $stopOnSkipped = $xmlConfiguration->phpunit()->stopOnSkipped();
87261 }
87262 if ($cliConfiguration->hasStopOnWarning()) {
87263 $stopOnWarning = $cliConfiguration->stopOnWarning();
87264 } else {
87265 $stopOnWarning = $xmlConfiguration->phpunit()->stopOnWarning();
87266 }
87267 if ($cliConfiguration->hasStderr() && $cliConfiguration->stderr()) {
87268 $outputToStandardErrorStream = \true;
87269 } else {
87270 $outputToStandardErrorStream = $xmlConfiguration->phpunit()->stderr();
87271 }
87272 if ($cliConfiguration->hasColumns()) {
87273 $columns = $cliConfiguration->columns();
87274 } else {
87275 $columns = $xmlConfiguration->phpunit()->columns();
87276 }
87277 if ($columns === 'max') {
87278 $columns = (new Console())->getNumberOfColumns();
87279 }
87280 if ($columns < 16) {
87281 $columns = 16;
87282 EventFacade::emitter()->testRunnerTriggeredPhpunitWarning('Less than 16 columns requested, number of columns set to 16');
87283 }
87284 assert(is_int($columns));
87285 $noExtensions = \false;
87286 if ($cliConfiguration->hasNoExtensions() && $cliConfiguration->noExtensions()) {
87287 $noExtensions = \true;
87288 }
87289 $pharExtensionDirectory = null;
87290 if ($xmlConfiguration->phpunit()->hasExtensionsDirectory()) {
87291 $pharExtensionDirectory = $xmlConfiguration->phpunit()->extensionsDirectory();
87292 }
87293 $extensionBootstrappers = [];
87294 foreach ($xmlConfiguration->extensions() as $extension) {
87295 $extensionBootstrappers[] = ['className' => $extension->className(), 'parameters' => $extension->parameters()];
87296 }
87297 if ($cliConfiguration->hasPathCoverage() && $cliConfiguration->pathCoverage()) {
87298 $pathCoverage = $cliConfiguration->pathCoverage();
87299 } else {
87300 $pathCoverage = $xmlConfiguration->codeCoverage()->pathCoverage();
87301 }
87302 $defaultColors = Colors::default();
87303 $defaultThresholds = Thresholds::default();
87304 $coverageClover = null;
87305 $coverageCobertura = null;
87306 $coverageCrap4j = null;
87307 $coverageCrap4jThreshold = 30;
87308 $coverageHtml = null;
87309 $coverageHtmlLowUpperBound = $defaultThresholds->lowUpperBound();
87310 $coverageHtmlHighLowerBound = $defaultThresholds->highLowerBound();
87311 $coverageHtmlColorSuccessLow = $defaultColors->successLow();
87312 $coverageHtmlColorSuccessMedium = $defaultColors->successMedium();
87313 $coverageHtmlColorSuccessHigh = $defaultColors->successHigh();
87314 $coverageHtmlColorWarning = $defaultColors->warning();
87315 $coverageHtmlColorDanger = $defaultColors->danger();
87316 $coverageHtmlCustomCssFile = null;
87317 $coveragePhp = null;
87318 $coverageText = null;
87319 $coverageTextShowUncoveredFiles = \false;
87320 $coverageTextShowOnlySummary = \false;
87321 $coverageXml = null;
87322 $coverageFromXmlConfiguration = \true;
87323 if ($cliConfiguration->hasNoCoverage() && $cliConfiguration->noCoverage()) {
87324 $coverageFromXmlConfiguration = \false;
87325 }
87326 if ($cliConfiguration->hasCoverageClover()) {
87327 $coverageClover = $cliConfiguration->coverageClover();
87328 } elseif ($coverageFromXmlConfiguration && $xmlConfiguration->codeCoverage()->hasClover()) {
87329 $coverageClover = $xmlConfiguration->codeCoverage()->clover()->target()->path();
87330 }
87331 if ($cliConfiguration->hasCoverageCobertura()) {
87332 $coverageCobertura = $cliConfiguration->coverageCobertura();
87333 } elseif ($coverageFromXmlConfiguration && $xmlConfiguration->codeCoverage()->hasCobertura()) {
87334 $coverageCobertura = $xmlConfiguration->codeCoverage()->cobertura()->target()->path();
87335 }
87336 if ($xmlConfiguration->codeCoverage()->hasCrap4j()) {
87337 $coverageCrap4jThreshold = $xmlConfiguration->codeCoverage()->crap4j()->threshold();
87338 }
87339 if ($cliConfiguration->hasCoverageCrap4J()) {
87340 $coverageCrap4j = $cliConfiguration->coverageCrap4J();
87341 } elseif ($coverageFromXmlConfiguration && $xmlConfiguration->codeCoverage()->hasCrap4j()) {
87342 $coverageCrap4j = $xmlConfiguration->codeCoverage()->crap4j()->target()->path();
87343 }
87344 if ($xmlConfiguration->codeCoverage()->hasHtml()) {
87345 $coverageHtmlHighLowerBound = $xmlConfiguration->codeCoverage()->html()->highLowerBound();
87346 $coverageHtmlLowUpperBound = $xmlConfiguration->codeCoverage()->html()->lowUpperBound();
87347 if ($coverageHtmlLowUpperBound > $coverageHtmlHighLowerBound) {
87348 $coverageHtmlLowUpperBound = $defaultThresholds->lowUpperBound();
87349 $coverageHtmlHighLowerBound = $defaultThresholds->highLowerBound();
87350 }
87351 $coverageHtmlColorSuccessLow = $xmlConfiguration->codeCoverage()->html()->colorSuccessLow();
87352 $coverageHtmlColorSuccessMedium = $xmlConfiguration->codeCoverage()->html()->colorSuccessMedium();
87353 $coverageHtmlColorSuccessHigh = $xmlConfiguration->codeCoverage()->html()->colorSuccessHigh();
87354 $coverageHtmlColorWarning = $xmlConfiguration->codeCoverage()->html()->colorWarning();
87355 $coverageHtmlColorDanger = $xmlConfiguration->codeCoverage()->html()->colorDanger();
87356 if ($xmlConfiguration->codeCoverage()->html()->hasCustomCssFile()) {
87357 $coverageHtmlCustomCssFile = $xmlConfiguration->codeCoverage()->html()->customCssFile();
87358 }
87359 }
87360 if ($cliConfiguration->hasCoverageHtml()) {
87361 $coverageHtml = $cliConfiguration->coverageHtml();
87362 } elseif ($coverageFromXmlConfiguration && $xmlConfiguration->codeCoverage()->hasHtml()) {
87363 $coverageHtml = $xmlConfiguration->codeCoverage()->html()->target()->path();
87364 }
87365 if ($cliConfiguration->hasCoveragePhp()) {
87366 $coveragePhp = $cliConfiguration->coveragePhp();
87367 } elseif ($coverageFromXmlConfiguration && $xmlConfiguration->codeCoverage()->hasPhp()) {
87368 $coveragePhp = $xmlConfiguration->codeCoverage()->php()->target()->path();
87369 }
87370 if ($xmlConfiguration->codeCoverage()->hasText()) {
87371 $coverageTextShowUncoveredFiles = $xmlConfiguration->codeCoverage()->text()->showUncoveredFiles();
87372 $coverageTextShowOnlySummary = $xmlConfiguration->codeCoverage()->text()->showOnlySummary();
87373 }
87374 if ($cliConfiguration->hasCoverageTextShowUncoveredFiles()) {
87375 $coverageTextShowUncoveredFiles = $cliConfiguration->coverageTextShowUncoveredFiles();
87376 }
87377 if ($cliConfiguration->hasCoverageTextShowOnlySummary()) {
87378 $coverageTextShowOnlySummary = $cliConfiguration->coverageTextShowOnlySummary();
87379 }
87380 if ($cliConfiguration->hasCoverageText()) {
87381 $coverageText = $cliConfiguration->coverageText();
87382 } elseif ($coverageFromXmlConfiguration && $xmlConfiguration->codeCoverage()->hasText()) {
87383 $coverageText = $xmlConfiguration->codeCoverage()->text()->target()->path();
87384 }
87385 if ($cliConfiguration->hasCoverageXml()) {
87386 $coverageXml = $cliConfiguration->coverageXml();
87387 } elseif ($coverageFromXmlConfiguration && $xmlConfiguration->codeCoverage()->hasXml()) {
87388 $coverageXml = $xmlConfiguration->codeCoverage()->xml()->target()->path();
87389 }
87390 if ($cliConfiguration->hasBackupGlobals()) {
87391 $backupGlobals = $cliConfiguration->backupGlobals();
87392 } else {
87393 $backupGlobals = $xmlConfiguration->phpunit()->backupGlobals();
87394 }
87395 if ($cliConfiguration->hasBackupStaticProperties()) {
87396 $backupStaticProperties = $cliConfiguration->backupStaticProperties();
87397 } else {
87398 $backupStaticProperties = $xmlConfiguration->phpunit()->backupStaticProperties();
87399 }
87400 if ($cliConfiguration->hasBeStrictAboutChangesToGlobalState()) {
87401 $beStrictAboutChangesToGlobalState = $cliConfiguration->beStrictAboutChangesToGlobalState();
87402 } else {
87403 $beStrictAboutChangesToGlobalState = $xmlConfiguration->phpunit()->beStrictAboutChangesToGlobalState();
87404 }
87405 if ($cliConfiguration->hasProcessIsolation()) {
87406 $processIsolation = $cliConfiguration->processIsolation();
87407 } else {
87408 $processIsolation = $xmlConfiguration->phpunit()->processIsolation();
87409 }
87410 if ($cliConfiguration->hasEnforceTimeLimit()) {
87411 $enforceTimeLimit = $cliConfiguration->enforceTimeLimit();
87412 } else {
87413 $enforceTimeLimit = $xmlConfiguration->phpunit()->enforceTimeLimit();
87414 }
87415 if ($enforceTimeLimit && !(new Invoker())->canInvokeWithTimeout()) {
87416 EventFacade::emitter()->testRunnerTriggeredPhpunitWarning('The pcntl extension is required for enforcing time limits');
87417 }
87418 if ($cliConfiguration->hasDefaultTimeLimit()) {
87419 $defaultTimeLimit = $cliConfiguration->defaultTimeLimit();
87420 } else {
87421 $defaultTimeLimit = $xmlConfiguration->phpunit()->defaultTimeLimit();
87422 }
87423 $timeoutForSmallTests = $xmlConfiguration->phpunit()->timeoutForSmallTests();
87424 $timeoutForMediumTests = $xmlConfiguration->phpunit()->timeoutForMediumTests();
87425 $timeoutForLargeTests = $xmlConfiguration->phpunit()->timeoutForLargeTests();
87426 if ($cliConfiguration->hasReportUselessTests()) {
87427 $reportUselessTests = $cliConfiguration->reportUselessTests();
87428 } else {
87429 $reportUselessTests = $xmlConfiguration->phpunit()->beStrictAboutTestsThatDoNotTestAnything();
87430 }
87431 if ($cliConfiguration->hasStrictCoverage()) {
87432 $strictCoverage = $cliConfiguration->strictCoverage();
87433 } else {
87434 $strictCoverage = $xmlConfiguration->phpunit()->beStrictAboutCoverageMetadata();
87435 }
87436 if ($cliConfiguration->hasDisallowTestOutput()) {
87437 $disallowTestOutput = $cliConfiguration->disallowTestOutput();
87438 } else {
87439 $disallowTestOutput = $xmlConfiguration->phpunit()->beStrictAboutOutputDuringTests();
87440 }
87441 if ($cliConfiguration->hasDisplayDetailsOnAllIssues()) {
87442 $displayDetailsOnAllIssues = $cliConfiguration->displayDetailsOnAllIssues();
87443 } else {
87444 $displayDetailsOnAllIssues = $xmlConfiguration->phpunit()->displayDetailsOnAllIssues();
87445 }
87446 if ($cliConfiguration->hasDisplayDetailsOnIncompleteTests()) {
87447 $displayDetailsOnIncompleteTests = $cliConfiguration->displayDetailsOnIncompleteTests();
87448 } else {
87449 $displayDetailsOnIncompleteTests = $xmlConfiguration->phpunit()->displayDetailsOnIncompleteTests();
87450 }
87451 if ($cliConfiguration->hasDisplayDetailsOnSkippedTests()) {
87452 $displayDetailsOnSkippedTests = $cliConfiguration->displayDetailsOnSkippedTests();
87453 } else {
87454 $displayDetailsOnSkippedTests = $xmlConfiguration->phpunit()->displayDetailsOnSkippedTests();
87455 }
87456 if ($cliConfiguration->hasDisplayDetailsOnTestsThatTriggerDeprecations()) {
87457 $displayDetailsOnTestsThatTriggerDeprecations = $cliConfiguration->displayDetailsOnTestsThatTriggerDeprecations();
87458 } else {
87459 $displayDetailsOnTestsThatTriggerDeprecations = $xmlConfiguration->phpunit()->displayDetailsOnTestsThatTriggerDeprecations();
87460 }
87461 if ($cliConfiguration->hasDisplayDetailsOnPhpunitDeprecations()) {
87462 $displayDetailsOnPhpunitDeprecations = $cliConfiguration->displayDetailsOnPhpunitDeprecations();
87463 } else {
87464 $displayDetailsOnPhpunitDeprecations = $xmlConfiguration->phpunit()->displayDetailsOnPhpunitDeprecations();
87465 }
87466 if ($cliConfiguration->hasDisplayDetailsOnTestsThatTriggerErrors()) {
87467 $displayDetailsOnTestsThatTriggerErrors = $cliConfiguration->displayDetailsOnTestsThatTriggerErrors();
87468 } else {
87469 $displayDetailsOnTestsThatTriggerErrors = $xmlConfiguration->phpunit()->displayDetailsOnTestsThatTriggerErrors();
87470 }
87471 if ($cliConfiguration->hasDisplayDetailsOnTestsThatTriggerNotices()) {
87472 $displayDetailsOnTestsThatTriggerNotices = $cliConfiguration->displayDetailsOnTestsThatTriggerNotices();
87473 } else {
87474 $displayDetailsOnTestsThatTriggerNotices = $xmlConfiguration->phpunit()->displayDetailsOnTestsThatTriggerNotices();
87475 }
87476 if ($cliConfiguration->hasDisplayDetailsOnTestsThatTriggerWarnings()) {
87477 $displayDetailsOnTestsThatTriggerWarnings = $cliConfiguration->displayDetailsOnTestsThatTriggerWarnings();
87478 } else {
87479 $displayDetailsOnTestsThatTriggerWarnings = $xmlConfiguration->phpunit()->displayDetailsOnTestsThatTriggerWarnings();
87480 }
87481 if ($cliConfiguration->hasReverseList()) {
87482 $reverseDefectList = $cliConfiguration->reverseList();
87483 } else {
87484 $reverseDefectList = $xmlConfiguration->phpunit()->reverseDefectList();
87485 }
87486 $requireCoverageMetadata = $xmlConfiguration->phpunit()->requireCoverageMetadata();
87487 $registerMockObjectsFromTestArgumentsRecursively = $xmlConfiguration->phpunit()->registerMockObjectsFromTestArgumentsRecursively();
87488 if ($cliConfiguration->hasExecutionOrder()) {
87489 $executionOrder = $cliConfiguration->executionOrder();
87490 } else {
87491 $executionOrder = $xmlConfiguration->phpunit()->executionOrder();
87492 }
87493 $executionOrderDefects = TestSuiteSorter::ORDER_DEFAULT;
87494 if ($cliConfiguration->hasExecutionOrderDefects()) {
87495 $executionOrderDefects = $cliConfiguration->executionOrderDefects();
87496 } elseif ($xmlConfiguration->phpunit()->defectsFirst()) {
87497 $executionOrderDefects = TestSuiteSorter::ORDER_DEFECTS_FIRST;
87498 }
87499 if ($cliConfiguration->hasResolveDependencies()) {
87500 $resolveDependencies = $cliConfiguration->resolveDependencies();
87501 } else {
87502 $resolveDependencies = $xmlConfiguration->phpunit()->resolveDependencies();
87503 }
87504 $colors = \false;
87505 $colorsSupported = (new Console())->hasColorSupport();
87506 if ($cliConfiguration->hasColors()) {
87507 if ($cliConfiguration->colors() === \PHPUnit\TextUI\Configuration\Configuration::COLOR_ALWAYS) {
87508 $colors = \true;
87509 } elseif ($colorsSupported && $cliConfiguration->colors() === \PHPUnit\TextUI\Configuration\Configuration::COLOR_AUTO) {
87510 $colors = \true;
87511 }
87512 } elseif ($xmlConfiguration->phpunit()->colors() === \PHPUnit\TextUI\Configuration\Configuration::COLOR_ALWAYS) {
87513 $colors = \true;
87514 } elseif ($colorsSupported && $xmlConfiguration->phpunit()->colors() === \PHPUnit\TextUI\Configuration\Configuration::COLOR_AUTO) {
87515 $colors = \true;
87516 }
87517 $logfileTeamcity = null;
87518 $logfileJunit = null;
87519 $logfileTestdoxHtml = null;
87520 $logfileTestdoxText = null;
87521 $loggingFromXmlConfiguration = \true;
87522 if ($cliConfiguration->hasNoLogging() && $cliConfiguration->noLogging()) {
87523 $loggingFromXmlConfiguration = \false;
87524 }
87525 if ($cliConfiguration->hasTeamcityLogfile()) {
87526 $logfileTeamcity = $cliConfiguration->teamcityLogfile();
87527 } elseif ($loggingFromXmlConfiguration && $xmlConfiguration->logging()->hasTeamCity()) {
87528 $logfileTeamcity = $xmlConfiguration->logging()->teamCity()->target()->path();
87529 }
87530 if ($cliConfiguration->hasJunitLogfile()) {
87531 $logfileJunit = $cliConfiguration->junitLogfile();
87532 } elseif ($loggingFromXmlConfiguration && $xmlConfiguration->logging()->hasJunit()) {
87533 $logfileJunit = $xmlConfiguration->logging()->junit()->target()->path();
87534 }
87535 if ($cliConfiguration->hasTestdoxHtmlFile()) {
87536 $logfileTestdoxHtml = $cliConfiguration->testdoxHtmlFile();
87537 } elseif ($loggingFromXmlConfiguration && $xmlConfiguration->logging()->hasTestDoxHtml()) {
87538 $logfileTestdoxHtml = $xmlConfiguration->logging()->testDoxHtml()->target()->path();
87539 }
87540 if ($cliConfiguration->hasTestdoxTextFile()) {
87541 $logfileTestdoxText = $cliConfiguration->testdoxTextFile();
87542 } elseif ($loggingFromXmlConfiguration && $xmlConfiguration->logging()->hasTestDoxText()) {
87543 $logfileTestdoxText = $xmlConfiguration->logging()->testDoxText()->target()->path();
87544 }
87545 $logEventsText = null;
87546 if ($cliConfiguration->hasLogEventsText()) {
87547 $logEventsText = $cliConfiguration->logEventsText();
87548 }
87549 $logEventsVerboseText = null;
87550 if ($cliConfiguration->hasLogEventsVerboseText()) {
87551 $logEventsVerboseText = $cliConfiguration->logEventsVerboseText();
87552 }
87553 $teamCityOutput = \false;
87554 if ($cliConfiguration->hasTeamCityPrinter() && $cliConfiguration->teamCityPrinter()) {
87555 $teamCityOutput = \true;
87556 }
87557 if ($cliConfiguration->hasTestDoxPrinter() && $cliConfiguration->testdoxPrinter()) {
87558 $testDoxOutput = \true;
87559 } else {
87560 $testDoxOutput = $xmlConfiguration->phpunit()->testdoxPrinter();
87561 }
87562 $noProgress = \false;
87563 if ($cliConfiguration->hasNoProgress() && $cliConfiguration->noProgress()) {
87564 $noProgress = \true;
87565 }
87566 $noResults = \false;
87567 if ($cliConfiguration->hasNoResults() && $cliConfiguration->noResults()) {
87568 $noResults = \true;
87569 }
87570 $noOutput = \false;
87571 if ($cliConfiguration->hasNoOutput() && $cliConfiguration->noOutput()) {
87572 $noOutput = \true;
87573 }
87574 $testsCovering = null;
87575 if ($cliConfiguration->hasTestsCovering()) {
87576 $testsCovering = $cliConfiguration->testsCovering();
87577 }
87578 $testsUsing = null;
87579 if ($cliConfiguration->hasTestsUsing()) {
87580 $testsUsing = $cliConfiguration->testsUsing();
87581 }
87582 $filter = null;
87583 if ($cliConfiguration->hasFilter()) {
87584 $filter = $cliConfiguration->filter();
87585 }
87586 if ($cliConfiguration->hasGroups()) {
87587 $groups = $cliConfiguration->groups();
87588 } else {
87589 $groups = $xmlConfiguration->groups()->include()->asArrayOfStrings();
87590 }
87591 if ($cliConfiguration->hasExcludeGroups()) {
87592 $excludeGroups = $cliConfiguration->excludeGroups();
87593 } else {
87594 $excludeGroups = $xmlConfiguration->groups()->exclude()->asArrayOfStrings();
87595 }
87596 $excludeGroups = array_diff($excludeGroups, $groups);
87597 if ($cliConfiguration->hasRandomOrderSeed()) {
87598 $randomOrderSeed = $cliConfiguration->randomOrderSeed();
87599 } else {
87600 $randomOrderSeed = time();
87601 }
87602 if ($xmlConfiguration->wasLoadedFromFile() && $xmlConfiguration->hasValidationErrors()) {
87603 if ((new SchemaDetector())->detect($xmlConfiguration->filename())->detected()) {
87604 EventFacade::emitter()->testRunnerTriggeredPhpunitDeprecation('Your XML configuration validates against a deprecated schema. Migrate your XML configuration using "--migrate-configuration"!');
87605 } else {
87606 EventFacade::emitter()->testRunnerTriggeredPhpunitWarning("Test results may not be as expected because the XML configuration file did not pass validation:\n" . $xmlConfiguration->validationErrors());
87607 }
87608 }
87609 $includeUncoveredFiles = $xmlConfiguration->codeCoverage()->includeUncoveredFiles();
87610 $includePaths = [];
87611 if ($cliConfiguration->hasIncludePath()) {
87612 foreach (explode(PATH_SEPARATOR, $cliConfiguration->includePath()) as $includePath) {
87613 $includePaths[] = new \PHPUnit\TextUI\Configuration\Directory($includePath);
87614 }
87615 }
87616 foreach ($xmlConfiguration->php()->includePaths() as $includePath) {
87617 $includePaths[] = $includePath;
87618 }
87619 $iniSettings = [];
87620 if ($cliConfiguration->hasIniSettings()) {
87621 foreach ($cliConfiguration->iniSettings() as $name => $value) {
87622 $iniSettings[] = new \PHPUnit\TextUI\Configuration\IniSetting($name, $value);
87623 }
87624 }
87625 foreach ($xmlConfiguration->php()->iniSettings() as $iniSetting) {
87626 $iniSettings[] = $iniSetting;
87627 }
87628 $includeTestSuite = '';
87629 if ($cliConfiguration->hasTestSuite()) {
87630 $includeTestSuite = $cliConfiguration->testSuite();
87631 } elseif ($xmlConfiguration->phpunit()->hasDefaultTestSuite()) {
87632 $includeTestSuite = $xmlConfiguration->phpunit()->defaultTestSuite();
87633 }
87634 $excludeTestSuite = '';
87635 if ($cliConfiguration->hasExcludedTestSuite()) {
87636 $excludeTestSuite = $cliConfiguration->excludedTestSuite();
87637 }
87638 $testSuffixes = ['Test.php', '.phpt'];
87639 if ($cliConfiguration->hasTestSuffixes()) {
87640 $testSuffixes = $cliConfiguration->testSuffixes();
87641 }
87642 $sourceIncludeDirectories = [];
87643 if ($cliConfiguration->hasCoverageFilter()) {
87644 foreach ($cliConfiguration->coverageFilter() as $directory) {
87645 $sourceIncludeDirectories[] = new \PHPUnit\TextUI\Configuration\FilterDirectory($directory, '', '.php');
87646 }
87647 }
87648 if ($xmlConfiguration->codeCoverage()->hasNonEmptyListOfFilesToBeIncludedInCodeCoverageReport()) {
87649 foreach ($xmlConfiguration->codeCoverage()->directories() as $directory) {
87650 $sourceIncludeDirectories[] = $directory;
87651 }
87652 $sourceIncludeFiles = $xmlConfiguration->codeCoverage()->files();
87653 $sourceExcludeDirectories = $xmlConfiguration->codeCoverage()->excludeDirectories();
87654 $sourceExcludeFiles = $xmlConfiguration->codeCoverage()->excludeFiles();
87655 } else {
87656 foreach ($xmlConfiguration->source()->includeDirectories() as $directory) {
87657 $sourceIncludeDirectories[] = $directory;
87658 }
87659 $sourceIncludeFiles = $xmlConfiguration->source()->includeFiles();
87660 $sourceExcludeDirectories = $xmlConfiguration->source()->excludeDirectories();
87661 $sourceExcludeFiles = $xmlConfiguration->source()->excludeFiles();
87662 }
87663 $useBaseline = null;
87664 $generateBaseline = null;
87665 if (!$cliConfiguration->hasGenerateBaseline()) {
87666 if ($cliConfiguration->hasUseBaseline()) {
87667 $useBaseline = $cliConfiguration->useBaseline();
87668 } elseif ($xmlConfiguration->source()->hasBaseline()) {
87669 $useBaseline = $xmlConfiguration->source()->baseline();
87670 }
87671 } else {
87672 $generateBaseline = $cliConfiguration->generateBaseline();
87673 }
87674 assert($useBaseline !== '');
87675 assert($generateBaseline !== '');
87676 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, $failOnAllIssues, $failOnDeprecation, $failOnPhpunitDeprecation, $failOnPhpunitWarning, $failOnEmptyTestSuite, $failOnIncomplete, $failOnNotice, $failOnRisky, $failOnSkipped, $failOnWarning, $doNotFailOnDeprecation, $doNotFailOnPhpunitDeprecation, $doNotFailOnPhpunitWarning, $doNotFailOnEmptyTestSuite, $doNotFailOnIncomplete, $doNotFailOnNotice, $doNotFailOnRisky, $doNotFailOnSkipped, $doNotFailOnWarning, $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, $displayDetailsOnAllIssues, $displayDetailsOnIncompleteTests, $displayDetailsOnSkippedTests, $displayDetailsOnTestsThatTriggerDeprecations, $displayDetailsOnPhpunitDeprecations, $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());
87677 }
87678 }
87679 <?php
87680
87681 declare (strict_types=1);
87682 /*
87683 * This file is part of PHPUnit.
87684 *
87685 * (c) Sebastian Bergmann <sebastian@phpunit.de>
87686 *
87687 * For the full copyright and license information, please view the LICENSE
87688 * file that was distributed with this source code.
87689 */
87690 namespace PHPUnit\TextUI\Configuration;
87691
87692 use const PATH_SEPARATOR;
87693 use function constant;
87694 use function define;
87695 use function defined;
87696 use function getenv;
87697 use function implode;
87698 use function ini_get;
87699 use function ini_set;
87700 use function putenv;
87701 /**
87702 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
87703 *
87704 * @internal This class is not covered by the backward compatibility promise for PHPUnit
87705 */
87706 final class PhpHandler
87707 {
87708 public function handle(\PHPUnit\TextUI\Configuration\Php $configuration): void
87709 {
87710 $this->handleIncludePaths($configuration->includePaths());
87711 $this->handleIniSettings($configuration->iniSettings());
87712 $this->handleConstants($configuration->constants());
87713 $this->handleGlobalVariables($configuration->globalVariables());
87714 $this->handleServerVariables($configuration->serverVariables());
87715 $this->handleEnvVariables($configuration->envVariables());
87716 $this->handleVariables('_POST', $configuration->postVariables());
87717 $this->handleVariables('_GET', $configuration->getVariables());
87718 $this->handleVariables('_COOKIE', $configuration->cookieVariables());
87719 $this->handleVariables('_FILES', $configuration->filesVariables());
87720 $this->handleVariables('_REQUEST', $configuration->requestVariables());
87721 }
87722 private function handleIncludePaths(\PHPUnit\TextUI\Configuration\DirectoryCollection $includePaths): void
87723 {
87724 if (!$includePaths->isEmpty()) {
87725 $includePathsAsStrings = [];
87726 foreach ($includePaths as $includePath) {
87727 $includePathsAsStrings[] = $includePath->path();
87728 }
87729 ini_set('include_path', implode(PATH_SEPARATOR, $includePathsAsStrings) . PATH_SEPARATOR . ini_get('include_path'));
87730 }
87731 }
87732 private function handleIniSettings(\PHPUnit\TextUI\Configuration\IniSettingCollection $iniSettings): void
87733 {
87734 foreach ($iniSettings as $iniSetting) {
87735 $value = $iniSetting->value();
87736 if (defined($value)) {
87737 $value = (string) constant($value);
87738 }
87739 ini_set($iniSetting->name(), $value);
87740 }
87741 }
87742 private function handleConstants(\PHPUnit\TextUI\Configuration\ConstantCollection $constants): void
87743 {
87744 foreach ($constants as $constant) {
87745 if (!defined($constant->name())) {
87746 define($constant->name(), $constant->value());
87747 }
87748 }
87749 }
87750 private function handleGlobalVariables(\PHPUnit\TextUI\Configuration\VariableCollection $variables): void
87751 {
87752 foreach ($variables as $variable) {
87753 $GLOBALS[$variable->name()] = $variable->value();
87754 }
87755 }
87756 private function handleServerVariables(\PHPUnit\TextUI\Configuration\VariableCollection $variables): void
87757 {
87758 foreach ($variables as $variable) {
87759 $_SERVER[$variable->name()] = $variable->value();
87760 }
87761 }
87762 private function handleVariables(string $target, \PHPUnit\TextUI\Configuration\VariableCollection $variables): void
87763 {
87764 foreach ($variables as $variable) {
87765 $GLOBALS[$target][$variable->name()] = $variable->value();
87766 }
87767 }
87768 private function handleEnvVariables(\PHPUnit\TextUI\Configuration\VariableCollection $variables): void
87769 {
87770 foreach ($variables as $variable) {
87771 $name = $variable->name();
87772 $value = $variable->value();
87773 $force = $variable->force();
87774 if ($force || getenv($name) === \false) {
87775 putenv("{$name}={$value}");
87776 }
87777 $value = getenv($name);
87778 if ($force || !isset($_ENV[$name])) {
87779 $_ENV[$name] = $value;
87780 }
87781 }
87782 }
87783 }
87784 <?php
87785
87786 declare (strict_types=1);
87787 /*
87788 * This file is part of PHPUnit.
87789 *
87790 * (c) Sebastian Bergmann <sebastian@phpunit.de>
87791 *
87792 * For the full copyright and license information, please view the LICENSE
87793 * file that was distributed with this source code.
87794 */
87795 namespace PHPUnit\TextUI\Configuration;
87796
87797 use function assert;
87798 use function file_get_contents;
87799 use function file_put_contents;
87800 use function serialize;
87801 use function unserialize;
87802 use PHPUnit\Event\Facade as EventFacade;
87803 use PHPUnit\TextUI\CliArguments\Configuration as CliConfiguration;
87804 use PHPUnit\TextUI\CliArguments\Exception;
87805 use PHPUnit\TextUI\XmlConfiguration\Configuration as XmlConfiguration;
87806 use PHPUnit\Util\VersionComparisonOperator;
87807 /**
87808 * CLI options and XML configuration are static within a single PHPUnit process.
87809 * It is therefore okay to use a Singleton registry here.
87810 *
87811 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
87812 *
87813 * @internal This class is not covered by the backward compatibility promise for PHPUnit
87814 */
87815 final class Registry
87816 {
87817 private static ?\PHPUnit\TextUI\Configuration\Configuration $instance = null;
87818 public static function saveTo(string $path): bool
87819 {
87820 $result = file_put_contents($path, serialize(self::get()));
87821 if ($result) {
87822 return \true;
87823 }
87824 // @codeCoverageIgnoreStart
87825 return \false;
87826 // @codeCoverageIgnoreEnd
87827 }
87828 /**
87829 * This method is used by the "run test(s) in separate process" templates.
87830 *
87831 * @noinspection PhpUnused
87832 *
87833 * @codeCoverageIgnore
87834 */
87835 public static function loadFrom(string $path): void
87836 {
87837 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]]);
87838 }
87839 public static function get(): \PHPUnit\TextUI\Configuration\Configuration
87840 {
87841 assert(self::$instance instanceof \PHPUnit\TextUI\Configuration\Configuration);
87842 return self::$instance;
87843 }
87844 /**
87845 * @throws \PHPUnit\TextUI\XmlConfiguration\Exception
87846 * @throws Exception
87847 * @throws NoCustomCssFileException
87848 */
87849 public static function init(CliConfiguration $cliConfiguration, XmlConfiguration $xmlConfiguration): \PHPUnit\TextUI\Configuration\Configuration
87850 {
87851 self::$instance = (new \PHPUnit\TextUI\Configuration\Merger())->merge($cliConfiguration, $xmlConfiguration);
87852 EventFacade::emitter()->testRunnerConfigured(self::$instance);
87853 return self::$instance;
87854 }
87855 }
87856 <?php
87857
87858 declare (strict_types=1);
87859 /*
87860 * This file is part of PHPUnit.
87861 *
87862 * (c) Sebastian Bergmann <sebastian@phpunit.de>
87863 *
87864 * For the full copyright and license information, please view the LICENSE
87865 * file that was distributed with this source code.
87866 */
87867 namespace PHPUnit\TextUI\Configuration;
87868
87869 /**
87870 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
87871 *
87872 * @internal This class is not covered by the backward compatibility promise for PHPUnit
87873 */
87874 final class SourceFilter
87875 {
87876 private static ?self $instance = null;
87877 /**
87878 * @psalm-var array<non-empty-string, true>
87879 */
87880 private readonly array $map;
87881 public static function instance(): self
87882 {
87883 if (self::$instance === null) {
87884 self::$instance = new self((new \PHPUnit\TextUI\Configuration\SourceMapper())->map(\PHPUnit\TextUI\Configuration\Registry::get()->source()));
87885 }
87886 return self::$instance;
87887 }
87888 /**
87889 * @psalm-param array<non-empty-string, true> $map
87890 */
87891 public function __construct(array $map)
87892 {
87893 $this->map = $map;
87894 }
87895 public function includes(string $path): bool
87896 {
87897 return isset($this->map[$path]);
87898 }
87899 }
87900 <?php
87901
87902 declare (strict_types=1);
87903 /*
87904 * This file is part of PHPUnit.
87905 *
87906 * (c) Sebastian Bergmann <sebastian@phpunit.de>
87907 *
87908 * For the full copyright and license information, please view the LICENSE
87909 * file that was distributed with this source code.
87910 */
87911 namespace PHPUnit\TextUI\Configuration;
87912
87913 use function realpath;
87914 use PHPUnitPHAR\SebastianBergmann\FileIterator\Facade as FileIteratorFacade;
87915 use SplObjectStorage;
87916 /**
87917 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
87918 *
87919 * @internal This class is not covered by the backward compatibility promise for PHPUnit
87920 */
87921 final class SourceMapper
87922 {
87923 /**
87924 * @psalm-var SplObjectStorage<Source, array<non-empty-string, true>>
87925 */
87926 private static ?SplObjectStorage $files = null;
87927 /**
87928 * @psalm-return array<non-empty-string, true>
87929 */
87930 public function map(\PHPUnit\TextUI\Configuration\Source $source): array
87931 {
87932 if (self::$files === null) {
87933 self::$files = new SplObjectStorage();
87934 }
87935 if (isset(self::$files[$source])) {
87936 return self::$files[$source];
87937 }
87938 $files = [];
87939 foreach ($source->includeDirectories() as $directory) {
87940 foreach ((new FileIteratorFacade())->getFilesAsArray($directory->path(), $directory->suffix(), $directory->prefix()) as $file) {
87941 $file = realpath($file);
87942 if (!$file) {
87943 continue;
87944 }
87945 $files[$file] = \true;
87946 }
87947 }
87948 foreach ($source->includeFiles() as $file) {
87949 $file = realpath($file->path());
87950 if (!$file) {
87951 continue;
87952 }
87953 $files[$file] = \true;
87954 }
87955 foreach ($source->excludeDirectories() as $directory) {
87956 foreach ((new FileIteratorFacade())->getFilesAsArray($directory->path(), $directory->suffix(), $directory->prefix()) as $file) {
87957 $file = realpath($file);
87958 if (!$file) {
87959 continue;
87960 }
87961 if (!isset($files[$file])) {
87962 continue;
87963 }
87964 unset($files[$file]);
87965 }
87966 }
87967 foreach ($source->excludeFiles() as $file) {
87968 $file = realpath($file->path());
87969 if (!$file) {
87970 continue;
87971 }
87972 if (!isset($files[$file])) {
87973 continue;
87974 }
87975 unset($files[$file]);
87976 }
87977 self::$files[$source] = $files;
87978 return $files;
87979 }
87980 }
87981 <?php
87982
87983 declare (strict_types=1);
87984 /*
87985 * This file is part of PHPUnit.
87986 *
87987 * (c) Sebastian Bergmann <sebastian@phpunit.de>
87988 *
87989 * For the full copyright and license information, please view the LICENSE
87990 * file that was distributed with this source code.
87991 */
87992 namespace PHPUnit\TextUI\Configuration;
87993
87994 use const PHP_EOL;
87995 use function assert;
87996 use function count;
87997 use function is_dir;
87998 use function is_file;
87999 use function realpath;
88000 use function str_ends_with;
88001 use PHPUnit\Event\Facade as EventFacade;
88002 use PHPUnit\Exception;
88003 use PHPUnit\Framework\TestSuite;
88004 use PHPUnit\Runner\TestSuiteLoader;
88005 use PHPUnit\TextUI\RuntimeException;
88006 use PHPUnit\TextUI\TestDirectoryNotFoundException;
88007 use PHPUnit\TextUI\TestFileNotFoundException;
88008 use PHPUnit\TextUI\XmlConfiguration\TestSuiteMapper;
88009 use PHPUnitPHAR\SebastianBergmann\FileIterator\Facade as FileIteratorFacade;
88010 /**
88011 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
88012 *
88013 * @internal This class is not covered by the backward compatibility promise for PHPUnit
88014 */
88015 final class TestSuiteBuilder
88016 {
88017 /**
88018 * @throws \PHPUnit\Framework\Exception
88019 * @throws RuntimeException
88020 * @throws TestDirectoryNotFoundException
88021 * @throws TestFileNotFoundException
88022 */
88023 public function build(\PHPUnit\TextUI\Configuration\Configuration $configuration): TestSuite
88024 {
88025 if ($configuration->hasCliArguments()) {
88026 $arguments = [];
88027 foreach ($configuration->cliArguments() as $cliArgument) {
88028 $argument = realpath($cliArgument);
88029 if (!$argument) {
88030 throw new TestFileNotFoundException($cliArgument);
88031 }
88032 $arguments[] = $argument;
88033 }
88034 if (count($arguments) === 1) {
88035 $testSuite = $this->testSuiteFromPath($arguments[0], $configuration->testSuffixes());
88036 } else {
88037 $testSuite = $this->testSuiteFromPathList($arguments, $configuration->testSuffixes());
88038 }
88039 }
88040 if (!isset($testSuite)) {
88041 $xmlConfigurationFile = $configuration->hasConfigurationFile() ? $configuration->configurationFile() : 'Root Test Suite';
88042 assert(!empty($xmlConfigurationFile));
88043 $testSuite = (new TestSuiteMapper())->map($xmlConfigurationFile, $configuration->testSuite(), $configuration->includeTestSuite(), $configuration->excludeTestSuite());
88044 }
88045 EventFacade::emitter()->testSuiteLoaded(\PHPUnit\Event\TestSuite\TestSuiteBuilder::from($testSuite));
88046 return $testSuite;
88047 }
88048 /**
88049 * @psalm-param non-empty-string $path
88050 * @psalm-param list<non-empty-string> $suffixes
88051 * @psalm-param ?TestSuite $suite
88052 *
88053 * @throws \PHPUnit\Framework\Exception
88054 */
88055 private function testSuiteFromPath(string $path, array $suffixes, ?TestSuite $suite = null): TestSuite
88056 {
88057 if (str_ends_with($path, '.phpt') && is_file($path)) {
88058 $suite = $suite ?: TestSuite::empty($path);
88059 $suite->addTestFile($path);
88060 return $suite;
88061 }
88062 if (is_dir($path)) {
88063 $files = (new FileIteratorFacade())->getFilesAsArray($path, $suffixes);
88064 $suite = $suite ?: TestSuite::empty('CLI Arguments');
88065 $suite->addTestFiles($files);
88066 return $suite;
88067 }
88068 try {
88069 $testClass = (new TestSuiteLoader())->load($path);
88070 } catch (Exception $e) {
88071 print $e->getMessage() . PHP_EOL;
88072 exit(1);
88073 }
88074 if (!$suite) {
88075 return TestSuite::fromClassReflector($testClass);
88076 }
88077 $suite->addTestSuite($testClass);
88078 return $suite;
88079 }
88080 /**
88081 * @psalm-param list<non-empty-string> $paths
88082 * @psalm-param list<non-empty-string> $suffixes
88083 *
88084 * @throws \PHPUnit\Framework\Exception
88085 */
88086 private function testSuiteFromPathList(array $paths, array $suffixes): TestSuite
88087 {
88088 $suite = TestSuite::empty('CLI Arguments');
88089 foreach ($paths as $path) {
88090 $this->testSuiteFromPath($path, $suffixes, $suite);
88091 }
88092 return $suite;
88093 }
88094 }
88095 <?php
88096
88097 declare (strict_types=1);
88098 /*
88099 * This file is part of PHPUnit.
88100 *
88101 * (c) Sebastian Bergmann <sebastian@phpunit.de>
88102 *
88103 * For the full copyright and license information, please view the LICENSE
88104 * file that was distributed with this source code.
88105 */
88106 namespace PHPUnit\TextUI\Configuration;
88107
88108 /**
88109 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
88110 *
88111 * @psalm-immutable
88112 */
88113 final class Constant
88114 {
88115 private readonly string $name;
88116 private readonly bool|string $value;
88117 public function __construct(string $name, bool|string $value)
88118 {
88119 $this->name = $name;
88120 $this->value = $value;
88121 }
88122 public function name(): string
88123 {
88124 return $this->name;
88125 }
88126 public function value(): bool|string
88127 {
88128 return $this->value;
88129 }
88130 }
88131 <?php
88132
88133 declare (strict_types=1);
88134 /*
88135 * This file is part of PHPUnit.
88136 *
88137 * (c) Sebastian Bergmann <sebastian@phpunit.de>
88138 *
88139 * For the full copyright and license information, please view the LICENSE
88140 * file that was distributed with this source code.
88141 */
88142 namespace PHPUnit\TextUI\Configuration;
88143
88144 use function count;
88145 use Countable;
88146 use IteratorAggregate;
88147 /**
88148 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
88149 *
88150 * @psalm-immutable
88151 *
88152 * @template-implements IteratorAggregate<int, Constant>
88153 */
88154 final class ConstantCollection implements Countable, IteratorAggregate
88155 {
88156 /**
88157 * @psalm-var list<Constant>
88158 */
88159 private readonly array $constants;
88160 /**
88161 * @psalm-param list<Constant> $constants
88162 */
88163 public static function fromArray(array $constants): self
88164 {
88165 return new self(...$constants);
88166 }
88167 private function __construct(\PHPUnit\TextUI\Configuration\Constant ...$constants)
88168 {
88169 $this->constants = $constants;
88170 }
88171 /**
88172 * @psalm-return list<Constant>
88173 */
88174 public function asArray(): array
88175 {
88176 return $this->constants;
88177 }
88178 public function count(): int
88179 {
88180 return count($this->constants);
88181 }
88182 public function getIterator(): \PHPUnit\TextUI\Configuration\ConstantCollectionIterator
88183 {
88184 return new \PHPUnit\TextUI\Configuration\ConstantCollectionIterator($this);
88185 }
88186 }
88187 <?php
88188
88189 declare (strict_types=1);
88190 /*
88191 * This file is part of PHPUnit.
88192 *
88193 * (c) Sebastian Bergmann <sebastian@phpunit.de>
88194 *
88195 * For the full copyright and license information, please view the LICENSE
88196 * file that was distributed with this source code.
88197 */
88198 namespace PHPUnit\TextUI\Configuration;
88199
88200 use function count;
88201 use function iterator_count;
88202 use Countable;
88203 use Iterator;
88204 /**
88205 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
88206 *
88207 * @template-implements Iterator<int, Constant>
88208 */
88209 final class ConstantCollectionIterator implements Countable, Iterator
88210 {
88211 /**
88212 * @psalm-var list<Constant>
88213 */
88214 private readonly array $constants;
88215 private int $position = 0;
88216 public function __construct(\PHPUnit\TextUI\Configuration\ConstantCollection $constants)
88217 {
88218 $this->constants = $constants->asArray();
88219 }
88220 public function count(): int
88221 {
88222 return iterator_count($this);
88223 }
88224 public function rewind(): void
88225 {
88226 $this->position = 0;
88227 }
88228 public function valid(): bool
88229 {
88230 return $this->position < count($this->constants);
88231 }
88232 public function key(): int
88233 {
88234 return $this->position;
88235 }
88236 public function current(): \PHPUnit\TextUI\Configuration\Constant
88237 {
88238 return $this->constants[$this->position];
88239 }
88240 public function next(): void
88241 {
88242 $this->position++;
88243 }
88244 }
88245 <?php
88246
88247 declare (strict_types=1);
88248 /*
88249 * This file is part of PHPUnit.
88250 *
88251 * (c) Sebastian Bergmann <sebastian@phpunit.de>
88252 *
88253 * For the full copyright and license information, please view the LICENSE
88254 * file that was distributed with this source code.
88255 */
88256 namespace PHPUnit\TextUI\Configuration;
88257
88258 /**
88259 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
88260 *
88261 * @psalm-immutable
88262 */
88263 final class Directory
88264 {
88265 private readonly string $path;
88266 public function __construct(string $path)
88267 {
88268 $this->path = $path;
88269 }
88270 public function path(): string
88271 {
88272 return $this->path;
88273 }
88274 }
88275 <?php
88276
88277 declare (strict_types=1);
88278 /*
88279 * This file is part of PHPUnit.
88280 *
88281 * (c) Sebastian Bergmann <sebastian@phpunit.de>
88282 *
88283 * For the full copyright and license information, please view the LICENSE
88284 * file that was distributed with this source code.
88285 */
88286 namespace PHPUnit\TextUI\Configuration;
88287
88288 use function count;
88289 use Countable;
88290 use IteratorAggregate;
88291 /**
88292 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
88293 *
88294 * @psalm-immutable
88295 *
88296 * @template-implements IteratorAggregate<int, Directory>
88297 */
88298 final class DirectoryCollection implements Countable, IteratorAggregate
88299 {
88300 /**
88301 * @psalm-var list<Directory>
88302 */
88303 private readonly array $directories;
88304 /**
88305 * @psalm-param list<Directory> $directories
88306 */
88307 public static function fromArray(array $directories): self
88308 {
88309 return new self(...$directories);
88310 }
88311 private function __construct(\PHPUnit\TextUI\Configuration\Directory ...$directories)
88312 {
88313 $this->directories = $directories;
88314 }
88315 /**
88316 * @psalm-return list<Directory>
88317 */
88318 public function asArray(): array
88319 {
88320 return $this->directories;
88321 }
88322 public function count(): int
88323 {
88324 return count($this->directories);
88325 }
88326 public function getIterator(): \PHPUnit\TextUI\Configuration\DirectoryCollectionIterator
88327 {
88328 return new \PHPUnit\TextUI\Configuration\DirectoryCollectionIterator($this);
88329 }
88330 public function isEmpty(): bool
88331 {
88332 return $this->count() === 0;
88333 }
88334 }
88335 <?php
88336
88337 declare (strict_types=1);
88338 /*
88339 * This file is part of PHPUnit.
88340 *
88341 * (c) Sebastian Bergmann <sebastian@phpunit.de>
88342 *
88343 * For the full copyright and license information, please view the LICENSE
88344 * file that was distributed with this source code.
88345 */
88346 namespace PHPUnit\TextUI\Configuration;
88347
88348 use function count;
88349 use function iterator_count;
88350 use Countable;
88351 use Iterator;
88352 /**
88353 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
88354 *
88355 * @template-implements Iterator<int, Directory>
88356 */
88357 final class DirectoryCollectionIterator implements Countable, Iterator
88358 {
88359 /**
88360 * @psalm-var list<Directory>
88361 */
88362 private readonly array $directories;
88363 private int $position = 0;
88364 public function __construct(\PHPUnit\TextUI\Configuration\DirectoryCollection $directories)
88365 {
88366 $this->directories = $directories->asArray();
88367 }
88368 public function count(): int
88369 {
88370 return iterator_count($this);
88371 }
88372 public function rewind(): void
88373 {
88374 $this->position = 0;
88375 }
88376 public function valid(): bool
88377 {
88378 return $this->position < count($this->directories);
88379 }
88380 public function key(): int
88381 {
88382 return $this->position;
88383 }
88384 public function current(): \PHPUnit\TextUI\Configuration\Directory
88385 {
88386 return $this->directories[$this->position];
88387 }
88388 public function next(): void
88389 {
88390 $this->position++;
88391 }
88392 }
88393 <?php
88394
88395 declare (strict_types=1);
88396 /*
88397 * This file is part of PHPUnit.
88398 *
88399 * (c) Sebastian Bergmann <sebastian@phpunit.de>
88400 *
88401 * For the full copyright and license information, please view the LICENSE
88402 * file that was distributed with this source code.
88403 */
88404 namespace PHPUnit\TextUI\Configuration;
88405
88406 /**
88407 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
88408 *
88409 * @psalm-immutable
88410 */
88411 final class ExtensionBootstrap
88412 {
88413 /**
88414 * @psalm-var class-string
88415 */
88416 private readonly string $className;
88417 /**
88418 * @psalm-var array<string,string>
88419 */
88420 private readonly array $parameters;
88421 /**
88422 * @psalm-param class-string $className
88423 * @psalm-param array<string,string> $parameters
88424 */
88425 public function __construct(string $className, array $parameters)
88426 {
88427 $this->className = $className;
88428 $this->parameters = $parameters;
88429 }
88430 /**
88431 * @psalm-return class-string
88432 */
88433 public function className(): string
88434 {
88435 return $this->className;
88436 }
88437 /**
88438 * @psalm-return array<string,string>
88439 */
88440 public function parameters(): array
88441 {
88442 return $this->parameters;
88443 }
88444 }
88445 <?php
88446
88447 declare (strict_types=1);
88448 /*
88449 * This file is part of PHPUnit.
88450 *
88451 * (c) Sebastian Bergmann <sebastian@phpunit.de>
88452 *
88453 * For the full copyright and license information, please view the LICENSE
88454 * file that was distributed with this source code.
88455 */
88456 namespace PHPUnit\TextUI\Configuration;
88457
88458 use IteratorAggregate;
88459 /**
88460 * @template-implements IteratorAggregate<int, ExtensionBootstrap>
88461 *
88462 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
88463 *
88464 * @psalm-immutable
88465 */
88466 final class ExtensionBootstrapCollection implements IteratorAggregate
88467 {
88468 /**
88469 * @psalm-var list<ExtensionBootstrap>
88470 */
88471 private readonly array $extensionBootstraps;
88472 /**
88473 * @psalm-param list<ExtensionBootstrap> $extensionBootstraps
88474 */
88475 public static function fromArray(array $extensionBootstraps): self
88476 {
88477 return new self(...$extensionBootstraps);
88478 }
88479 private function __construct(\PHPUnit\TextUI\Configuration\ExtensionBootstrap ...$extensionBootstraps)
88480 {
88481 $this->extensionBootstraps = $extensionBootstraps;
88482 }
88483 /**
88484 * @psalm-return list<ExtensionBootstrap>
88485 */
88486 public function asArray(): array
88487 {
88488 return $this->extensionBootstraps;
88489 }
88490 public function getIterator(): \PHPUnit\TextUI\Configuration\ExtensionBootstrapCollectionIterator
88491 {
88492 return new \PHPUnit\TextUI\Configuration\ExtensionBootstrapCollectionIterator($this);
88493 }
88494 }
88495 <?php
88496
88497 declare (strict_types=1);
88498 /*
88499 * This file is part of PHPUnit.
88500 *
88501 * (c) Sebastian Bergmann <sebastian@phpunit.de>
88502 *
88503 * For the full copyright and license information, please view the LICENSE
88504 * file that was distributed with this source code.
88505 */
88506 namespace PHPUnit\TextUI\Configuration;
88507
88508 use function count;
88509 use function iterator_count;
88510 use Countable;
88511 use Iterator;
88512 /**
88513 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
88514 *
88515 * @template-implements Iterator<int, ExtensionBootstrap>
88516 */
88517 final class ExtensionBootstrapCollectionIterator implements Countable, Iterator
88518 {
88519 /**
88520 * @psalm-var list<ExtensionBootstrap>
88521 */
88522 private readonly array $extensionBootstraps;
88523 private int $position = 0;
88524 public function __construct(\PHPUnit\TextUI\Configuration\ExtensionBootstrapCollection $extensionBootstraps)
88525 {
88526 $this->extensionBootstraps = $extensionBootstraps->asArray();
88527 }
88528 public function count(): int
88529 {
88530 return iterator_count($this);
88531 }
88532 public function rewind(): void
88533 {
88534 $this->position = 0;
88535 }
88536 public function valid(): bool
88537 {
88538 return $this->position < count($this->extensionBootstraps);
88539 }
88540 public function key(): int
88541 {
88542 return $this->position;
88543 }
88544 public function current(): \PHPUnit\TextUI\Configuration\ExtensionBootstrap
88545 {
88546 return $this->extensionBootstraps[$this->position];
88547 }
88548 public function next(): void
88549 {
88550 $this->position++;
88551 }
88552 }
88553 <?php
88554
88555 declare (strict_types=1);
88556 /*
88557 * This file is part of PHPUnit.
88558 *
88559 * (c) Sebastian Bergmann <sebastian@phpunit.de>
88560 *
88561 * For the full copyright and license information, please view the LICENSE
88562 * file that was distributed with this source code.
88563 */
88564 namespace PHPUnit\TextUI\Configuration;
88565
88566 /**
88567 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
88568 *
88569 * @psalm-immutable
88570 */
88571 final class File
88572 {
88573 /**
88574 * @psalm-var non-empty-string
88575 */
88576 private readonly string $path;
88577 /**
88578 * @psalm-param non-empty-string $path
88579 */
88580 public function __construct(string $path)
88581 {
88582 $this->path = $path;
88583 }
88584 /**
88585 * @psalm-return non-empty-string
88586 */
88587 public function path(): string
88588 {
88589 return $this->path;
88590 }
88591 }
88592 <?php
88593
88594 declare (strict_types=1);
88595 /*
88596 * This file is part of PHPUnit.
88597 *
88598 * (c) Sebastian Bergmann <sebastian@phpunit.de>
88599 *
88600 * For the full copyright and license information, please view the LICENSE
88601 * file that was distributed with this source code.
88602 */
88603 namespace PHPUnit\TextUI\Configuration;
88604
88605 use function count;
88606 use Countable;
88607 use IteratorAggregate;
88608 /**
88609 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
88610 *
88611 * @psalm-immutable
88612 *
88613 * @template-implements IteratorAggregate<int, File>
88614 */
88615 final class FileCollection implements Countable, IteratorAggregate
88616 {
88617 /**
88618 * @psalm-var list<File>
88619 */
88620 private readonly array $files;
88621 /**
88622 * @psalm-param list<File> $files
88623 */
88624 public static function fromArray(array $files): self
88625 {
88626 return new self(...$files);
88627 }
88628 private function __construct(\PHPUnit\TextUI\Configuration\File ...$files)
88629 {
88630 $this->files = $files;
88631 }
88632 /**
88633 * @psalm-return list<File>
88634 */
88635 public function asArray(): array
88636 {
88637 return $this->files;
88638 }
88639 public function count(): int
88640 {
88641 return count($this->files);
88642 }
88643 public function notEmpty(): bool
88644 {
88645 return !empty($this->files);
88646 }
88647 public function getIterator(): \PHPUnit\TextUI\Configuration\FileCollectionIterator
88648 {
88649 return new \PHPUnit\TextUI\Configuration\FileCollectionIterator($this);
88650 }
88651 }
88652 <?php
88653
88654 declare (strict_types=1);
88655 /*
88656 * This file is part of PHPUnit.
88657 *
88658 * (c) Sebastian Bergmann <sebastian@phpunit.de>
88659 *
88660 * For the full copyright and license information, please view the LICENSE
88661 * file that was distributed with this source code.
88662 */
88663 namespace PHPUnit\TextUI\Configuration;
88664
88665 use function count;
88666 use function iterator_count;
88667 use Countable;
88668 use Iterator;
88669 /**
88670 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
88671 *
88672 * @template-implements Iterator<int, File>
88673 */
88674 final class FileCollectionIterator implements Countable, Iterator
88675 {
88676 /**
88677 * @psalm-var list<File>
88678 */
88679 private readonly array $files;
88680 private int $position = 0;
88681 public function __construct(\PHPUnit\TextUI\Configuration\FileCollection $files)
88682 {
88683 $this->files = $files->asArray();
88684 }
88685 public function count(): int
88686 {
88687 return iterator_count($this);
88688 }
88689 public function rewind(): void
88690 {
88691 $this->position = 0;
88692 }
88693 public function valid(): bool
88694 {
88695 return $this->position < count($this->files);
88696 }
88697 public function key(): int
88698 {
88699 return $this->position;
88700 }
88701 public function current(): \PHPUnit\TextUI\Configuration\File
88702 {
88703 return $this->files[$this->position];
88704 }
88705 public function next(): void
88706 {
88707 $this->position++;
88708 }
88709 }
88710 <?php
88711
88712 declare (strict_types=1);
88713 /*
88714 * This file is part of PHPUnit.
88715 *
88716 * (c) Sebastian Bergmann <sebastian@phpunit.de>
88717 *
88718 * For the full copyright and license information, please view the LICENSE
88719 * file that was distributed with this source code.
88720 */
88721 namespace PHPUnit\TextUI\Configuration;
88722
88723 /**
88724 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
88725 *
88726 * @psalm-immutable
88727 */
88728 final class FilterDirectory
88729 {
88730 /**
88731 * @psalm-var non-empty-string
88732 */
88733 private readonly string $path;
88734 private readonly string $prefix;
88735 private readonly string $suffix;
88736 /**
88737 * @psalm-param non-empty-string $path
88738 */
88739 public function __construct(string $path, string $prefix, string $suffix)
88740 {
88741 $this->path = $path;
88742 $this->prefix = $prefix;
88743 $this->suffix = $suffix;
88744 }
88745 /**
88746 * @psalm-return non-empty-string
88747 */
88748 public function path(): string
88749 {
88750 return $this->path;
88751 }
88752 public function prefix(): string
88753 {
88754 return $this->prefix;
88755 }
88756 public function suffix(): string
88757 {
88758 return $this->suffix;
88759 }
88760 }
88761 <?php
88762
88763 declare (strict_types=1);
88764 /*
88765 * This file is part of PHPUnit.
88766 *
88767 * (c) Sebastian Bergmann <sebastian@phpunit.de>
88768 *
88769 * For the full copyright and license information, please view the LICENSE
88770 * file that was distributed with this source code.
88771 */
88772 namespace PHPUnit\TextUI\Configuration;
88773
88774 use function count;
88775 use Countable;
88776 use IteratorAggregate;
88777 /**
88778 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
88779 *
88780 * @psalm-immutable
88781 *
88782 * @template-implements IteratorAggregate<int, FilterDirectory>
88783 */
88784 final class FilterDirectoryCollection implements Countable, IteratorAggregate
88785 {
88786 /**
88787 * @psalm-var list<FilterDirectory>
88788 */
88789 private readonly array $directories;
88790 /**
88791 * @psalm-param list<FilterDirectory> $directories
88792 */
88793 public static function fromArray(array $directories): self
88794 {
88795 return new self(...$directories);
88796 }
88797 private function __construct(\PHPUnit\TextUI\Configuration\FilterDirectory ...$directories)
88798 {
88799 $this->directories = $directories;
88800 }
88801 /**
88802 * @psalm-return list<FilterDirectory>
88803 */
88804 public function asArray(): array
88805 {
88806 return $this->directories;
88807 }
88808 public function count(): int
88809 {
88810 return count($this->directories);
88811 }
88812 public function notEmpty(): bool
88813 {
88814 return !empty($this->directories);
88815 }
88816 public function getIterator(): \PHPUnit\TextUI\Configuration\FilterDirectoryCollectionIterator
88817 {
88818 return new \PHPUnit\TextUI\Configuration\FilterDirectoryCollectionIterator($this);
88819 }
88820 }
88821 <?php
88822
88823 declare (strict_types=1);
88824 /*
88825 * This file is part of PHPUnit.
88826 *
88827 * (c) Sebastian Bergmann <sebastian@phpunit.de>
88828 *
88829 * For the full copyright and license information, please view the LICENSE
88830 * file that was distributed with this source code.
88831 */
88832 namespace PHPUnit\TextUI\Configuration;
88833
88834 use function count;
88835 use function iterator_count;
88836 use Countable;
88837 use Iterator;
88838 /**
88839 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
88840 *
88841 * @template-implements Iterator<int, FilterDirectory>
88842 */
88843 final class FilterDirectoryCollectionIterator implements Countable, Iterator
88844 {
88845 /**
88846 * @psalm-var list<FilterDirectory>
88847 */
88848 private readonly array $directories;
88849 private int $position = 0;
88850 public function __construct(\PHPUnit\TextUI\Configuration\FilterDirectoryCollection $directories)
88851 {
88852 $this->directories = $directories->asArray();
88853 }
88854 public function count(): int
88855 {
88856 return iterator_count($this);
88857 }
88858 public function rewind(): void
88859 {
88860 $this->position = 0;
88861 }
88862 public function valid(): bool
88863 {
88864 return $this->position < count($this->directories);
88865 }
88866 public function key(): int
88867 {
88868 return $this->position;
88869 }
88870 public function current(): \PHPUnit\TextUI\Configuration\FilterDirectory
88871 {
88872 return $this->directories[$this->position];
88873 }
88874 public function next(): void
88875 {
88876 $this->position++;
88877 }
88878 }
88879 <?php
88880
88881 declare (strict_types=1);
88882 /*
88883 * This file is part of PHPUnit.
88884 *
88885 * (c) Sebastian Bergmann <sebastian@phpunit.de>
88886 *
88887 * For the full copyright and license information, please view the LICENSE
88888 * file that was distributed with this source code.
88889 */
88890 namespace PHPUnit\TextUI\Configuration;
88891
88892 /**
88893 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
88894 *
88895 * @psalm-immutable
88896 */
88897 final class Group
88898 {
88899 private readonly string $name;
88900 public function __construct(string $name)
88901 {
88902 $this->name = $name;
88903 }
88904 public function name(): string
88905 {
88906 return $this->name;
88907 }
88908 }
88909 <?php
88910
88911 declare (strict_types=1);
88912 /*
88913 * This file is part of PHPUnit.
88914 *
88915 * (c) Sebastian Bergmann <sebastian@phpunit.de>
88916 *
88917 * For the full copyright and license information, please view the LICENSE
88918 * file that was distributed with this source code.
88919 */
88920 namespace PHPUnit\TextUI\Configuration;
88921
88922 use IteratorAggregate;
88923 /**
88924 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
88925 *
88926 * @psalm-immutable
88927 *
88928 * @template-implements IteratorAggregate<int, Group>
88929 */
88930 final class GroupCollection implements IteratorAggregate
88931 {
88932 /**
88933 * @psalm-var list<Group>
88934 */
88935 private readonly array $groups;
88936 /**
88937 * @psalm-param list<Group> $groups
88938 */
88939 public static function fromArray(array $groups): self
88940 {
88941 return new self(...$groups);
88942 }
88943 private function __construct(\PHPUnit\TextUI\Configuration\Group ...$groups)
88944 {
88945 $this->groups = $groups;
88946 }
88947 /**
88948 * @psalm-return list<Group>
88949 */
88950 public function asArray(): array
88951 {
88952 return $this->groups;
88953 }
88954 /**
88955 * @psalm-return list<string>
88956 */
88957 public function asArrayOfStrings(): array
88958 {
88959 $result = [];
88960 foreach ($this->groups as $group) {
88961 $result[] = $group->name();
88962 }
88963 return $result;
88964 }
88965 public function isEmpty(): bool
88966 {
88967 return empty($this->groups);
88968 }
88969 public function getIterator(): \PHPUnit\TextUI\Configuration\GroupCollectionIterator
88970 {
88971 return new \PHPUnit\TextUI\Configuration\GroupCollectionIterator($this);
88972 }
88973 }
88974 <?php
88975
88976 declare (strict_types=1);
88977 /*
88978 * This file is part of PHPUnit.
88979 *
88980 * (c) Sebastian Bergmann <sebastian@phpunit.de>
88981 *
88982 * For the full copyright and license information, please view the LICENSE
88983 * file that was distributed with this source code.
88984 */
88985 namespace PHPUnit\TextUI\Configuration;
88986
88987 use function count;
88988 use function iterator_count;
88989 use Countable;
88990 use Iterator;
88991 /**
88992 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
88993 *
88994 * @template-implements Iterator<int, Group>
88995 */
88996 final class GroupCollectionIterator implements Countable, Iterator
88997 {
88998 /**
88999 * @psalm-var list<Group>
89000 */
89001 private readonly array $groups;
89002 private int $position = 0;
89003 public function __construct(\PHPUnit\TextUI\Configuration\GroupCollection $groups)
89004 {
89005 $this->groups = $groups->asArray();
89006 }
89007 public function count(): int
89008 {
89009 return iterator_count($this);
89010 }
89011 public function rewind(): void
89012 {
89013 $this->position = 0;
89014 }
89015 public function valid(): bool
89016 {
89017 return $this->position < count($this->groups);
89018 }
89019 public function key(): int
89020 {
89021 return $this->position;
89022 }
89023 public function current(): \PHPUnit\TextUI\Configuration\Group
89024 {
89025 return $this->groups[$this->position];
89026 }
89027 public function next(): void
89028 {
89029 $this->position++;
89030 }
89031 }
89032 <?php
89033
89034 declare (strict_types=1);
89035 /*
89036 * This file is part of PHPUnit.
89037 *
89038 * (c) Sebastian Bergmann <sebastian@phpunit.de>
89039 *
89040 * For the full copyright and license information, please view the LICENSE
89041 * file that was distributed with this source code.
89042 */
89043 namespace PHPUnit\TextUI\Configuration;
89044
89045 /**
89046 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
89047 *
89048 * @psalm-immutable
89049 */
89050 final class IniSetting
89051 {
89052 private readonly string $name;
89053 private readonly string $value;
89054 public function __construct(string $name, string $value)
89055 {
89056 $this->name = $name;
89057 $this->value = $value;
89058 }
89059 public function name(): string
89060 {
89061 return $this->name;
89062 }
89063 public function value(): string
89064 {
89065 return $this->value;
89066 }
89067 }
89068 <?php
89069
89070 declare (strict_types=1);
89071 /*
89072 * This file is part of PHPUnit.
89073 *
89074 * (c) Sebastian Bergmann <sebastian@phpunit.de>
89075 *
89076 * For the full copyright and license information, please view the LICENSE
89077 * file that was distributed with this source code.
89078 */
89079 namespace PHPUnit\TextUI\Configuration;
89080
89081 use function count;
89082 use Countable;
89083 use IteratorAggregate;
89084 /**
89085 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
89086 *
89087 * @psalm-immutable
89088 *
89089 * @template-implements IteratorAggregate<int, IniSetting>
89090 */
89091 final class IniSettingCollection implements Countable, IteratorAggregate
89092 {
89093 /**
89094 * @psalm-var list<IniSetting>
89095 */
89096 private readonly array $iniSettings;
89097 /**
89098 * @psalm-param list<IniSetting> $iniSettings
89099 */
89100 public static function fromArray(array $iniSettings): self
89101 {
89102 return new self(...$iniSettings);
89103 }
89104 private function __construct(\PHPUnit\TextUI\Configuration\IniSetting ...$iniSettings)
89105 {
89106 $this->iniSettings = $iniSettings;
89107 }
89108 /**
89109 * @psalm-return list<IniSetting>
89110 */
89111 public function asArray(): array
89112 {
89113 return $this->iniSettings;
89114 }
89115 public function count(): int
89116 {
89117 return count($this->iniSettings);
89118 }
89119 public function getIterator(): \PHPUnit\TextUI\Configuration\IniSettingCollectionIterator
89120 {
89121 return new \PHPUnit\TextUI\Configuration\IniSettingCollectionIterator($this);
89122 }
89123 }
89124 <?php
89125
89126 declare (strict_types=1);
89127 /*
89128 * This file is part of PHPUnit.
89129 *
89130 * (c) Sebastian Bergmann <sebastian@phpunit.de>
89131 *
89132 * For the full copyright and license information, please view the LICENSE
89133 * file that was distributed with this source code.
89134 */
89135 namespace PHPUnit\TextUI\Configuration;
89136
89137 use function count;
89138 use function iterator_count;
89139 use Countable;
89140 use Iterator;
89141 /**
89142 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
89143 *
89144 * @template-implements Iterator<int, IniSetting>
89145 */
89146 final class IniSettingCollectionIterator implements Countable, Iterator
89147 {
89148 /**
89149 * @psalm-var list<IniSetting>
89150 */
89151 private readonly array $iniSettings;
89152 private int $position = 0;
89153 public function __construct(\PHPUnit\TextUI\Configuration\IniSettingCollection $iniSettings)
89154 {
89155 $this->iniSettings = $iniSettings->asArray();
89156 }
89157 public function count(): int
89158 {
89159 return iterator_count($this);
89160 }
89161 public function rewind(): void
89162 {
89163 $this->position = 0;
89164 }
89165 public function valid(): bool
89166 {
89167 return $this->position < count($this->iniSettings);
89168 }
89169 public function key(): int
89170 {
89171 return $this->position;
89172 }
89173 public function current(): \PHPUnit\TextUI\Configuration\IniSetting
89174 {
89175 return $this->iniSettings[$this->position];
89176 }
89177 public function next(): void
89178 {
89179 $this->position++;
89180 }
89181 }
89182 <?php
89183
89184 declare (strict_types=1);
89185 /*
89186 * This file is part of PHPUnit.
89187 *
89188 * (c) Sebastian Bergmann <sebastian@phpunit.de>
89189 *
89190 * For the full copyright and license information, please view the LICENSE
89191 * file that was distributed with this source code.
89192 */
89193 namespace PHPUnit\TextUI\Configuration;
89194
89195 /**
89196 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
89197 *
89198 * @psalm-immutable
89199 */
89200 final class Php
89201 {
89202 private readonly \PHPUnit\TextUI\Configuration\DirectoryCollection $includePaths;
89203 private readonly \PHPUnit\TextUI\Configuration\IniSettingCollection $iniSettings;
89204 private readonly \PHPUnit\TextUI\Configuration\ConstantCollection $constants;
89205 private readonly \PHPUnit\TextUI\Configuration\VariableCollection $globalVariables;
89206 private readonly \PHPUnit\TextUI\Configuration\VariableCollection $envVariables;
89207 private readonly \PHPUnit\TextUI\Configuration\VariableCollection $postVariables;
89208 private readonly \PHPUnit\TextUI\Configuration\VariableCollection $getVariables;
89209 private readonly \PHPUnit\TextUI\Configuration\VariableCollection $cookieVariables;
89210 private readonly \PHPUnit\TextUI\Configuration\VariableCollection $serverVariables;
89211 private readonly \PHPUnit\TextUI\Configuration\VariableCollection $filesVariables;
89212 private readonly \PHPUnit\TextUI\Configuration\VariableCollection $requestVariables;
89213 public function __construct(\PHPUnit\TextUI\Configuration\DirectoryCollection $includePaths, \PHPUnit\TextUI\Configuration\IniSettingCollection $iniSettings, \PHPUnit\TextUI\Configuration\ConstantCollection $constants, \PHPUnit\TextUI\Configuration\VariableCollection $globalVariables, \PHPUnit\TextUI\Configuration\VariableCollection $envVariables, \PHPUnit\TextUI\Configuration\VariableCollection $postVariables, \PHPUnit\TextUI\Configuration\VariableCollection $getVariables, \PHPUnit\TextUI\Configuration\VariableCollection $cookieVariables, \PHPUnit\TextUI\Configuration\VariableCollection $serverVariables, \PHPUnit\TextUI\Configuration\VariableCollection $filesVariables, \PHPUnit\TextUI\Configuration\VariableCollection $requestVariables)
89214 {
89215 $this->includePaths = $includePaths;
89216 $this->iniSettings = $iniSettings;
89217 $this->constants = $constants;
89218 $this->globalVariables = $globalVariables;
89219 $this->envVariables = $envVariables;
89220 $this->postVariables = $postVariables;
89221 $this->getVariables = $getVariables;
89222 $this->cookieVariables = $cookieVariables;
89223 $this->serverVariables = $serverVariables;
89224 $this->filesVariables = $filesVariables;
89225 $this->requestVariables = $requestVariables;
89226 }
89227 public function includePaths(): \PHPUnit\TextUI\Configuration\DirectoryCollection
89228 {
89229 return $this->includePaths;
89230 }
89231 public function iniSettings(): \PHPUnit\TextUI\Configuration\IniSettingCollection
89232 {
89233 return $this->iniSettings;
89234 }
89235 public function constants(): \PHPUnit\TextUI\Configuration\ConstantCollection
89236 {
89237 return $this->constants;
89238 }
89239 public function globalVariables(): \PHPUnit\TextUI\Configuration\VariableCollection
89240 {
89241 return $this->globalVariables;
89242 }
89243 public function envVariables(): \PHPUnit\TextUI\Configuration\VariableCollection
89244 {
89245 return $this->envVariables;
89246 }
89247 public function postVariables(): \PHPUnit\TextUI\Configuration\VariableCollection
89248 {
89249 return $this->postVariables;
89250 }
89251 public function getVariables(): \PHPUnit\TextUI\Configuration\VariableCollection
89252 {
89253 return $this->getVariables;
89254 }
89255 public function cookieVariables(): \PHPUnit\TextUI\Configuration\VariableCollection
89256 {
89257 return $this->cookieVariables;
89258 }
89259 public function serverVariables(): \PHPUnit\TextUI\Configuration\VariableCollection
89260 {
89261 return $this->serverVariables;
89262 }
89263 public function filesVariables(): \PHPUnit\TextUI\Configuration\VariableCollection
89264 {
89265 return $this->filesVariables;
89266 }
89267 public function requestVariables(): \PHPUnit\TextUI\Configuration\VariableCollection
89268 {
89269 return $this->requestVariables;
89270 }
89271 }
89272 <?php
89273
89274 declare (strict_types=1);
89275 /*
89276 * This file is part of PHPUnit.
89277 *
89278 * (c) Sebastian Bergmann <sebastian@phpunit.de>
89279 *
89280 * For the full copyright and license information, please view the LICENSE
89281 * file that was distributed with this source code.
89282 */
89283 namespace PHPUnit\TextUI\Configuration;
89284
89285 /**
89286 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
89287 *
89288 * @psalm-immutable
89289 */
89290 final class Source
89291 {
89292 /**
89293 * @psalm-var non-empty-string
89294 */
89295 private readonly ?string $baseline;
89296 private readonly bool $ignoreBaseline;
89297 private readonly \PHPUnit\TextUI\Configuration\FilterDirectoryCollection $includeDirectories;
89298 private readonly \PHPUnit\TextUI\Configuration\FileCollection $includeFiles;
89299 private readonly \PHPUnit\TextUI\Configuration\FilterDirectoryCollection $excludeDirectories;
89300 private readonly \PHPUnit\TextUI\Configuration\FileCollection $excludeFiles;
89301 private readonly bool $restrictDeprecations;
89302 private readonly bool $restrictNotices;
89303 private readonly bool $restrictWarnings;
89304 private readonly bool $ignoreSuppressionOfDeprecations;
89305 private readonly bool $ignoreSuppressionOfPhpDeprecations;
89306 private readonly bool $ignoreSuppressionOfErrors;
89307 private readonly bool $ignoreSuppressionOfNotices;
89308 private readonly bool $ignoreSuppressionOfPhpNotices;
89309 private readonly bool $ignoreSuppressionOfWarnings;
89310 private readonly bool $ignoreSuppressionOfPhpWarnings;
89311 /**
89312 * @psalm-param non-empty-string $baseline
89313 */
89314 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)
89315 {
89316 $this->baseline = $baseline;
89317 $this->ignoreBaseline = $ignoreBaseline;
89318 $this->includeDirectories = $includeDirectories;
89319 $this->includeFiles = $includeFiles;
89320 $this->excludeDirectories = $excludeDirectories;
89321 $this->excludeFiles = $excludeFiles;
89322 $this->restrictDeprecations = $restrictDeprecations;
89323 $this->restrictNotices = $restrictNotices;
89324 $this->restrictWarnings = $restrictWarnings;
89325 $this->ignoreSuppressionOfDeprecations = $ignoreSuppressionOfDeprecations;
89326 $this->ignoreSuppressionOfPhpDeprecations = $ignoreSuppressionOfPhpDeprecations;
89327 $this->ignoreSuppressionOfErrors = $ignoreSuppressionOfErrors;
89328 $this->ignoreSuppressionOfNotices = $ignoreSuppressionOfNotices;
89329 $this->ignoreSuppressionOfPhpNotices = $ignoreSuppressionOfPhpNotices;
89330 $this->ignoreSuppressionOfWarnings = $ignoreSuppressionOfWarnings;
89331 $this->ignoreSuppressionOfPhpWarnings = $ignoreSuppressionOfPhpWarnings;
89332 }
89333 /**
89334 * @psalm-assert-if-true !null $this->baseline
89335 */
89336 public function useBaseline(): bool
89337 {
89338 return $this->hasBaseline() && !$this->ignoreBaseline;
89339 }
89340 /**
89341 * @psalm-assert-if-true !null $this->baseline
89342 */
89343 public function hasBaseline(): bool
89344 {
89345 return $this->baseline !== null;
89346 }
89347 /**
89348 * @throws NoBaselineException
89349 *
89350 * @psalm-return non-empty-string
89351 */
89352 public function baseline(): string
89353 {
89354 if (!$this->hasBaseline()) {
89355 throw new \PHPUnit\TextUI\Configuration\NoBaselineException();
89356 }
89357 return $this->baseline;
89358 }
89359 public function includeDirectories(): \PHPUnit\TextUI\Configuration\FilterDirectoryCollection
89360 {
89361 return $this->includeDirectories;
89362 }
89363 public function includeFiles(): \PHPUnit\TextUI\Configuration\FileCollection
89364 {
89365 return $this->includeFiles;
89366 }
89367 public function excludeDirectories(): \PHPUnit\TextUI\Configuration\FilterDirectoryCollection
89368 {
89369 return $this->excludeDirectories;
89370 }
89371 public function excludeFiles(): \PHPUnit\TextUI\Configuration\FileCollection
89372 {
89373 return $this->excludeFiles;
89374 }
89375 public function notEmpty(): bool
89376 {
89377 return $this->includeDirectories->notEmpty() || $this->includeFiles->notEmpty();
89378 }
89379 public function restrictDeprecations(): bool
89380 {
89381 return $this->restrictDeprecations;
89382 }
89383 public function restrictNotices(): bool
89384 {
89385 return $this->restrictNotices;
89386 }
89387 public function restrictWarnings(): bool
89388 {
89389 return $this->restrictWarnings;
89390 }
89391 public function ignoreSuppressionOfDeprecations(): bool
89392 {
89393 return $this->ignoreSuppressionOfDeprecations;
89394 }
89395 public function ignoreSuppressionOfPhpDeprecations(): bool
89396 {
89397 return $this->ignoreSuppressionOfPhpDeprecations;
89398 }
89399 public function ignoreSuppressionOfErrors(): bool
89400 {
89401 return $this->ignoreSuppressionOfErrors;
89402 }
89403 public function ignoreSuppressionOfNotices(): bool
89404 {
89405 return $this->ignoreSuppressionOfNotices;
89406 }
89407 public function ignoreSuppressionOfPhpNotices(): bool
89408 {
89409 return $this->ignoreSuppressionOfPhpNotices;
89410 }
89411 public function ignoreSuppressionOfWarnings(): bool
89412 {
89413 return $this->ignoreSuppressionOfWarnings;
89414 }
89415 public function ignoreSuppressionOfPhpWarnings(): bool
89416 {
89417 return $this->ignoreSuppressionOfPhpWarnings;
89418 }
89419 }
89420 <?php
89421
89422 declare (strict_types=1);
89423 /*
89424 * This file is part of PHPUnit.
89425 *
89426 * (c) Sebastian Bergmann <sebastian@phpunit.de>
89427 *
89428 * For the full copyright and license information, please view the LICENSE
89429 * file that was distributed with this source code.
89430 */
89431 namespace PHPUnit\TextUI\Configuration;
89432
89433 use PHPUnit\Util\VersionComparisonOperator;
89434 /**
89435 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
89436 *
89437 * @psalm-immutable
89438 */
89439 final class TestDirectory
89440 {
89441 /**
89442 * @psalm-var non-empty-string
89443 */
89444 private readonly string $path;
89445 private readonly string $prefix;
89446 private readonly string $suffix;
89447 private readonly string $phpVersion;
89448 private readonly VersionComparisonOperator $phpVersionOperator;
89449 /**
89450 * @psalm-param non-empty-string $path
89451 */
89452 public function __construct(string $path, string $prefix, string $suffix, string $phpVersion, VersionComparisonOperator $phpVersionOperator)
89453 {
89454 $this->path = $path;
89455 $this->prefix = $prefix;
89456 $this->suffix = $suffix;
89457 $this->phpVersion = $phpVersion;
89458 $this->phpVersionOperator = $phpVersionOperator;
89459 }
89460 /**
89461 * @psalm-return non-empty-string
89462 */
89463 public function path(): string
89464 {
89465 return $this->path;
89466 }
89467 public function prefix(): string
89468 {
89469 return $this->prefix;
89470 }
89471 public function suffix(): string
89472 {
89473 return $this->suffix;
89474 }
89475 public function phpVersion(): string
89476 {
89477 return $this->phpVersion;
89478 }
89479 public function phpVersionOperator(): VersionComparisonOperator
89480 {
89481 return $this->phpVersionOperator;
89482 }
89483 }
89484 <?php
89485
89486 declare (strict_types=1);
89487 /*
89488 * This file is part of PHPUnit.
89489 *
89490 * (c) Sebastian Bergmann <sebastian@phpunit.de>
89491 *
89492 * For the full copyright and license information, please view the LICENSE
89493 * file that was distributed with this source code.
89494 */
89495 namespace PHPUnit\TextUI\Configuration;
89496
89497 use function count;
89498 use Countable;
89499 use IteratorAggregate;
89500 /**
89501 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
89502 *
89503 * @psalm-immutable
89504 *
89505 * @template-implements IteratorAggregate<int, TestDirectory>
89506 */
89507 final class TestDirectoryCollection implements Countable, IteratorAggregate
89508 {
89509 /**
89510 * @psalm-var list<TestDirectory>
89511 */
89512 private readonly array $directories;
89513 /**
89514 * @psalm-param list<TestDirectory> $directories
89515 */
89516 public static function fromArray(array $directories): self
89517 {
89518 return new self(...$directories);
89519 }
89520 private function __construct(\PHPUnit\TextUI\Configuration\TestDirectory ...$directories)
89521 {
89522 $this->directories = $directories;
89523 }
89524 /**
89525 * @psalm-return list<TestDirectory>
89526 */
89527 public function asArray(): array
89528 {
89529 return $this->directories;
89530 }
89531 public function count(): int
89532 {
89533 return count($this->directories);
89534 }
89535 public function getIterator(): \PHPUnit\TextUI\Configuration\TestDirectoryCollectionIterator
89536 {
89537 return new \PHPUnit\TextUI\Configuration\TestDirectoryCollectionIterator($this);
89538 }
89539 public function isEmpty(): bool
89540 {
89541 return $this->count() === 0;
89542 }
89543 }
89544 <?php
89545
89546 declare (strict_types=1);
89547 /*
89548 * This file is part of PHPUnit.
89549 *
89550 * (c) Sebastian Bergmann <sebastian@phpunit.de>
89551 *
89552 * For the full copyright and license information, please view the LICENSE
89553 * file that was distributed with this source code.
89554 */
89555 namespace PHPUnit\TextUI\Configuration;
89556
89557 use function count;
89558 use function iterator_count;
89559 use Countable;
89560 use Iterator;
89561 /**
89562 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
89563 *
89564 * @template-implements Iterator<int, TestDirectory>
89565 */
89566 final class TestDirectoryCollectionIterator implements Countable, Iterator
89567 {
89568 /**
89569 * @psalm-var list<TestDirectory>
89570 */
89571 private readonly array $directories;
89572 private int $position = 0;
89573 public function __construct(\PHPUnit\TextUI\Configuration\TestDirectoryCollection $directories)
89574 {
89575 $this->directories = $directories->asArray();
89576 }
89577 public function count(): int
89578 {
89579 return iterator_count($this);
89580 }
89581 public function rewind(): void
89582 {
89583 $this->position = 0;
89584 }
89585 public function valid(): bool
89586 {
89587 return $this->position < count($this->directories);
89588 }
89589 public function key(): int
89590 {
89591 return $this->position;
89592 }
89593 public function current(): \PHPUnit\TextUI\Configuration\TestDirectory
89594 {
89595 return $this->directories[$this->position];
89596 }
89597 public function next(): void
89598 {
89599 $this->position++;
89600 }
89601 }
89602 <?php
89603
89604 declare (strict_types=1);
89605 /*
89606 * This file is part of PHPUnit.
89607 *
89608 * (c) Sebastian Bergmann <sebastian@phpunit.de>
89609 *
89610 * For the full copyright and license information, please view the LICENSE
89611 * file that was distributed with this source code.
89612 */
89613 namespace PHPUnit\TextUI\Configuration;
89614
89615 use PHPUnit\Util\VersionComparisonOperator;
89616 /**
89617 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
89618 *
89619 * @psalm-immutable
89620 */
89621 final class TestFile
89622 {
89623 private readonly string $path;
89624 private readonly string $phpVersion;
89625 private readonly VersionComparisonOperator $phpVersionOperator;
89626 public function __construct(string $path, string $phpVersion, VersionComparisonOperator $phpVersionOperator)
89627 {
89628 $this->path = $path;
89629 $this->phpVersion = $phpVersion;
89630 $this->phpVersionOperator = $phpVersionOperator;
89631 }
89632 public function path(): string
89633 {
89634 return $this->path;
89635 }
89636 public function phpVersion(): string
89637 {
89638 return $this->phpVersion;
89639 }
89640 public function phpVersionOperator(): VersionComparisonOperator
89641 {
89642 return $this->phpVersionOperator;
89643 }
89644 }
89645 <?php
89646
89647 declare (strict_types=1);
89648 /*
89649 * This file is part of PHPUnit.
89650 *
89651 * (c) Sebastian Bergmann <sebastian@phpunit.de>
89652 *
89653 * For the full copyright and license information, please view the LICENSE
89654 * file that was distributed with this source code.
89655 */
89656 namespace PHPUnit\TextUI\Configuration;
89657
89658 use function count;
89659 use Countable;
89660 use IteratorAggregate;
89661 /**
89662 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
89663 *
89664 * @psalm-immutable
89665 *
89666 * @template-implements IteratorAggregate<int, TestFile>
89667 */
89668 final class TestFileCollection implements Countable, IteratorAggregate
89669 {
89670 /**
89671 * @psalm-var list<TestFile>
89672 */
89673 private readonly array $files;
89674 /**
89675 * @psalm-param list<TestFile> $files
89676 */
89677 public static function fromArray(array $files): self
89678 {
89679 return new self(...$files);
89680 }
89681 private function __construct(\PHPUnit\TextUI\Configuration\TestFile ...$files)
89682 {
89683 $this->files = $files;
89684 }
89685 /**
89686 * @psalm-return list<TestFile>
89687 */
89688 public function asArray(): array
89689 {
89690 return $this->files;
89691 }
89692 public function count(): int
89693 {
89694 return count($this->files);
89695 }
89696 public function getIterator(): \PHPUnit\TextUI\Configuration\TestFileCollectionIterator
89697 {
89698 return new \PHPUnit\TextUI\Configuration\TestFileCollectionIterator($this);
89699 }
89700 public function isEmpty(): bool
89701 {
89702 return $this->count() === 0;
89703 }
89704 }
89705 <?php
89706
89707 declare (strict_types=1);
89708 /*
89709 * This file is part of PHPUnit.
89710 *
89711 * (c) Sebastian Bergmann <sebastian@phpunit.de>
89712 *
89713 * For the full copyright and license information, please view the LICENSE
89714 * file that was distributed with this source code.
89715 */
89716 namespace PHPUnit\TextUI\Configuration;
89717
89718 use function count;
89719 use function iterator_count;
89720 use Countable;
89721 use Iterator;
89722 /**
89723 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
89724 *
89725 * @template-implements Iterator<int, TestFile>
89726 */
89727 final class TestFileCollectionIterator implements Countable, Iterator
89728 {
89729 /**
89730 * @psalm-var list<TestFile>
89731 */
89732 private readonly array $files;
89733 private int $position = 0;
89734 public function __construct(\PHPUnit\TextUI\Configuration\TestFileCollection $files)
89735 {
89736 $this->files = $files->asArray();
89737 }
89738 public function count(): int
89739 {
89740 return iterator_count($this);
89741 }
89742 public function rewind(): void
89743 {
89744 $this->position = 0;
89745 }
89746 public function valid(): bool
89747 {
89748 return $this->position < count($this->files);
89749 }
89750 public function key(): int
89751 {
89752 return $this->position;
89753 }
89754 public function current(): \PHPUnit\TextUI\Configuration\TestFile
89755 {
89756 return $this->files[$this->position];
89757 }
89758 public function next(): void
89759 {
89760 $this->position++;
89761 }
89762 }
89763 <?php
89764
89765 declare (strict_types=1);
89766 /*
89767 * This file is part of PHPUnit.
89768 *
89769 * (c) Sebastian Bergmann <sebastian@phpunit.de>
89770 *
89771 * For the full copyright and license information, please view the LICENSE
89772 * file that was distributed with this source code.
89773 */
89774 namespace PHPUnit\TextUI\Configuration;
89775
89776 /**
89777 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
89778 *
89779 * @psalm-immutable
89780 */
89781 final class TestSuite
89782 {
89783 /**
89784 * @psalm-var non-empty-string
89785 */
89786 private readonly string $name;
89787 private readonly \PHPUnit\TextUI\Configuration\TestDirectoryCollection $directories;
89788 private readonly \PHPUnit\TextUI\Configuration\TestFileCollection $files;
89789 private readonly \PHPUnit\TextUI\Configuration\FileCollection $exclude;
89790 /**
89791 * @psalm-param non-empty-string $name
89792 */
89793 public function __construct(string $name, \PHPUnit\TextUI\Configuration\TestDirectoryCollection $directories, \PHPUnit\TextUI\Configuration\TestFileCollection $files, \PHPUnit\TextUI\Configuration\FileCollection $exclude)
89794 {
89795 $this->name = $name;
89796 $this->directories = $directories;
89797 $this->files = $files;
89798 $this->exclude = $exclude;
89799 }
89800 /**
89801 * @psalm-return non-empty-string
89802 */
89803 public function name(): string
89804 {
89805 return $this->name;
89806 }
89807 public function directories(): \PHPUnit\TextUI\Configuration\TestDirectoryCollection
89808 {
89809 return $this->directories;
89810 }
89811 public function files(): \PHPUnit\TextUI\Configuration\TestFileCollection
89812 {
89813 return $this->files;
89814 }
89815 public function exclude(): \PHPUnit\TextUI\Configuration\FileCollection
89816 {
89817 return $this->exclude;
89818 }
89819 }
89820 <?php
89821
89822 declare (strict_types=1);
89823 /*
89824 * This file is part of PHPUnit.
89825 *
89826 * (c) Sebastian Bergmann <sebastian@phpunit.de>
89827 *
89828 * For the full copyright and license information, please view the LICENSE
89829 * file that was distributed with this source code.
89830 */
89831 namespace PHPUnit\TextUI\Configuration;
89832
89833 use function count;
89834 use Countable;
89835 use IteratorAggregate;
89836 /**
89837 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
89838 *
89839 * @psalm-immutable
89840 *
89841 * @template-implements IteratorAggregate<int, TestSuite>
89842 */
89843 final class TestSuiteCollection implements Countable, IteratorAggregate
89844 {
89845 /**
89846 * @psalm-var list<TestSuite>
89847 */
89848 private readonly array $testSuites;
89849 /**
89850 * @psalm-param list<TestSuite> $testSuites
89851 */
89852 public static function fromArray(array $testSuites): self
89853 {
89854 return new self(...$testSuites);
89855 }
89856 private function __construct(\PHPUnit\TextUI\Configuration\TestSuite ...$testSuites)
89857 {
89858 $this->testSuites = $testSuites;
89859 }
89860 /**
89861 * @psalm-return list<TestSuite>
89862 */
89863 public function asArray(): array
89864 {
89865 return $this->testSuites;
89866 }
89867 public function count(): int
89868 {
89869 return count($this->testSuites);
89870 }
89871 public function getIterator(): \PHPUnit\TextUI\Configuration\TestSuiteCollectionIterator
89872 {
89873 return new \PHPUnit\TextUI\Configuration\TestSuiteCollectionIterator($this);
89874 }
89875 public function isEmpty(): bool
89876 {
89877 return $this->count() === 0;
89878 }
89879 }
89880 <?php
89881
89882 declare (strict_types=1);
89883 /*
89884 * This file is part of PHPUnit.
89885 *
89886 * (c) Sebastian Bergmann <sebastian@phpunit.de>
89887 *
89888 * For the full copyright and license information, please view the LICENSE
89889 * file that was distributed with this source code.
89890 */
89891 namespace PHPUnit\TextUI\Configuration;
89892
89893 use function count;
89894 use function iterator_count;
89895 use Countable;
89896 use Iterator;
89897 /**
89898 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
89899 *
89900 * @template-implements Iterator<int, TestSuite>
89901 */
89902 final class TestSuiteCollectionIterator implements Countable, Iterator
89903 {
89904 /**
89905 * @psalm-var list<TestSuite>
89906 */
89907 private readonly array $testSuites;
89908 private int $position = 0;
89909 public function __construct(\PHPUnit\TextUI\Configuration\TestSuiteCollection $testSuites)
89910 {
89911 $this->testSuites = $testSuites->asArray();
89912 }
89913 public function count(): int
89914 {
89915 return iterator_count($this);
89916 }
89917 public function rewind(): void
89918 {
89919 $this->position = 0;
89920 }
89921 public function valid(): bool
89922 {
89923 return $this->position < count($this->testSuites);
89924 }
89925 public function key(): int
89926 {
89927 return $this->position;
89928 }
89929 public function current(): \PHPUnit\TextUI\Configuration\TestSuite
89930 {
89931 return $this->testSuites[$this->position];
89932 }
89933 public function next(): void
89934 {
89935 $this->position++;
89936 }
89937 }
89938 <?php
89939
89940 declare (strict_types=1);
89941 /*
89942 * This file is part of PHPUnit.
89943 *
89944 * (c) Sebastian Bergmann <sebastian@phpunit.de>
89945 *
89946 * For the full copyright and license information, please view the LICENSE
89947 * file that was distributed with this source code.
89948 */
89949 namespace PHPUnit\TextUI\Configuration;
89950
89951 /**
89952 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
89953 *
89954 * @psalm-immutable
89955 */
89956 final class Variable
89957 {
89958 private readonly string $name;
89959 private readonly mixed $value;
89960 private readonly bool $force;
89961 public function __construct(string $name, mixed $value, bool $force)
89962 {
89963 $this->name = $name;
89964 $this->value = $value;
89965 $this->force = $force;
89966 }
89967 public function name(): string
89968 {
89969 return $this->name;
89970 }
89971 public function value(): mixed
89972 {
89973 return $this->value;
89974 }
89975 public function force(): bool
89976 {
89977 return $this->force;
89978 }
89979 }
89980 <?php
89981
89982 declare (strict_types=1);
89983 /*
89984 * This file is part of PHPUnit.
89985 *
89986 * (c) Sebastian Bergmann <sebastian@phpunit.de>
89987 *
89988 * For the full copyright and license information, please view the LICENSE
89989 * file that was distributed with this source code.
89990 */
89991 namespace PHPUnit\TextUI\Configuration;
89992
89993 use function count;
89994 use Countable;
89995 use IteratorAggregate;
89996 /**
89997 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
89998 *
89999 * @psalm-immutable
90000 *
90001 * @template-implements IteratorAggregate<int, Variable>
90002 */
90003 final class VariableCollection implements Countable, IteratorAggregate
90004 {
90005 /**
90006 * @psalm-var list<Variable>
90007 */
90008 private readonly array $variables;
90009 /**
90010 * @psalm-param list<Variable> $variables
90011 */
90012 public static function fromArray(array $variables): self
90013 {
90014 return new self(...$variables);
90015 }
90016 private function __construct(\PHPUnit\TextUI\Configuration\Variable ...$variables)
90017 {
90018 $this->variables = $variables;
90019 }
90020 /**
90021 * @psalm-return list<Variable>
90022 */
90023 public function asArray(): array
90024 {
90025 return $this->variables;
90026 }
90027 public function count(): int
90028 {
90029 return count($this->variables);
90030 }
90031 public function getIterator(): \PHPUnit\TextUI\Configuration\VariableCollectionIterator
90032 {
90033 return new \PHPUnit\TextUI\Configuration\VariableCollectionIterator($this);
90034 }
90035 }
90036 <?php
90037
90038 declare (strict_types=1);
90039 /*
90040 * This file is part of PHPUnit.
90041 *
90042 * (c) Sebastian Bergmann <sebastian@phpunit.de>
90043 *
90044 * For the full copyright and license information, please view the LICENSE
90045 * file that was distributed with this source code.
90046 */
90047 namespace PHPUnit\TextUI\Configuration;
90048
90049 use function count;
90050 use function iterator_count;
90051 use Countable;
90052 use Iterator;
90053 /**
90054 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
90055 *
90056 * @template-implements Iterator<int, Variable>
90057 */
90058 final class VariableCollectionIterator implements Countable, Iterator
90059 {
90060 /**
90061 * @psalm-var list<Variable>
90062 */
90063 private readonly array $variables;
90064 private int $position = 0;
90065 public function __construct(\PHPUnit\TextUI\Configuration\VariableCollection $variables)
90066 {
90067 $this->variables = $variables->asArray();
90068 }
90069 public function count(): int
90070 {
90071 return iterator_count($this);
90072 }
90073 public function rewind(): void
90074 {
90075 $this->position = 0;
90076 }
90077 public function valid(): bool
90078 {
90079 return $this->position < count($this->variables);
90080 }
90081 public function key(): int
90082 {
90083 return $this->position;
90084 }
90085 public function current(): \PHPUnit\TextUI\Configuration\Variable
90086 {
90087 return $this->variables[$this->position];
90088 }
90089 public function next(): void
90090 {
90091 $this->position++;
90092 }
90093 }
90094 <?php
90095
90096 declare (strict_types=1);
90097 /*
90098 * This file is part of PHPUnit.
90099 *
90100 * (c) Sebastian Bergmann <sebastian@phpunit.de>
90101 *
90102 * For the full copyright and license information, please view the LICENSE
90103 * file that was distributed with this source code.
90104 */
90105 namespace PHPUnit\TextUI\XmlConfiguration\CodeCoverage;
90106
90107 use function count;
90108 use PHPUnit\TextUI\Configuration\Directory;
90109 use PHPUnit\TextUI\Configuration\FileCollection;
90110 use PHPUnit\TextUI\Configuration\FilterDirectoryCollection;
90111 use PHPUnit\TextUI\XmlConfiguration\CodeCoverage\Report\Clover;
90112 use PHPUnit\TextUI\XmlConfiguration\CodeCoverage\Report\Cobertura;
90113 use PHPUnit\TextUI\XmlConfiguration\CodeCoverage\Report\Crap4j;
90114 use PHPUnit\TextUI\XmlConfiguration\CodeCoverage\Report\Html;
90115 use PHPUnit\TextUI\XmlConfiguration\CodeCoverage\Report\Php;
90116 use PHPUnit\TextUI\XmlConfiguration\CodeCoverage\Report\Text;
90117 use PHPUnit\TextUI\XmlConfiguration\CodeCoverage\Report\Xml;
90118 use PHPUnit\TextUI\XmlConfiguration\Exception;
90119 /**
90120 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
90121 *
90122 * @internal This class is not covered by the backward compatibility promise for PHPUnit
90123 *
90124 * @psalm-immutable
90125 */
90126 final class CodeCoverage
90127 {
90128 private readonly ?Directory $cacheDirectory;
90129 private readonly FilterDirectoryCollection $directories;
90130 private readonly FileCollection $files;
90131 private readonly FilterDirectoryCollection $excludeDirectories;
90132 private readonly FileCollection $excludeFiles;
90133 private readonly bool $pathCoverage;
90134 private readonly bool $includeUncoveredFiles;
90135 private readonly bool $ignoreDeprecatedCodeUnits;
90136 private readonly bool $disableCodeCoverageIgnore;
90137 private readonly ?Clover $clover;
90138 private readonly ?Cobertura $cobertura;
90139 private readonly ?Crap4j $crap4j;
90140 private readonly ?Html $html;
90141 private readonly ?Php $php;
90142 private readonly ?Text $text;
90143 private readonly ?Xml $xml;
90144 public function __construct(?Directory $cacheDirectory, FilterDirectoryCollection $directories, FileCollection $files, FilterDirectoryCollection $excludeDirectories, FileCollection $excludeFiles, bool $pathCoverage, bool $includeUncoveredFiles, bool $ignoreDeprecatedCodeUnits, bool $disableCodeCoverageIgnore, ?Clover $clover, ?Cobertura $cobertura, ?Crap4j $crap4j, ?Html $html, ?Php $php, ?Text $text, ?Xml $xml)
90145 {
90146 $this->cacheDirectory = $cacheDirectory;
90147 $this->directories = $directories;
90148 $this->files = $files;
90149 $this->excludeDirectories = $excludeDirectories;
90150 $this->excludeFiles = $excludeFiles;
90151 $this->pathCoverage = $pathCoverage;
90152 $this->includeUncoveredFiles = $includeUncoveredFiles;
90153 $this->ignoreDeprecatedCodeUnits = $ignoreDeprecatedCodeUnits;
90154 $this->disableCodeCoverageIgnore = $disableCodeCoverageIgnore;
90155 $this->clover = $clover;
90156 $this->cobertura = $cobertura;
90157 $this->crap4j = $crap4j;
90158 $this->html = $html;
90159 $this->php = $php;
90160 $this->text = $text;
90161 $this->xml = $xml;
90162 }
90163 /**
90164 * @psalm-assert-if-true !null $this->cacheDirectory
90165 *
90166 * @deprecated
90167 */
90168 public function hasCacheDirectory(): bool
90169 {
90170 return $this->cacheDirectory !== null;
90171 }
90172 /**
90173 * @throws Exception
90174 *
90175 * @deprecated
90176 */
90177 public function cacheDirectory(): Directory
90178 {
90179 if (!$this->hasCacheDirectory()) {
90180 throw new Exception('No cache directory has been configured');
90181 }
90182 return $this->cacheDirectory;
90183 }
90184 public function hasNonEmptyListOfFilesToBeIncludedInCodeCoverageReport(): bool
90185 {
90186 return count($this->directories) > 0 || count($this->files) > 0;
90187 }
90188 public function directories(): FilterDirectoryCollection
90189 {
90190 return $this->directories;
90191 }
90192 public function files(): FileCollection
90193 {
90194 return $this->files;
90195 }
90196 public function excludeDirectories(): FilterDirectoryCollection
90197 {
90198 return $this->excludeDirectories;
90199 }
90200 public function excludeFiles(): FileCollection
90201 {
90202 return $this->excludeFiles;
90203 }
90204 public function pathCoverage(): bool
90205 {
90206 return $this->pathCoverage;
90207 }
90208 public function includeUncoveredFiles(): bool
90209 {
90210 return $this->includeUncoveredFiles;
90211 }
90212 public function ignoreDeprecatedCodeUnits(): bool
90213 {
90214 return $this->ignoreDeprecatedCodeUnits;
90215 }
90216 public function disableCodeCoverageIgnore(): bool
90217 {
90218 return $this->disableCodeCoverageIgnore;
90219 }
90220 /**
90221 * @psalm-assert-if-true !null $this->clover
90222 */
90223 public function hasClover(): bool
90224 {
90225 return $this->clover !== null;
90226 }
90227 /**
90228 * @throws Exception
90229 */
90230 public function clover(): Clover
90231 {
90232 if (!$this->hasClover()) {
90233 throw new Exception('Code Coverage report "Clover XML" has not been configured');
90234 }
90235 return $this->clover;
90236 }
90237 /**
90238 * @psalm-assert-if-true !null $this->cobertura
90239 */
90240 public function hasCobertura(): bool
90241 {
90242 return $this->cobertura !== null;
90243 }
90244 /**
90245 * @throws Exception
90246 */
90247 public function cobertura(): Cobertura
90248 {
90249 if (!$this->hasCobertura()) {
90250 throw new Exception('Code Coverage report "Cobertura XML" has not been configured');
90251 }
90252 return $this->cobertura;
90253 }
90254 /**
90255 * @psalm-assert-if-true !null $this->crap4j
90256 */
90257 public function hasCrap4j(): bool
90258 {
90259 return $this->crap4j !== null;
90260 }
90261 /**
90262 * @throws Exception
90263 */
90264 public function crap4j(): Crap4j
90265 {
90266 if (!$this->hasCrap4j()) {
90267 throw new Exception('Code Coverage report "Crap4J" has not been configured');
90268 }
90269 return $this->crap4j;
90270 }
90271 /**
90272 * @psalm-assert-if-true !null $this->html
90273 */
90274 public function hasHtml(): bool
90275 {
90276 return $this->html !== null;
90277 }
90278 /**
90279 * @throws Exception
90280 */
90281 public function html(): Html
90282 {
90283 if (!$this->hasHtml()) {
90284 throw new Exception('Code Coverage report "HTML" has not been configured');
90285 }
90286 return $this->html;
90287 }
90288 /**
90289 * @psalm-assert-if-true !null $this->php
90290 */
90291 public function hasPhp(): bool
90292 {
90293 return $this->php !== null;
90294 }
90295 /**
90296 * @throws Exception
90297 */
90298 public function php(): Php
90299 {
90300 if (!$this->hasPhp()) {
90301 throw new Exception('Code Coverage report "PHP" has not been configured');
90302 }
90303 return $this->php;
90304 }
90305 /**
90306 * @psalm-assert-if-true !null $this->text
90307 */
90308 public function hasText(): bool
90309 {
90310 return $this->text !== null;
90311 }
90312 /**
90313 * @throws Exception
90314 */
90315 public function text(): Text
90316 {
90317 if (!$this->hasText()) {
90318 throw new Exception('Code Coverage report "Text" has not been configured');
90319 }
90320 return $this->text;
90321 }
90322 /**
90323 * @psalm-assert-if-true !null $this->xml
90324 */
90325 public function hasXml(): bool
90326 {
90327 return $this->xml !== null;
90328 }
90329 /**
90330 * @throws Exception
90331 */
90332 public function xml(): Xml
90333 {
90334 if (!$this->hasXml()) {
90335 throw new Exception('Code Coverage report "XML" has not been configured');
90336 }
90337 return $this->xml;
90338 }
90339 }
90340 <?php
90341
90342 declare (strict_types=1);
90343 /*
90344 * This file is part of PHPUnit.
90345 *
90346 * (c) Sebastian Bergmann <sebastian@phpunit.de>
90347 *
90348 * For the full copyright and license information, please view the LICENSE
90349 * file that was distributed with this source code.
90350 */
90351 namespace PHPUnit\TextUI\XmlConfiguration\CodeCoverage\Report;
90352
90353 use PHPUnit\TextUI\Configuration\File;
90354 /**
90355 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
90356 *
90357 * @internal This class is not covered by the backward compatibility promise for PHPUnit
90358 *
90359 * @psalm-immutable
90360 */
90361 final class Clover
90362 {
90363 private readonly File $target;
90364 public function __construct(File $target)
90365 {
90366 $this->target = $target;
90367 }
90368 public function target(): File
90369 {
90370 return $this->target;
90371 }
90372 }
90373 <?php
90374
90375 declare (strict_types=1);
90376 /*
90377 * This file is part of PHPUnit.
90378 *
90379 * (c) Sebastian Bergmann <sebastian@phpunit.de>
90380 *
90381 * For the full copyright and license information, please view the LICENSE
90382 * file that was distributed with this source code.
90383 */
90384 namespace PHPUnit\TextUI\XmlConfiguration\CodeCoverage\Report;
90385
90386 use PHPUnit\TextUI\Configuration\File;
90387 /**
90388 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
90389 *
90390 * @internal This class is not covered by the backward compatibility promise for PHPUnit
90391 *
90392 * @psalm-immutable
90393 */
90394 final class Cobertura
90395 {
90396 private readonly File $target;
90397 public function __construct(File $target)
90398 {
90399 $this->target = $target;
90400 }
90401 public function target(): File
90402 {
90403 return $this->target;
90404 }
90405 }
90406 <?php
90407
90408 declare (strict_types=1);
90409 /*
90410 * This file is part of PHPUnit.
90411 *
90412 * (c) Sebastian Bergmann <sebastian@phpunit.de>
90413 *
90414 * For the full copyright and license information, please view the LICENSE
90415 * file that was distributed with this source code.
90416 */
90417 namespace PHPUnit\TextUI\XmlConfiguration\CodeCoverage\Report;
90418
90419 use PHPUnit\TextUI\Configuration\File;
90420 /**
90421 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
90422 *
90423 * @internal This class is not covered by the backward compatibility promise for PHPUnit
90424 *
90425 * @psalm-immutable
90426 */
90427 final class Crap4j
90428 {
90429 private readonly File $target;
90430 private readonly int $threshold;
90431 public function __construct(File $target, int $threshold)
90432 {
90433 $this->target = $target;
90434 $this->threshold = $threshold;
90435 }
90436 public function target(): File
90437 {
90438 return $this->target;
90439 }
90440 public function threshold(): int
90441 {
90442 return $this->threshold;
90443 }
90444 }
90445 <?php
90446
90447 declare (strict_types=1);
90448 /*
90449 * This file is part of PHPUnit.
90450 *
90451 * (c) Sebastian Bergmann <sebastian@phpunit.de>
90452 *
90453 * For the full copyright and license information, please view the LICENSE
90454 * file that was distributed with this source code.
90455 */
90456 namespace PHPUnit\TextUI\XmlConfiguration\CodeCoverage\Report;
90457
90458 use PHPUnit\TextUI\Configuration\Directory;
90459 use PHPUnit\TextUI\Configuration\NoCustomCssFileException;
90460 /**
90461 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
90462 *
90463 * @internal This class is not covered by the backward compatibility promise for PHPUnit
90464 *
90465 * @psalm-immutable
90466 */
90467 final class Html
90468 {
90469 private readonly Directory $target;
90470 private readonly int $lowUpperBound;
90471 private readonly int $highLowerBound;
90472 private readonly string $colorSuccessLow;
90473 private readonly string $colorSuccessMedium;
90474 private readonly string $colorSuccessHigh;
90475 private readonly string $colorWarning;
90476 private readonly string $colorDanger;
90477 private readonly ?string $customCssFile;
90478 public function __construct(Directory $target, int $lowUpperBound, int $highLowerBound, string $colorSuccessLow, string $colorSuccessMedium, string $colorSuccessHigh, string $colorWarning, string $colorDanger, ?string $customCssFile)
90479 {
90480 $this->target = $target;
90481 $this->lowUpperBound = $lowUpperBound;
90482 $this->highLowerBound = $highLowerBound;
90483 $this->colorSuccessLow = $colorSuccessLow;
90484 $this->colorSuccessMedium = $colorSuccessMedium;
90485 $this->colorSuccessHigh = $colorSuccessHigh;
90486 $this->colorWarning = $colorWarning;
90487 $this->colorDanger = $colorDanger;
90488 $this->customCssFile = $customCssFile;
90489 }
90490 public function target(): Directory
90491 {
90492 return $this->target;
90493 }
90494 public function lowUpperBound(): int
90495 {
90496 return $this->lowUpperBound;
90497 }
90498 public function highLowerBound(): int
90499 {
90500 return $this->highLowerBound;
90501 }
90502 public function colorSuccessLow(): string
90503 {
90504 return $this->colorSuccessLow;
90505 }
90506 public function colorSuccessMedium(): string
90507 {
90508 return $this->colorSuccessMedium;
90509 }
90510 public function colorSuccessHigh(): string
90511 {
90512 return $this->colorSuccessHigh;
90513 }
90514 public function colorWarning(): string
90515 {
90516 return $this->colorWarning;
90517 }
90518 public function colorDanger(): string
90519 {
90520 return $this->colorDanger;
90521 }
90522 /**
90523 * @psalm-assert-if-true !null $this->customCssFile
90524 */
90525 public function hasCustomCssFile(): bool
90526 {
90527 return $this->customCssFile !== null;
90528 }
90529 /**
90530 * @throws NoCustomCssFileException
90531 */
90532 public function customCssFile(): string
90533 {
90534 if (!$this->hasCustomCssFile()) {
90535 throw new NoCustomCssFileException();
90536 }
90537 return $this->customCssFile;
90538 }
90539 }
90540 <?php
90541
90542 declare (strict_types=1);
90543 /*
90544 * This file is part of PHPUnit.
90545 *
90546 * (c) Sebastian Bergmann <sebastian@phpunit.de>
90547 *
90548 * For the full copyright and license information, please view the LICENSE
90549 * file that was distributed with this source code.
90550 */
90551 namespace PHPUnit\TextUI\XmlConfiguration\CodeCoverage\Report;
90552
90553 use PHPUnit\TextUI\Configuration\File;
90554 /**
90555 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
90556 *
90557 * @internal This class is not covered by the backward compatibility promise for PHPUnit
90558 *
90559 * @psalm-immutable
90560 */
90561 final class Php
90562 {
90563 private readonly File $target;
90564 public function __construct(File $target)
90565 {
90566 $this->target = $target;
90567 }
90568 public function target(): File
90569 {
90570 return $this->target;
90571 }
90572 }
90573 <?php
90574
90575 declare (strict_types=1);
90576 /*
90577 * This file is part of PHPUnit.
90578 *
90579 * (c) Sebastian Bergmann <sebastian@phpunit.de>
90580 *
90581 * For the full copyright and license information, please view the LICENSE
90582 * file that was distributed with this source code.
90583 */
90584 namespace PHPUnit\TextUI\XmlConfiguration\CodeCoverage\Report;
90585
90586 use PHPUnit\TextUI\Configuration\File;
90587 /**
90588 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
90589 *
90590 * @internal This class is not covered by the backward compatibility promise for PHPUnit
90591 *
90592 * @psalm-immutable
90593 */
90594 final class Text
90595 {
90596 private readonly File $target;
90597 private readonly bool $showUncoveredFiles;
90598 private readonly bool $showOnlySummary;
90599 public function __construct(File $target, bool $showUncoveredFiles, bool $showOnlySummary)
90600 {
90601 $this->target = $target;
90602 $this->showUncoveredFiles = $showUncoveredFiles;
90603 $this->showOnlySummary = $showOnlySummary;
90604 }
90605 public function target(): File
90606 {
90607 return $this->target;
90608 }
90609 public function showUncoveredFiles(): bool
90610 {
90611 return $this->showUncoveredFiles;
90612 }
90613 public function showOnlySummary(): bool
90614 {
90615 return $this->showOnlySummary;
90616 }
90617 }
90618 <?php
90619
90620 declare (strict_types=1);
90621 /*
90622 * This file is part of PHPUnit.
90623 *
90624 * (c) Sebastian Bergmann <sebastian@phpunit.de>
90625 *
90626 * For the full copyright and license information, please view the LICENSE
90627 * file that was distributed with this source code.
90628 */
90629 namespace PHPUnit\TextUI\XmlConfiguration\CodeCoverage\Report;
90630
90631 use PHPUnit\TextUI\Configuration\Directory;
90632 /**
90633 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
90634 *
90635 * @internal This class is not covered by the backward compatibility promise for PHPUnit
90636 *
90637 * @psalm-immutable
90638 */
90639 final class Xml
90640 {
90641 private readonly Directory $target;
90642 public function __construct(Directory $target)
90643 {
90644 $this->target = $target;
90645 }
90646 public function target(): Directory
90647 {
90648 return $this->target;
90649 }
90650 }
90651 <?php
90652
90653 declare (strict_types=1);
90654 /*
90655 * This file is part of PHPUnit.
90656 *
90657 * (c) Sebastian Bergmann <sebastian@phpunit.de>
90658 *
90659 * For the full copyright and license information, please view the LICENSE
90660 * file that was distributed with this source code.
90661 */
90662 namespace PHPUnit\TextUI\XmlConfiguration;
90663
90664 use PHPUnit\TextUI\Configuration\ExtensionBootstrapCollection;
90665 use PHPUnit\TextUI\Configuration\Php;
90666 use PHPUnit\TextUI\Configuration\Source;
90667 use PHPUnit\TextUI\Configuration\TestSuiteCollection;
90668 use PHPUnit\TextUI\XmlConfiguration\CodeCoverage\CodeCoverage;
90669 use PHPUnit\TextUI\XmlConfiguration\Logging\Logging;
90670 /**
90671 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
90672 *
90673 * @internal This class is not covered by the backward compatibility promise for PHPUnit
90674 *
90675 * @psalm-immutable
90676 */
90677 abstract class Configuration
90678 {
90679 private readonly ExtensionBootstrapCollection $extensions;
90680 private readonly Source $source;
90681 private readonly CodeCoverage $codeCoverage;
90682 private readonly \PHPUnit\TextUI\XmlConfiguration\Groups $groups;
90683 private readonly Logging $logging;
90684 private readonly Php $php;
90685 private readonly \PHPUnit\TextUI\XmlConfiguration\PHPUnit $phpunit;
90686 private readonly TestSuiteCollection $testSuite;
90687 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)
90688 {
90689 $this->extensions = $extensions;
90690 $this->source = $source;
90691 $this->codeCoverage = $codeCoverage;
90692 $this->groups = $groups;
90693 $this->logging = $logging;
90694 $this->php = $php;
90695 $this->phpunit = $phpunit;
90696 $this->testSuite = $testSuite;
90697 }
90698 public function extensions(): ExtensionBootstrapCollection
90699 {
90700 return $this->extensions;
90701 }
90702 public function source(): Source
90703 {
90704 return $this->source;
90705 }
90706 public function codeCoverage(): CodeCoverage
90707 {
90708 return $this->codeCoverage;
90709 }
90710 public function groups(): \PHPUnit\TextUI\XmlConfiguration\Groups
90711 {
90712 return $this->groups;
90713 }
90714 public function logging(): Logging
90715 {
90716 return $this->logging;
90717 }
90718 public function php(): Php
90719 {
90720 return $this->php;
90721 }
90722 public function phpunit(): \PHPUnit\TextUI\XmlConfiguration\PHPUnit
90723 {
90724 return $this->phpunit;
90725 }
90726 public function testSuite(): TestSuiteCollection
90727 {
90728 return $this->testSuite;
90729 }
90730 /**
90731 * @psalm-assert-if-true DefaultConfiguration $this
90732 */
90733 public function isDefault(): bool
90734 {
90735 return \false;
90736 }
90737 /**
90738 * @psalm-assert-if-true LoadedFromFileConfiguration $this
90739 */
90740 public function wasLoadedFromFile(): bool
90741 {
90742 return \false;
90743 }
90744 }
90745 <?php
90746
90747 declare (strict_types=1);
90748 /*
90749 * This file is part of PHPUnit.
90750 *
90751 * (c) Sebastian Bergmann <sebastian@phpunit.de>
90752 *
90753 * For the full copyright and license information, please view the LICENSE
90754 * file that was distributed with this source code.
90755 */
90756 namespace PHPUnit\TextUI\XmlConfiguration;
90757
90758 use PHPUnit\Runner\TestSuiteSorter;
90759 use PHPUnit\TextUI\Configuration\ConstantCollection;
90760 use PHPUnit\TextUI\Configuration\DirectoryCollection;
90761 use PHPUnit\TextUI\Configuration\ExtensionBootstrapCollection;
90762 use PHPUnit\TextUI\Configuration\FileCollection;
90763 use PHPUnit\TextUI\Configuration\FilterDirectoryCollection as CodeCoverageFilterDirectoryCollection;
90764 use PHPUnit\TextUI\Configuration\GroupCollection;
90765 use PHPUnit\TextUI\Configuration\IniSettingCollection;
90766 use PHPUnit\TextUI\Configuration\Php;
90767 use PHPUnit\TextUI\Configuration\Source;
90768 use PHPUnit\TextUI\Configuration\TestSuiteCollection;
90769 use PHPUnit\TextUI\Configuration\VariableCollection;
90770 use PHPUnit\TextUI\XmlConfiguration\CodeCoverage\CodeCoverage;
90771 use PHPUnit\TextUI\XmlConfiguration\Logging\Logging;
90772 /**
90773 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
90774 *
90775 * @internal This class is not covered by the backward compatibility promise for PHPUnit
90776 *
90777 * @psalm-immutable
90778 */
90779 final class DefaultConfiguration extends \PHPUnit\TextUI\XmlConfiguration\Configuration
90780 {
90781 public static function create(): self
90782 {
90783 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, \false, \false, null, \false, \false, \false, \false, \true, \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([]));
90784 }
90785 public function isDefault(): bool
90786 {
90787 return \true;
90788 }
90789 }
90790 <?php
90791
90792 declare (strict_types=1);
90793 /*
90794 * This file is part of PHPUnit.
90795 *
90796 * (c) Sebastian Bergmann <sebastian@phpunit.de>
90797 *
90798 * For the full copyright and license information, please view the LICENSE
90799 * file that was distributed with this source code.
90800 */
90801 namespace PHPUnit\TextUI\XmlConfiguration;
90802
90803 use RuntimeException;
90804 /**
90805 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
90806 *
90807 * @internal This class is not covered by the backward compatibility promise for PHPUnit
90808 */
90809 final class Exception extends RuntimeException implements \PHPUnit\Exception
90810 {
90811 }
90812 <?php
90813
90814 declare (strict_types=1);
90815 /*
90816 * This file is part of PHPUnit.
90817 *
90818 * (c) Sebastian Bergmann <sebastian@phpunit.de>
90819 *
90820 * For the full copyright and license information, please view the LICENSE
90821 * file that was distributed with this source code.
90822 */
90823 namespace PHPUnit\TextUI\XmlConfiguration;
90824
90825 use function str_replace;
90826 /**
90827 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
90828 *
90829 * @internal This class is not covered by the backward compatibility promise for PHPUnit
90830 */
90831 final class Generator
90832 {
90833 /**
90834 * @var string
90835 */
90836 private const TEMPLATE = <<<'EOT'
90837 <?xml version="1.0" encoding="UTF-8"?>
90838 <phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
90839 xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/{phpunit_version}/phpunit.xsd"
90840 bootstrap="{bootstrap_script}"
90841 cacheDirectory="{cache_directory}"
90842 executionOrder="depends,defects"
90843 requireCoverageMetadata="true"
90844 beStrictAboutCoverageMetadata="true"
90845 beStrictAboutOutputDuringTests="true"
90846 displayDetailsOnPhpunitDeprecations="true"
90847 failOnPhpunitDeprecation="true"
90848 failOnRisky="true"
90849 failOnWarning="true">
90850 <testsuites>
90851 <testsuite name="default">
90852 <directory>{tests_directory}</directory>
90853 </testsuite>
90854 </testsuites>
90855
90856 <source restrictDeprecations="true" restrictNotices="true" restrictWarnings="true">
90857 <include>
90858 <directory>{src_directory}</directory>
90859 </include>
90860 </source>
90861 </phpunit>
90862
90863 EOT;
90864 public function generateDefaultConfiguration(string $phpunitVersion, string $bootstrapScript, string $testsDirectory, string $srcDirectory, string $cacheDirectory): string
90865 {
90866 return str_replace(['{phpunit_version}', '{bootstrap_script}', '{tests_directory}', '{src_directory}', '{cache_directory}'], [$phpunitVersion, $bootstrapScript, $testsDirectory, $srcDirectory, $cacheDirectory], self::TEMPLATE);
90867 }
90868 }
90869 <?php
90870
90871 declare (strict_types=1);
90872 /*
90873 * This file is part of PHPUnit.
90874 *
90875 * (c) Sebastian Bergmann <sebastian@phpunit.de>
90876 *
90877 * For the full copyright and license information, please view the LICENSE
90878 * file that was distributed with this source code.
90879 */
90880 namespace PHPUnit\TextUI\XmlConfiguration;
90881
90882 use PHPUnit\TextUI\Configuration\GroupCollection;
90883 /**
90884 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
90885 *
90886 * @internal This class is not covered by the backward compatibility promise for PHPUnit
90887 *
90888 * @psalm-immutable
90889 */
90890 final class Groups
90891 {
90892 private readonly GroupCollection $include;
90893 private readonly GroupCollection $exclude;
90894 public function __construct(GroupCollection $include, GroupCollection $exclude)
90895 {
90896 $this->include = $include;
90897 $this->exclude = $exclude;
90898 }
90899 public function hasInclude(): bool
90900 {
90901 return !$this->include->isEmpty();
90902 }
90903 public function include(): GroupCollection
90904 {
90905 return $this->include;
90906 }
90907 public function hasExclude(): bool
90908 {
90909 return !$this->exclude->isEmpty();
90910 }
90911 public function exclude(): GroupCollection
90912 {
90913 return $this->exclude;
90914 }
90915 }
90916 <?php
90917
90918 declare (strict_types=1);
90919 /*
90920 * This file is part of PHPUnit.
90921 *
90922 * (c) Sebastian Bergmann <sebastian@phpunit.de>
90923 *
90924 * For the full copyright and license information, please view the LICENSE
90925 * file that was distributed with this source code.
90926 */
90927 namespace PHPUnit\TextUI\XmlConfiguration;
90928
90929 use PHPUnit\TextUI\Configuration\ExtensionBootstrapCollection;
90930 use PHPUnit\TextUI\Configuration\Php;
90931 use PHPUnit\TextUI\Configuration\Source;
90932 use PHPUnit\TextUI\Configuration\TestSuiteCollection;
90933 use PHPUnit\TextUI\XmlConfiguration\CodeCoverage\CodeCoverage;
90934 use PHPUnit\TextUI\XmlConfiguration\Logging\Logging;
90935 /**
90936 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
90937 *
90938 * @internal This class is not covered by the backward compatibility promise for PHPUnit
90939 *
90940 * @psalm-immutable
90941 */
90942 final class LoadedFromFileConfiguration extends \PHPUnit\TextUI\XmlConfiguration\Configuration
90943 {
90944 private readonly string $filename;
90945 private readonly \PHPUnit\TextUI\XmlConfiguration\ValidationResult $validationResult;
90946 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)
90947 {
90948 $this->filename = $filename;
90949 $this->validationResult = $validationResult;
90950 parent::__construct($extensions, $source, $codeCoverage, $groups, $logging, $php, $phpunit, $testSuite);
90951 }
90952 public function filename(): string
90953 {
90954 return $this->filename;
90955 }
90956 public function hasValidationErrors(): bool
90957 {
90958 return $this->validationResult->hasValidationErrors();
90959 }
90960 public function validationErrors(): string
90961 {
90962 return $this->validationResult->asString();
90963 }
90964 public function wasLoadedFromFile(): bool
90965 {
90966 return \true;
90967 }
90968 }
90969 <?php
90970
90971 declare (strict_types=1);
90972 /*
90973 * This file is part of PHPUnit.
90974 *
90975 * (c) Sebastian Bergmann <sebastian@phpunit.de>
90976 *
90977 * For the full copyright and license information, please view the LICENSE
90978 * file that was distributed with this source code.
90979 */
90980 namespace PHPUnit\TextUI\XmlConfiguration;
90981
90982 use const DIRECTORY_SEPARATOR;
90983 use const PHP_VERSION;
90984 use function assert;
90985 use function defined;
90986 use function dirname;
90987 use function explode;
90988 use function is_numeric;
90989 use function preg_match;
90990 use function realpath;
90991 use function str_contains;
90992 use function str_starts_with;
90993 use function strlen;
90994 use function strtolower;
90995 use function substr;
90996 use function trim;
90997 use DOMDocument;
90998 use DOMElement;
90999 use DOMNode;
91000 use DOMXPath;
91001 use PHPUnit\Runner\TestSuiteSorter;
91002 use PHPUnit\Runner\Version;
91003 use PHPUnit\TextUI\Configuration\Configuration;
91004 use PHPUnit\TextUI\Configuration\Constant;
91005 use PHPUnit\TextUI\Configuration\ConstantCollection;
91006 use PHPUnit\TextUI\Configuration\Directory;
91007 use PHPUnit\TextUI\Configuration\DirectoryCollection;
91008 use PHPUnit\TextUI\Configuration\ExtensionBootstrap;
91009 use PHPUnit\TextUI\Configuration\ExtensionBootstrapCollection;
91010 use PHPUnit\TextUI\Configuration\File;
91011 use PHPUnit\TextUI\Configuration\FileCollection;
91012 use PHPUnit\TextUI\Configuration\FilterDirectory;
91013 use PHPUnit\TextUI\Configuration\FilterDirectoryCollection;
91014 use PHPUnit\TextUI\Configuration\Group;
91015 use PHPUnit\TextUI\Configuration\GroupCollection;
91016 use PHPUnit\TextUI\Configuration\IniSetting;
91017 use PHPUnit\TextUI\Configuration\IniSettingCollection;
91018 use PHPUnit\TextUI\Configuration\Php;
91019 use PHPUnit\TextUI\Configuration\Source;
91020 use PHPUnit\TextUI\Configuration\TestDirectory;
91021 use PHPUnit\TextUI\Configuration\TestDirectoryCollection;
91022 use PHPUnit\TextUI\Configuration\TestFile;
91023 use PHPUnit\TextUI\Configuration\TestFileCollection;
91024 use PHPUnit\TextUI\Configuration\TestSuite as TestSuiteConfiguration;
91025 use PHPUnit\TextUI\Configuration\TestSuiteCollection;
91026 use PHPUnit\TextUI\Configuration\Variable;
91027 use PHPUnit\TextUI\Configuration\VariableCollection;
91028 use PHPUnit\TextUI\XmlConfiguration\CodeCoverage\CodeCoverage;
91029 use PHPUnit\TextUI\XmlConfiguration\CodeCoverage\Report\Clover;
91030 use PHPUnit\TextUI\XmlConfiguration\CodeCoverage\Report\Cobertura;
91031 use PHPUnit\TextUI\XmlConfiguration\CodeCoverage\Report\Crap4j;
91032 use PHPUnit\TextUI\XmlConfiguration\CodeCoverage\Report\Html as CodeCoverageHtml;
91033 use PHPUnit\TextUI\XmlConfiguration\CodeCoverage\Report\Php as CodeCoveragePhp;
91034 use PHPUnit\TextUI\XmlConfiguration\CodeCoverage\Report\Text as CodeCoverageText;
91035 use PHPUnit\TextUI\XmlConfiguration\CodeCoverage\Report\Xml as CodeCoverageXml;
91036 use PHPUnit\TextUI\XmlConfiguration\Logging\Junit;
91037 use PHPUnit\TextUI\XmlConfiguration\Logging\Logging;
91038 use PHPUnit\TextUI\XmlConfiguration\Logging\TeamCity;
91039 use PHPUnit\TextUI\XmlConfiguration\Logging\TestDox\Html as TestDoxHtml;
91040 use PHPUnit\TextUI\XmlConfiguration\Logging\TestDox\Text as TestDoxText;
91041 use PHPUnit\Util\VersionComparisonOperator;
91042 use PHPUnit\Util\Xml\Loader as XmlLoader;
91043 use PHPUnit\Util\Xml\XmlException;
91044 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Report\Html\Colors;
91045 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Report\Thresholds;
91046 /**
91047 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
91048 *
91049 * @internal This class is not covered by the backward compatibility promise for PHPUnit
91050 */
91051 final class Loader
91052 {
91053 /**
91054 * @throws Exception
91055 */
91056 public function load(string $filename): \PHPUnit\TextUI\XmlConfiguration\LoadedFromFileConfiguration
91057 {
91058 try {
91059 $document = (new XmlLoader())->loadFile($filename);
91060 } catch (XmlException $e) {
91061 throw new \PHPUnit\TextUI\XmlConfiguration\Exception($e->getMessage(), $e->getCode(), $e);
91062 }
91063 $xpath = new DOMXPath($document);
91064 try {
91065 $xsdFilename = (new \PHPUnit\TextUI\XmlConfiguration\SchemaFinder())->find(Version::series());
91066 } catch (\PHPUnit\TextUI\XmlConfiguration\CannotFindSchemaException $e) {
91067 throw new \PHPUnit\TextUI\XmlConfiguration\Exception($e->getMessage(), $e->getCode(), $e);
91068 }
91069 $configurationFileRealpath = realpath($filename);
91070 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));
91071 }
91072 private function logging(string $filename, DOMXPath $xpath): Logging
91073 {
91074 $junit = null;
91075 $element = $this->element($xpath, 'logging/junit');
91076 if ($element) {
91077 $junit = new Junit(new File($this->toAbsolutePath($filename, (string) $this->getStringAttribute($element, 'outputFile'))));
91078 }
91079 $teamCity = null;
91080 $element = $this->element($xpath, 'logging/teamcity');
91081 if ($element) {
91082 $teamCity = new TeamCity(new File($this->toAbsolutePath($filename, (string) $this->getStringAttribute($element, 'outputFile'))));
91083 }
91084 $testDoxHtml = null;
91085 $element = $this->element($xpath, 'logging/testdoxHtml');
91086 if ($element) {
91087 $testDoxHtml = new TestDoxHtml(new File($this->toAbsolutePath($filename, (string) $this->getStringAttribute($element, 'outputFile'))));
91088 }
91089 $testDoxText = null;
91090 $element = $this->element($xpath, 'logging/testdoxText');
91091 if ($element) {
91092 $testDoxText = new TestDoxText(new File($this->toAbsolutePath($filename, (string) $this->getStringAttribute($element, 'outputFile'))));
91093 }
91094 return new Logging($junit, $teamCity, $testDoxHtml, $testDoxText);
91095 }
91096 private function extensions(DOMXPath $xpath): ExtensionBootstrapCollection
91097 {
91098 $extensionBootstrappers = [];
91099 foreach ($xpath->query('extensions/bootstrap') as $bootstrap) {
91100 assert($bootstrap instanceof DOMElement);
91101 $parameters = [];
91102 foreach ($xpath->query('parameter', $bootstrap) as $parameter) {
91103 assert($parameter instanceof DOMElement);
91104 $parameters[$parameter->getAttribute('name')] = $parameter->getAttribute('value');
91105 }
91106 $extensionBootstrappers[] = new ExtensionBootstrap($bootstrap->getAttribute('class'), $parameters);
91107 }
91108 return ExtensionBootstrapCollection::fromArray($extensionBootstrappers);
91109 }
91110 /**
91111 * @psalm-return non-empty-string
91112 */
91113 private function toAbsolutePath(string $filename, string $path): string
91114 {
91115 $path = trim($path);
91116 if (str_starts_with($path, '/')) {
91117 return $path;
91118 }
91119 // Matches the following on Windows:
91120 // - \\NetworkComputer\Path
91121 // - \\.\D:
91122 // - \\.\c:
91123 // - C:\Windows
91124 // - C:\windows
91125 // - C:/windows
91126 // - c:/windows
91127 if (defined('PHP_WINDOWS_VERSION_BUILD') && !empty($path) && ($path[0] === '\\' || strlen($path) >= 3 && preg_match('#^[A-Z]:[/\\\\]#i', substr($path, 0, 3)))) {
91128 return $path;
91129 }
91130 if (str_contains($path, '://')) {
91131 return $path;
91132 }
91133 return dirname($filename) . DIRECTORY_SEPARATOR . $path;
91134 }
91135 private function source(string $filename, DOMXPath $xpath): Source
91136 {
91137 $baseline = null;
91138 $restrictDeprecations = \false;
91139 $restrictNotices = \false;
91140 $restrictWarnings = \false;
91141 $ignoreSuppressionOfDeprecations = \false;
91142 $ignoreSuppressionOfPhpDeprecations = \false;
91143 $ignoreSuppressionOfErrors = \false;
91144 $ignoreSuppressionOfNotices = \false;
91145 $ignoreSuppressionOfPhpNotices = \false;
91146 $ignoreSuppressionOfWarnings = \false;
91147 $ignoreSuppressionOfPhpWarnings = \false;
91148 $element = $this->element($xpath, 'source');
91149 if ($element) {
91150 $baseline = $this->getStringAttribute($element, 'baseline');
91151 if ($baseline !== null) {
91152 $baseline = $this->toAbsolutePath($filename, $baseline);
91153 }
91154 $restrictDeprecations = $this->getBooleanAttribute($element, 'restrictDeprecations', \false);
91155 $restrictNotices = $this->getBooleanAttribute($element, 'restrictNotices', \false);
91156 $restrictWarnings = $this->getBooleanAttribute($element, 'restrictWarnings', \false);
91157 $ignoreSuppressionOfDeprecations = $this->getBooleanAttribute($element, 'ignoreSuppressionOfDeprecations', \false);
91158 $ignoreSuppressionOfPhpDeprecations = $this->getBooleanAttribute($element, 'ignoreSuppressionOfPhpDeprecations', \false);
91159 $ignoreSuppressionOfErrors = $this->getBooleanAttribute($element, 'ignoreSuppressionOfErrors', \false);
91160 $ignoreSuppressionOfNotices = $this->getBooleanAttribute($element, 'ignoreSuppressionOfNotices', \false);
91161 $ignoreSuppressionOfPhpNotices = $this->getBooleanAttribute($element, 'ignoreSuppressionOfPhpNotices', \false);
91162 $ignoreSuppressionOfWarnings = $this->getBooleanAttribute($element, 'ignoreSuppressionOfWarnings', \false);
91163 $ignoreSuppressionOfPhpWarnings = $this->getBooleanAttribute($element, 'ignoreSuppressionOfPhpWarnings', \false);
91164 }
91165 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);
91166 }
91167 private function codeCoverage(string $filename, DOMXPath $xpath): CodeCoverage
91168 {
91169 $cacheDirectory = null;
91170 $pathCoverage = \false;
91171 $includeUncoveredFiles = \true;
91172 $ignoreDeprecatedCodeUnits = \false;
91173 $disableCodeCoverageIgnore = \false;
91174 $element = $this->element($xpath, 'coverage');
91175 if ($element) {
91176 $cacheDirectory = $this->getStringAttribute($element, 'cacheDirectory');
91177 if ($cacheDirectory !== null) {
91178 $cacheDirectory = new Directory($this->toAbsolutePath($filename, $cacheDirectory));
91179 }
91180 $pathCoverage = $this->getBooleanAttribute($element, 'pathCoverage', \false);
91181 $includeUncoveredFiles = $this->getBooleanAttribute($element, 'includeUncoveredFiles', \true);
91182 $ignoreDeprecatedCodeUnits = $this->getBooleanAttribute($element, 'ignoreDeprecatedCodeUnits', \false);
91183 $disableCodeCoverageIgnore = $this->getBooleanAttribute($element, 'disableCodeCoverageIgnore', \false);
91184 }
91185 $clover = null;
91186 $element = $this->element($xpath, 'coverage/report/clover');
91187 if ($element) {
91188 $clover = new Clover(new File($this->toAbsolutePath($filename, (string) $this->getStringAttribute($element, 'outputFile'))));
91189 }
91190 $cobertura = null;
91191 $element = $this->element($xpath, 'coverage/report/cobertura');
91192 if ($element) {
91193 $cobertura = new Cobertura(new File($this->toAbsolutePath($filename, (string) $this->getStringAttribute($element, 'outputFile'))));
91194 }
91195 $crap4j = null;
91196 $element = $this->element($xpath, 'coverage/report/crap4j');
91197 if ($element) {
91198 $crap4j = new Crap4j(new File($this->toAbsolutePath($filename, (string) $this->getStringAttribute($element, 'outputFile'))), $this->getIntegerAttribute($element, 'threshold', 30));
91199 }
91200 $html = null;
91201 $element = $this->element($xpath, 'coverage/report/html');
91202 if ($element) {
91203 $defaultColors = Colors::default();
91204 $defaultThresholds = Thresholds::default();
91205 $html = new CodeCoverageHtml(new Directory($this->toAbsolutePath($filename, (string) $this->getStringAttribute($element, 'outputDirectory'))), $this->getIntegerAttribute($element, 'lowUpperBound', $defaultThresholds->lowUpperBound()), $this->getIntegerAttribute($element, 'highLowerBound', $defaultThresholds->highLowerBound()), $this->getStringAttributeWithDefault($element, 'colorSuccessLow', $defaultColors->successLow()), $this->getStringAttributeWithDefault($element, 'colorSuccessMedium', $defaultColors->successMedium()), $this->getStringAttributeWithDefault($element, 'colorSuccessHigh', $defaultColors->successHigh()), $this->getStringAttributeWithDefault($element, 'colorWarning', $defaultColors->warning()), $this->getStringAttributeWithDefault($element, 'colorDanger', $defaultColors->danger()), $this->getStringAttribute($element, 'customCssFile'));
91206 }
91207 $php = null;
91208 $element = $this->element($xpath, 'coverage/report/php');
91209 if ($element) {
91210 $php = new CodeCoveragePhp(new File($this->toAbsolutePath($filename, (string) $this->getStringAttribute($element, 'outputFile'))));
91211 }
91212 $text = null;
91213 $element = $this->element($xpath, 'coverage/report/text');
91214 if ($element) {
91215 $text = new CodeCoverageText(new File($this->toAbsolutePath($filename, (string) $this->getStringAttribute($element, 'outputFile'))), $this->getBooleanAttribute($element, 'showUncoveredFiles', \false), $this->getBooleanAttribute($element, 'showOnlySummary', \false));
91216 }
91217 $xml = null;
91218 $element = $this->element($xpath, 'coverage/report/xml');
91219 if ($element) {
91220 $xml = new CodeCoverageXml(new Directory($this->toAbsolutePath($filename, (string) $this->getStringAttribute($element, 'outputDirectory'))));
91221 }
91222 return new CodeCoverage($cacheDirectory, $this->readFilterDirectories($filename, $xpath, 'coverage/include/directory'), $this->readFilterFiles($filename, $xpath, 'coverage/include/file'), $this->readFilterDirectories($filename, $xpath, 'coverage/exclude/directory'), $this->readFilterFiles($filename, $xpath, 'coverage/exclude/file'), $pathCoverage, $includeUncoveredFiles, $ignoreDeprecatedCodeUnits, $disableCodeCoverageIgnore, $clover, $cobertura, $crap4j, $html, $php, $text, $xml);
91223 }
91224 private function getBoolean(string $value, bool $default): bool
91225 {
91226 if (strtolower($value) === 'false') {
91227 return \false;
91228 }
91229 if (strtolower($value) === 'true') {
91230 return \true;
91231 }
91232 return $default;
91233 }
91234 private function getValue(string $value): bool|string
91235 {
91236 if (strtolower($value) === 'false') {
91237 return \false;
91238 }
91239 if (strtolower($value) === 'true') {
91240 return \true;
91241 }
91242 return $value;
91243 }
91244 private function readFilterDirectories(string $filename, DOMXPath $xpath, string $query): FilterDirectoryCollection
91245 {
91246 $directories = [];
91247 foreach ($xpath->query($query) as $directoryNode) {
91248 assert($directoryNode instanceof DOMElement);
91249 $directoryPath = $directoryNode->textContent;
91250 if (!$directoryPath) {
91251 continue;
91252 }
91253 $directories[] = new FilterDirectory($this->toAbsolutePath($filename, $directoryPath), $directoryNode->hasAttribute('prefix') ? $directoryNode->getAttribute('prefix') : '', $directoryNode->hasAttribute('suffix') ? $directoryNode->getAttribute('suffix') : '.php');
91254 }
91255 return FilterDirectoryCollection::fromArray($directories);
91256 }
91257 private function readFilterFiles(string $filename, DOMXPath $xpath, string $query): FileCollection
91258 {
91259 $files = [];
91260 foreach ($xpath->query($query) as $file) {
91261 assert($file instanceof DOMNode);
91262 $filePath = $file->textContent;
91263 if ($filePath) {
91264 $files[] = new File($this->toAbsolutePath($filename, $filePath));
91265 }
91266 }
91267 return FileCollection::fromArray($files);
91268 }
91269 private function groups(DOMXPath $xpath): \PHPUnit\TextUI\XmlConfiguration\Groups
91270 {
91271 $include = [];
91272 $exclude = [];
91273 foreach ($xpath->query('groups/include/group') as $group) {
91274 assert($group instanceof DOMNode);
91275 $include[] = new Group($group->textContent);
91276 }
91277 foreach ($xpath->query('groups/exclude/group') as $group) {
91278 assert($group instanceof DOMNode);
91279 $exclude[] = new Group($group->textContent);
91280 }
91281 return new \PHPUnit\TextUI\XmlConfiguration\Groups(GroupCollection::fromArray($include), GroupCollection::fromArray($exclude));
91282 }
91283 private function getBooleanAttribute(DOMElement $element, string $attribute, bool $default): bool
91284 {
91285 if (!$element->hasAttribute($attribute)) {
91286 return $default;
91287 }
91288 return $this->getBoolean($element->getAttribute($attribute), \false);
91289 }
91290 private function getIntegerAttribute(DOMElement $element, string $attribute, int $default): int
91291 {
91292 if (!$element->hasAttribute($attribute)) {
91293 return $default;
91294 }
91295 return $this->getInteger($element->getAttribute($attribute), $default);
91296 }
91297 private function getStringAttribute(DOMElement $element, string $attribute): ?string
91298 {
91299 if (!$element->hasAttribute($attribute)) {
91300 return null;
91301 }
91302 return $element->getAttribute($attribute);
91303 }
91304 private function getStringAttributeWithDefault(DOMElement $element, string $attribute, string $default): string
91305 {
91306 if (!$element->hasAttribute($attribute)) {
91307 return $default;
91308 }
91309 return $element->getAttribute($attribute);
91310 }
91311 private function getInteger(string $value, int $default): int
91312 {
91313 if (is_numeric($value)) {
91314 return (int) $value;
91315 }
91316 return $default;
91317 }
91318 private function php(string $filename, DOMXPath $xpath): Php
91319 {
91320 $includePaths = [];
91321 foreach ($xpath->query('php/includePath') as $includePath) {
91322 assert($includePath instanceof DOMNode);
91323 $path = $includePath->textContent;
91324 if ($path) {
91325 $includePaths[] = new Directory($this->toAbsolutePath($filename, $path));
91326 }
91327 }
91328 $iniSettings = [];
91329 foreach ($xpath->query('php/ini') as $ini) {
91330 assert($ini instanceof DOMElement);
91331 $iniSettings[] = new IniSetting($ini->getAttribute('name'), $ini->getAttribute('value'));
91332 }
91333 $constants = [];
91334 foreach ($xpath->query('php/const') as $const) {
91335 assert($const instanceof DOMElement);
91336 $value = $const->getAttribute('value');
91337 $constants[] = new Constant($const->getAttribute('name'), $this->getValue($value));
91338 }
91339 $variables = ['var' => [], 'env' => [], 'post' => [], 'get' => [], 'cookie' => [], 'server' => [], 'files' => [], 'request' => []];
91340 foreach (['var', 'env', 'post', 'get', 'cookie', 'server', 'files', 'request'] as $array) {
91341 foreach ($xpath->query('php/' . $array) as $var) {
91342 assert($var instanceof DOMElement);
91343 $name = $var->getAttribute('name');
91344 $value = $var->getAttribute('value');
91345 $force = \false;
91346 $verbatim = \false;
91347 if ($var->hasAttribute('force')) {
91348 $force = $this->getBoolean($var->getAttribute('force'), \false);
91349 }
91350 if ($var->hasAttribute('verbatim')) {
91351 $verbatim = $this->getBoolean($var->getAttribute('verbatim'), \false);
91352 }
91353 if (!$verbatim) {
91354 $value = $this->getValue($value);
91355 }
91356 $variables[$array][] = new Variable($name, $value, $force);
91357 }
91358 }
91359 return new Php(DirectoryCollection::fromArray($includePaths), IniSettingCollection::fromArray($iniSettings), ConstantCollection::fromArray($constants), VariableCollection::fromArray($variables['var']), VariableCollection::fromArray($variables['env']), VariableCollection::fromArray($variables['post']), VariableCollection::fromArray($variables['get']), VariableCollection::fromArray($variables['cookie']), VariableCollection::fromArray($variables['server']), VariableCollection::fromArray($variables['files']), VariableCollection::fromArray($variables['request']));
91360 }
91361 private function phpunit(string $filename, DOMDocument $document): \PHPUnit\TextUI\XmlConfiguration\PHPUnit
91362 {
91363 $executionOrder = TestSuiteSorter::ORDER_DEFAULT;
91364 $defectsFirst = \false;
91365 $resolveDependencies = $this->getBooleanAttribute($document->documentElement, 'resolveDependencies', \true);
91366 if ($document->documentElement->hasAttribute('executionOrder')) {
91367 foreach (explode(',', $document->documentElement->getAttribute('executionOrder')) as $order) {
91368 switch ($order) {
91369 case 'default':
91370 $executionOrder = TestSuiteSorter::ORDER_DEFAULT;
91371 $defectsFirst = \false;
91372 $resolveDependencies = \true;
91373 break;
91374 case 'depends':
91375 $resolveDependencies = \true;
91376 break;
91377 case 'no-depends':
91378 $resolveDependencies = \false;
91379 break;
91380 case 'defects':
91381 $defectsFirst = \true;
91382 break;
91383 case 'duration':
91384 $executionOrder = TestSuiteSorter::ORDER_DURATION;
91385 break;
91386 case 'random':
91387 $executionOrder = TestSuiteSorter::ORDER_RANDOMIZED;
91388 break;
91389 case 'reverse':
91390 $executionOrder = TestSuiteSorter::ORDER_REVERSED;
91391 break;
91392 case 'size':
91393 $executionOrder = TestSuiteSorter::ORDER_SIZE;
91394 break;
91395 }
91396 }
91397 }
91398 $cacheDirectory = $this->getStringAttribute($document->documentElement, 'cacheDirectory');
91399 if ($cacheDirectory !== null) {
91400 $cacheDirectory = $this->toAbsolutePath($filename, $cacheDirectory);
91401 }
91402 $cacheResultFile = $this->getStringAttribute($document->documentElement, 'cacheResultFile');
91403 if ($cacheResultFile !== null) {
91404 $cacheResultFile = $this->toAbsolutePath($filename, $cacheResultFile);
91405 }
91406 $bootstrap = $this->getStringAttribute($document->documentElement, 'bootstrap');
91407 if ($bootstrap !== null) {
91408 $bootstrap = $this->toAbsolutePath($filename, $bootstrap);
91409 }
91410 $extensionsDirectory = $this->getStringAttribute($document->documentElement, 'extensionsDirectory');
91411 if ($extensionsDirectory !== null) {
91412 $extensionsDirectory = $this->toAbsolutePath($filename, $extensionsDirectory);
91413 }
91414 $backupStaticProperties = \false;
91415 if ($document->documentElement->hasAttribute('backupStaticProperties')) {
91416 $backupStaticProperties = $this->getBooleanAttribute($document->documentElement, 'backupStaticProperties', \false);
91417 } elseif ($document->documentElement->hasAttribute('backupStaticAttributes')) {
91418 $backupStaticProperties = $this->getBooleanAttribute($document->documentElement, 'backupStaticAttributes', \false);
91419 }
91420 $requireCoverageMetadata = \false;
91421 if ($document->documentElement->hasAttribute('requireCoverageMetadata')) {
91422 $requireCoverageMetadata = $this->getBooleanAttribute($document->documentElement, 'requireCoverageMetadata', \false);
91423 } elseif ($document->documentElement->hasAttribute('forceCoversAnnotation')) {
91424 $requireCoverageMetadata = $this->getBooleanAttribute($document->documentElement, 'forceCoversAnnotation', \false);
91425 }
91426 $beStrictAboutCoverageMetadata = \false;
91427 if ($document->documentElement->hasAttribute('beStrictAboutCoverageMetadata')) {
91428 $beStrictAboutCoverageMetadata = $this->getBooleanAttribute($document->documentElement, 'beStrictAboutCoverageMetadata', \false);
91429 } elseif ($document->documentElement->hasAttribute('forceCoversAnnotation')) {
91430 $beStrictAboutCoverageMetadata = $this->getBooleanAttribute($document->documentElement, 'beStrictAboutCoversAnnotation', \false);
91431 }
91432 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, 'displayDetailsOnAllIssues', \false), $this->getBooleanAttribute($document->documentElement, 'displayDetailsOnIncompleteTests', \false), $this->getBooleanAttribute($document->documentElement, 'displayDetailsOnSkippedTests', \false), $this->getBooleanAttribute($document->documentElement, 'displayDetailsOnTestsThatTriggerDeprecations', \false), $this->getBooleanAttribute($document->documentElement, 'displayDetailsOnPhpunitDeprecations', \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, 'failOnAllIssues', \false), $this->getBooleanAttribute($document->documentElement, 'failOnDeprecation', \false), $this->getBooleanAttribute($document->documentElement, 'failOnPhpunitDeprecation', \false), $this->getBooleanAttribute($document->documentElement, 'failOnPhpunitWarning', \true), $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));
91433 }
91434 private function getColors(DOMDocument $document): string
91435 {
91436 $colors = Configuration::COLOR_DEFAULT;
91437 if ($document->documentElement->hasAttribute('colors')) {
91438 /* only allow boolean for compatibility with previous versions
91439 'always' only allowed from command line */
91440 if ($this->getBoolean($document->documentElement->getAttribute('colors'), \false)) {
91441 $colors = Configuration::COLOR_AUTO;
91442 } else {
91443 $colors = Configuration::COLOR_NEVER;
91444 }
91445 }
91446 return $colors;
91447 }
91448 private function getColumns(DOMDocument $document): int|string
91449 {
91450 $columns = 80;
91451 if ($document->documentElement->hasAttribute('columns')) {
91452 $columns = $document->documentElement->getAttribute('columns');
91453 if ($columns !== 'max') {
91454 $columns = $this->getInteger($columns, 80);
91455 }
91456 }
91457 return $columns;
91458 }
91459 private function testSuite(string $filename, DOMXPath $xpath): TestSuiteCollection
91460 {
91461 $testSuites = [];
91462 foreach ($this->getTestSuiteElements($xpath) as $element) {
91463 $exclude = [];
91464 foreach ($element->getElementsByTagName('exclude') as $excludeNode) {
91465 $excludeFile = $excludeNode->textContent;
91466 if ($excludeFile) {
91467 $exclude[] = new File($this->toAbsolutePath($filename, $excludeFile));
91468 }
91469 }
91470 $directories = [];
91471 foreach ($element->getElementsByTagName('directory') as $directoryNode) {
91472 assert($directoryNode instanceof DOMElement);
91473 $directory = $directoryNode->textContent;
91474 if (empty($directory)) {
91475 continue;
91476 }
91477 $prefix = '';
91478 if ($directoryNode->hasAttribute('prefix')) {
91479 $prefix = $directoryNode->getAttribute('prefix');
91480 }
91481 $suffix = 'Test.php';
91482 if ($directoryNode->hasAttribute('suffix')) {
91483 $suffix = $directoryNode->getAttribute('suffix');
91484 }
91485 $phpVersion = PHP_VERSION;
91486 if ($directoryNode->hasAttribute('phpVersion')) {
91487 $phpVersion = $directoryNode->getAttribute('phpVersion');
91488 }
91489 $phpVersionOperator = new VersionComparisonOperator('>=');
91490 if ($directoryNode->hasAttribute('phpVersionOperator')) {
91491 $phpVersionOperator = new VersionComparisonOperator($directoryNode->getAttribute('phpVersionOperator'));
91492 }
91493 $directories[] = new TestDirectory($this->toAbsolutePath($filename, $directory), $prefix, $suffix, $phpVersion, $phpVersionOperator);
91494 }
91495 $files = [];
91496 foreach ($element->getElementsByTagName('file') as $fileNode) {
91497 assert($fileNode instanceof DOMElement);
91498 $file = $fileNode->textContent;
91499 if (empty($file)) {
91500 continue;
91501 }
91502 $phpVersion = PHP_VERSION;
91503 if ($fileNode->hasAttribute('phpVersion')) {
91504 $phpVersion = $fileNode->getAttribute('phpVersion');
91505 }
91506 $phpVersionOperator = new VersionComparisonOperator('>=');
91507 if ($fileNode->hasAttribute('phpVersionOperator')) {
91508 $phpVersionOperator = new VersionComparisonOperator($fileNode->getAttribute('phpVersionOperator'));
91509 }
91510 $files[] = new TestFile($this->toAbsolutePath($filename, $file), $phpVersion, $phpVersionOperator);
91511 }
91512 $name = $element->getAttribute('name');
91513 assert(!empty($name));
91514 $testSuites[] = new TestSuiteConfiguration($name, TestDirectoryCollection::fromArray($directories), TestFileCollection::fromArray($files), FileCollection::fromArray($exclude));
91515 }
91516 return TestSuiteCollection::fromArray($testSuites);
91517 }
91518 /**
91519 * @psalm-return list<DOMElement>
91520 */
91521 private function getTestSuiteElements(DOMXPath $xpath): array
91522 {
91523 $elements = [];
91524 $testSuiteNodes = $xpath->query('testsuites/testsuite');
91525 if ($testSuiteNodes->length === 0) {
91526 $testSuiteNodes = $xpath->query('testsuite');
91527 }
91528 if ($testSuiteNodes->length === 1) {
91529 $element = $testSuiteNodes->item(0);
91530 assert($element instanceof DOMElement);
91531 $elements[] = $element;
91532 } else {
91533 foreach ($testSuiteNodes as $testSuiteNode) {
91534 assert($testSuiteNode instanceof DOMElement);
91535 $elements[] = $testSuiteNode;
91536 }
91537 }
91538 return $elements;
91539 }
91540 private function element(DOMXPath $xpath, string $element): ?DOMElement
91541 {
91542 $nodes = $xpath->query($element);
91543 if ($nodes->length === 1) {
91544 $node = $nodes->item(0);
91545 assert($node instanceof DOMElement);
91546 return $node;
91547 }
91548 return null;
91549 }
91550 }
91551 <?php
91552
91553 declare (strict_types=1);
91554 /*
91555 * This file is part of PHPUnit.
91556 *
91557 * (c) Sebastian Bergmann <sebastian@phpunit.de>
91558 *
91559 * For the full copyright and license information, please view the LICENSE
91560 * file that was distributed with this source code.
91561 */
91562 namespace PHPUnit\TextUI\XmlConfiguration\Logging;
91563
91564 use PHPUnit\TextUI\Configuration\File;
91565 /**
91566 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
91567 *
91568 * @internal This class is not covered by the backward compatibility promise for PHPUnit
91569 *
91570 * @psalm-immutable
91571 */
91572 final class Junit
91573 {
91574 private readonly File $target;
91575 public function __construct(File $target)
91576 {
91577 $this->target = $target;
91578 }
91579 public function target(): File
91580 {
91581 return $this->target;
91582 }
91583 }
91584 <?php
91585
91586 declare (strict_types=1);
91587 /*
91588 * This file is part of PHPUnit.
91589 *
91590 * (c) Sebastian Bergmann <sebastian@phpunit.de>
91591 *
91592 * For the full copyright and license information, please view the LICENSE
91593 * file that was distributed with this source code.
91594 */
91595 namespace PHPUnit\TextUI\XmlConfiguration\Logging;
91596
91597 use PHPUnit\TextUI\XmlConfiguration\Exception;
91598 use PHPUnit\TextUI\XmlConfiguration\Logging\TestDox\Html as TestDoxHtml;
91599 use PHPUnit\TextUI\XmlConfiguration\Logging\TestDox\Text as TestDoxText;
91600 /**
91601 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
91602 *
91603 * @internal This class is not covered by the backward compatibility promise for PHPUnit
91604 *
91605 * @psalm-immutable
91606 */
91607 final class Logging
91608 {
91609 private readonly ?\PHPUnit\TextUI\XmlConfiguration\Logging\Junit $junit;
91610 private readonly ?\PHPUnit\TextUI\XmlConfiguration\Logging\TeamCity $teamCity;
91611 private readonly ?TestDoxHtml $testDoxHtml;
91612 private readonly ?TestDoxText $testDoxText;
91613 public function __construct(?\PHPUnit\TextUI\XmlConfiguration\Logging\Junit $junit, ?\PHPUnit\TextUI\XmlConfiguration\Logging\TeamCity $teamCity, ?TestDoxHtml $testDoxHtml, ?TestDoxText $testDoxText)
91614 {
91615 $this->junit = $junit;
91616 $this->teamCity = $teamCity;
91617 $this->testDoxHtml = $testDoxHtml;
91618 $this->testDoxText = $testDoxText;
91619 }
91620 public function hasJunit(): bool
91621 {
91622 return $this->junit !== null;
91623 }
91624 /**
91625 * @throws Exception
91626 */
91627 public function junit(): \PHPUnit\TextUI\XmlConfiguration\Logging\Junit
91628 {
91629 if ($this->junit === null) {
91630 throw new Exception('Logger "JUnit XML" is not configured');
91631 }
91632 return $this->junit;
91633 }
91634 public function hasTeamCity(): bool
91635 {
91636 return $this->teamCity !== null;
91637 }
91638 /**
91639 * @throws Exception
91640 */
91641 public function teamCity(): \PHPUnit\TextUI\XmlConfiguration\Logging\TeamCity
91642 {
91643 if ($this->teamCity === null) {
91644 throw new Exception('Logger "Team City" is not configured');
91645 }
91646 return $this->teamCity;
91647 }
91648 public function hasTestDoxHtml(): bool
91649 {
91650 return $this->testDoxHtml !== null;
91651 }
91652 /**
91653 * @throws Exception
91654 */
91655 public function testDoxHtml(): TestDoxHtml
91656 {
91657 if ($this->testDoxHtml === null) {
91658 throw new Exception('Logger "TestDox HTML" is not configured');
91659 }
91660 return $this->testDoxHtml;
91661 }
91662 public function hasTestDoxText(): bool
91663 {
91664 return $this->testDoxText !== null;
91665 }
91666 /**
91667 * @throws Exception
91668 */
91669 public function testDoxText(): TestDoxText
91670 {
91671 if ($this->testDoxText === null) {
91672 throw new Exception('Logger "TestDox Text" is not configured');
91673 }
91674 return $this->testDoxText;
91675 }
91676 }
91677 <?php
91678
91679 declare (strict_types=1);
91680 /*
91681 * This file is part of PHPUnit.
91682 *
91683 * (c) Sebastian Bergmann <sebastian@phpunit.de>
91684 *
91685 * For the full copyright and license information, please view the LICENSE
91686 * file that was distributed with this source code.
91687 */
91688 namespace PHPUnit\TextUI\XmlConfiguration\Logging;
91689
91690 use PHPUnit\TextUI\Configuration\File;
91691 /**
91692 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
91693 *
91694 * @internal This class is not covered by the backward compatibility promise for PHPUnit
91695 *
91696 * @psalm-immutable
91697 */
91698 final class TeamCity
91699 {
91700 private readonly File $target;
91701 public function __construct(File $target)
91702 {
91703 $this->target = $target;
91704 }
91705 public function target(): File
91706 {
91707 return $this->target;
91708 }
91709 }
91710 <?php
91711
91712 declare (strict_types=1);
91713 /*
91714 * This file is part of PHPUnit.
91715 *
91716 * (c) Sebastian Bergmann <sebastian@phpunit.de>
91717 *
91718 * For the full copyright and license information, please view the LICENSE
91719 * file that was distributed with this source code.
91720 */
91721 namespace PHPUnit\TextUI\XmlConfiguration\Logging\TestDox;
91722
91723 use PHPUnit\TextUI\Configuration\File;
91724 /**
91725 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
91726 *
91727 * @internal This class is not covered by the backward compatibility promise for PHPUnit
91728 *
91729 * @psalm-immutable
91730 */
91731 final class Html
91732 {
91733 private readonly File $target;
91734 public function __construct(File $target)
91735 {
91736 $this->target = $target;
91737 }
91738 public function target(): File
91739 {
91740 return $this->target;
91741 }
91742 }
91743 <?php
91744
91745 declare (strict_types=1);
91746 /*
91747 * This file is part of PHPUnit.
91748 *
91749 * (c) Sebastian Bergmann <sebastian@phpunit.de>
91750 *
91751 * For the full copyright and license information, please view the LICENSE
91752 * file that was distributed with this source code.
91753 */
91754 namespace PHPUnit\TextUI\XmlConfiguration\Logging\TestDox;
91755
91756 use PHPUnit\TextUI\Configuration\File;
91757 /**
91758 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
91759 *
91760 * @internal This class is not covered by the backward compatibility promise for PHPUnit
91761 *
91762 * @psalm-immutable
91763 */
91764 final class Text
91765 {
91766 private readonly File $target;
91767 public function __construct(File $target)
91768 {
91769 $this->target = $target;
91770 }
91771 public function target(): File
91772 {
91773 return $this->target;
91774 }
91775 }
91776 <?php
91777
91778 declare (strict_types=1);
91779 /*
91780 * This file is part of PHPUnit.
91781 *
91782 * (c) Sebastian Bergmann <sebastian@phpunit.de>
91783 *
91784 * For the full copyright and license information, please view the LICENSE
91785 * file that was distributed with this source code.
91786 */
91787 namespace PHPUnit\TextUI\XmlConfiguration;
91788
91789 use function version_compare;
91790 /**
91791 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
91792 *
91793 * @internal This class is not covered by the backward compatibility promise for PHPUnit
91794 */
91795 final class MigrationBuilder
91796 {
91797 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], '10.4' => [\PHPUnit\TextUI\XmlConfiguration\RemoveBeStrictAboutTodoAnnotatedTestsAttribute::class]];
91798 public function build(string $fromVersion): array
91799 {
91800 $stack = [new \PHPUnit\TextUI\XmlConfiguration\UpdateSchemaLocation()];
91801 foreach (self::AVAILABLE_MIGRATIONS as $version => $migrations) {
91802 if (version_compare($version, $fromVersion, '<')) {
91803 continue;
91804 }
91805 foreach ($migrations as $migration) {
91806 $stack[] = new $migration();
91807 }
91808 }
91809 return $stack;
91810 }
91811 }
91812 <?php
91813
91814 declare (strict_types=1);
91815 /*
91816 * This file is part of PHPUnit.
91817 *
91818 * (c) Sebastian Bergmann <sebastian@phpunit.de>
91819 *
91820 * For the full copyright and license information, please view the LICENSE
91821 * file that was distributed with this source code.
91822 */
91823 namespace PHPUnit\TextUI\XmlConfiguration;
91824
91825 use PHPUnit\Exception;
91826 use RuntimeException;
91827 /**
91828 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
91829 *
91830 * @internal This class is not covered by the backward compatibility promise for PHPUnit
91831 */
91832 final class MigrationException extends RuntimeException implements Exception
91833 {
91834 }
91835 <?php
91836
91837 declare (strict_types=1);
91838 /*
91839 * This file is part of PHPUnit.
91840 *
91841 * (c) Sebastian Bergmann <sebastian@phpunit.de>
91842 *
91843 * For the full copyright and license information, please view the LICENSE
91844 * file that was distributed with this source code.
91845 */
91846 namespace PHPUnit\TextUI\XmlConfiguration;
91847
91848 use DOMDocument;
91849 use DOMElement;
91850 /**
91851 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
91852 *
91853 * @internal This class is not covered by the backward compatibility promise for PHPUnit
91854 */
91855 final class ConvertLogTypes implements \PHPUnit\TextUI\XmlConfiguration\Migration
91856 {
91857 public function migrate(DOMDocument $document): void
91858 {
91859 $logging = $document->getElementsByTagName('logging')->item(0);
91860 if (!$logging instanceof DOMElement) {
91861 return;
91862 }
91863 $types = ['junit' => 'junit', 'teamcity' => 'teamcity', 'testdox-html' => 'testdoxHtml', 'testdox-text' => 'testdoxText', 'testdox-xml' => 'testdoxXml', 'plain' => 'text'];
91864 $logNodes = [];
91865 foreach ($logging->getElementsByTagName('log') as $logNode) {
91866 if (!isset($types[$logNode->getAttribute('type')])) {
91867 continue;
91868 }
91869 $logNodes[] = $logNode;
91870 }
91871 foreach ($logNodes as $oldNode) {
91872 $newLogNode = $document->createElement($types[$oldNode->getAttribute('type')]);
91873 $newLogNode->setAttribute('outputFile', $oldNode->getAttribute('target'));
91874 $logging->replaceChild($newLogNode, $oldNode);
91875 }
91876 }
91877 }
91878 <?php
91879
91880 declare (strict_types=1);
91881 /*
91882 * This file is part of PHPUnit.
91883 *
91884 * (c) Sebastian Bergmann <sebastian@phpunit.de>
91885 *
91886 * For the full copyright and license information, please view the LICENSE
91887 * file that was distributed with this source code.
91888 */
91889 namespace PHPUnit\TextUI\XmlConfiguration;
91890
91891 use DOMElement;
91892 /**
91893 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
91894 *
91895 * @internal This class is not covered by the backward compatibility promise for PHPUnit
91896 */
91897 final class CoverageCloverToReport extends \PHPUnit\TextUI\XmlConfiguration\LogToReportMigration
91898 {
91899 protected function forType(): string
91900 {
91901 return 'coverage-clover';
91902 }
91903 protected function toReportFormat(DOMElement $logNode): DOMElement
91904 {
91905 $clover = $logNode->ownerDocument->createElement('clover');
91906 $clover->setAttribute('outputFile', $logNode->getAttribute('target'));
91907 return $clover;
91908 }
91909 }
91910 <?php
91911
91912 declare (strict_types=1);
91913 /*
91914 * This file is part of PHPUnit.
91915 *
91916 * (c) Sebastian Bergmann <sebastian@phpunit.de>
91917 *
91918 * For the full copyright and license information, please view the LICENSE
91919 * file that was distributed with this source code.
91920 */
91921 namespace PHPUnit\TextUI\XmlConfiguration;
91922
91923 use DOMElement;
91924 /**
91925 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
91926 *
91927 * @internal This class is not covered by the backward compatibility promise for PHPUnit
91928 */
91929 final class CoverageCrap4jToReport extends \PHPUnit\TextUI\XmlConfiguration\LogToReportMigration
91930 {
91931 protected function forType(): string
91932 {
91933 return 'coverage-crap4j';
91934 }
91935 protected function toReportFormat(DOMElement $logNode): DOMElement
91936 {
91937 $crap4j = $logNode->ownerDocument->createElement('crap4j');
91938 $crap4j->setAttribute('outputFile', $logNode->getAttribute('target'));
91939 $this->migrateAttributes($logNode, $crap4j, ['threshold']);
91940 return $crap4j;
91941 }
91942 }
91943 <?php
91944
91945 declare (strict_types=1);
91946 /*
91947 * This file is part of PHPUnit.
91948 *
91949 * (c) Sebastian Bergmann <sebastian@phpunit.de>
91950 *
91951 * For the full copyright and license information, please view the LICENSE
91952 * file that was distributed with this source code.
91953 */
91954 namespace PHPUnit\TextUI\XmlConfiguration;
91955
91956 use DOMElement;
91957 /**
91958 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
91959 *
91960 * @internal This class is not covered by the backward compatibility promise for PHPUnit
91961 */
91962 final class CoverageHtmlToReport extends \PHPUnit\TextUI\XmlConfiguration\LogToReportMigration
91963 {
91964 protected function forType(): string
91965 {
91966 return 'coverage-html';
91967 }
91968 protected function toReportFormat(DOMElement $logNode): DOMElement
91969 {
91970 $html = $logNode->ownerDocument->createElement('html');
91971 $html->setAttribute('outputDirectory', $logNode->getAttribute('target'));
91972 $this->migrateAttributes($logNode, $html, ['lowUpperBound', 'highLowerBound']);
91973 return $html;
91974 }
91975 }
91976 <?php
91977
91978 declare (strict_types=1);
91979 /*
91980 * This file is part of PHPUnit.
91981 *
91982 * (c) Sebastian Bergmann <sebastian@phpunit.de>
91983 *
91984 * For the full copyright and license information, please view the LICENSE
91985 * file that was distributed with this source code.
91986 */
91987 namespace PHPUnit\TextUI\XmlConfiguration;
91988
91989 use DOMElement;
91990 /**
91991 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
91992 *
91993 * @internal This class is not covered by the backward compatibility promise for PHPUnit
91994 */
91995 final class CoveragePhpToReport extends \PHPUnit\TextUI\XmlConfiguration\LogToReportMigration
91996 {
91997 protected function forType(): string
91998 {
91999 return 'coverage-php';
92000 }
92001 protected function toReportFormat(DOMElement $logNode): DOMElement
92002 {
92003 $php = $logNode->ownerDocument->createElement('php');
92004 $php->setAttribute('outputFile', $logNode->getAttribute('target'));
92005 return $php;
92006 }
92007 }
92008 <?php
92009
92010 declare (strict_types=1);
92011 /*
92012 * This file is part of PHPUnit.
92013 *
92014 * (c) Sebastian Bergmann <sebastian@phpunit.de>
92015 *
92016 * For the full copyright and license information, please view the LICENSE
92017 * file that was distributed with this source code.
92018 */
92019 namespace PHPUnit\TextUI\XmlConfiguration;
92020
92021 use DOMElement;
92022 /**
92023 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
92024 *
92025 * @internal This class is not covered by the backward compatibility promise for PHPUnit
92026 */
92027 final class CoverageTextToReport extends \PHPUnit\TextUI\XmlConfiguration\LogToReportMigration
92028 {
92029 protected function forType(): string
92030 {
92031 return 'coverage-text';
92032 }
92033 protected function toReportFormat(DOMElement $logNode): DOMElement
92034 {
92035 $text = $logNode->ownerDocument->createElement('text');
92036 $text->setAttribute('outputFile', $logNode->getAttribute('target'));
92037 $this->migrateAttributes($logNode, $text, ['showUncoveredFiles', 'showOnlySummary']);
92038 return $text;
92039 }
92040 }
92041 <?php
92042
92043 declare (strict_types=1);
92044 /*
92045 * This file is part of PHPUnit.
92046 *
92047 * (c) Sebastian Bergmann <sebastian@phpunit.de>
92048 *
92049 * For the full copyright and license information, please view the LICENSE
92050 * file that was distributed with this source code.
92051 */
92052 namespace PHPUnit\TextUI\XmlConfiguration;
92053
92054 use DOMElement;
92055 /**
92056 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
92057 *
92058 * @internal This class is not covered by the backward compatibility promise for PHPUnit
92059 */
92060 final class CoverageXmlToReport extends \PHPUnit\TextUI\XmlConfiguration\LogToReportMigration
92061 {
92062 protected function forType(): string
92063 {
92064 return 'coverage-xml';
92065 }
92066 protected function toReportFormat(DOMElement $logNode): DOMElement
92067 {
92068 $xml = $logNode->ownerDocument->createElement('xml');
92069 $xml->setAttribute('outputDirectory', $logNode->getAttribute('target'));
92070 return $xml;
92071 }
92072 }
92073 <?php
92074
92075 declare (strict_types=1);
92076 /*
92077 * This file is part of PHPUnit.
92078 *
92079 * (c) Sebastian Bergmann <sebastian@phpunit.de>
92080 *
92081 * For the full copyright and license information, please view the LICENSE
92082 * file that was distributed with this source code.
92083 */
92084 namespace PHPUnit\TextUI\XmlConfiguration;
92085
92086 use function assert;
92087 use DOMDocument;
92088 use DOMElement;
92089 /**
92090 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
92091 *
92092 * @internal This class is not covered by the backward compatibility promise for PHPUnit
92093 */
92094 final class IntroduceCacheDirectoryAttribute implements \PHPUnit\TextUI\XmlConfiguration\Migration
92095 {
92096 public function migrate(DOMDocument $document): void
92097 {
92098 $root = $document->documentElement;
92099 assert($root instanceof DOMElement);
92100 if ($root->hasAttribute('cacheDirectory')) {
92101 return;
92102 }
92103 $root->setAttribute('cacheDirectory', '.phpunit.cache');
92104 }
92105 }
92106 <?php
92107
92108 declare (strict_types=1);
92109 /*
92110 * This file is part of PHPUnit.
92111 *
92112 * (c) Sebastian Bergmann <sebastian@phpunit.de>
92113 *
92114 * For the full copyright and license information, please view the LICENSE
92115 * file that was distributed with this source code.
92116 */
92117 namespace PHPUnit\TextUI\XmlConfiguration;
92118
92119 use DOMDocument;
92120 /**
92121 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
92122 *
92123 * @internal This class is not covered by the backward compatibility promise for PHPUnit
92124 */
92125 final class IntroduceCoverageElement implements \PHPUnit\TextUI\XmlConfiguration\Migration
92126 {
92127 public function migrate(DOMDocument $document): void
92128 {
92129 $coverage = $document->createElement('coverage');
92130 $document->documentElement->insertBefore($coverage, $document->documentElement->firstChild);
92131 }
92132 }
92133 <?php
92134
92135 declare (strict_types=1);
92136 /*
92137 * This file is part of PHPUnit.
92138 *
92139 * (c) Sebastian Bergmann <sebastian@phpunit.de>
92140 *
92141 * For the full copyright and license information, please view the LICENSE
92142 * file that was distributed with this source code.
92143 */
92144 namespace PHPUnit\TextUI\XmlConfiguration;
92145
92146 use function sprintf;
92147 use DOMDocument;
92148 use DOMElement;
92149 use DOMXPath;
92150 /**
92151 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
92152 *
92153 * @internal This class is not covered by the backward compatibility promise for PHPUnit
92154 */
92155 abstract class LogToReportMigration implements \PHPUnit\TextUI\XmlConfiguration\Migration
92156 {
92157 /**
92158 * @throws MigrationException
92159 */
92160 public function migrate(DOMDocument $document): void
92161 {
92162 $coverage = $document->getElementsByTagName('coverage')->item(0);
92163 if (!$coverage instanceof DOMElement) {
92164 throw new \PHPUnit\TextUI\XmlConfiguration\MigrationException('Unexpected state - No coverage element');
92165 }
92166 $logNode = $this->findLogNode($document);
92167 if ($logNode === null) {
92168 return;
92169 }
92170 $reportChild = $this->toReportFormat($logNode);
92171 $report = $coverage->getElementsByTagName('report')->item(0);
92172 if ($report === null) {
92173 $report = $coverage->appendChild($document->createElement('report'));
92174 }
92175 $report->appendChild($reportChild);
92176 $logNode->parentNode->removeChild($logNode);
92177 }
92178 protected function migrateAttributes(DOMElement $src, DOMElement $dest, array $attributes): void
92179 {
92180 foreach ($attributes as $attr) {
92181 if (!$src->hasAttribute($attr)) {
92182 continue;
92183 }
92184 $dest->setAttribute($attr, $src->getAttribute($attr));
92185 $src->removeAttribute($attr);
92186 }
92187 }
92188 abstract protected function forType(): string;
92189 abstract protected function toReportFormat(DOMElement $logNode): DOMElement;
92190 private function findLogNode(DOMDocument $document): ?DOMElement
92191 {
92192 $logNode = (new DOMXPath($document))->query(sprintf('//logging/log[@type="%s"]', $this->forType()))->item(0);
92193 if (!$logNode instanceof DOMElement) {
92194 return null;
92195 }
92196 return $logNode;
92197 }
92198 }
92199 <?php
92200
92201 declare (strict_types=1);
92202 /*
92203 * This file is part of PHPUnit.
92204 *
92205 * (c) Sebastian Bergmann <sebastian@phpunit.de>
92206 *
92207 * For the full copyright and license information, please view the LICENSE
92208 * file that was distributed with this source code.
92209 */
92210 namespace PHPUnit\TextUI\XmlConfiguration;
92211
92212 use DOMDocument;
92213 /**
92214 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
92215 *
92216 * @internal This interface is not covered by the backward compatibility promise for PHPUnit
92217 */
92218 interface Migration
92219 {
92220 public function migrate(DOMDocument $document): void;
92221 }
92222 <?php
92223
92224 declare (strict_types=1);
92225 /*
92226 * This file is part of PHPUnit.
92227 *
92228 * (c) Sebastian Bergmann <sebastian@phpunit.de>
92229 *
92230 * For the full copyright and license information, please view the LICENSE
92231 * file that was distributed with this source code.
92232 */
92233 namespace PHPUnit\TextUI\XmlConfiguration;
92234
92235 use DOMDocument;
92236 use DOMElement;
92237 /**
92238 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
92239 *
92240 * @internal This class is not covered by the backward compatibility promise for PHPUnit
92241 */
92242 final class MoveAttributesFromFilterWhitelistToCoverage implements \PHPUnit\TextUI\XmlConfiguration\Migration
92243 {
92244 /**
92245 * @throws MigrationException
92246 */
92247 public function migrate(DOMDocument $document): void
92248 {
92249 $whitelist = $document->getElementsByTagName('whitelist')->item(0);
92250 if (!$whitelist) {
92251 return;
92252 }
92253 $coverage = $document->getElementsByTagName('coverage')->item(0);
92254 if (!$coverage instanceof DOMElement) {
92255 throw new \PHPUnit\TextUI\XmlConfiguration\MigrationException('Unexpected state - No coverage element');
92256 }
92257 $map = ['addUncoveredFilesFromWhitelist' => 'includeUncoveredFiles', 'processUncoveredFilesFromWhitelist' => 'processUncoveredFiles'];
92258 foreach ($map as $old => $new) {
92259 if (!$whitelist->hasAttribute($old)) {
92260 continue;
92261 }
92262 $coverage->setAttribute($new, $whitelist->getAttribute($old));
92263 $whitelist->removeAttribute($old);
92264 }
92265 }
92266 }
92267 <?php
92268
92269 declare (strict_types=1);
92270 /*
92271 * This file is part of PHPUnit.
92272 *
92273 * (c) Sebastian Bergmann <sebastian@phpunit.de>
92274 *
92275 * For the full copyright and license information, please view the LICENSE
92276 * file that was distributed with this source code.
92277 */
92278 namespace PHPUnit\TextUI\XmlConfiguration;
92279
92280 use function assert;
92281 use DOMDocument;
92282 use DOMElement;
92283 /**
92284 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
92285 *
92286 * @internal This class is not covered by the backward compatibility promise for PHPUnit
92287 */
92288 final class MoveAttributesFromRootToCoverage implements \PHPUnit\TextUI\XmlConfiguration\Migration
92289 {
92290 /**
92291 * @throws MigrationException
92292 */
92293 public function migrate(DOMDocument $document): void
92294 {
92295 $map = ['disableCodeCoverageIgnore' => 'disableCodeCoverageIgnore', 'ignoreDeprecatedCodeUnitsFromCodeCoverage' => 'ignoreDeprecatedCodeUnits'];
92296 $root = $document->documentElement;
92297 assert($root instanceof DOMElement);
92298 $coverage = $document->getElementsByTagName('coverage')->item(0);
92299 if (!$coverage instanceof DOMElement) {
92300 throw new \PHPUnit\TextUI\XmlConfiguration\MigrationException('Unexpected state - No coverage element');
92301 }
92302 foreach ($map as $old => $new) {
92303 if (!$root->hasAttribute($old)) {
92304 continue;
92305 }
92306 $coverage->setAttribute($new, $root->getAttribute($old));
92307 $root->removeAttribute($old);
92308 }
92309 }
92310 }
92311 <?php
92312
92313 declare (strict_types=1);
92314 /*
92315 * This file is part of PHPUnit.
92316 *
92317 * (c) Sebastian Bergmann <sebastian@phpunit.de>
92318 *
92319 * For the full copyright and license information, please view the LICENSE
92320 * file that was distributed with this source code.
92321 */
92322 namespace PHPUnit\TextUI\XmlConfiguration;
92323
92324 use function assert;
92325 use DOMDocument;
92326 use DOMElement;
92327 use DOMXPath;
92328 /**
92329 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
92330 *
92331 * @internal This class is not covered by the backward compatibility promise for PHPUnit
92332 */
92333 final class MoveCoverageDirectoriesToSource implements \PHPUnit\TextUI\XmlConfiguration\Migration
92334 {
92335 /**
92336 * @throws MigrationException
92337 */
92338 public function migrate(DOMDocument $document): void
92339 {
92340 $source = $document->getElementsByTagName('source')->item(0);
92341 if ($source !== null) {
92342 return;
92343 }
92344 $coverage = $document->getElementsByTagName('coverage')->item(0);
92345 if ($coverage === null) {
92346 return;
92347 }
92348 $root = $document->documentElement;
92349 assert($root instanceof DOMElement);
92350 $source = $document->createElement('source');
92351 $root->appendChild($source);
92352 $xpath = new DOMXPath($document);
92353 foreach (['include', 'exclude'] as $element) {
92354 foreach (\PHPUnit\TextUI\XmlConfiguration\SnapshotNodeList::fromNodeList($xpath->query('//coverage/' . $element)) as $node) {
92355 $source->appendChild($node);
92356 }
92357 }
92358 if ($coverage->childElementCount !== 0) {
92359 return;
92360 }
92361 assert($coverage->parentNode !== null);
92362 $coverage->parentNode->removeChild($coverage);
92363 }
92364 }
92365 <?php
92366
92367 declare (strict_types=1);
92368 /*
92369 * This file is part of PHPUnit.
92370 *
92371 * (c) Sebastian Bergmann <sebastian@phpunit.de>
92372 *
92373 * For the full copyright and license information, please view the LICENSE
92374 * file that was distributed with this source code.
92375 */
92376 namespace PHPUnit\TextUI\XmlConfiguration;
92377
92378 use function assert;
92379 use function in_array;
92380 use DOMDocument;
92381 use DOMElement;
92382 /**
92383 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
92384 *
92385 * @internal This class is not covered by the backward compatibility promise for PHPUnit
92386 */
92387 final class MoveWhitelistExcludesToCoverage implements \PHPUnit\TextUI\XmlConfiguration\Migration
92388 {
92389 /**
92390 * @throws MigrationException
92391 */
92392 public function migrate(DOMDocument $document): void
92393 {
92394 $whitelist = $document->getElementsByTagName('whitelist')->item(0);
92395 if ($whitelist === null) {
92396 return;
92397 }
92398 $excludeNodes = \PHPUnit\TextUI\XmlConfiguration\SnapshotNodeList::fromNodeList($whitelist->getElementsByTagName('exclude'));
92399 if ($excludeNodes->count() === 0) {
92400 return;
92401 }
92402 $coverage = $document->getElementsByTagName('coverage')->item(0);
92403 if (!$coverage instanceof DOMElement) {
92404 throw new \PHPUnit\TextUI\XmlConfiguration\MigrationException('Unexpected state - No coverage element');
92405 }
92406 $targetExclude = $coverage->getElementsByTagName('exclude')->item(0);
92407 if ($targetExclude === null) {
92408 $targetExclude = $coverage->appendChild($document->createElement('exclude'));
92409 }
92410 foreach ($excludeNodes as $excludeNode) {
92411 assert($excludeNode instanceof DOMElement);
92412 foreach (\PHPUnit\TextUI\XmlConfiguration\SnapshotNodeList::fromNodeList($excludeNode->childNodes) as $child) {
92413 if (!$child instanceof DOMElement || !in_array($child->nodeName, ['directory', 'file'], \true)) {
92414 continue;
92415 }
92416 $targetExclude->appendChild($child);
92417 }
92418 if ($excludeNode->getElementsByTagName('*')->count() !== 0) {
92419 throw new \PHPUnit\TextUI\XmlConfiguration\MigrationException('Dangling child elements in exclude found.');
92420 }
92421 $whitelist->removeChild($excludeNode);
92422 }
92423 }
92424 }
92425 <?php
92426
92427 declare (strict_types=1);
92428 /*
92429 * This file is part of PHPUnit.
92430 *
92431 * (c) Sebastian Bergmann <sebastian@phpunit.de>
92432 *
92433 * For the full copyright and license information, please view the LICENSE
92434 * file that was distributed with this source code.
92435 */
92436 namespace PHPUnit\TextUI\XmlConfiguration;
92437
92438 use DOMDocument;
92439 use DOMElement;
92440 /**
92441 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
92442 *
92443 * @internal This class is not covered by the backward compatibility promise for PHPUnit
92444 */
92445 final class MoveWhitelistIncludesToCoverage implements \PHPUnit\TextUI\XmlConfiguration\Migration
92446 {
92447 /**
92448 * @throws MigrationException
92449 */
92450 public function migrate(DOMDocument $document): void
92451 {
92452 $whitelist = $document->getElementsByTagName('whitelist')->item(0);
92453 if ($whitelist === null) {
92454 return;
92455 }
92456 $coverage = $document->getElementsByTagName('coverage')->item(0);
92457 if (!$coverage instanceof DOMElement) {
92458 throw new \PHPUnit\TextUI\XmlConfiguration\MigrationException('Unexpected state - No coverage element');
92459 }
92460 $include = $document->createElement('include');
92461 $coverage->appendChild($include);
92462 foreach (\PHPUnit\TextUI\XmlConfiguration\SnapshotNodeList::fromNodeList($whitelist->childNodes) as $child) {
92463 if (!$child instanceof DOMElement) {
92464 continue;
92465 }
92466 if (!($child->nodeName === 'directory' || $child->nodeName === 'file')) {
92467 continue;
92468 }
92469 $include->appendChild($child);
92470 }
92471 }
92472 }
92473 <?php
92474
92475 declare (strict_types=1);
92476 /*
92477 * This file is part of PHPUnit.
92478 *
92479 * (c) Sebastian Bergmann <sebastian@phpunit.de>
92480 *
92481 * For the full copyright and license information, please view the LICENSE
92482 * file that was distributed with this source code.
92483 */
92484 namespace PHPUnit\TextUI\XmlConfiguration;
92485
92486 use function assert;
92487 use DOMDocument;
92488 use DOMElement;
92489 /**
92490 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
92491 *
92492 * @internal This class is not covered by the backward compatibility promise for PHPUnit
92493 */
92494 final class RemoveBeStrictAboutResourceUsageDuringSmallTestsAttribute implements \PHPUnit\TextUI\XmlConfiguration\Migration
92495 {
92496 public function migrate(DOMDocument $document): void
92497 {
92498 $root = $document->documentElement;
92499 assert($root instanceof DOMElement);
92500 if ($root->hasAttribute('beStrictAboutResourceUsageDuringSmallTests')) {
92501 $root->removeAttribute('beStrictAboutResourceUsageDuringSmallTests');
92502 }
92503 }
92504 }
92505 <?php
92506
92507 declare (strict_types=1);
92508 /*
92509 * This file is part of PHPUnit.
92510 *
92511 * (c) Sebastian Bergmann <sebastian@phpunit.de>
92512 *
92513 * For the full copyright and license information, please view the LICENSE
92514 * file that was distributed with this source code.
92515 */
92516 namespace PHPUnit\TextUI\XmlConfiguration;
92517
92518 use function assert;
92519 use DOMDocument;
92520 use DOMElement;
92521 /**
92522 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
92523 *
92524 * @internal This class is not covered by the backward compatibility promise for PHPUnit
92525 */
92526 final class RemoveBeStrictAboutTodoAnnotatedTestsAttribute implements \PHPUnit\TextUI\XmlConfiguration\Migration
92527 {
92528 public function migrate(DOMDocument $document): void
92529 {
92530 $root = $document->documentElement;
92531 assert($root instanceof DOMElement);
92532 if ($root->hasAttribute('beStrictAboutTodoAnnotatedTests')) {
92533 $root->removeAttribute('beStrictAboutTodoAnnotatedTests');
92534 }
92535 }
92536 }
92537 <?php
92538
92539 declare (strict_types=1);
92540 /*
92541 * This file is part of PHPUnit.
92542 *
92543 * (c) Sebastian Bergmann <sebastian@phpunit.de>
92544 *
92545 * For the full copyright and license information, please view the LICENSE
92546 * file that was distributed with this source code.
92547 */
92548 namespace PHPUnit\TextUI\XmlConfiguration;
92549
92550 use function assert;
92551 use DOMDocument;
92552 use DOMElement;
92553 /**
92554 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
92555 *
92556 * @internal This class is not covered by the backward compatibility promise for PHPUnit
92557 */
92558 final class RemoveCacheResultFileAttribute implements \PHPUnit\TextUI\XmlConfiguration\Migration
92559 {
92560 public function migrate(DOMDocument $document): void
92561 {
92562 $root = $document->documentElement;
92563 assert($root instanceof DOMElement);
92564 if ($root->hasAttribute('cacheResultFile')) {
92565 $root->removeAttribute('cacheResultFile');
92566 }
92567 }
92568 }
92569 <?php
92570
92571 declare (strict_types=1);
92572 /*
92573 * This file is part of PHPUnit.
92574 *
92575 * (c) Sebastian Bergmann <sebastian@phpunit.de>
92576 *
92577 * For the full copyright and license information, please view the LICENSE
92578 * file that was distributed with this source code.
92579 */
92580 namespace PHPUnit\TextUI\XmlConfiguration;
92581
92582 use function assert;
92583 use DOMDocument;
92584 use DOMElement;
92585 /**
92586 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
92587 *
92588 * @internal This class is not covered by the backward compatibility promise for PHPUnit
92589 */
92590 final class RemoveCacheTokensAttribute implements \PHPUnit\TextUI\XmlConfiguration\Migration
92591 {
92592 public function migrate(DOMDocument $document): void
92593 {
92594 $root = $document->documentElement;
92595 assert($root instanceof DOMElement);
92596 if ($root->hasAttribute('cacheTokens')) {
92597 $root->removeAttribute('cacheTokens');
92598 }
92599 }
92600 }
92601 <?php
92602
92603 declare (strict_types=1);
92604 /*
92605 * This file is part of PHPUnit.
92606 *
92607 * (c) Sebastian Bergmann <sebastian@phpunit.de>
92608 *
92609 * For the full copyright and license information, please view the LICENSE
92610 * file that was distributed with this source code.
92611 */
92612 namespace PHPUnit\TextUI\XmlConfiguration;
92613
92614 use function assert;
92615 use DOMDocument;
92616 use DOMElement;
92617 /**
92618 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
92619 *
92620 * @internal This class is not covered by the backward compatibility promise for PHPUnit
92621 */
92622 final class RemoveConversionToExceptionsAttributes implements \PHPUnit\TextUI\XmlConfiguration\Migration
92623 {
92624 public function migrate(DOMDocument $document): void
92625 {
92626 $root = $document->documentElement;
92627 assert($root instanceof DOMElement);
92628 if ($root->hasAttribute('convertDeprecationsToExceptions')) {
92629 $root->removeAttribute('convertDeprecationsToExceptions');
92630 }
92631 if ($root->hasAttribute('convertErrorsToExceptions')) {
92632 $root->removeAttribute('convertErrorsToExceptions');
92633 }
92634 if ($root->hasAttribute('convertNoticesToExceptions')) {
92635 $root->removeAttribute('convertNoticesToExceptions');
92636 }
92637 if ($root->hasAttribute('convertWarningsToExceptions')) {
92638 $root->removeAttribute('convertWarningsToExceptions');
92639 }
92640 }
92641 }
92642 <?php
92643
92644 declare (strict_types=1);
92645 /*
92646 * This file is part of PHPUnit.
92647 *
92648 * (c) Sebastian Bergmann <sebastian@phpunit.de>
92649 *
92650 * For the full copyright and license information, please view the LICENSE
92651 * file that was distributed with this source code.
92652 */
92653 namespace PHPUnit\TextUI\XmlConfiguration;
92654
92655 use DOMDocument;
92656 use DOMElement;
92657 /**
92658 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
92659 *
92660 * @internal This class is not covered by the backward compatibility promise for PHPUnit
92661 */
92662 final class RemoveCoverageElementCacheDirectoryAttribute implements \PHPUnit\TextUI\XmlConfiguration\Migration
92663 {
92664 public function migrate(DOMDocument $document): void
92665 {
92666 $node = $document->getElementsByTagName('coverage')->item(0);
92667 if (!$node instanceof DOMElement || $node->parentNode === null) {
92668 return;
92669 }
92670 if ($node->hasAttribute('cacheDirectory')) {
92671 $node->removeAttribute('cacheDirectory');
92672 }
92673 }
92674 }
92675 <?php
92676
92677 declare (strict_types=1);
92678 /*
92679 * This file is part of PHPUnit.
92680 *
92681 * (c) Sebastian Bergmann <sebastian@phpunit.de>
92682 *
92683 * For the full copyright and license information, please view the LICENSE
92684 * file that was distributed with this source code.
92685 */
92686 namespace PHPUnit\TextUI\XmlConfiguration;
92687
92688 use DOMDocument;
92689 use DOMElement;
92690 /**
92691 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
92692 *
92693 * @internal This class is not covered by the backward compatibility promise for PHPUnit
92694 */
92695 final class RemoveCoverageElementProcessUncoveredFilesAttribute implements \PHPUnit\TextUI\XmlConfiguration\Migration
92696 {
92697 public function migrate(DOMDocument $document): void
92698 {
92699 $node = $document->getElementsByTagName('coverage')->item(0);
92700 if (!$node instanceof DOMElement || $node->parentNode === null) {
92701 return;
92702 }
92703 if ($node->hasAttribute('processUncoveredFiles')) {
92704 $node->removeAttribute('processUncoveredFiles');
92705 }
92706 }
92707 }
92708 <?php
92709
92710 declare (strict_types=1);
92711 /*
92712 * This file is part of PHPUnit.
92713 *
92714 * (c) Sebastian Bergmann <sebastian@phpunit.de>
92715 *
92716 * For the full copyright and license information, please view the LICENSE
92717 * file that was distributed with this source code.
92718 */
92719 namespace PHPUnit\TextUI\XmlConfiguration;
92720
92721 use function sprintf;
92722 use DOMDocument;
92723 use DOMElement;
92724 /**
92725 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
92726 *
92727 * @internal This class is not covered by the backward compatibility promise for PHPUnit
92728 */
92729 final class RemoveEmptyFilter implements \PHPUnit\TextUI\XmlConfiguration\Migration
92730 {
92731 /**
92732 * @throws MigrationException
92733 */
92734 public function migrate(DOMDocument $document): void
92735 {
92736 $whitelist = $document->getElementsByTagName('whitelist')->item(0);
92737 if ($whitelist instanceof DOMElement) {
92738 $this->ensureEmpty($whitelist);
92739 $whitelist->parentNode->removeChild($whitelist);
92740 }
92741 $filter = $document->getElementsByTagName('filter')->item(0);
92742 if ($filter instanceof DOMElement) {
92743 $this->ensureEmpty($filter);
92744 $filter->parentNode->removeChild($filter);
92745 }
92746 }
92747 /**
92748 * @throws MigrationException
92749 */
92750 private function ensureEmpty(DOMElement $element): void
92751 {
92752 if ($element->attributes->length > 0) {
92753 throw new \PHPUnit\TextUI\XmlConfiguration\MigrationException(sprintf('%s element has unexpected attributes', $element->nodeName));
92754 }
92755 if ($element->getElementsByTagName('*')->length > 0) {
92756 throw new \PHPUnit\TextUI\XmlConfiguration\MigrationException(sprintf('%s element has unexpected children', $element->nodeName));
92757 }
92758 }
92759 }
92760 <?php
92761
92762 declare (strict_types=1);
92763 /*
92764 * This file is part of PHPUnit.
92765 *
92766 * (c) Sebastian Bergmann <sebastian@phpunit.de>
92767 *
92768 * For the full copyright and license information, please view the LICENSE
92769 * file that was distributed with this source code.
92770 */
92771 namespace PHPUnit\TextUI\XmlConfiguration;
92772
92773 use DOMDocument;
92774 use DOMElement;
92775 /**
92776 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
92777 *
92778 * @internal This class is not covered by the backward compatibility promise for PHPUnit
92779 */
92780 final class RemoveListeners implements \PHPUnit\TextUI\XmlConfiguration\Migration
92781 {
92782 public function migrate(DOMDocument $document): void
92783 {
92784 $node = $document->getElementsByTagName('listeners')->item(0);
92785 if (!$node instanceof DOMElement || $node->parentNode === null) {
92786 return;
92787 }
92788 $node->parentNode->removeChild($node);
92789 }
92790 }
92791 <?php
92792
92793 declare (strict_types=1);
92794 /*
92795 * This file is part of PHPUnit.
92796 *
92797 * (c) Sebastian Bergmann <sebastian@phpunit.de>
92798 *
92799 * For the full copyright and license information, please view the LICENSE
92800 * file that was distributed with this source code.
92801 */
92802 namespace PHPUnit\TextUI\XmlConfiguration;
92803
92804 use function assert;
92805 use DOMDocument;
92806 use DOMElement;
92807 /**
92808 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
92809 *
92810 * @internal This class is not covered by the backward compatibility promise for PHPUnit
92811 */
92812 final class RemoveLogTypes implements \PHPUnit\TextUI\XmlConfiguration\Migration
92813 {
92814 public function migrate(DOMDocument $document): void
92815 {
92816 $logging = $document->getElementsByTagName('logging')->item(0);
92817 if (!$logging instanceof DOMElement) {
92818 return;
92819 }
92820 foreach (\PHPUnit\TextUI\XmlConfiguration\SnapshotNodeList::fromNodeList($logging->getElementsByTagName('log')) as $logNode) {
92821 assert($logNode instanceof DOMElement);
92822 switch ($logNode->getAttribute('type')) {
92823 case 'json':
92824 case 'tap':
92825 $logging->removeChild($logNode);
92826 }
92827 }
92828 }
92829 }
92830 <?php
92831
92832 declare (strict_types=1);
92833 /*
92834 * This file is part of PHPUnit.
92835 *
92836 * (c) Sebastian Bergmann <sebastian@phpunit.de>
92837 *
92838 * For the full copyright and license information, please view the LICENSE
92839 * file that was distributed with this source code.
92840 */
92841 namespace PHPUnit\TextUI\XmlConfiguration;
92842
92843 use DOMDocument;
92844 use DOMElement;
92845 use DOMXPath;
92846 /**
92847 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
92848 *
92849 * @internal This class is not covered by the backward compatibility promise for PHPUnit
92850 */
92851 final class RemoveLoggingElements implements \PHPUnit\TextUI\XmlConfiguration\Migration
92852 {
92853 public function migrate(DOMDocument $document): void
92854 {
92855 $this->removeTestDoxElement($document);
92856 $this->removeTextElement($document);
92857 }
92858 private function removeTestDoxElement(DOMDocument $document): void
92859 {
92860 $node = (new DOMXPath($document))->query('logging/testdoxXml')->item(0);
92861 if (!$node instanceof DOMElement || $node->parentNode === null) {
92862 return;
92863 }
92864 $node->parentNode->removeChild($node);
92865 }
92866 private function removeTextElement(DOMDocument $document): void
92867 {
92868 $node = (new DOMXPath($document))->query('logging/text')->item(0);
92869 if (!$node instanceof DOMElement || $node->parentNode === null) {
92870 return;
92871 }
92872 $node->parentNode->removeChild($node);
92873 }
92874 }
92875 <?php
92876
92877 declare (strict_types=1);
92878 /*
92879 * This file is part of PHPUnit.
92880 *
92881 * (c) Sebastian Bergmann <sebastian@phpunit.de>
92882 *
92883 * For the full copyright and license information, please view the LICENSE
92884 * file that was distributed with this source code.
92885 */
92886 namespace PHPUnit\TextUI\XmlConfiguration;
92887
92888 use function assert;
92889 use DOMDocument;
92890 use DOMElement;
92891 /**
92892 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
92893 *
92894 * @internal This class is not covered by the backward compatibility promise for PHPUnit
92895 */
92896 final class RemoveNoInteractionAttribute implements \PHPUnit\TextUI\XmlConfiguration\Migration
92897 {
92898 public function migrate(DOMDocument $document): void
92899 {
92900 $root = $document->documentElement;
92901 assert($root instanceof DOMElement);
92902 if ($root->hasAttribute('noInteraction')) {
92903 $root->removeAttribute('noInteraction');
92904 }
92905 }
92906 }
92907 <?php
92908
92909 declare (strict_types=1);
92910 /*
92911 * This file is part of PHPUnit.
92912 *
92913 * (c) Sebastian Bergmann <sebastian@phpunit.de>
92914 *
92915 * For the full copyright and license information, please view the LICENSE
92916 * file that was distributed with this source code.
92917 */
92918 namespace PHPUnit\TextUI\XmlConfiguration;
92919
92920 use function assert;
92921 use DOMDocument;
92922 use DOMElement;
92923 /**
92924 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
92925 *
92926 * @internal This class is not covered by the backward compatibility promise for PHPUnit
92927 */
92928 final class RemovePrinterAttributes implements \PHPUnit\TextUI\XmlConfiguration\Migration
92929 {
92930 public function migrate(DOMDocument $document): void
92931 {
92932 $root = $document->documentElement;
92933 assert($root instanceof DOMElement);
92934 if ($root->hasAttribute('printerClass')) {
92935 $root->removeAttribute('printerClass');
92936 }
92937 if ($root->hasAttribute('printerFile')) {
92938 $root->removeAttribute('printerFile');
92939 }
92940 }
92941 }
92942 <?php
92943
92944 declare (strict_types=1);
92945 /*
92946 * This file is part of PHPUnit.
92947 *
92948 * (c) Sebastian Bergmann <sebastian@phpunit.de>
92949 *
92950 * For the full copyright and license information, please view the LICENSE
92951 * file that was distributed with this source code.
92952 */
92953 namespace PHPUnit\TextUI\XmlConfiguration;
92954
92955 use DOMDocument;
92956 use DOMElement;
92957 /**
92958 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
92959 *
92960 * @internal This class is not covered by the backward compatibility promise for PHPUnit
92961 */
92962 final class RemoveTestDoxGroupsElement implements \PHPUnit\TextUI\XmlConfiguration\Migration
92963 {
92964 public function migrate(DOMDocument $document): void
92965 {
92966 $node = $document->getElementsByTagName('testdoxGroups')->item(0);
92967 if (!$node instanceof DOMElement || $node->parentNode === null) {
92968 return;
92969 }
92970 $node->parentNode->removeChild($node);
92971 }
92972 }
92973 <?php
92974
92975 declare (strict_types=1);
92976 /*
92977 * This file is part of PHPUnit.
92978 *
92979 * (c) Sebastian Bergmann <sebastian@phpunit.de>
92980 *
92981 * For the full copyright and license information, please view the LICENSE
92982 * file that was distributed with this source code.
92983 */
92984 namespace PHPUnit\TextUI\XmlConfiguration;
92985
92986 use function assert;
92987 use DOMDocument;
92988 use DOMElement;
92989 /**
92990 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
92991 *
92992 * @internal This class is not covered by the backward compatibility promise for PHPUnit
92993 */
92994 final class RemoveTestSuiteLoaderAttributes implements \PHPUnit\TextUI\XmlConfiguration\Migration
92995 {
92996 public function migrate(DOMDocument $document): void
92997 {
92998 $root = $document->documentElement;
92999 assert($root instanceof DOMElement);
93000 if ($root->hasAttribute('testSuiteLoaderClass')) {
93001 $root->removeAttribute('testSuiteLoaderClass');
93002 }
93003 if ($root->hasAttribute('testSuiteLoaderFile')) {
93004 $root->removeAttribute('testSuiteLoaderFile');
93005 }
93006 }
93007 }
93008 <?php
93009
93010 declare (strict_types=1);
93011 /*
93012 * This file is part of PHPUnit.
93013 *
93014 * (c) Sebastian Bergmann <sebastian@phpunit.de>
93015 *
93016 * For the full copyright and license information, please view the LICENSE
93017 * file that was distributed with this source code.
93018 */
93019 namespace PHPUnit\TextUI\XmlConfiguration;
93020
93021 use function assert;
93022 use DOMDocument;
93023 use DOMElement;
93024 /**
93025 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
93026 *
93027 * @internal This class is not covered by the backward compatibility promise for PHPUnit
93028 */
93029 final class RemoveVerboseAttribute implements \PHPUnit\TextUI\XmlConfiguration\Migration
93030 {
93031 public function migrate(DOMDocument $document): void
93032 {
93033 $root = $document->documentElement;
93034 assert($root instanceof DOMElement);
93035 if ($root->hasAttribute('verbose')) {
93036 $root->removeAttribute('verbose');
93037 }
93038 }
93039 }
93040 <?php
93041
93042 declare (strict_types=1);
93043 /*
93044 * This file is part of PHPUnit.
93045 *
93046 * (c) Sebastian Bergmann <sebastian@phpunit.de>
93047 *
93048 * For the full copyright and license information, please view the LICENSE
93049 * file that was distributed with this source code.
93050 */
93051 namespace PHPUnit\TextUI\XmlConfiguration;
93052
93053 use function assert;
93054 use DOMDocument;
93055 use DOMElement;
93056 /**
93057 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
93058 *
93059 * @internal This class is not covered by the backward compatibility promise for PHPUnit
93060 */
93061 final class RenameBackupStaticAttributesAttribute implements \PHPUnit\TextUI\XmlConfiguration\Migration
93062 {
93063 public function migrate(DOMDocument $document): void
93064 {
93065 $root = $document->documentElement;
93066 assert($root instanceof DOMElement);
93067 if ($root->hasAttribute('backupStaticProperties')) {
93068 return;
93069 }
93070 if (!$root->hasAttribute('backupStaticAttributes')) {
93071 return;
93072 }
93073 $root->setAttribute('backupStaticProperties', $root->getAttribute('backupStaticAttributes'));
93074 $root->removeAttribute('backupStaticAttributes');
93075 }
93076 }
93077 <?php
93078
93079 declare (strict_types=1);
93080 /*
93081 * This file is part of PHPUnit.
93082 *
93083 * (c) Sebastian Bergmann <sebastian@phpunit.de>
93084 *
93085 * For the full copyright and license information, please view the LICENSE
93086 * file that was distributed with this source code.
93087 */
93088 namespace PHPUnit\TextUI\XmlConfiguration;
93089
93090 use function assert;
93091 use DOMDocument;
93092 use DOMElement;
93093 /**
93094 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
93095 *
93096 * @internal This class is not covered by the backward compatibility promise for PHPUnit
93097 */
93098 final class RenameBeStrictAboutCoversAnnotationAttribute implements \PHPUnit\TextUI\XmlConfiguration\Migration
93099 {
93100 public function migrate(DOMDocument $document): void
93101 {
93102 $root = $document->documentElement;
93103 assert($root instanceof DOMElement);
93104 if ($root->hasAttribute('beStrictAboutCoverageMetadata')) {
93105 return;
93106 }
93107 if (!$root->hasAttribute('beStrictAboutCoversAnnotation')) {
93108 return;
93109 }
93110 $root->setAttribute('beStrictAboutCoverageMetadata', $root->getAttribute('beStrictAboutCoversAnnotation'));
93111 $root->removeAttribute('beStrictAboutCoversAnnotation');
93112 }
93113 }
93114 <?php
93115
93116 declare (strict_types=1);
93117 /*
93118 * This file is part of PHPUnit.
93119 *
93120 * (c) Sebastian Bergmann <sebastian@phpunit.de>
93121 *
93122 * For the full copyright and license information, please view the LICENSE
93123 * file that was distributed with this source code.
93124 */
93125 namespace PHPUnit\TextUI\XmlConfiguration;
93126
93127 use function assert;
93128 use DOMDocument;
93129 use DOMElement;
93130 /**
93131 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
93132 *
93133 * @internal This class is not covered by the backward compatibility promise for PHPUnit
93134 */
93135 final class RenameForceCoversAnnotationAttribute implements \PHPUnit\TextUI\XmlConfiguration\Migration
93136 {
93137 public function migrate(DOMDocument $document): void
93138 {
93139 $root = $document->documentElement;
93140 assert($root instanceof DOMElement);
93141 if ($root->hasAttribute('requireCoverageMetadata')) {
93142 return;
93143 }
93144 if (!$root->hasAttribute('forceCoversAnnotation')) {
93145 return;
93146 }
93147 $root->setAttribute('requireCoverageMetadata', $root->getAttribute('forceCoversAnnotation'));
93148 $root->removeAttribute('forceCoversAnnotation');
93149 }
93150 }
93151 <?php
93152
93153 declare (strict_types=1);
93154 /*
93155 * This file is part of PHPUnit.
93156 *
93157 * (c) Sebastian Bergmann <sebastian@phpunit.de>
93158 *
93159 * For the full copyright and license information, please view the LICENSE
93160 * file that was distributed with this source code.
93161 */
93162 namespace PHPUnit\TextUI\XmlConfiguration;
93163
93164 use function assert;
93165 use DOMDocument;
93166 use DOMElement;
93167 use PHPUnit\Runner\Version;
93168 /**
93169 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
93170 *
93171 * @internal This class is not covered by the backward compatibility promise for PHPUnit
93172 */
93173 final class UpdateSchemaLocation implements \PHPUnit\TextUI\XmlConfiguration\Migration
93174 {
93175 public function migrate(DOMDocument $document): void
93176 {
93177 $root = $document->documentElement;
93178 assert($root instanceof DOMElement);
93179 $root->setAttributeNS('http://www.w3.org/2001/XMLSchema-instance', 'xsi:noNamespaceSchemaLocation', 'https://schema.phpunit.de/' . Version::series() . '/phpunit.xsd');
93180 }
93181 }
93182 <?php
93183
93184 declare (strict_types=1);
93185 /*
93186 * This file is part of PHPUnit.
93187 *
93188 * (c) Sebastian Bergmann <sebastian@phpunit.de>
93189 *
93190 * For the full copyright and license information, please view the LICENSE
93191 * file that was distributed with this source code.
93192 */
93193 namespace PHPUnit\TextUI\XmlConfiguration;
93194
93195 use PHPUnit\Runner\Version;
93196 use PHPUnit\Util\Xml\Loader as XmlLoader;
93197 use PHPUnit\Util\Xml\XmlException;
93198 /**
93199 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
93200 *
93201 * @internal This class is not covered by the backward compatibility promise for PHPUnit
93202 */
93203 final class Migrator
93204 {
93205 /**
93206 * @throws Exception
93207 * @throws MigrationException
93208 * @throws XmlException
93209 */
93210 public function migrate(string $filename): string
93211 {
93212 $origin = (new \PHPUnit\TextUI\XmlConfiguration\SchemaDetector())->detect($filename);
93213 if (!$origin->detected()) {
93214 throw new \PHPUnit\TextUI\XmlConfiguration\Exception('The file does not validate against any known schema');
93215 }
93216 if ($origin->version() === Version::series()) {
93217 throw new \PHPUnit\TextUI\XmlConfiguration\Exception('The file does not need to be migrated');
93218 }
93219 $configurationDocument = (new XmlLoader())->loadFile($filename);
93220 foreach ((new \PHPUnit\TextUI\XmlConfiguration\MigrationBuilder())->build($origin->version()) as $migration) {
93221 $migration->migrate($configurationDocument);
93222 }
93223 $configurationDocument->formatOutput = \true;
93224 $configurationDocument->preserveWhiteSpace = \false;
93225 return $configurationDocument->saveXML();
93226 }
93227 }
93228 <?php
93229
93230 declare (strict_types=1);
93231 /*
93232 * This file is part of PHPUnit.
93233 *
93234 * (c) Sebastian Bergmann <sebastian@phpunit.de>
93235 *
93236 * For the full copyright and license information, please view the LICENSE
93237 * file that was distributed with this source code.
93238 */
93239 namespace PHPUnit\TextUI\XmlConfiguration;
93240
93241 use function count;
93242 use ArrayIterator;
93243 use Countable;
93244 use DOMNode;
93245 use DOMNodeList;
93246 use IteratorAggregate;
93247 /**
93248 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
93249 *
93250 * @internal This class is not covered by the backward compatibility promise for PHPUnit
93251 *
93252 * @template-implements IteratorAggregate<int, DOMNode>
93253 */
93254 final class SnapshotNodeList implements Countable, IteratorAggregate
93255 {
93256 /**
93257 * @psalm-var list<DOMNode>
93258 */
93259 private array $nodes = [];
93260 public static function fromNodeList(DOMNodeList $list): self
93261 {
93262 $snapshot = new self();
93263 foreach ($list as $node) {
93264 $snapshot->nodes[] = $node;
93265 }
93266 return $snapshot;
93267 }
93268 public function count(): int
93269 {
93270 return count($this->nodes);
93271 }
93272 public function getIterator(): ArrayIterator
93273 {
93274 return new ArrayIterator($this->nodes);
93275 }
93276 }
93277 <?php
93278
93279 declare (strict_types=1);
93280 /*
93281 * This file is part of PHPUnit.
93282 *
93283 * (c) Sebastian Bergmann <sebastian@phpunit.de>
93284 *
93285 * For the full copyright and license information, please view the LICENSE
93286 * file that was distributed with this source code.
93287 */
93288 namespace PHPUnit\TextUI\XmlConfiguration;
93289
93290 /**
93291 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
93292 *
93293 * @internal This class is not covered by the backward compatibility promise for PHPUnit
93294 *
93295 * @psalm-immutable
93296 */
93297 final class PHPUnit
93298 {
93299 private readonly ?string $cacheDirectory;
93300 private readonly bool $cacheResult;
93301 private readonly ?string $cacheResultFile;
93302 private readonly int|string $columns;
93303 private readonly string $colors;
93304 private readonly bool $stderr;
93305 private readonly bool $displayDetailsOnAllIssues;
93306 private readonly bool $displayDetailsOnIncompleteTests;
93307 private readonly bool $displayDetailsOnSkippedTests;
93308 private readonly bool $displayDetailsOnTestsThatTriggerDeprecations;
93309 private readonly bool $displayDetailsOnPhpunitDeprecations;
93310 private readonly bool $displayDetailsOnTestsThatTriggerErrors;
93311 private readonly bool $displayDetailsOnTestsThatTriggerNotices;
93312 private readonly bool $displayDetailsOnTestsThatTriggerWarnings;
93313 private readonly bool $reverseDefectList;
93314 private readonly bool $requireCoverageMetadata;
93315 private readonly ?string $bootstrap;
93316 private readonly bool $processIsolation;
93317 private readonly bool $failOnAllIssues;
93318 private readonly bool $failOnDeprecation;
93319 private readonly bool $failOnPhpunitDeprecation;
93320 private readonly bool $failOnPhpunitWarning;
93321 private readonly bool $failOnEmptyTestSuite;
93322 private readonly bool $failOnIncomplete;
93323 private readonly bool $failOnNotice;
93324 private readonly bool $failOnRisky;
93325 private readonly bool $failOnSkipped;
93326 private readonly bool $failOnWarning;
93327 private readonly bool $stopOnDefect;
93328 private readonly bool $stopOnDeprecation;
93329 private readonly bool $stopOnError;
93330 private readonly bool $stopOnFailure;
93331 private readonly bool $stopOnIncomplete;
93332 private readonly bool $stopOnNotice;
93333 private readonly bool $stopOnRisky;
93334 private readonly bool $stopOnSkipped;
93335 private readonly bool $stopOnWarning;
93336 /**
93337 * @psalm-var ?non-empty-string
93338 */
93339 private readonly ?string $extensionsDirectory;
93340 private readonly bool $beStrictAboutChangesToGlobalState;
93341 private readonly bool $beStrictAboutOutputDuringTests;
93342 private readonly bool $beStrictAboutTestsThatDoNotTestAnything;
93343 private readonly bool $beStrictAboutCoverageMetadata;
93344 private readonly bool $enforceTimeLimit;
93345 private readonly int $defaultTimeLimit;
93346 private readonly int $timeoutForSmallTests;
93347 private readonly int $timeoutForMediumTests;
93348 private readonly int $timeoutForLargeTests;
93349 private readonly ?string $defaultTestSuite;
93350 private readonly int $executionOrder;
93351 private readonly bool $resolveDependencies;
93352 private readonly bool $defectsFirst;
93353 private readonly bool $backupGlobals;
93354 private readonly bool $backupStaticProperties;
93355 private readonly bool $registerMockObjectsFromTestArgumentsRecursively;
93356 private readonly bool $testdoxPrinter;
93357 private readonly bool $controlGarbageCollector;
93358 private readonly int $numberOfTestsBeforeGarbageCollection;
93359 /**
93360 * @psalm-param ?non-empty-string $extensionsDirectory
93361 */
93362 public function __construct(?string $cacheDirectory, bool $cacheResult, ?string $cacheResultFile, int|string $columns, string $colors, bool $stderr, bool $displayDetailsOnAllIssues, bool $displayDetailsOnIncompleteTests, bool $displayDetailsOnSkippedTests, bool $displayDetailsOnTestsThatTriggerDeprecations, bool $displayDetailsOnPhpunitDeprecations, bool $displayDetailsOnTestsThatTriggerErrors, bool $displayDetailsOnTestsThatTriggerNotices, bool $displayDetailsOnTestsThatTriggerWarnings, bool $reverseDefectList, bool $requireCoverageMetadata, ?string $bootstrap, bool $processIsolation, bool $failOnAllIssues, bool $failOnDeprecation, bool $failOnPhpunitDeprecation, bool $failOnPhpunitWarning, 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)
93363 {
93364 $this->cacheDirectory = $cacheDirectory;
93365 $this->cacheResult = $cacheResult;
93366 $this->cacheResultFile = $cacheResultFile;
93367 $this->columns = $columns;
93368 $this->colors = $colors;
93369 $this->stderr = $stderr;
93370 $this->displayDetailsOnAllIssues = $displayDetailsOnAllIssues;
93371 $this->displayDetailsOnIncompleteTests = $displayDetailsOnIncompleteTests;
93372 $this->displayDetailsOnSkippedTests = $displayDetailsOnSkippedTests;
93373 $this->displayDetailsOnTestsThatTriggerDeprecations = $displayDetailsOnTestsThatTriggerDeprecations;
93374 $this->displayDetailsOnPhpunitDeprecations = $displayDetailsOnPhpunitDeprecations;
93375 $this->displayDetailsOnTestsThatTriggerErrors = $displayDetailsOnTestsThatTriggerErrors;
93376 $this->displayDetailsOnTestsThatTriggerNotices = $displayDetailsOnTestsThatTriggerNotices;
93377 $this->displayDetailsOnTestsThatTriggerWarnings = $displayDetailsOnTestsThatTriggerWarnings;
93378 $this->reverseDefectList = $reverseDefectList;
93379 $this->requireCoverageMetadata = $requireCoverageMetadata;
93380 $this->bootstrap = $bootstrap;
93381 $this->processIsolation = $processIsolation;
93382 $this->failOnAllIssues = $failOnAllIssues;
93383 $this->failOnDeprecation = $failOnDeprecation;
93384 $this->failOnPhpunitDeprecation = $failOnPhpunitDeprecation;
93385 $this->failOnPhpunitWarning = $failOnPhpunitWarning;
93386 $this->failOnEmptyTestSuite = $failOnEmptyTestSuite;
93387 $this->failOnIncomplete = $failOnIncomplete;
93388 $this->failOnNotice = $failOnNotice;
93389 $this->failOnRisky = $failOnRisky;
93390 $this->failOnSkipped = $failOnSkipped;
93391 $this->failOnWarning = $failOnWarning;
93392 $this->stopOnDefect = $stopOnDefect;
93393 $this->stopOnDeprecation = $stopOnDeprecation;
93394 $this->stopOnError = $stopOnError;
93395 $this->stopOnFailure = $stopOnFailure;
93396 $this->stopOnIncomplete = $stopOnIncomplete;
93397 $this->stopOnNotice = $stopOnNotice;
93398 $this->stopOnRisky = $stopOnRisky;
93399 $this->stopOnSkipped = $stopOnSkipped;
93400 $this->stopOnWarning = $stopOnWarning;
93401 $this->extensionsDirectory = $extensionsDirectory;
93402 $this->beStrictAboutChangesToGlobalState = $beStrictAboutChangesToGlobalState;
93403 $this->beStrictAboutOutputDuringTests = $beStrictAboutOutputDuringTests;
93404 $this->beStrictAboutTestsThatDoNotTestAnything = $beStrictAboutTestsThatDoNotTestAnything;
93405 $this->beStrictAboutCoverageMetadata = $beStrictAboutCoverageMetadata;
93406 $this->enforceTimeLimit = $enforceTimeLimit;
93407 $this->defaultTimeLimit = $defaultTimeLimit;
93408 $this->timeoutForSmallTests = $timeoutForSmallTests;
93409 $this->timeoutForMediumTests = $timeoutForMediumTests;
93410 $this->timeoutForLargeTests = $timeoutForLargeTests;
93411 $this->defaultTestSuite = $defaultTestSuite;
93412 $this->executionOrder = $executionOrder;
93413 $this->resolveDependencies = $resolveDependencies;
93414 $this->defectsFirst = $defectsFirst;
93415 $this->backupGlobals = $backupGlobals;
93416 $this->backupStaticProperties = $backupStaticProperties;
93417 $this->registerMockObjectsFromTestArgumentsRecursively = $registerMockObjectsFromTestArgumentsRecursively;
93418 $this->testdoxPrinter = $testdoxPrinter;
93419 $this->controlGarbageCollector = $controlGarbageCollector;
93420 $this->numberOfTestsBeforeGarbageCollection = $numberOfTestsBeforeGarbageCollection;
93421 }
93422 /**
93423 * @psalm-assert-if-true !null $this->cacheDirectory
93424 */
93425 public function hasCacheDirectory(): bool
93426 {
93427 return $this->cacheDirectory !== null;
93428 }
93429 /**
93430 * @throws Exception
93431 */
93432 public function cacheDirectory(): string
93433 {
93434 if (!$this->hasCacheDirectory()) {
93435 throw new \PHPUnit\TextUI\XmlConfiguration\Exception('Cache directory is not configured');
93436 }
93437 return $this->cacheDirectory;
93438 }
93439 public function cacheResult(): bool
93440 {
93441 return $this->cacheResult;
93442 }
93443 /**
93444 * @psalm-assert-if-true !null $this->cacheResultFile
93445 *
93446 * @deprecated
93447 */
93448 public function hasCacheResultFile(): bool
93449 {
93450 return $this->cacheResultFile !== null;
93451 }
93452 /**
93453 * @throws Exception
93454 *
93455 * @deprecated
93456 */
93457 public function cacheResultFile(): string
93458 {
93459 if (!$this->hasCacheResultFile()) {
93460 throw new \PHPUnit\TextUI\XmlConfiguration\Exception('Cache result file is not configured');
93461 }
93462 return $this->cacheResultFile;
93463 }
93464 public function columns(): int|string
93465 {
93466 return $this->columns;
93467 }
93468 public function colors(): string
93469 {
93470 return $this->colors;
93471 }
93472 public function stderr(): bool
93473 {
93474 return $this->stderr;
93475 }
93476 public function displayDetailsOnAllIssues(): bool
93477 {
93478 return $this->displayDetailsOnAllIssues;
93479 }
93480 public function displayDetailsOnIncompleteTests(): bool
93481 {
93482 return $this->displayDetailsOnIncompleteTests;
93483 }
93484 public function displayDetailsOnSkippedTests(): bool
93485 {
93486 return $this->displayDetailsOnSkippedTests;
93487 }
93488 public function displayDetailsOnTestsThatTriggerDeprecations(): bool
93489 {
93490 return $this->displayDetailsOnTestsThatTriggerDeprecations;
93491 }
93492 public function displayDetailsOnPhpunitDeprecations(): bool
93493 {
93494 return $this->displayDetailsOnPhpunitDeprecations;
93495 }
93496 public function displayDetailsOnTestsThatTriggerErrors(): bool
93497 {
93498 return $this->displayDetailsOnTestsThatTriggerErrors;
93499 }
93500 public function displayDetailsOnTestsThatTriggerNotices(): bool
93501 {
93502 return $this->displayDetailsOnTestsThatTriggerNotices;
93503 }
93504 public function displayDetailsOnTestsThatTriggerWarnings(): bool
93505 {
93506 return $this->displayDetailsOnTestsThatTriggerWarnings;
93507 }
93508 public function reverseDefectList(): bool
93509 {
93510 return $this->reverseDefectList;
93511 }
93512 public function requireCoverageMetadata(): bool
93513 {
93514 return $this->requireCoverageMetadata;
93515 }
93516 /**
93517 * @psalm-assert-if-true !null $this->bootstrap
93518 */
93519 public function hasBootstrap(): bool
93520 {
93521 return $this->bootstrap !== null;
93522 }
93523 /**
93524 * @throws Exception
93525 */
93526 public function bootstrap(): string
93527 {
93528 if (!$this->hasBootstrap()) {
93529 throw new \PHPUnit\TextUI\XmlConfiguration\Exception('Bootstrap script is not configured');
93530 }
93531 return $this->bootstrap;
93532 }
93533 public function processIsolation(): bool
93534 {
93535 return $this->processIsolation;
93536 }
93537 public function failOnAllIssues(): bool
93538 {
93539 return $this->failOnAllIssues;
93540 }
93541 public function failOnDeprecation(): bool
93542 {
93543 return $this->failOnDeprecation;
93544 }
93545 public function failOnPhpunitDeprecation(): bool
93546 {
93547 return $this->failOnPhpunitDeprecation;
93548 }
93549 public function failOnPhpunitWarning(): bool
93550 {
93551 return $this->failOnPhpunitWarning;
93552 }
93553 public function failOnEmptyTestSuite(): bool
93554 {
93555 return $this->failOnEmptyTestSuite;
93556 }
93557 public function failOnIncomplete(): bool
93558 {
93559 return $this->failOnIncomplete;
93560 }
93561 public function failOnNotice(): bool
93562 {
93563 return $this->failOnNotice;
93564 }
93565 public function failOnRisky(): bool
93566 {
93567 return $this->failOnRisky;
93568 }
93569 public function failOnSkipped(): bool
93570 {
93571 return $this->failOnSkipped;
93572 }
93573 public function failOnWarning(): bool
93574 {
93575 return $this->failOnWarning;
93576 }
93577 public function stopOnDefect(): bool
93578 {
93579 return $this->stopOnDefect;
93580 }
93581 public function stopOnDeprecation(): bool
93582 {
93583 return $this->stopOnDeprecation;
93584 }
93585 public function stopOnError(): bool
93586 {
93587 return $this->stopOnError;
93588 }
93589 public function stopOnFailure(): bool
93590 {
93591 return $this->stopOnFailure;
93592 }
93593 public function stopOnIncomplete(): bool
93594 {
93595 return $this->stopOnIncomplete;
93596 }
93597 public function stopOnNotice(): bool
93598 {
93599 return $this->stopOnNotice;
93600 }
93601 public function stopOnRisky(): bool
93602 {
93603 return $this->stopOnRisky;
93604 }
93605 public function stopOnSkipped(): bool
93606 {
93607 return $this->stopOnSkipped;
93608 }
93609 public function stopOnWarning(): bool
93610 {
93611 return $this->stopOnWarning;
93612 }
93613 /**
93614 * @psalm-assert-if-true !null $this->extensionsDirectory
93615 */
93616 public function hasExtensionsDirectory(): bool
93617 {
93618 return $this->extensionsDirectory !== null;
93619 }
93620 /**
93621 * @throws Exception
93622 *
93623 * @psalm-return non-empty-string
93624 */
93625 public function extensionsDirectory(): string
93626 {
93627 if (!$this->hasExtensionsDirectory()) {
93628 throw new \PHPUnit\TextUI\XmlConfiguration\Exception('Extensions directory is not configured');
93629 }
93630 return $this->extensionsDirectory;
93631 }
93632 public function beStrictAboutChangesToGlobalState(): bool
93633 {
93634 return $this->beStrictAboutChangesToGlobalState;
93635 }
93636 public function beStrictAboutOutputDuringTests(): bool
93637 {
93638 return $this->beStrictAboutOutputDuringTests;
93639 }
93640 public function beStrictAboutTestsThatDoNotTestAnything(): bool
93641 {
93642 return $this->beStrictAboutTestsThatDoNotTestAnything;
93643 }
93644 public function beStrictAboutCoverageMetadata(): bool
93645 {
93646 return $this->beStrictAboutCoverageMetadata;
93647 }
93648 public function enforceTimeLimit(): bool
93649 {
93650 return $this->enforceTimeLimit;
93651 }
93652 public function defaultTimeLimit(): int
93653 {
93654 return $this->defaultTimeLimit;
93655 }
93656 public function timeoutForSmallTests(): int
93657 {
93658 return $this->timeoutForSmallTests;
93659 }
93660 public function timeoutForMediumTests(): int
93661 {
93662 return $this->timeoutForMediumTests;
93663 }
93664 public function timeoutForLargeTests(): int
93665 {
93666 return $this->timeoutForLargeTests;
93667 }
93668 /**
93669 * @psalm-assert-if-true !null $this->defaultTestSuite
93670 */
93671 public function hasDefaultTestSuite(): bool
93672 {
93673 return $this->defaultTestSuite !== null;
93674 }
93675 /**
93676 * @throws Exception
93677 */
93678 public function defaultTestSuite(): string
93679 {
93680 if (!$this->hasDefaultTestSuite()) {
93681 throw new \PHPUnit\TextUI\XmlConfiguration\Exception('Default test suite is not configured');
93682 }
93683 return $this->defaultTestSuite;
93684 }
93685 public function executionOrder(): int
93686 {
93687 return $this->executionOrder;
93688 }
93689 public function resolveDependencies(): bool
93690 {
93691 return $this->resolveDependencies;
93692 }
93693 public function defectsFirst(): bool
93694 {
93695 return $this->defectsFirst;
93696 }
93697 public function backupGlobals(): bool
93698 {
93699 return $this->backupGlobals;
93700 }
93701 public function backupStaticProperties(): bool
93702 {
93703 return $this->backupStaticProperties;
93704 }
93705 /**
93706 * @deprecated
93707 */
93708 public function registerMockObjectsFromTestArgumentsRecursively(): bool
93709 {
93710 return $this->registerMockObjectsFromTestArgumentsRecursively;
93711 }
93712 public function testdoxPrinter(): bool
93713 {
93714 return $this->testdoxPrinter;
93715 }
93716 public function controlGarbageCollector(): bool
93717 {
93718 return $this->controlGarbageCollector;
93719 }
93720 public function numberOfTestsBeforeGarbageCollection(): int
93721 {
93722 return $this->numberOfTestsBeforeGarbageCollection;
93723 }
93724 }
93725 <?php
93726
93727 declare (strict_types=1);
93728 /*
93729 * This file is part of PHPUnit.
93730 *
93731 * (c) Sebastian Bergmann <sebastian@phpunit.de>
93732 *
93733 * For the full copyright and license information, please view the LICENSE
93734 * file that was distributed with this source code.
93735 */
93736 namespace PHPUnit\TextUI\XmlConfiguration;
93737
93738 /**
93739 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
93740 *
93741 * @internal This class is not covered by the backward compatibility promise for PHPUnit
93742 *
93743 * @psalm-immutable
93744 */
93745 final class FailedSchemaDetectionResult extends \PHPUnit\TextUI\XmlConfiguration\SchemaDetectionResult
93746 {
93747 }
93748 <?php
93749
93750 declare (strict_types=1);
93751 /*
93752 * This file is part of PHPUnit.
93753 *
93754 * (c) Sebastian Bergmann <sebastian@phpunit.de>
93755 *
93756 * For the full copyright and license information, please view the LICENSE
93757 * file that was distributed with this source code.
93758 */
93759 namespace PHPUnit\TextUI\XmlConfiguration;
93760
93761 use PHPUnit\Util\Xml\XmlException;
93762 /**
93763 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
93764 *
93765 * @internal This class is not covered by the backward compatibility promise for PHPUnit
93766 *
93767 * @psalm-immutable
93768 */
93769 abstract class SchemaDetectionResult
93770 {
93771 /**
93772 * @psalm-assert-if-true SuccessfulSchemaDetectionResult $this
93773 */
93774 public function detected(): bool
93775 {
93776 return \false;
93777 }
93778 /**
93779 * @throws XmlException
93780 */
93781 public function version(): string
93782 {
93783 throw new XmlException('No supported schema was detected');
93784 }
93785 }
93786 <?php
93787
93788 declare (strict_types=1);
93789 /*
93790 * This file is part of PHPUnit.
93791 *
93792 * (c) Sebastian Bergmann <sebastian@phpunit.de>
93793 *
93794 * For the full copyright and license information, please view the LICENSE
93795 * file that was distributed with this source code.
93796 */
93797 namespace PHPUnit\TextUI\XmlConfiguration;
93798
93799 use PHPUnit\Util\Xml\Loader;
93800 use PHPUnit\Util\Xml\XmlException;
93801 /**
93802 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
93803 *
93804 * @internal This class is not covered by the backward compatibility promise for PHPUnit
93805 */
93806 final class SchemaDetector
93807 {
93808 /**
93809 * @throws XmlException
93810 */
93811 public function detect(string $filename): \PHPUnit\TextUI\XmlConfiguration\SchemaDetectionResult
93812 {
93813 $document = (new Loader())->loadFile($filename);
93814 $schemaFinder = new \PHPUnit\TextUI\XmlConfiguration\SchemaFinder();
93815 foreach ($schemaFinder->available() as $candidate) {
93816 $schema = (new \PHPUnit\TextUI\XmlConfiguration\SchemaFinder())->find($candidate);
93817 if (!(new \PHPUnit\TextUI\XmlConfiguration\Validator())->validate($document, $schema)->hasValidationErrors()) {
93818 return new \PHPUnit\TextUI\XmlConfiguration\SuccessfulSchemaDetectionResult($candidate);
93819 }
93820 }
93821 return new \PHPUnit\TextUI\XmlConfiguration\FailedSchemaDetectionResult();
93822 }
93823 }
93824 <?php
93825
93826 declare (strict_types=1);
93827 /*
93828 * This file is part of PHPUnit.
93829 *
93830 * (c) Sebastian Bergmann <sebastian@phpunit.de>
93831 *
93832 * For the full copyright and license information, please view the LICENSE
93833 * file that was distributed with this source code.
93834 */
93835 namespace PHPUnit\TextUI\XmlConfiguration;
93836
93837 /**
93838 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
93839 *
93840 * @internal This class is not covered by the backward compatibility promise for PHPUnit
93841 *
93842 * @psalm-immutable
93843 */
93844 final class SuccessfulSchemaDetectionResult extends \PHPUnit\TextUI\XmlConfiguration\SchemaDetectionResult
93845 {
93846 /**
93847 * @psalm-var non-empty-string
93848 */
93849 private readonly string $version;
93850 /**
93851 * @psalm-param non-empty-string $version
93852 */
93853 public function __construct(string $version)
93854 {
93855 $this->version = $version;
93856 }
93857 /**
93858 * @psalm-assert-if-true SuccessfulSchemaDetectionResult $this
93859 */
93860 public function detected(): bool
93861 {
93862 return \true;
93863 }
93864 /**
93865 * @psalm-return non-empty-string
93866 */
93867 public function version(): string
93868 {
93869 return $this->version;
93870 }
93871 }
93872 <?php
93873
93874 declare (strict_types=1);
93875 /*
93876 * This file is part of PHPUnit.
93877 *
93878 * (c) Sebastian Bergmann <sebastian@phpunit.de>
93879 *
93880 * For the full copyright and license information, please view the LICENSE
93881 * file that was distributed with this source code.
93882 */
93883 namespace PHPUnit\TextUI\XmlConfiguration;
93884
93885 use function assert;
93886 use function defined;
93887 use function is_file;
93888 use function rsort;
93889 use function sprintf;
93890 use DirectoryIterator;
93891 use PHPUnit\Runner\Version;
93892 /**
93893 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
93894 *
93895 * @internal This class is not covered by the backward compatibility promise for PHPUnit
93896 */
93897 final class SchemaFinder
93898 {
93899 /**
93900 * @psalm-return non-empty-list<non-empty-string>
93901 */
93902 public function available(): array
93903 {
93904 $result = [Version::series()];
93905 foreach (new DirectoryIterator($this->path() . 'schema') as $file) {
93906 if ($file->isDot()) {
93907 continue;
93908 }
93909 $version = $file->getBasename('.xsd');
93910 assert(!empty($version));
93911 $result[] = $version;
93912 }
93913 rsort($result);
93914 return $result;
93915 }
93916 /**
93917 * @throws CannotFindSchemaException
93918 */
93919 public function find(string $version): string
93920 {
93921 if ($version === Version::series()) {
93922 $filename = $this->path() . 'phpunit.xsd';
93923 } else {
93924 $filename = $this->path() . 'schema/' . $version . '.xsd';
93925 }
93926 if (!is_file($filename)) {
93927 throw new \PHPUnit\TextUI\XmlConfiguration\CannotFindSchemaException(sprintf('Schema for PHPUnit %s is not available', $version));
93928 }
93929 return $filename;
93930 }
93931 private function path(): string
93932 {
93933 if (defined('__PHPUNIT_PHAR_ROOT__')) {
93934 return __PHPUNIT_PHAR_ROOT__ . '/';
93935 }
93936 return __DIR__ . '/../../../../';
93937 }
93938 }
93939 <?php
93940
93941 declare (strict_types=1);
93942 /*
93943 * This file is part of PHPUnit.
93944 *
93945 * (c) Sebastian Bergmann <sebastian@phpunit.de>
93946 *
93947 * For the full copyright and license information, please view the LICENSE
93948 * file that was distributed with this source code.
93949 */
93950 namespace PHPUnit\TextUI\XmlConfiguration;
93951
93952 use const PHP_VERSION;
93953 use function array_merge;
93954 use function array_unique;
93955 use function explode;
93956 use function in_array;
93957 use function is_dir;
93958 use function is_file;
93959 use function str_contains;
93960 use function version_compare;
93961 use PHPUnit\Framework\Exception as FrameworkException;
93962 use PHPUnit\Framework\TestSuite as TestSuiteObject;
93963 use PHPUnit\TextUI\Configuration\TestSuiteCollection;
93964 use PHPUnit\TextUI\RuntimeException;
93965 use PHPUnit\TextUI\TestDirectoryNotFoundException;
93966 use PHPUnit\TextUI\TestFileNotFoundException;
93967 use PHPUnitPHAR\SebastianBergmann\FileIterator\Facade;
93968 /**
93969 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
93970 *
93971 * @internal This class is not covered by the backward compatibility promise for PHPUnit
93972 */
93973 final class TestSuiteMapper
93974 {
93975 /**
93976 * @psalm-param non-empty-string $xmlConfigurationFile,
93977 *
93978 * @throws RuntimeException
93979 * @throws TestDirectoryNotFoundException
93980 * @throws TestFileNotFoundException
93981 */
93982 public function map(string $xmlConfigurationFile, TestSuiteCollection $configuration, string $filter, string $excludedTestSuites): TestSuiteObject
93983 {
93984 try {
93985 $filterAsArray = $filter ? explode(',', $filter) : [];
93986 $excludedFilterAsArray = $excludedTestSuites ? explode(',', $excludedTestSuites) : [];
93987 $result = TestSuiteObject::empty($xmlConfigurationFile);
93988 foreach ($configuration as $testSuiteConfiguration) {
93989 if (!empty($filterAsArray) && !in_array($testSuiteConfiguration->name(), $filterAsArray, \true)) {
93990 continue;
93991 }
93992 if (!empty($excludedFilterAsArray) && in_array($testSuiteConfiguration->name(), $excludedFilterAsArray, \true)) {
93993 continue;
93994 }
93995 $exclude = [];
93996 foreach ($testSuiteConfiguration->exclude()->asArray() as $file) {
93997 $exclude[] = $file->path();
93998 }
93999 $files = [];
94000 foreach ($testSuiteConfiguration->directories() as $directory) {
94001 if (!str_contains($directory->path(), '*') && !is_dir($directory->path())) {
94002 throw new TestDirectoryNotFoundException($directory->path());
94003 }
94004 if (!version_compare(PHP_VERSION, $directory->phpVersion(), $directory->phpVersionOperator()->asString())) {
94005 continue;
94006 }
94007 $files = array_merge($files, (new Facade())->getFilesAsArray($directory->path(), $directory->suffix(), $directory->prefix(), $exclude));
94008 }
94009 foreach ($testSuiteConfiguration->files() as $file) {
94010 if (!is_file($file->path())) {
94011 throw new TestFileNotFoundException($file->path());
94012 }
94013 if (!version_compare(PHP_VERSION, $file->phpVersion(), $file->phpVersionOperator()->asString())) {
94014 continue;
94015 }
94016 $files[] = $file->path();
94017 }
94018 if (!empty($files)) {
94019 $testSuite = TestSuiteObject::empty($testSuiteConfiguration->name());
94020 $testSuite->addTestFiles(array_unique($files));
94021 $result->addTest($testSuite);
94022 }
94023 }
94024 return $result;
94025 } catch (FrameworkException $e) {
94026 throw new RuntimeException($e->getMessage(), $e->getCode(), $e);
94027 }
94028 }
94029 }
94030 <?php
94031
94032 declare (strict_types=1);
94033 /*
94034 * This file is part of PHPUnit.
94035 *
94036 * (c) Sebastian Bergmann <sebastian@phpunit.de>
94037 *
94038 * For the full copyright and license information, please view the LICENSE
94039 * file that was distributed with this source code.
94040 */
94041 namespace PHPUnit\TextUI\XmlConfiguration;
94042
94043 use const PHP_EOL;
94044 use function sprintf;
94045 use function trim;
94046 use LibXMLError;
94047 /**
94048 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
94049 *
94050 * @internal This class is not covered by the backward compatibility promise for PHPUnit
94051 *
94052 * @psalm-immutable
94053 */
94054 final class ValidationResult
94055 {
94056 /**
94057 * @psalm-var array<int,list<string>>
94058 */
94059 private readonly array $validationErrors;
94060 /**
94061 * @psalm-param array<int,LibXMLError> $errors
94062 */
94063 public static function fromArray(array $errors): self
94064 {
94065 $validationErrors = [];
94066 foreach ($errors as $error) {
94067 if (!isset($validationErrors[$error->line])) {
94068 $validationErrors[$error->line] = [];
94069 }
94070 $validationErrors[$error->line][] = trim($error->message);
94071 }
94072 return new self($validationErrors);
94073 }
94074 private function __construct(array $validationErrors)
94075 {
94076 $this->validationErrors = $validationErrors;
94077 }
94078 public function hasValidationErrors(): bool
94079 {
94080 return !empty($this->validationErrors);
94081 }
94082 public function asString(): string
94083 {
94084 $buffer = '';
94085 foreach ($this->validationErrors as $line => $validationErrorsOnLine) {
94086 $buffer .= sprintf(PHP_EOL . ' Line %d:' . PHP_EOL, $line);
94087 foreach ($validationErrorsOnLine as $validationError) {
94088 $buffer .= sprintf(' - %s' . PHP_EOL, $validationError);
94089 }
94090 }
94091 return $buffer;
94092 }
94093 }
94094 <?php
94095
94096 declare (strict_types=1);
94097 /*
94098 * This file is part of PHPUnit.
94099 *
94100 * (c) Sebastian Bergmann <sebastian@phpunit.de>
94101 *
94102 * For the full copyright and license information, please view the LICENSE
94103 * file that was distributed with this source code.
94104 */
94105 namespace PHPUnit\TextUI\XmlConfiguration;
94106
94107 use function file_get_contents;
94108 use function libxml_clear_errors;
94109 use function libxml_get_errors;
94110 use function libxml_use_internal_errors;
94111 use DOMDocument;
94112 /**
94113 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
94114 *
94115 * @internal This class is not covered by the backward compatibility promise for PHPUnit
94116 */
94117 final class Validator
94118 {
94119 public function validate(DOMDocument $document, string $xsdFilename): \PHPUnit\TextUI\XmlConfiguration\ValidationResult
94120 {
94121 $originalErrorHandling = libxml_use_internal_errors(\true);
94122 $document->schemaValidateSource(file_get_contents($xsdFilename));
94123 $errors = libxml_get_errors();
94124 libxml_clear_errors();
94125 libxml_use_internal_errors($originalErrorHandling);
94126 return \PHPUnit\TextUI\XmlConfiguration\ValidationResult::fromArray($errors);
94127 }
94128 }
94129 <?php
94130
94131 declare (strict_types=1);
94132 /*
94133 * This file is part of PHPUnit.
94134 *
94135 * (c) Sebastian Bergmann <sebastian@phpunit.de>
94136 *
94137 * For the full copyright and license information, please view the LICENSE
94138 * file that was distributed with this source code.
94139 */
94140 namespace PHPUnit\TextUI;
94141
94142 use function sprintf;
94143 use RuntimeException;
94144 /**
94145 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
94146 *
94147 * @internal This class is not covered by the backward compatibility promise for PHPUnit
94148 */
94149 final class CannotOpenSocketException extends RuntimeException implements \PHPUnit\TextUI\Exception
94150 {
94151 public function __construct(string $hostname, int $port)
94152 {
94153 parent::__construct(sprintf('Cannot open socket %s:%d', $hostname, $port));
94154 }
94155 }
94156 <?php
94157
94158 declare (strict_types=1);
94159 /*
94160 * This file is part of PHPUnit.
94161 *
94162 * (c) Sebastian Bergmann <sebastian@phpunit.de>
94163 *
94164 * For the full copyright and license information, please view the LICENSE
94165 * file that was distributed with this source code.
94166 */
94167 namespace PHPUnit\TextUI;
94168
94169 use Throwable;
94170 /**
94171 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
94172 *
94173 * @internal This interface is not covered by the backward compatibility promise for PHPUnit
94174 */
94175 interface Exception extends Throwable
94176 {
94177 }
94178 <?php
94179
94180 declare (strict_types=1);
94181 /*
94182 * This file is part of PHPUnit.
94183 *
94184 * (c) Sebastian Bergmann <sebastian@phpunit.de>
94185 *
94186 * For the full copyright and license information, please view the LICENSE
94187 * file that was distributed with this source code.
94188 */
94189 namespace PHPUnit\TextUI;
94190
94191 use function sprintf;
94192 use RuntimeException;
94193 /**
94194 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
94195 *
94196 * @internal This class is not covered by the backward compatibility promise for PHPUnit
94197 */
94198 final class InvalidSocketException extends RuntimeException implements \PHPUnit\TextUI\Exception
94199 {
94200 public function __construct(string $socket)
94201 {
94202 parent::__construct(sprintf('"%s" does not match "socket://hostname:port" format', $socket));
94203 }
94204 }
94205 <?php
94206
94207 declare (strict_types=1);
94208 /*
94209 * This file is part of PHPUnit.
94210 *
94211 * (c) Sebastian Bergmann <sebastian@phpunit.de>
94212 *
94213 * For the full copyright and license information, please view the LICENSE
94214 * file that was distributed with this source code.
94215 */
94216 namespace PHPUnit\TextUI;
94217
94218 /**
94219 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
94220 *
94221 * @internal This class is not covered by the backward compatibility promise for PHPUnit
94222 */
94223 final class RuntimeException extends \RuntimeException implements \PHPUnit\TextUI\Exception
94224 {
94225 }
94226 <?php
94227
94228 declare (strict_types=1);
94229 /*
94230 * This file is part of PHPUnit.
94231 *
94232 * (c) Sebastian Bergmann <sebastian@phpunit.de>
94233 *
94234 * For the full copyright and license information, please view the LICENSE
94235 * file that was distributed with this source code.
94236 */
94237 namespace PHPUnit\TextUI;
94238
94239 use function sprintf;
94240 use RuntimeException;
94241 /**
94242 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
94243 *
94244 * @internal This class is not covered by the backward compatibility promise for PHPUnit
94245 */
94246 final class TestDirectoryNotFoundException extends RuntimeException implements \PHPUnit\TextUI\Exception
94247 {
94248 public function __construct(string $path)
94249 {
94250 parent::__construct(sprintf('Test directory "%s" not found', $path));
94251 }
94252 }
94253 <?php
94254
94255 declare (strict_types=1);
94256 /*
94257 * This file is part of PHPUnit.
94258 *
94259 * (c) Sebastian Bergmann <sebastian@phpunit.de>
94260 *
94261 * For the full copyright and license information, please view the LICENSE
94262 * file that was distributed with this source code.
94263 */
94264 namespace PHPUnit\TextUI;
94265
94266 use function sprintf;
94267 use RuntimeException;
94268 /**
94269 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
94270 *
94271 * @internal This class is not covered by the backward compatibility promise for PHPUnit
94272 */
94273 final class TestFileNotFoundException extends RuntimeException implements \PHPUnit\TextUI\Exception
94274 {
94275 public function __construct(string $path)
94276 {
94277 parent::__construct(sprintf('Test file "%s" not found', $path));
94278 }
94279 }
94280 <?php
94281
94282 declare (strict_types=1);
94283 /*
94284 * This file is part of PHPUnit.
94285 *
94286 * (c) Sebastian Bergmann <sebastian@phpunit.de>
94287 *
94288 * For the full copyright and license information, please view the LICENSE
94289 * file that was distributed with this source code.
94290 */
94291 namespace PHPUnit\TextUI;
94292
94293 use const PHP_EOL;
94294 use function count;
94295 use function defined;
94296 use function explode;
94297 use function max;
94298 use function preg_replace_callback;
94299 use function str_pad;
94300 use function str_repeat;
94301 use function strlen;
94302 use function wordwrap;
94303 use PHPUnit\Util\Color;
94304 use PHPUnitPHAR\SebastianBergmann\Environment\Console;
94305 /**
94306 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
94307 *
94308 * @internal This class is not covered by the backward compatibility promise for PHPUnit
94309 */
94310 final class Help
94311 {
94312 private const LEFT_MARGIN = ' ';
94313 private int $lengthOfLongestOptionName = 0;
94314 private readonly int $columnsAvailableForDescription;
94315 private ?bool $hasColor;
94316 public function __construct(?int $width = null, ?bool $withColor = null)
94317 {
94318 if ($width === null) {
94319 $width = (new Console())->getNumberOfColumns();
94320 }
94321 if ($withColor === null) {
94322 $this->hasColor = (new Console())->hasColorSupport();
94323 } else {
94324 $this->hasColor = $withColor;
94325 }
94326 foreach ($this->elements() as $options) {
94327 foreach ($options as $option) {
94328 if (isset($option['arg'])) {
94329 $this->lengthOfLongestOptionName = max($this->lengthOfLongestOptionName, strlen($option['arg']));
94330 }
94331 }
94332 }
94333 $this->columnsAvailableForDescription = $width - $this->lengthOfLongestOptionName - 4;
94334 }
94335 public function generate(): string
94336 {
94337 if ($this->hasColor) {
94338 return $this->writeWithColor();
94339 }
94340 return $this->writeWithoutColor();
94341 }
94342 private function writeWithoutColor(): string
94343 {
94344 $buffer = '';
94345 foreach ($this->elements() as $section => $options) {
94346 $buffer .= "{$section}:" . PHP_EOL;
94347 if ($section !== 'Usage') {
94348 $buffer .= PHP_EOL;
94349 }
94350 foreach ($options as $option) {
94351 if (isset($option['spacer'])) {
94352 $buffer .= PHP_EOL;
94353 }
94354 if (isset($option['text'])) {
94355 $buffer .= self::LEFT_MARGIN . $option['text'] . PHP_EOL;
94356 }
94357 if (isset($option['arg'])) {
94358 $arg = str_pad($option['arg'], $this->lengthOfLongestOptionName);
94359 $buffer .= self::LEFT_MARGIN . $arg . ' ' . $option['desc'] . PHP_EOL;
94360 }
94361 }
94362 $buffer .= PHP_EOL;
94363 }
94364 return $buffer;
94365 }
94366 private function writeWithColor(): string
94367 {
94368 $buffer = '';
94369 foreach ($this->elements() as $section => $options) {
94370 $buffer .= Color::colorize('fg-yellow', "{$section}:") . PHP_EOL;
94371 if ($section !== 'Usage') {
94372 $buffer .= PHP_EOL;
94373 }
94374 foreach ($options as $option) {
94375 if (isset($option['spacer'])) {
94376 $buffer .= PHP_EOL;
94377 }
94378 if (isset($option['text'])) {
94379 $buffer .= self::LEFT_MARGIN . $option['text'] . PHP_EOL;
94380 }
94381 if (isset($option['arg'])) {
94382 $arg = Color::colorize('fg-green', str_pad($option['arg'], $this->lengthOfLongestOptionName));
94383 $arg = preg_replace_callback('/(<[^>]+>)/', static fn($matches) => Color::colorize('fg-cyan', $matches[0]), $arg);
94384 $desc = explode(PHP_EOL, wordwrap($option['desc'], $this->columnsAvailableForDescription, PHP_EOL));
94385 $buffer .= self::LEFT_MARGIN . $arg . ' ' . $desc[0] . PHP_EOL;
94386 for ($i = 1; $i < count($desc); $i++) {
94387 $buffer .= str_repeat(' ', $this->lengthOfLongestOptionName + 3) . $desc[$i] . PHP_EOL;
94388 }
94389 }
94390 }
94391 $buffer .= PHP_EOL;
94392 }
94393 return $buffer;
94394 }
94395 /**
94396 * @psalm-return array<non-empty-string, non-empty-list<array{text: non-empty-string}|array{arg: non-empty-string, desc: non-empty-string}|array{spacer: ''}>>
94397 */
94398 private function elements(): array
94399 {
94400 $elements = ['Usage' => [['text' => 'phpunit [options] <directory|file> ...']], 'Configuration' => [['arg' => '--bootstrap <file>', 'desc' => 'A PHP script that is included before the tests run'], ['arg' => '-c|--configuration <file>', '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 <path(s)>', 'desc' => 'Prepend PHP\'s include_path with given path(s)'], ['arg' => '-d <key[=value]>', 'desc' => 'Sets a php.ini value'], ['arg' => '--cache-directory <dir>', '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 <file>', 'desc' => 'Generate baseline for issues'], ['arg' => '--use-baseline <file>', '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 <name>', 'desc' => 'Only run tests from the specified test suite(s)'], ['arg' => '--exclude-testsuite <name>', 'desc' => 'Exclude tests from the specified test suite(s)'], ['arg' => '--list-groups', 'desc' => 'List available test groups'], ['arg' => '--group <name>', 'desc' => 'Only run tests from the specified group(s)'], ['arg' => '--exclude-group <name>', 'desc' => 'Exclude tests from the specified group(s)'], ['arg' => '--covers <name>', 'desc' => 'Only run tests that intend to cover <name>'], ['arg' => '--uses <name>', 'desc' => 'Only run tests that intend to use <name>'], ['arg' => '--list-tests', 'desc' => 'List available tests'], ['arg' => '--list-tests-xml <file>', 'desc' => 'List available tests in XML format'], ['arg' => '--filter <pattern>', 'desc' => 'Filter which tests to run'], ['arg' => '--test-suffix <suffixes>', '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 <sec>', 'desc' => 'Timeout in seconds for tests that have no declared size'], ['arg' => '--do-not-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-empty-test-suite', 'desc' => 'Signal failure using shell exit code when no tests were run'], ['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-phpunit-deprecation', 'desc' => 'Signal failure using shell exit code when a PHPUnit deprecation was triggered'], ['arg' => '--fail-on-phpunit-warning', 'desc' => 'Signal failure using shell exit code when a PHPUnit warning 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'], ['arg' => '--fail-on-all-issues', 'desc' => 'Signal failure using shell exit code when an issue is triggered'], ['spacer' => ''], ['arg' => '--do-not-fail-on-empty-test-suite', 'desc' => 'Do not signal failure using shell exit code when no tests were run'], ['arg' => '--do-not-fail-on-warning', 'desc' => 'Do not signal failure using shell exit code when a warning was triggered'], ['arg' => '--do-not-fail-on-risky', 'desc' => 'Do not signal failure using shell exit code when a test was considered risky'], ['arg' => '--do-not-fail-on-deprecation', 'desc' => 'Do not signal failure using shell exit code when a deprecation was triggered'], ['arg' => '--do-not-fail-on-phpunit-deprecation', 'desc' => 'Do not signal failure using shell exit code when a PHPUnit deprecation was triggered'], ['arg' => '--do-not-fail-on-phpunit-warning', 'desc' => 'Do not signal failure using shell exit code when a PHPUnit warning was triggered'], ['arg' => '--do-not-fail-on-notice', 'desc' => 'Do not signal failure using shell exit code when a notice was triggered'], ['arg' => '--do-not-fail-on-skipped', 'desc' => 'Do not signal failure using shell exit code when a test was skipped'], ['arg' => '--do-not-fail-on-incomplete', 'desc' => 'Do not 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 <order>', 'desc' => 'Run tests in order: default|defects|depends|duration|no-depends|random|reverse|size'], ['arg' => '--random-order-seed <N>', 'desc' => 'Use the specified random seed when running tests in random order']], 'Reporting' => [['arg' => '--colors <flag>', 'desc' => 'Use colors in output ("never", "auto" or "always")'], ['arg' => '--columns <n>', '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-phpunit-deprecations', 'desc' => 'Display details for PHPUnit deprecations'], ['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' => '--display-all-issues', 'desc' => 'Display details for all issues that are triggered'], ['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 <file>', 'desc' => 'Write test results in JUnit XML format to file'], ['arg' => '--log-teamcity <file>', 'desc' => 'Write test results in TeamCity format to file'], ['arg' => '--testdox-html <file>', 'desc' => 'Write test results in TestDox format (HTML) to file'], ['arg' => '--testdox-text <file>', 'desc' => 'Write test results in TestDox format (plain text) to file'], ['arg' => '--log-events-text <file>', 'desc' => 'Stream events as plain text to file'], ['arg' => '--log-events-verbose-text <file>', '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 <file>', 'desc' => 'Write code coverage report in Clover XML format to file'], ['arg' => '--coverage-cobertura <file>', 'desc' => 'Write code coverage report in Cobertura XML format to file'], ['arg' => '--coverage-crap4j <file>', 'desc' => 'Write code coverage report in Crap4J XML format to file'], ['arg' => '--coverage-html <dir>', 'desc' => 'Write code coverage report in HTML format to directory'], ['arg' => '--coverage-php <file>', 'desc' => 'Write serialized code coverage data to file'], ['arg' => '--coverage-text=<file>', 'desc' => 'Write code coverage report in text format to file [default: standard output]'], ['arg' => '--only-summary-for-coverage-text', 'desc' => 'Option for code coverage report in text format: only show summary'], ['arg' => '--show-uncovered-for-coverage-text', 'desc' => 'Option for code coverage report in text format: show uncovered files'], ['arg' => '--coverage-xml <dir>', 'desc' => 'Write code coverage report in XML format to directory'], ['arg' => '--warm-coverage-cache', 'desc' => 'Warm static analysis cache'], ['arg' => '--coverage-filter <dir>', 'desc' => 'Include <dir> 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']]];
94401 if (defined('__PHPUNIT_PHAR__')) {
94402 $elements['PHAR'] = [['arg' => '--manifest', 'desc' => 'Print Software Bill of Materials (SBOM) in plain-text format'], ['arg' => '--sbom', 'desc' => 'Print Software Bill of Materials (SBOM) in CycloneDX XML format'], ['arg' => '--composer-lock', 'desc' => 'Print composer.lock file used to build the PHAR']];
94403 }
94404 $elements['Miscellaneous'] = [['arg' => '-h|--help', 'desc' => 'Prints this usage information'], ['arg' => '--version', 'desc' => 'Prints the version and exits'], ['arg' => '--atleast-version <min>', 'desc' => 'Checks that version is greater than <min> and exits'], ['arg' => '--check-version', 'desc' => 'Checks whether PHPUnit is the latest version and exits'], ['arg' => '--check-php-configuration', 'desc' => 'Checks whether PHP configuration follows best practices']];
94405 return $elements;
94406 }
94407 }
94408 <?php
94409
94410 declare (strict_types=1);
94411 /*
94412 * This file is part of PHPUnit.
94413 *
94414 * (c) Sebastian Bergmann <sebastian@phpunit.de>
94415 *
94416 * For the full copyright and license information, please view the LICENSE
94417 * file that was distributed with this source code.
94418 */
94419 namespace PHPUnit\TextUI\Output\Default\ProgressPrinter;
94420
94421 use function floor;
94422 use function sprintf;
94423 use function str_contains;
94424 use function str_repeat;
94425 use function strlen;
94426 use PHPUnit\Event\EventFacadeIsSealedException;
94427 use PHPUnit\Event\Facade;
94428 use PHPUnit\Event\Test\DeprecationTriggered;
94429 use PHPUnit\Event\Test\Errored;
94430 use PHPUnit\Event\Test\ErrorTriggered;
94431 use PHPUnit\Event\Test\NoticeTriggered;
94432 use PHPUnit\Event\Test\PhpDeprecationTriggered;
94433 use PHPUnit\Event\Test\PhpNoticeTriggered;
94434 use PHPUnit\Event\Test\PhpWarningTriggered;
94435 use PHPUnit\Event\Test\WarningTriggered;
94436 use PHPUnit\Event\TestRunner\ExecutionStarted;
94437 use PHPUnit\Event\UnknownSubscriberTypeException;
94438 use PHPUnit\Framework\TestStatus\TestStatus;
94439 use PHPUnit\TextUI\Configuration\Source;
94440 use PHPUnit\TextUI\Configuration\SourceFilter;
94441 use PHPUnit\TextUI\Output\Printer;
94442 use PHPUnit\Util\Color;
94443 /**
94444 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
94445 *
94446 * @internal This class is not covered by the backward compatibility promise for PHPUnit
94447 */
94448 final class ProgressPrinter
94449 {
94450 private readonly Printer $printer;
94451 private readonly bool $colors;
94452 private readonly int $numberOfColumns;
94453 private readonly Source $source;
94454 private int $column = 0;
94455 private int $numberOfTests = 0;
94456 private int $numberOfTestsWidth = 0;
94457 private int $maxColumn = 0;
94458 private int $numberOfTestsRun = 0;
94459 private ?TestStatus $status = null;
94460 private bool $prepared = \false;
94461 /**
94462 * @throws EventFacadeIsSealedException
94463 * @throws UnknownSubscriberTypeException
94464 */
94465 public function __construct(Printer $printer, Facade $facade, bool $colors, int $numberOfColumns, Source $source)
94466 {
94467 $this->printer = $printer;
94468 $this->colors = $colors;
94469 $this->numberOfColumns = $numberOfColumns;
94470 $this->source = $source;
94471 $this->registerSubscribers($facade);
94472 }
94473 public function testRunnerExecutionStarted(ExecutionStarted $event): void
94474 {
94475 $this->numberOfTestsRun = 0;
94476 $this->numberOfTests = $event->testSuite()->count();
94477 $this->numberOfTestsWidth = strlen((string) $this->numberOfTests);
94478 $this->column = 0;
94479 $this->maxColumn = $this->numberOfColumns - strlen(' / (XXX%)') - 2 * $this->numberOfTestsWidth;
94480 }
94481 public function beforeTestClassMethodErrored(): void
94482 {
94483 $this->printProgressForError();
94484 $this->updateTestStatus(TestStatus::error());
94485 }
94486 public function testPrepared(): void
94487 {
94488 $this->prepared = \true;
94489 }
94490 public function testSkipped(): void
94491 {
94492 if (!$this->prepared) {
94493 $this->printProgressForSkipped();
94494 } else {
94495 $this->updateTestStatus(TestStatus::skipped());
94496 }
94497 }
94498 public function testMarkedIncomplete(): void
94499 {
94500 $this->updateTestStatus(TestStatus::incomplete());
94501 }
94502 public function testTriggeredNotice(NoticeTriggered $event): void
94503 {
94504 if ($event->ignoredByBaseline()) {
94505 return;
94506 }
94507 if ($this->source->restrictNotices() && !SourceFilter::instance()->includes($event->file())) {
94508 return;
94509 }
94510 if (!$this->source->ignoreSuppressionOfNotices() && $event->wasSuppressed()) {
94511 return;
94512 }
94513 $this->updateTestStatus(TestStatus::notice());
94514 }
94515 public function testTriggeredPhpNotice(PhpNoticeTriggered $event): void
94516 {
94517 if ($event->ignoredByBaseline()) {
94518 return;
94519 }
94520 if ($this->source->restrictNotices() && !SourceFilter::instance()->includes($event->file())) {
94521 return;
94522 }
94523 if (!$this->source->ignoreSuppressionOfPhpNotices() && $event->wasSuppressed()) {
94524 return;
94525 }
94526 $this->updateTestStatus(TestStatus::notice());
94527 }
94528 public function testTriggeredDeprecation(DeprecationTriggered $event): void
94529 {
94530 if ($event->ignoredByBaseline() || $event->ignoredByTest()) {
94531 return;
94532 }
94533 if ($this->source->restrictDeprecations() && !SourceFilter::instance()->includes($event->file())) {
94534 return;
94535 }
94536 if (!$this->source->ignoreSuppressionOfDeprecations() && $event->wasSuppressed()) {
94537 return;
94538 }
94539 $this->updateTestStatus(TestStatus::deprecation());
94540 }
94541 public function testTriggeredPhpDeprecation(PhpDeprecationTriggered $event): void
94542 {
94543 if ($event->ignoredByBaseline() || $event->ignoredByTest()) {
94544 return;
94545 }
94546 if ($this->source->restrictDeprecations() && !SourceFilter::instance()->includes($event->file())) {
94547 return;
94548 }
94549 if (!$this->source->ignoreSuppressionOfPhpDeprecations() && $event->wasSuppressed()) {
94550 return;
94551 }
94552 $this->updateTestStatus(TestStatus::deprecation());
94553 }
94554 public function testTriggeredPhpunitDeprecation(): void
94555 {
94556 $this->updateTestStatus(TestStatus::deprecation());
94557 }
94558 public function testConsideredRisky(): void
94559 {
94560 $this->updateTestStatus(TestStatus::risky());
94561 }
94562 public function testTriggeredWarning(WarningTriggered $event): void
94563 {
94564 if ($event->ignoredByBaseline()) {
94565 return;
94566 }
94567 if ($this->source->restrictWarnings() && !SourceFilter::instance()->includes($event->file())) {
94568 return;
94569 }
94570 if (!$this->source->ignoreSuppressionOfWarnings() && $event->wasSuppressed()) {
94571 return;
94572 }
94573 $this->updateTestStatus(TestStatus::warning());
94574 }
94575 public function testTriggeredPhpWarning(PhpWarningTriggered $event): void
94576 {
94577 if ($event->ignoredByBaseline()) {
94578 return;
94579 }
94580 if ($this->source->restrictWarnings() && !SourceFilter::instance()->includes($event->file())) {
94581 return;
94582 }
94583 if (!$this->source->ignoreSuppressionOfPhpWarnings() && $event->wasSuppressed()) {
94584 return;
94585 }
94586 $this->updateTestStatus(TestStatus::warning());
94587 }
94588 public function testTriggeredPhpunitWarning(): void
94589 {
94590 $this->updateTestStatus(TestStatus::warning());
94591 }
94592 public function testTriggeredError(ErrorTriggered $event): void
94593 {
94594 if (!$this->source->ignoreSuppressionOfErrors() && $event->wasSuppressed()) {
94595 return;
94596 }
94597 $this->updateTestStatus(TestStatus::error());
94598 }
94599 public function testFailed(): void
94600 {
94601 $this->updateTestStatus(TestStatus::failure());
94602 }
94603 public function testErrored(Errored $event): void
94604 {
94605 /*
94606 * @todo Eliminate this special case
94607 */
94608 if (str_contains($event->asString(), 'Test was run in child process and ended unexpectedly')) {
94609 $this->updateTestStatus(TestStatus::error());
94610 return;
94611 }
94612 if (!$this->prepared) {
94613 $this->printProgressForError();
94614 } else {
94615 $this->updateTestStatus(TestStatus::error());
94616 }
94617 }
94618 public function testFinished(): void
94619 {
94620 if ($this->status === null) {
94621 $this->printProgressForSuccess();
94622 } elseif ($this->status->isSkipped()) {
94623 $this->printProgressForSkipped();
94624 } elseif ($this->status->isIncomplete()) {
94625 $this->printProgressForIncomplete();
94626 } elseif ($this->status->isRisky()) {
94627 $this->printProgressForRisky();
94628 } elseif ($this->status->isNotice()) {
94629 $this->printProgressForNotice();
94630 } elseif ($this->status->isDeprecation()) {
94631 $this->printProgressForDeprecation();
94632 } elseif ($this->status->isWarning()) {
94633 $this->printProgressForWarning();
94634 } elseif ($this->status->isFailure()) {
94635 $this->printProgressForFailure();
94636 } else {
94637 $this->printProgressForError();
94638 }
94639 $this->status = null;
94640 $this->prepared = \false;
94641 }
94642 /**
94643 * @throws EventFacadeIsSealedException
94644 * @throws UnknownSubscriberTypeException
94645 */
94646 private function registerSubscribers(Facade $facade): void
94647 {
94648 $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));
94649 }
94650 private function updateTestStatus(TestStatus $status): void
94651 {
94652 if ($this->status !== null && $this->status->isMoreImportantThan($status)) {
94653 return;
94654 }
94655 $this->status = $status;
94656 }
94657 private function printProgressForSuccess(): void
94658 {
94659 $this->printProgress('.');
94660 }
94661 private function printProgressForSkipped(): void
94662 {
94663 $this->printProgressWithColor('fg-cyan, bold', 'S');
94664 }
94665 private function printProgressForIncomplete(): void
94666 {
94667 $this->printProgressWithColor('fg-yellow, bold', 'I');
94668 }
94669 private function printProgressForNotice(): void
94670 {
94671 $this->printProgressWithColor('fg-yellow, bold', 'N');
94672 }
94673 private function printProgressForDeprecation(): void
94674 {
94675 $this->printProgressWithColor('fg-yellow, bold', 'D');
94676 }
94677 private function printProgressForRisky(): void
94678 {
94679 $this->printProgressWithColor('fg-yellow, bold', 'R');
94680 }
94681 private function printProgressForWarning(): void
94682 {
94683 $this->printProgressWithColor('fg-yellow, bold', 'W');
94684 }
94685 private function printProgressForFailure(): void
94686 {
94687 $this->printProgressWithColor('bg-red, fg-white', 'F');
94688 }
94689 private function printProgressForError(): void
94690 {
94691 $this->printProgressWithColor('fg-red, bold', 'E');
94692 }
94693 private function printProgressWithColor(string $color, string $progress): void
94694 {
94695 if ($this->colors) {
94696 $progress = Color::colorizeTextBox($color, $progress);
94697 }
94698 $this->printProgress($progress);
94699 }
94700 private function printProgress(string $progress): void
94701 {
94702 $this->printer->print($progress);
94703 $this->column++;
94704 $this->numberOfTestsRun++;
94705 if ($this->column === $this->maxColumn || $this->numberOfTestsRun === $this->numberOfTests) {
94706 if ($this->numberOfTestsRun === $this->numberOfTests) {
94707 $this->printer->print(str_repeat(' ', $this->maxColumn - $this->column));
94708 }
94709 $this->printer->print(sprintf(' %' . $this->numberOfTestsWidth . 'd / %' . $this->numberOfTestsWidth . 'd (%3s%%)', $this->numberOfTestsRun, $this->numberOfTests, floor($this->numberOfTestsRun / $this->numberOfTests * 100)));
94710 if ($this->column === $this->maxColumn) {
94711 $this->column = 0;
94712 $this->printer->print("\n");
94713 }
94714 }
94715 }
94716 }
94717 <?php
94718
94719 declare (strict_types=1);
94720 /*
94721 * This file is part of PHPUnit.
94722 *
94723 * (c) Sebastian Bergmann <sebastian@phpunit.de>
94724 *
94725 * For the full copyright and license information, please view the LICENSE
94726 * file that was distributed with this source code.
94727 */
94728 namespace PHPUnit\TextUI\Output\Default\ProgressPrinter;
94729
94730 use PHPUnit\Event\Test\BeforeFirstTestMethodErrored;
94731 use PHPUnit\Event\Test\BeforeFirstTestMethodErroredSubscriber;
94732 /**
94733 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
94734 *
94735 * @internal This class is not covered by the backward compatibility promise for PHPUnit
94736 */
94737 final class BeforeTestClassMethodErroredSubscriber extends \PHPUnit\TextUI\Output\Default\ProgressPrinter\Subscriber implements BeforeFirstTestMethodErroredSubscriber
94738 {
94739 public function notify(BeforeFirstTestMethodErrored $event): void
94740 {
94741 $this->printer()->beforeTestClassMethodErrored();
94742 }
94743 }
94744 <?php
94745
94746 declare (strict_types=1);
94747 /*
94748 * This file is part of PHPUnit.
94749 *
94750 * (c) Sebastian Bergmann <sebastian@phpunit.de>
94751 *
94752 * For the full copyright and license information, please view the LICENSE
94753 * file that was distributed with this source code.
94754 */
94755 namespace PHPUnit\TextUI\Output\Default\ProgressPrinter;
94756
94757 /**
94758 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
94759 *
94760 * @internal This class is not covered by the backward compatibility promise for PHPUnit
94761 */
94762 abstract class Subscriber
94763 {
94764 private readonly \PHPUnit\TextUI\Output\Default\ProgressPrinter\ProgressPrinter $printer;
94765 public function __construct(\PHPUnit\TextUI\Output\Default\ProgressPrinter\ProgressPrinter $printer)
94766 {
94767 $this->printer = $printer;
94768 }
94769 protected function printer(): \PHPUnit\TextUI\Output\Default\ProgressPrinter\ProgressPrinter
94770 {
94771 return $this->printer;
94772 }
94773 }
94774 <?php
94775
94776 declare (strict_types=1);
94777 /*
94778 * This file is part of PHPUnit.
94779 *
94780 * (c) Sebastian Bergmann <sebastian@phpunit.de>
94781 *
94782 * For the full copyright and license information, please view the LICENSE
94783 * file that was distributed with this source code.
94784 */
94785 namespace PHPUnit\TextUI\Output\Default\ProgressPrinter;
94786
94787 use PHPUnit\Event\Test\ConsideredRisky;
94788 use PHPUnit\Event\Test\ConsideredRiskySubscriber;
94789 /**
94790 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
94791 *
94792 * @internal This class is not covered by the backward compatibility promise for PHPUnit
94793 */
94794 final class TestConsideredRiskySubscriber extends \PHPUnit\TextUI\Output\Default\ProgressPrinter\Subscriber implements ConsideredRiskySubscriber
94795 {
94796 public function notify(ConsideredRisky $event): void
94797 {
94798 $this->printer()->testConsideredRisky();
94799 }
94800 }
94801 <?php
94802
94803 declare (strict_types=1);
94804 /*
94805 * This file is part of PHPUnit.
94806 *
94807 * (c) Sebastian Bergmann <sebastian@phpunit.de>
94808 *
94809 * For the full copyright and license information, please view the LICENSE
94810 * file that was distributed with this source code.
94811 */
94812 namespace PHPUnit\TextUI\Output\Default\ProgressPrinter;
94813
94814 use PHPUnit\Event\Test\Errored;
94815 use PHPUnit\Event\Test\ErroredSubscriber;
94816 /**
94817 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
94818 *
94819 * @internal This class is not covered by the backward compatibility promise for PHPUnit
94820 */
94821 final class TestErroredSubscriber extends \PHPUnit\TextUI\Output\Default\ProgressPrinter\Subscriber implements ErroredSubscriber
94822 {
94823 public function notify(Errored $event): void
94824 {
94825 $this->printer()->testErrored($event);
94826 }
94827 }
94828 <?php
94829
94830 declare (strict_types=1);
94831 /*
94832 * This file is part of PHPUnit.
94833 *
94834 * (c) Sebastian Bergmann <sebastian@phpunit.de>
94835 *
94836 * For the full copyright and license information, please view the LICENSE
94837 * file that was distributed with this source code.
94838 */
94839 namespace PHPUnit\TextUI\Output\Default\ProgressPrinter;
94840
94841 use PHPUnit\Event\Test\Failed;
94842 use PHPUnit\Event\Test\FailedSubscriber;
94843 /**
94844 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
94845 *
94846 * @internal This class is not covered by the backward compatibility promise for PHPUnit
94847 */
94848 final class TestFailedSubscriber extends \PHPUnit\TextUI\Output\Default\ProgressPrinter\Subscriber implements FailedSubscriber
94849 {
94850 public function notify(Failed $event): void
94851 {
94852 $this->printer()->testFailed();
94853 }
94854 }
94855 <?php
94856
94857 declare (strict_types=1);
94858 /*
94859 * This file is part of PHPUnit.
94860 *
94861 * (c) Sebastian Bergmann <sebastian@phpunit.de>
94862 *
94863 * For the full copyright and license information, please view the LICENSE
94864 * file that was distributed with this source code.
94865 */
94866 namespace PHPUnit\TextUI\Output\Default\ProgressPrinter;
94867
94868 use PHPUnit\Event\Test\Finished;
94869 use PHPUnit\Event\Test\FinishedSubscriber;
94870 /**
94871 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
94872 *
94873 * @internal This class is not covered by the backward compatibility promise for PHPUnit
94874 */
94875 final class TestFinishedSubscriber extends \PHPUnit\TextUI\Output\Default\ProgressPrinter\Subscriber implements FinishedSubscriber
94876 {
94877 public function notify(Finished $event): void
94878 {
94879 $this->printer()->testFinished();
94880 }
94881 }
94882 <?php
94883
94884 declare (strict_types=1);
94885 /*
94886 * This file is part of PHPUnit.
94887 *
94888 * (c) Sebastian Bergmann <sebastian@phpunit.de>
94889 *
94890 * For the full copyright and license information, please view the LICENSE
94891 * file that was distributed with this source code.
94892 */
94893 namespace PHPUnit\TextUI\Output\Default\ProgressPrinter;
94894
94895 use PHPUnit\Event\Test\MarkedIncomplete;
94896 use PHPUnit\Event\Test\MarkedIncompleteSubscriber;
94897 /**
94898 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
94899 *
94900 * @internal This class is not covered by the backward compatibility promise for PHPUnit
94901 */
94902 final class TestMarkedIncompleteSubscriber extends \PHPUnit\TextUI\Output\Default\ProgressPrinter\Subscriber implements MarkedIncompleteSubscriber
94903 {
94904 public function notify(MarkedIncomplete $event): void
94905 {
94906 $this->printer()->testMarkedIncomplete();
94907 }
94908 }
94909 <?php
94910
94911 declare (strict_types=1);
94912 /*
94913 * This file is part of PHPUnit.
94914 *
94915 * (c) Sebastian Bergmann <sebastian@phpunit.de>
94916 *
94917 * For the full copyright and license information, please view the LICENSE
94918 * file that was distributed with this source code.
94919 */
94920 namespace PHPUnit\TextUI\Output\Default\ProgressPrinter;
94921
94922 use PHPUnit\Event\Test\Prepared;
94923 use PHPUnit\Event\Test\PreparedSubscriber;
94924 /**
94925 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
94926 *
94927 * @internal This class is not covered by the backward compatibility promise for PHPUnit
94928 */
94929 final class TestPreparedSubscriber extends \PHPUnit\TextUI\Output\Default\ProgressPrinter\Subscriber implements PreparedSubscriber
94930 {
94931 public function notify(Prepared $event): void
94932 {
94933 $this->printer()->testPrepared();
94934 }
94935 }
94936 <?php
94937
94938 declare (strict_types=1);
94939 /*
94940 * This file is part of PHPUnit.
94941 *
94942 * (c) Sebastian Bergmann <sebastian@phpunit.de>
94943 *
94944 * For the full copyright and license information, please view the LICENSE
94945 * file that was distributed with this source code.
94946 */
94947 namespace PHPUnit\TextUI\Output\Default\ProgressPrinter;
94948
94949 use PHPUnit\Event\TestRunner\ExecutionStarted;
94950 use PHPUnit\Event\TestRunner\ExecutionStartedSubscriber;
94951 /**
94952 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
94953 *
94954 * @internal This class is not covered by the backward compatibility promise for PHPUnit
94955 */
94956 final class TestRunnerExecutionStartedSubscriber extends \PHPUnit\TextUI\Output\Default\ProgressPrinter\Subscriber implements ExecutionStartedSubscriber
94957 {
94958 public function notify(ExecutionStarted $event): void
94959 {
94960 $this->printer()->testRunnerExecutionStarted($event);
94961 }
94962 }
94963 <?php
94964
94965 declare (strict_types=1);
94966 /*
94967 * This file is part of PHPUnit.
94968 *
94969 * (c) Sebastian Bergmann <sebastian@phpunit.de>
94970 *
94971 * For the full copyright and license information, please view the LICENSE
94972 * file that was distributed with this source code.
94973 */
94974 namespace PHPUnit\TextUI\Output\Default\ProgressPrinter;
94975
94976 use PHPUnit\Event\Test\Skipped;
94977 use PHPUnit\Event\Test\SkippedSubscriber;
94978 /**
94979 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
94980 *
94981 * @internal This class is not covered by the backward compatibility promise for PHPUnit
94982 */
94983 final class TestSkippedSubscriber extends \PHPUnit\TextUI\Output\Default\ProgressPrinter\Subscriber implements SkippedSubscriber
94984 {
94985 public function notify(Skipped $event): void
94986 {
94987 $this->printer()->testSkipped();
94988 }
94989 }
94990 <?php
94991
94992 declare (strict_types=1);
94993 /*
94994 * This file is part of PHPUnit.
94995 *
94996 * (c) Sebastian Bergmann <sebastian@phpunit.de>
94997 *
94998 * For the full copyright and license information, please view the LICENSE
94999 * file that was distributed with this source code.
95000 */
95001 namespace PHPUnit\TextUI\Output\Default\ProgressPrinter;
95002
95003 use PHPUnit\Event\Test\DeprecationTriggered;
95004 use PHPUnit\Event\Test\DeprecationTriggeredSubscriber;
95005 /**
95006 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
95007 *
95008 * @internal This class is not covered by the backward compatibility promise for PHPUnit
95009 */
95010 final class TestTriggeredDeprecationSubscriber extends \PHPUnit\TextUI\Output\Default\ProgressPrinter\Subscriber implements DeprecationTriggeredSubscriber
95011 {
95012 public function notify(DeprecationTriggered $event): void
95013 {
95014 $this->printer()->testTriggeredDeprecation($event);
95015 }
95016 }
95017 <?php
95018
95019 declare (strict_types=1);
95020 /*
95021 * This file is part of PHPUnit.
95022 *
95023 * (c) Sebastian Bergmann <sebastian@phpunit.de>
95024 *
95025 * For the full copyright and license information, please view the LICENSE
95026 * file that was distributed with this source code.
95027 */
95028 namespace PHPUnit\TextUI\Output\Default\ProgressPrinter;
95029
95030 use PHPUnit\Event\Test\ErrorTriggered;
95031 use PHPUnit\Event\Test\ErrorTriggeredSubscriber;
95032 /**
95033 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
95034 *
95035 * @internal This class is not covered by the backward compatibility promise for PHPUnit
95036 */
95037 final class TestTriggeredErrorSubscriber extends \PHPUnit\TextUI\Output\Default\ProgressPrinter\Subscriber implements ErrorTriggeredSubscriber
95038 {
95039 public function notify(ErrorTriggered $event): void
95040 {
95041 $this->printer()->testTriggeredError($event);
95042 }
95043 }
95044 <?php
95045
95046 declare (strict_types=1);
95047 /*
95048 * This file is part of PHPUnit.
95049 *
95050 * (c) Sebastian Bergmann <sebastian@phpunit.de>
95051 *
95052 * For the full copyright and license information, please view the LICENSE
95053 * file that was distributed with this source code.
95054 */
95055 namespace PHPUnit\TextUI\Output\Default\ProgressPrinter;
95056
95057 use PHPUnit\Event\Test\NoticeTriggered;
95058 use PHPUnit\Event\Test\NoticeTriggeredSubscriber;
95059 /**
95060 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
95061 *
95062 * @internal This class is not covered by the backward compatibility promise for PHPUnit
95063 */
95064 final class TestTriggeredNoticeSubscriber extends \PHPUnit\TextUI\Output\Default\ProgressPrinter\Subscriber implements NoticeTriggeredSubscriber
95065 {
95066 public function notify(NoticeTriggered $event): void
95067 {
95068 $this->printer()->testTriggeredNotice($event);
95069 }
95070 }
95071 <?php
95072
95073 declare (strict_types=1);
95074 /*
95075 * This file is part of PHPUnit.
95076 *
95077 * (c) Sebastian Bergmann <sebastian@phpunit.de>
95078 *
95079 * For the full copyright and license information, please view the LICENSE
95080 * file that was distributed with this source code.
95081 */
95082 namespace PHPUnit\TextUI\Output\Default\ProgressPrinter;
95083
95084 use PHPUnit\Event\Test\PhpDeprecationTriggered;
95085 use PHPUnit\Event\Test\PhpDeprecationTriggeredSubscriber;
95086 /**
95087 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
95088 *
95089 * @internal This class is not covered by the backward compatibility promise for PHPUnit
95090 */
95091 final class TestTriggeredPhpDeprecationSubscriber extends \PHPUnit\TextUI\Output\Default\ProgressPrinter\Subscriber implements PhpDeprecationTriggeredSubscriber
95092 {
95093 public function notify(PhpDeprecationTriggered $event): void
95094 {
95095 $this->printer()->testTriggeredPhpDeprecation($event);
95096 }
95097 }
95098 <?php
95099
95100 declare (strict_types=1);
95101 /*
95102 * This file is part of PHPUnit.
95103 *
95104 * (c) Sebastian Bergmann <sebastian@phpunit.de>
95105 *
95106 * For the full copyright and license information, please view the LICENSE
95107 * file that was distributed with this source code.
95108 */
95109 namespace PHPUnit\TextUI\Output\Default\ProgressPrinter;
95110
95111 use PHPUnit\Event\Test\PhpNoticeTriggered;
95112 use PHPUnit\Event\Test\PhpNoticeTriggeredSubscriber;
95113 /**
95114 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
95115 *
95116 * @internal This class is not covered by the backward compatibility promise for PHPUnit
95117 */
95118 final class TestTriggeredPhpNoticeSubscriber extends \PHPUnit\TextUI\Output\Default\ProgressPrinter\Subscriber implements PhpNoticeTriggeredSubscriber
95119 {
95120 public function notify(PhpNoticeTriggered $event): void
95121 {
95122 $this->printer()->testTriggeredPhpNotice($event);
95123 }
95124 }
95125 <?php
95126
95127 declare (strict_types=1);
95128 /*
95129 * This file is part of PHPUnit.
95130 *
95131 * (c) Sebastian Bergmann <sebastian@phpunit.de>
95132 *
95133 * For the full copyright and license information, please view the LICENSE
95134 * file that was distributed with this source code.
95135 */
95136 namespace PHPUnit\TextUI\Output\Default\ProgressPrinter;
95137
95138 use PHPUnit\Event\Test\PhpWarningTriggered;
95139 use PHPUnit\Event\Test\PhpWarningTriggeredSubscriber;
95140 /**
95141 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
95142 *
95143 * @internal This class is not covered by the backward compatibility promise for PHPUnit
95144 */
95145 final class TestTriggeredPhpWarningSubscriber extends \PHPUnit\TextUI\Output\Default\ProgressPrinter\Subscriber implements PhpWarningTriggeredSubscriber
95146 {
95147 public function notify(PhpWarningTriggered $event): void
95148 {
95149 $this->printer()->testTriggeredPhpWarning($event);
95150 }
95151 }
95152 <?php
95153
95154 declare (strict_types=1);
95155 /*
95156 * This file is part of PHPUnit.
95157 *
95158 * (c) Sebastian Bergmann <sebastian@phpunit.de>
95159 *
95160 * For the full copyright and license information, please view the LICENSE
95161 * file that was distributed with this source code.
95162 */
95163 namespace PHPUnit\TextUI\Output\Default\ProgressPrinter;
95164
95165 use PHPUnit\Event\Test\PhpunitDeprecationTriggered;
95166 use PHPUnit\Event\Test\PhpunitDeprecationTriggeredSubscriber;
95167 /**
95168 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
95169 *
95170 * @internal This class is not covered by the backward compatibility promise for PHPUnit
95171 */
95172 final class TestTriggeredPhpunitDeprecationSubscriber extends \PHPUnit\TextUI\Output\Default\ProgressPrinter\Subscriber implements PhpunitDeprecationTriggeredSubscriber
95173 {
95174 public function notify(PhpunitDeprecationTriggered $event): void
95175 {
95176 $this->printer()->testTriggeredPhpunitDeprecation();
95177 }
95178 }
95179 <?php
95180
95181 declare (strict_types=1);
95182 /*
95183 * This file is part of PHPUnit.
95184 *
95185 * (c) Sebastian Bergmann <sebastian@phpunit.de>
95186 *
95187 * For the full copyright and license information, please view the LICENSE
95188 * file that was distributed with this source code.
95189 */
95190 namespace PHPUnit\TextUI\Output\Default\ProgressPrinter;
95191
95192 use PHPUnit\Event\Test\PhpunitWarningTriggered;
95193 use PHPUnit\Event\Test\PhpunitWarningTriggeredSubscriber;
95194 /**
95195 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
95196 *
95197 * @internal This class is not covered by the backward compatibility promise for PHPUnit
95198 */
95199 final class TestTriggeredPhpunitWarningSubscriber extends \PHPUnit\TextUI\Output\Default\ProgressPrinter\Subscriber implements PhpunitWarningTriggeredSubscriber
95200 {
95201 public function notify(PhpunitWarningTriggered $event): void
95202 {
95203 $this->printer()->testTriggeredPhpunitWarning();
95204 }
95205 }
95206 <?php
95207
95208 declare (strict_types=1);
95209 /*
95210 * This file is part of PHPUnit.
95211 *
95212 * (c) Sebastian Bergmann <sebastian@phpunit.de>
95213 *
95214 * For the full copyright and license information, please view the LICENSE
95215 * file that was distributed with this source code.
95216 */
95217 namespace PHPUnit\TextUI\Output\Default\ProgressPrinter;
95218
95219 use PHPUnit\Event\Test\WarningTriggered;
95220 use PHPUnit\Event\Test\WarningTriggeredSubscriber;
95221 /**
95222 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
95223 *
95224 * @internal This class is not covered by the backward compatibility promise for PHPUnit
95225 */
95226 final class TestTriggeredWarningSubscriber extends \PHPUnit\TextUI\Output\Default\ProgressPrinter\Subscriber implements WarningTriggeredSubscriber
95227 {
95228 public function notify(WarningTriggered $event): void
95229 {
95230 $this->printer()->testTriggeredWarning($event);
95231 }
95232 }
95233 <?php
95234
95235 declare (strict_types=1);
95236 /*
95237 * This file is part of PHPUnit.
95238 *
95239 * (c) Sebastian Bergmann <sebastian@phpunit.de>
95240 *
95241 * For the full copyright and license information, please view the LICENSE
95242 * file that was distributed with this source code.
95243 */
95244 namespace PHPUnit\TextUI\Output\Default;
95245
95246 use const PHP_EOL;
95247 use function array_keys;
95248 use function array_merge;
95249 use function array_reverse;
95250 use function array_unique;
95251 use function assert;
95252 use function count;
95253 use function explode;
95254 use function ksort;
95255 use function range;
95256 use function sprintf;
95257 use function str_starts_with;
95258 use function strlen;
95259 use function substr;
95260 use function trim;
95261 use PHPUnit\Event\Code\Test;
95262 use PHPUnit\Event\Code\TestMethod;
95263 use PHPUnit\Event\Test\AfterLastTestMethodErrored;
95264 use PHPUnit\Event\Test\BeforeFirstTestMethodErrored;
95265 use PHPUnit\Event\Test\ConsideredRisky;
95266 use PHPUnit\Event\Test\DeprecationTriggered;
95267 use PHPUnit\Event\Test\ErrorTriggered;
95268 use PHPUnit\Event\Test\NoticeTriggered;
95269 use PHPUnit\Event\Test\PhpDeprecationTriggered;
95270 use PHPUnit\Event\Test\PhpNoticeTriggered;
95271 use PHPUnit\Event\Test\PhpunitDeprecationTriggered;
95272 use PHPUnit\Event\Test\PhpunitErrorTriggered;
95273 use PHPUnit\Event\Test\PhpunitWarningTriggered;
95274 use PHPUnit\Event\Test\PhpWarningTriggered;
95275 use PHPUnit\Event\Test\WarningTriggered;
95276 use PHPUnit\TestRunner\TestResult\Issues\Issue;
95277 use PHPUnit\TestRunner\TestResult\TestResult;
95278 use PHPUnit\TextUI\Output\Printer;
95279 /**
95280 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
95281 *
95282 * @internal This class is not covered by the backward compatibility promise for PHPUnit
95283 */
95284 final class ResultPrinter
95285 {
95286 private readonly Printer $printer;
95287 private readonly bool $displayPhpunitErrors;
95288 private readonly bool $displayPhpunitWarnings;
95289 private readonly bool $displayTestsWithErrors;
95290 private readonly bool $displayTestsWithFailedAssertions;
95291 private readonly bool $displayRiskyTests;
95292 private readonly bool $displayPhpunitDeprecations;
95293 private readonly bool $displayDetailsOnIncompleteTests;
95294 private readonly bool $displayDetailsOnSkippedTests;
95295 private readonly bool $displayDetailsOnTestsThatTriggerDeprecations;
95296 private readonly bool $displayDetailsOnTestsThatTriggerErrors;
95297 private readonly bool $displayDetailsOnTestsThatTriggerNotices;
95298 private readonly bool $displayDetailsOnTestsThatTriggerWarnings;
95299 private readonly bool $displayDefectsInReverseOrder;
95300 private bool $listPrinted = \false;
95301 public function __construct(Printer $printer, bool $displayPhpunitErrors, bool $displayPhpunitWarnings, bool $displayPhpunitDeprecations, bool $displayTestsWithErrors, bool $displayTestsWithFailedAssertions, bool $displayRiskyTests, bool $displayDetailsOnIncompleteTests, bool $displayDetailsOnSkippedTests, bool $displayDetailsOnTestsThatTriggerDeprecations, bool $displayDetailsOnTestsThatTriggerErrors, bool $displayDetailsOnTestsThatTriggerNotices, bool $displayDetailsOnTestsThatTriggerWarnings, bool $displayDefectsInReverseOrder)
95302 {
95303 $this->printer = $printer;
95304 $this->displayPhpunitErrors = $displayPhpunitErrors;
95305 $this->displayPhpunitWarnings = $displayPhpunitWarnings;
95306 $this->displayPhpunitDeprecations = $displayPhpunitDeprecations;
95307 $this->displayTestsWithErrors = $displayTestsWithErrors;
95308 $this->displayTestsWithFailedAssertions = $displayTestsWithFailedAssertions;
95309 $this->displayRiskyTests = $displayRiskyTests;
95310 $this->displayDetailsOnIncompleteTests = $displayDetailsOnIncompleteTests;
95311 $this->displayDetailsOnSkippedTests = $displayDetailsOnSkippedTests;
95312 $this->displayDetailsOnTestsThatTriggerDeprecations = $displayDetailsOnTestsThatTriggerDeprecations;
95313 $this->displayDetailsOnTestsThatTriggerErrors = $displayDetailsOnTestsThatTriggerErrors;
95314 $this->displayDetailsOnTestsThatTriggerNotices = $displayDetailsOnTestsThatTriggerNotices;
95315 $this->displayDetailsOnTestsThatTriggerWarnings = $displayDetailsOnTestsThatTriggerWarnings;
95316 $this->displayDefectsInReverseOrder = $displayDefectsInReverseOrder;
95317 }
95318 public function print(TestResult $result): void
95319 {
95320 if ($this->displayPhpunitErrors) {
95321 $this->printPhpunitErrors($result);
95322 }
95323 if ($this->displayPhpunitWarnings) {
95324 $this->printTestRunnerWarnings($result);
95325 }
95326 if ($this->displayPhpunitDeprecations) {
95327 $this->printTestRunnerDeprecations($result);
95328 }
95329 if ($this->displayTestsWithErrors) {
95330 $this->printTestsWithErrors($result);
95331 }
95332 if ($this->displayTestsWithFailedAssertions) {
95333 $this->printTestsWithFailedAssertions($result);
95334 }
95335 if ($this->displayPhpunitWarnings) {
95336 $this->printDetailsOnTestsThatTriggeredPhpunitWarnings($result);
95337 }
95338 if ($this->displayPhpunitDeprecations) {
95339 $this->printDetailsOnTestsThatTriggeredPhpunitDeprecations($result);
95340 }
95341 if ($this->displayRiskyTests) {
95342 $this->printRiskyTests($result);
95343 }
95344 if ($this->displayDetailsOnIncompleteTests) {
95345 $this->printIncompleteTests($result);
95346 }
95347 if ($this->displayDetailsOnSkippedTests) {
95348 $this->printSkippedTestSuites($result);
95349 $this->printSkippedTests($result);
95350 }
95351 if ($this->displayDetailsOnTestsThatTriggerErrors) {
95352 $this->printIssueList('error', $result->errors());
95353 }
95354 if ($this->displayDetailsOnTestsThatTriggerWarnings) {
95355 $this->printIssueList('PHP warning', $result->phpWarnings());
95356 $this->printIssueList('warning', $result->warnings());
95357 }
95358 if ($this->displayDetailsOnTestsThatTriggerNotices) {
95359 $this->printIssueList('PHP notice', $result->phpNotices());
95360 $this->printIssueList('notice', $result->notices());
95361 }
95362 if ($this->displayDetailsOnTestsThatTriggerDeprecations) {
95363 $this->printIssueList('PHP deprecation', $result->phpDeprecations());
95364 $this->printIssueList('deprecation', $result->deprecations());
95365 }
95366 }
95367 private function printPhpunitErrors(TestResult $result): void
95368 {
95369 if (!$result->hasTestTriggeredPhpunitErrorEvents()) {
95370 return;
95371 }
95372 $elements = $this->mapTestsWithIssuesEventsToElements($result->testTriggeredPhpunitErrorEvents());
95373 $this->printListHeaderWithNumber($elements['numberOfTestsWithIssues'], 'PHPUnit error');
95374 $this->printList($elements['elements']);
95375 }
95376 private function printDetailsOnTestsThatTriggeredPhpunitDeprecations(TestResult $result): void
95377 {
95378 if (!$result->hasTestTriggeredPhpunitDeprecationEvents()) {
95379 return;
95380 }
95381 $elements = $this->mapTestsWithIssuesEventsToElements($result->testTriggeredPhpunitDeprecationEvents());
95382 $this->printListHeaderWithNumberOfTestsAndNumberOfIssues($elements['numberOfTestsWithIssues'], $elements['numberOfIssues'], 'PHPUnit deprecation');
95383 $this->printList($elements['elements']);
95384 }
95385 private function printTestRunnerWarnings(TestResult $result): void
95386 {
95387 if (!$result->hasTestRunnerTriggeredWarningEvents()) {
95388 return;
95389 }
95390 $elements = [];
95391 $messages = [];
95392 foreach ($result->testRunnerTriggeredWarningEvents() as $event) {
95393 if (isset($messages[$event->message()])) {
95394 continue;
95395 }
95396 $elements[] = ['title' => $event->message(), 'body' => ''];
95397 $messages[$event->message()] = \true;
95398 }
95399 $this->printListHeaderWithNumber(count($elements), 'PHPUnit test runner warning');
95400 $this->printList($elements);
95401 }
95402 private function printTestRunnerDeprecations(TestResult $result): void
95403 {
95404 if (!$result->hasTestRunnerTriggeredDeprecationEvents()) {
95405 return;
95406 }
95407 $elements = [];
95408 foreach ($result->testRunnerTriggeredDeprecationEvents() as $event) {
95409 $elements[] = ['title' => $event->message(), 'body' => ''];
95410 }
95411 $this->printListHeaderWithNumber(count($elements), 'PHPUnit test runner deprecation');
95412 $this->printList($elements);
95413 }
95414 private function printDetailsOnTestsThatTriggeredPhpunitWarnings(TestResult $result): void
95415 {
95416 if (!$result->hasTestTriggeredPhpunitWarningEvents()) {
95417 return;
95418 }
95419 $elements = $this->mapTestsWithIssuesEventsToElements($result->testTriggeredPhpunitWarningEvents());
95420 $this->printListHeaderWithNumberOfTestsAndNumberOfIssues($elements['numberOfTestsWithIssues'], $elements['numberOfIssues'], 'PHPUnit warning');
95421 $this->printList($elements['elements']);
95422 }
95423 private function printTestsWithErrors(TestResult $result): void
95424 {
95425 if (!$result->hasTestErroredEvents()) {
95426 return;
95427 }
95428 $elements = [];
95429 foreach ($result->testErroredEvents() as $event) {
95430 if ($event instanceof AfterLastTestMethodErrored || $event instanceof BeforeFirstTestMethodErrored) {
95431 $title = $event->testClassName();
95432 } else {
95433 $title = $this->name($event->test());
95434 }
95435 $elements[] = ['title' => $title, 'body' => $event->throwable()->asString()];
95436 }
95437 $this->printListHeaderWithNumber(count($elements), 'error');
95438 $this->printList($elements);
95439 }
95440 private function printTestsWithFailedAssertions(TestResult $result): void
95441 {
95442 if (!$result->hasTestFailedEvents()) {
95443 return;
95444 }
95445 $elements = [];
95446 foreach ($result->testFailedEvents() as $event) {
95447 $body = $event->throwable()->asString();
95448 if (str_starts_with($body, 'AssertionError: ')) {
95449 $body = substr($body, strlen('AssertionError: '));
95450 }
95451 $elements[] = ['title' => $this->name($event->test()), 'body' => $body];
95452 }
95453 $this->printListHeaderWithNumber(count($elements), 'failure');
95454 $this->printList($elements);
95455 }
95456 private function printRiskyTests(TestResult $result): void
95457 {
95458 if (!$result->hasTestConsideredRiskyEvents()) {
95459 return;
95460 }
95461 $elements = $this->mapTestsWithIssuesEventsToElements($result->testConsideredRiskyEvents());
95462 $this->printListHeaderWithNumber($elements['numberOfTestsWithIssues'], 'risky test');
95463 $this->printList($elements['elements']);
95464 }
95465 private function printIncompleteTests(TestResult $result): void
95466 {
95467 if (!$result->hasTestMarkedIncompleteEvents()) {
95468 return;
95469 }
95470 $elements = [];
95471 foreach ($result->testMarkedIncompleteEvents() as $event) {
95472 $elements[] = ['title' => $this->name($event->test()), 'body' => $event->throwable()->asString()];
95473 }
95474 $this->printListHeaderWithNumber(count($elements), 'incomplete test');
95475 $this->printList($elements);
95476 }
95477 private function printSkippedTestSuites(TestResult $result): void
95478 {
95479 if (!$result->hasTestSuiteSkippedEvents()) {
95480 return;
95481 }
95482 $elements = [];
95483 foreach ($result->testSuiteSkippedEvents() as $event) {
95484 $elements[] = ['title' => $event->testSuite()->name(), 'body' => $event->message()];
95485 }
95486 $this->printListHeaderWithNumber(count($elements), 'skipped test suite');
95487 $this->printList($elements);
95488 }
95489 private function printSkippedTests(TestResult $result): void
95490 {
95491 if (!$result->hasTestSkippedEvents()) {
95492 return;
95493 }
95494 $elements = [];
95495 foreach ($result->testSkippedEvents() as $event) {
95496 $elements[] = ['title' => $this->name($event->test()), 'body' => $event->message()];
95497 }
95498 $this->printListHeaderWithNumber(count($elements), 'skipped test');
95499 $this->printList($elements);
95500 }
95501 /**
95502 * @psalm-param non-empty-string $type
95503 * @psalm-param list<Issue> $issues
95504 */
95505 private function printIssueList(string $type, array $issues): void
95506 {
95507 if (empty($issues)) {
95508 return;
95509 }
95510 $numberOfUniqueIssues = count($issues);
95511 $triggeringTests = [];
95512 foreach ($issues as $issue) {
95513 $triggeringTests = array_merge($triggeringTests, array_keys($issue->triggeringTests()));
95514 }
95515 $numberOfTests = count(array_unique($triggeringTests));
95516 unset($triggeringTests);
95517 $this->printListHeader(sprintf('%d test%s triggered %d %s%s:' . PHP_EOL . PHP_EOL, $numberOfTests, $numberOfTests !== 1 ? 's' : '', $numberOfUniqueIssues, $type, $numberOfUniqueIssues !== 1 ? 's' : ''));
95518 $i = 1;
95519 foreach ($issues as $issue) {
95520 $title = sprintf('%s:%d', $issue->file(), $issue->line());
95521 $body = trim($issue->description()) . PHP_EOL . PHP_EOL . 'Triggered by:';
95522 $triggeringTests = $issue->triggeringTests();
95523 ksort($triggeringTests);
95524 foreach ($triggeringTests as $triggeringTest) {
95525 $body .= PHP_EOL . PHP_EOL . '* ' . $triggeringTest['test']->id();
95526 if ($triggeringTest['count'] > 1) {
95527 $body .= sprintf(' (%d times)', $triggeringTest['count']);
95528 }
95529 if ($triggeringTest['test']->isTestMethod()) {
95530 $body .= PHP_EOL . ' ' . $triggeringTest['test']->file() . ':' . $triggeringTest['test']->line();
95531 }
95532 }
95533 $this->printIssueListElement($i++, $title, $body);
95534 $this->printer->print(PHP_EOL);
95535 }
95536 }
95537 private function printListHeaderWithNumberOfTestsAndNumberOfIssues(int $numberOfTestsWithIssues, int $numberOfIssues, string $type): void
95538 {
95539 $this->printListHeader(sprintf("%d test%s triggered %d %s%s:\n\n", $numberOfTestsWithIssues, $numberOfTestsWithIssues !== 1 ? 's' : '', $numberOfIssues, $type, $numberOfIssues !== 1 ? 's' : ''));
95540 }
95541 private function printListHeaderWithNumber(int $number, string $type): void
95542 {
95543 $this->printListHeader(sprintf("There %s %d %s%s:\n\n", $number === 1 ? 'was' : 'were', $number, $type, $number === 1 ? '' : 's'));
95544 }
95545 private function printListHeader(string $header): void
95546 {
95547 if ($this->listPrinted) {
95548 $this->printer->print("--\n\n");
95549 }
95550 $this->listPrinted = \true;
95551 $this->printer->print($header);
95552 }
95553 /**
95554 * @psalm-param list<array{title: string, body: string}> $elements
95555 */
95556 private function printList(array $elements): void
95557 {
95558 $i = 1;
95559 if ($this->displayDefectsInReverseOrder) {
95560 $elements = array_reverse($elements);
95561 }
95562 foreach ($elements as $element) {
95563 $this->printListElement($i++, $element['title'], $element['body']);
95564 }
95565 $this->printer->print("\n");
95566 }
95567 private function printListElement(int $number, string $title, string $body): void
95568 {
95569 $body = trim($body);
95570 $this->printer->print(sprintf("%s%d) %s\n%s%s", $number > 1 ? "\n" : '', $number, $title, $body, !empty($body) ? "\n" : ''));
95571 }
95572 private function printIssueListElement(int $number, string $title, string $body): void
95573 {
95574 $body = trim($body);
95575 $this->printer->print(sprintf("%d) %s\n%s%s", $number, $title, $body, !empty($body) ? "\n" : ''));
95576 }
95577 private function name(Test $test): string
95578 {
95579 if ($test->isTestMethod()) {
95580 assert($test instanceof TestMethod);
95581 if (!$test->testData()->hasDataFromDataProvider()) {
95582 return $test->nameWithClass();
95583 }
95584 return $test->className() . '::' . $test->methodName() . $test->testData()->dataFromDataProvider()->dataAsStringForResultOutput();
95585 }
95586 return $test->name();
95587 }
95588 /**
95589 * @psalm-param array<string,list<ConsideredRisky|DeprecationTriggered|PhpDeprecationTriggered|PhpunitDeprecationTriggered|ErrorTriggered|NoticeTriggered|PhpNoticeTriggered|WarningTriggered|PhpWarningTriggered|PhpunitErrorTriggered|PhpunitWarningTriggered>> $events
95590 *
95591 * @psalm-return array{numberOfTestsWithIssues: int, numberOfIssues: int, elements: list<array{title: string, body: string}>}
95592 */
95593 private function mapTestsWithIssuesEventsToElements(array $events): array
95594 {
95595 $elements = [];
95596 $issues = 0;
95597 foreach ($events as $reasons) {
95598 $test = $reasons[0]->test();
95599 $testLocation = $this->testLocation($test);
95600 $title = $this->name($test);
95601 $body = '';
95602 $first = \true;
95603 $single = count($reasons) === 1;
95604 foreach ($reasons as $reason) {
95605 if ($first) {
95606 $first = \false;
95607 } else {
95608 $body .= PHP_EOL;
95609 }
95610 $body .= $this->reasonMessage($reason, $single);
95611 $body .= $this->reasonLocation($reason, $single);
95612 $issues++;
95613 }
95614 if (!empty($testLocation)) {
95615 $body .= $testLocation;
95616 }
95617 $elements[] = ['title' => $title, 'body' => $body];
95618 }
95619 return ['numberOfTestsWithIssues' => count($events), 'numberOfIssues' => $issues, 'elements' => $elements];
95620 }
95621 private function testLocation(Test $test): string
95622 {
95623 if (!$test->isTestMethod()) {
95624 return '';
95625 }
95626 assert($test instanceof TestMethod);
95627 return sprintf('%s%s:%d%s', PHP_EOL, $test->file(), $test->line(), PHP_EOL);
95628 }
95629 private function reasonMessage(ConsideredRisky|DeprecationTriggered|ErrorTriggered|NoticeTriggered|PhpDeprecationTriggered|PhpNoticeTriggered|PhpunitDeprecationTriggered|PhpunitErrorTriggered|PhpunitWarningTriggered|PhpWarningTriggered|WarningTriggered $reason, bool $single): string
95630 {
95631 $message = trim($reason->message());
95632 if ($single) {
95633 return $message . PHP_EOL;
95634 }
95635 $lines = explode(PHP_EOL, $message);
95636 $buffer = '* ' . $lines[0] . PHP_EOL;
95637 if (count($lines) > 1) {
95638 foreach (range(1, count($lines) - 1) as $line) {
95639 $buffer .= ' ' . $lines[$line] . PHP_EOL;
95640 }
95641 }
95642 return $buffer;
95643 }
95644 private function reasonLocation(ConsideredRisky|DeprecationTriggered|ErrorTriggered|NoticeTriggered|PhpDeprecationTriggered|PhpNoticeTriggered|PhpunitDeprecationTriggered|PhpunitErrorTriggered|PhpunitWarningTriggered|PhpWarningTriggered|WarningTriggered $reason, bool $single): string
95645 {
95646 if (!$reason instanceof DeprecationTriggered && !$reason instanceof PhpDeprecationTriggered && !$reason instanceof ErrorTriggered && !$reason instanceof NoticeTriggered && !$reason instanceof PhpNoticeTriggered && !$reason instanceof WarningTriggered && !$reason instanceof PhpWarningTriggered) {
95647 return '';
95648 }
95649 return sprintf('%s%s:%d%s', $single ? '' : ' ', $reason->file(), $reason->line(), PHP_EOL);
95650 }
95651 }
95652 <?php
95653
95654 declare (strict_types=1);
95655 /*
95656 * This file is part of PHPUnit.
95657 *
95658 * (c) Sebastian Bergmann <sebastian@phpunit.de>
95659 *
95660 * For the full copyright and license information, please view the LICENSE
95661 * file that was distributed with this source code.
95662 */
95663 namespace PHPUnit\TextUI\Output\Default;
95664
95665 use PHPUnit\Event\EventFacadeIsSealedException;
95666 use PHPUnit\Event\Facade;
95667 use PHPUnit\Event\Test\PrintedUnexpectedOutput;
95668 use PHPUnit\Event\Test\PrintedUnexpectedOutputSubscriber;
95669 use PHPUnit\Event\UnknownSubscriberTypeException;
95670 use PHPUnit\TextUI\Output\Printer;
95671 final class UnexpectedOutputPrinter implements PrintedUnexpectedOutputSubscriber
95672 {
95673 private readonly Printer $printer;
95674 /**
95675 * @throws EventFacadeIsSealedException
95676 * @throws UnknownSubscriberTypeException
95677 */
95678 public function __construct(Printer $printer, Facade $facade)
95679 {
95680 $this->printer = $printer;
95681 $facade->registerSubscriber($this);
95682 }
95683 public function notify(PrintedUnexpectedOutput $event): void
95684 {
95685 $this->printer->print($event->output());
95686 }
95687 }
95688 <?php
95689
95690 declare (strict_types=1);
95691 /*
95692 * This file is part of PHPUnit.
95693 *
95694 * (c) Sebastian Bergmann <sebastian@phpunit.de>
95695 *
95696 * For the full copyright and license information, please view the LICENSE
95697 * file that was distributed with this source code.
95698 */
95699 namespace PHPUnit\TextUI\Output;
95700
95701 use const PHP_EOL;
95702 use function assert;
95703 use PHPUnit\Event\EventFacadeIsSealedException;
95704 use PHPUnit\Event\Facade as EventFacade;
95705 use PHPUnit\Event\UnknownSubscriberTypeException;
95706 use PHPUnit\Logging\TeamCity\TeamCityLogger;
95707 use PHPUnit\Logging\TestDox\TestResultCollection;
95708 use PHPUnit\Runner\DirectoryDoesNotExistException;
95709 use PHPUnit\TestRunner\TestResult\TestResult;
95710 use PHPUnit\TextUI\CannotOpenSocketException;
95711 use PHPUnit\TextUI\Configuration\Configuration;
95712 use PHPUnit\TextUI\InvalidSocketException;
95713 use PHPUnit\TextUI\Output\Default\ProgressPrinter\ProgressPrinter as DefaultProgressPrinter;
95714 use PHPUnit\TextUI\Output\Default\ResultPrinter as DefaultResultPrinter;
95715 use PHPUnit\TextUI\Output\Default\UnexpectedOutputPrinter;
95716 use PHPUnit\TextUI\Output\TestDox\ResultPrinter as TestDoxResultPrinter;
95717 use PHPUnitPHAR\SebastianBergmann\Timer\Duration;
95718 use PHPUnitPHAR\SebastianBergmann\Timer\ResourceUsageFormatter;
95719 /**
95720 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
95721 *
95722 * @internal This class is not covered by the backward compatibility promise for PHPUnit
95723 */
95724 final class Facade
95725 {
95726 private static ?\PHPUnit\TextUI\Output\Printer $printer = null;
95727 private static ?DefaultResultPrinter $defaultResultPrinter = null;
95728 private static ?TestDoxResultPrinter $testDoxResultPrinter = null;
95729 private static ?\PHPUnit\TextUI\Output\SummaryPrinter $summaryPrinter = null;
95730 private static bool $defaultProgressPrinter = \false;
95731 /**
95732 * @throws EventFacadeIsSealedException
95733 * @throws UnknownSubscriberTypeException
95734 */
95735 public static function init(Configuration $configuration, bool $extensionReplacesProgressOutput, bool $extensionReplacesResultOutput): \PHPUnit\TextUI\Output\Printer
95736 {
95737 self::createPrinter($configuration);
95738 assert(self::$printer !== null);
95739 if ($configuration->debug()) {
95740 return self::$printer;
95741 }
95742 self::createUnexpectedOutputPrinter();
95743 if (!$extensionReplacesProgressOutput) {
95744 self::createProgressPrinter($configuration);
95745 }
95746 if (!$extensionReplacesResultOutput) {
95747 self::createResultPrinter($configuration);
95748 self::createSummaryPrinter($configuration);
95749 }
95750 if ($configuration->outputIsTeamCity()) {
95751 new TeamCityLogger(\PHPUnit\TextUI\Output\DefaultPrinter::standardOutput(), EventFacade::instance());
95752 }
95753 return self::$printer;
95754 }
95755 /**
95756 * @psalm-param ?array<string, TestResultCollection> $testDoxResult
95757 */
95758 public static function printResult(TestResult $result, ?array $testDoxResult, Duration $duration): void
95759 {
95760 assert(self::$printer !== null);
95761 if ($result->numberOfTestsRun() > 0) {
95762 if (self::$defaultProgressPrinter) {
95763 self::$printer->print(PHP_EOL . PHP_EOL);
95764 }
95765 self::$printer->print((new ResourceUsageFormatter())->resourceUsage($duration) . PHP_EOL . PHP_EOL);
95766 }
95767 if (self::$testDoxResultPrinter !== null && $testDoxResult !== null) {
95768 self::$testDoxResultPrinter->print($testDoxResult);
95769 }
95770 if (self::$defaultResultPrinter !== null) {
95771 self::$defaultResultPrinter->print($result);
95772 }
95773 if (self::$summaryPrinter !== null) {
95774 self::$summaryPrinter->print($result);
95775 }
95776 }
95777 /**
95778 * @throws CannotOpenSocketException
95779 * @throws DirectoryDoesNotExistException
95780 * @throws InvalidSocketException
95781 */
95782 public static function printerFor(string $target): \PHPUnit\TextUI\Output\Printer
95783 {
95784 if ($target === 'php://stdout') {
95785 if (!self::$printer instanceof \PHPUnit\TextUI\Output\NullPrinter) {
95786 return self::$printer;
95787 }
95788 return \PHPUnit\TextUI\Output\DefaultPrinter::standardOutput();
95789 }
95790 return \PHPUnit\TextUI\Output\DefaultPrinter::from($target);
95791 }
95792 private static function createPrinter(Configuration $configuration): void
95793 {
95794 $printerNeeded = \false;
95795 if ($configuration->debug()) {
95796 $printerNeeded = \true;
95797 }
95798 if ($configuration->outputIsTeamCity()) {
95799 $printerNeeded = \true;
95800 }
95801 if ($configuration->outputIsTestDox()) {
95802 $printerNeeded = \true;
95803 }
95804 if (!$configuration->noOutput() && !$configuration->noProgress()) {
95805 $printerNeeded = \true;
95806 }
95807 if (!$configuration->noOutput() && !$configuration->noResults()) {
95808 $printerNeeded = \true;
95809 }
95810 if ($printerNeeded) {
95811 if ($configuration->outputToStandardErrorStream()) {
95812 self::$printer = \PHPUnit\TextUI\Output\DefaultPrinter::standardError();
95813 return;
95814 }
95815 self::$printer = \PHPUnit\TextUI\Output\DefaultPrinter::standardOutput();
95816 return;
95817 }
95818 self::$printer = new \PHPUnit\TextUI\Output\NullPrinter();
95819 }
95820 private static function createProgressPrinter(Configuration $configuration): void
95821 {
95822 assert(self::$printer !== null);
95823 if (!self::useDefaultProgressPrinter($configuration)) {
95824 return;
95825 }
95826 new DefaultProgressPrinter(self::$printer, EventFacade::instance(), $configuration->colors(), $configuration->columns(), $configuration->source());
95827 self::$defaultProgressPrinter = \true;
95828 }
95829 private static function useDefaultProgressPrinter(Configuration $configuration): bool
95830 {
95831 if ($configuration->noOutput()) {
95832 return \false;
95833 }
95834 if ($configuration->noProgress()) {
95835 return \false;
95836 }
95837 if ($configuration->outputIsTeamCity()) {
95838 return \false;
95839 }
95840 return \true;
95841 }
95842 private static function createResultPrinter(Configuration $configuration): void
95843 {
95844 assert(self::$printer !== null);
95845 if ($configuration->outputIsTestDox()) {
95846 self::$defaultResultPrinter = new DefaultResultPrinter(self::$printer, \true, \true, $configuration->displayDetailsOnPhpunitDeprecations() || $configuration->displayDetailsOnAllIssues(), \false, \false, \true, \false, \false, $configuration->displayDetailsOnTestsThatTriggerDeprecations() || $configuration->displayDetailsOnAllIssues(), $configuration->displayDetailsOnTestsThatTriggerErrors() || $configuration->displayDetailsOnAllIssues(), $configuration->displayDetailsOnTestsThatTriggerNotices() || $configuration->displayDetailsOnAllIssues(), $configuration->displayDetailsOnTestsThatTriggerWarnings() || $configuration->displayDetailsOnAllIssues(), $configuration->reverseDefectList());
95847 }
95848 if ($configuration->outputIsTestDox()) {
95849 self::$testDoxResultPrinter = new TestDoxResultPrinter(self::$printer, $configuration->colors());
95850 }
95851 if ($configuration->noOutput() || $configuration->noResults()) {
95852 return;
95853 }
95854 if (self::$defaultResultPrinter !== null) {
95855 return;
95856 }
95857 self::$defaultResultPrinter = new DefaultResultPrinter(self::$printer, \true, \true, $configuration->displayDetailsOnPhpunitDeprecations() || $configuration->displayDetailsOnAllIssues(), \true, \true, \true, $configuration->displayDetailsOnIncompleteTests() || $configuration->displayDetailsOnAllIssues(), $configuration->displayDetailsOnSkippedTests() || $configuration->displayDetailsOnAllIssues(), $configuration->displayDetailsOnTestsThatTriggerDeprecations() || $configuration->displayDetailsOnAllIssues(), $configuration->displayDetailsOnTestsThatTriggerErrors() || $configuration->displayDetailsOnAllIssues(), $configuration->displayDetailsOnTestsThatTriggerNotices() || $configuration->displayDetailsOnAllIssues(), $configuration->displayDetailsOnTestsThatTriggerWarnings() || $configuration->displayDetailsOnAllIssues(), $configuration->reverseDefectList());
95858 }
95859 private static function createSummaryPrinter(Configuration $configuration): void
95860 {
95861 assert(self::$printer !== null);
95862 if (($configuration->noOutput() || $configuration->noResults()) && !($configuration->outputIsTeamCity() || $configuration->outputIsTestDox())) {
95863 return;
95864 }
95865 self::$summaryPrinter = new \PHPUnit\TextUI\Output\SummaryPrinter(self::$printer, $configuration->colors());
95866 }
95867 /**
95868 * @throws EventFacadeIsSealedException
95869 * @throws UnknownSubscriberTypeException
95870 */
95871 private static function createUnexpectedOutputPrinter(): void
95872 {
95873 assert(self::$printer !== null);
95874 new UnexpectedOutputPrinter(self::$printer, EventFacade::instance());
95875 }
95876 }
95877 <?php
95878
95879 declare (strict_types=1);
95880 /*
95881 * This file is part of PHPUnit.
95882 *
95883 * (c) Sebastian Bergmann <sebastian@phpunit.de>
95884 *
95885 * For the full copyright and license information, please view the LICENSE
95886 * file that was distributed with this source code.
95887 */
95888 namespace PHPUnit\TextUI\Output;
95889
95890 use function assert;
95891 use function count;
95892 use function dirname;
95893 use function explode;
95894 use function fclose;
95895 use function fopen;
95896 use function fsockopen;
95897 use function fwrite;
95898 use function str_replace;
95899 use function str_starts_with;
95900 use PHPUnit\Runner\DirectoryDoesNotExistException;
95901 use PHPUnit\TextUI\CannotOpenSocketException;
95902 use PHPUnit\TextUI\InvalidSocketException;
95903 use PHPUnit\Util\Filesystem;
95904 /**
95905 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
95906 *
95907 * @internal This class is not covered by the backward compatibility promise for PHPUnit
95908 */
95909 final class DefaultPrinter implements \PHPUnit\TextUI\Output\Printer
95910 {
95911 /**
95912 * @psalm-var closed-resource|resource
95913 */
95914 private $stream;
95915 private readonly bool $isPhpStream;
95916 private bool $isOpen;
95917 /**
95918 * @throws CannotOpenSocketException
95919 * @throws DirectoryDoesNotExistException
95920 * @throws InvalidSocketException
95921 */
95922 public static function from(string $out): self
95923 {
95924 return new self($out);
95925 }
95926 /**
95927 * @throws CannotOpenSocketException
95928 * @throws DirectoryDoesNotExistException
95929 * @throws InvalidSocketException
95930 */
95931 public static function standardOutput(): self
95932 {
95933 return new self('php://stdout');
95934 }
95935 /**
95936 * @throws CannotOpenSocketException
95937 * @throws DirectoryDoesNotExistException
95938 * @throws InvalidSocketException
95939 */
95940 public static function standardError(): self
95941 {
95942 return new self('php://stderr');
95943 }
95944 /**
95945 * @throws CannotOpenSocketException
95946 * @throws DirectoryDoesNotExistException
95947 * @throws InvalidSocketException
95948 */
95949 private function __construct(string $out)
95950 {
95951 $this->isPhpStream = str_starts_with($out, 'php://');
95952 if (str_starts_with($out, 'socket://')) {
95953 $tmp = explode(':', str_replace('socket://', '', $out));
95954 if (count($tmp) !== 2) {
95955 throw new InvalidSocketException($out);
95956 }
95957 $stream = @fsockopen($tmp[0], (int) $tmp[1]);
95958 if ($stream === \false) {
95959 throw new CannotOpenSocketException($tmp[0], (int) $tmp[1]);
95960 }
95961 $this->stream = $stream;
95962 $this->isOpen = \true;
95963 return;
95964 }
95965 if (!$this->isPhpStream && !Filesystem::createDirectory(dirname($out))) {
95966 throw new DirectoryDoesNotExistException(dirname($out));
95967 }
95968 $this->stream = fopen($out, 'wb');
95969 $this->isOpen = \true;
95970 }
95971 public function print(string $buffer): void
95972 {
95973 assert($this->isOpen);
95974 fwrite($this->stream, $buffer);
95975 }
95976 public function flush(): void
95977 {
95978 if ($this->isOpen && $this->isPhpStream) {
95979 fclose($this->stream);
95980 $this->isOpen = \false;
95981 }
95982 }
95983 }
95984 <?php
95985
95986 declare (strict_types=1);
95987 /*
95988 * This file is part of PHPUnit.
95989 *
95990 * (c) Sebastian Bergmann <sebastian@phpunit.de>
95991 *
95992 * For the full copyright and license information, please view the LICENSE
95993 * file that was distributed with this source code.
95994 */
95995 namespace PHPUnit\TextUI\Output;
95996
95997 /**
95998 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
95999 *
96000 * @internal This class is not covered by the backward compatibility promise for PHPUnit
96001 */
96002 final class NullPrinter implements \PHPUnit\TextUI\Output\Printer
96003 {
96004 public function print(string $buffer): void
96005 {
96006 }
96007 public function flush(): void
96008 {
96009 }
96010 }
96011 <?php
96012
96013 declare (strict_types=1);
96014 /*
96015 * This file is part of PHPUnit.
96016 *
96017 * (c) Sebastian Bergmann <sebastian@phpunit.de>
96018 *
96019 * For the full copyright and license information, please view the LICENSE
96020 * file that was distributed with this source code.
96021 */
96022 namespace PHPUnit\TextUI\Output;
96023
96024 /**
96025 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
96026 *
96027 * @internal This interface is not covered by the backward compatibility promise for PHPUnit
96028 */
96029 interface Printer
96030 {
96031 public function print(string $buffer): void;
96032 public function flush(): void;
96033 }
96034 <?php
96035
96036 declare (strict_types=1);
96037 /*
96038 * This file is part of PHPUnit.
96039 *
96040 * (c) Sebastian Bergmann <sebastian@phpunit.de>
96041 *
96042 * For the full copyright and license information, please view the LICENSE
96043 * file that was distributed with this source code.
96044 */
96045 namespace PHPUnit\TextUI\Output;
96046
96047 use const PHP_EOL;
96048 use function sprintf;
96049 use PHPUnit\TestRunner\TestResult\TestResult;
96050 use PHPUnit\Util\Color;
96051 /**
96052 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
96053 *
96054 * @internal This class is not covered by the backward compatibility promise for PHPUnit
96055 */
96056 final class SummaryPrinter
96057 {
96058 private readonly \PHPUnit\TextUI\Output\Printer $printer;
96059 private readonly bool $colors;
96060 private bool $countPrinted = \false;
96061 public function __construct(\PHPUnit\TextUI\Output\Printer $printer, bool $colors)
96062 {
96063 $this->printer = $printer;
96064 $this->colors = $colors;
96065 }
96066 public function print(TestResult $result): void
96067 {
96068 if ($result->numberOfTestsRun() === 0) {
96069 $this->printWithColor('fg-black, bg-yellow', 'No tests executed!');
96070 return;
96071 }
96072 if ($result->wasSuccessful() && !$result->hasIssues() && !$result->hasTestSuiteSkippedEvents() && !$result->hasTestSkippedEvents()) {
96073 $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'));
96074 $this->printNumberOfIssuesIgnoredByBaseline($result);
96075 return;
96076 }
96077 $color = 'fg-black, bg-yellow';
96078 if ($result->wasSuccessful()) {
96079 if ($result->hasIssues()) {
96080 $this->printWithColor($color, 'OK, but there were issues!');
96081 } else {
96082 $this->printWithColor($color, 'OK, but some tests were skipped!');
96083 }
96084 } else if ($result->hasTestErroredEvents() || $result->hasTestTriggeredPhpunitErrorEvents()) {
96085 $color = 'fg-white, bg-red';
96086 $this->printWithColor($color, 'ERRORS!');
96087 } elseif ($result->hasTestFailedEvents()) {
96088 $color = 'fg-white, bg-red';
96089 $this->printWithColor($color, 'FAILURES!');
96090 }
96091 $this->printCountString($result->numberOfTestsRun(), 'Tests', $color, \true);
96092 $this->printCountString($result->numberOfAssertions(), 'Assertions', $color, \true);
96093 $this->printCountString($result->numberOfErrors(), 'Errors', $color);
96094 $this->printCountString($result->numberOfTestFailedEvents(), 'Failures', $color);
96095 $this->printCountString($result->numberOfPhpunitWarnings(), 'PHPUnit Warnings', $color);
96096 $this->printCountString($result->numberOfWarnings(), 'Warnings', $color);
96097 $this->printCountString($result->numberOfPhpOrUserDeprecations(), 'Deprecations', $color);
96098 $this->printCountString($result->numberOfPhpunitDeprecations(), 'PHPUnit Deprecations', $color);
96099 $this->printCountString($result->numberOfNotices(), 'Notices', $color);
96100 $this->printCountString($result->numberOfTestSuiteSkippedEvents() + $result->numberOfTestSkippedEvents(), 'Skipped', $color);
96101 $this->printCountString($result->numberOfTestMarkedIncompleteEvents(), 'Incomplete', $color);
96102 $this->printCountString($result->numberOfTestsWithTestConsideredRiskyEvents(), 'Risky', $color);
96103 $this->printWithColor($color, '.');
96104 $this->printNumberOfIssuesIgnoredByBaseline($result);
96105 }
96106 private function printCountString(int $count, string $name, string $color, bool $always = \false): void
96107 {
96108 if ($always || $count > 0) {
96109 $this->printWithColor($color, sprintf('%s%s: %d', $this->countPrinted ? ', ' : '', $name, $count), \false);
96110 $this->countPrinted = \true;
96111 }
96112 }
96113 private function printWithColor(string $color, string $buffer, bool $lf = \true): void
96114 {
96115 if ($this->colors) {
96116 $buffer = Color::colorizeTextBox($color, $buffer);
96117 }
96118 $this->printer->print($buffer);
96119 if ($lf) {
96120 $this->printer->print(PHP_EOL);
96121 }
96122 }
96123 private function printNumberOfIssuesIgnoredByBaseline(TestResult $result): void
96124 {
96125 if ($result->hasIssuesIgnoredByBaseline()) {
96126 $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));
96127 }
96128 }
96129 }
96130 <?php
96131
96132 declare (strict_types=1);
96133 /*
96134 * This file is part of PHPUnit.
96135 *
96136 * (c) Sebastian Bergmann <sebastian@phpunit.de>
96137 *
96138 * For the full copyright and license information, please view the LICENSE
96139 * file that was distributed with this source code.
96140 */
96141 namespace PHPUnit\TextUI\Output\TestDox;
96142
96143 use const PHP_EOL;
96144 use function array_map;
96145 use function assert;
96146 use function explode;
96147 use function implode;
96148 use function preg_match;
96149 use function preg_split;
96150 use function rtrim;
96151 use function str_starts_with;
96152 use function trim;
96153 use PHPUnit\Event\Code\Throwable;
96154 use PHPUnit\Framework\TestStatus\TestStatus;
96155 use PHPUnit\Logging\TestDox\TestResult as TestDoxTestResult;
96156 use PHPUnit\Logging\TestDox\TestResultCollection;
96157 use PHPUnit\TextUI\Output\Printer;
96158 use PHPUnit\Util\Color;
96159 /**
96160 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
96161 *
96162 * @internal This class is not covered by the backward compatibility promise for PHPUnit
96163 */
96164 final class ResultPrinter
96165 {
96166 private readonly Printer $printer;
96167 private readonly bool $colors;
96168 public function __construct(Printer $printer, bool $colors)
96169 {
96170 $this->printer = $printer;
96171 $this->colors = $colors;
96172 }
96173 /**
96174 * @psalm-param array<string, TestResultCollection> $tests
96175 */
96176 public function print(array $tests): void
96177 {
96178 foreach ($tests as $prettifiedClassName => $_tests) {
96179 $this->printPrettifiedClassName($prettifiedClassName);
96180 foreach ($_tests as $test) {
96181 $this->printTestResult($test);
96182 }
96183 $this->printer->print(PHP_EOL);
96184 }
96185 }
96186 /**
96187 * @psalm-param string $prettifiedClassName
96188 */
96189 private function printPrettifiedClassName(string $prettifiedClassName): void
96190 {
96191 $buffer = $prettifiedClassName;
96192 if ($this->colors) {
96193 $buffer = Color::colorizeTextBox('underlined', $buffer);
96194 }
96195 $this->printer->print($buffer . PHP_EOL);
96196 }
96197 private function printTestResult(TestDoxTestResult $test): void
96198 {
96199 $this->printTestResultHeader($test);
96200 $this->printTestResultBody($test);
96201 }
96202 private function printTestResultHeader(TestDoxTestResult $test): void
96203 {
96204 $buffer = ' ' . $this->symbolFor($test->status()) . ' ';
96205 if ($this->colors) {
96206 $this->printer->print(Color::colorizeTextBox($this->colorFor($test->status()), $buffer));
96207 } else {
96208 $this->printer->print($buffer);
96209 }
96210 $this->printer->print($test->test()->testDox()->prettifiedMethodName($this->colors) . PHP_EOL);
96211 }
96212 private function printTestResultBody(TestDoxTestResult $test): void
96213 {
96214 if ($test->status()->isSuccess()) {
96215 return;
96216 }
96217 if (!$test->hasThrowable()) {
96218 return;
96219 }
96220 $this->printTestResultBodyStart($test);
96221 $this->printThrowable($test);
96222 $this->printTestResultBodyEnd($test);
96223 }
96224 private function printTestResultBodyStart(TestDoxTestResult $test): void
96225 {
96226 $this->printer->print($this->prefixLines($this->prefixFor('start', $test->status()), ''));
96227 $this->printer->print(PHP_EOL);
96228 }
96229 private function printTestResultBodyEnd(TestDoxTestResult $test): void
96230 {
96231 $this->printer->print(PHP_EOL);
96232 $this->printer->print($this->prefixLines($this->prefixFor('last', $test->status()), ''));
96233 $this->printer->print(PHP_EOL);
96234 }
96235 private function printThrowable(TestDoxTestResult $test): void
96236 {
96237 $throwable = $test->throwable();
96238 assert($throwable instanceof Throwable);
96239 $message = trim($throwable->description());
96240 $stackTrace = $this->formatStackTrace($throwable->stackTrace());
96241 $diff = '';
96242 if (!empty($message) && $this->colors) {
96243 ['message' => $message, 'diff' => $diff] = $this->colorizeMessageAndDiff($message, $this->messageColorFor($test->status()));
96244 }
96245 if (!empty($message)) {
96246 $this->printer->print($this->prefixLines($this->prefixFor('message', $test->status()), $message));
96247 $this->printer->print(PHP_EOL);
96248 }
96249 if (!empty($diff)) {
96250 $this->printer->print($this->prefixLines($this->prefixFor('diff', $test->status()), $diff));
96251 $this->printer->print(PHP_EOL);
96252 }
96253 if (!empty($stackTrace)) {
96254 if (!empty($message) || !empty($diff)) {
96255 $prefix = $this->prefixFor('default', $test->status());
96256 } else {
96257 $prefix = $this->prefixFor('trace', $test->status());
96258 }
96259 $this->printer->print($this->prefixLines($prefix, PHP_EOL . $stackTrace));
96260 }
96261 }
96262 /**
96263 * @psalm-return array{message: string, diff: string}
96264 */
96265 private function colorizeMessageAndDiff(string $buffer, string $style): array
96266 {
96267 $lines = $buffer ? array_map('\rtrim', explode(PHP_EOL, $buffer)) : [];
96268 $message = [];
96269 $diff = [];
96270 $insideDiff = \false;
96271 foreach ($lines as $line) {
96272 if ($line === '--- Expected') {
96273 $insideDiff = \true;
96274 }
96275 if (!$insideDiff) {
96276 $message[] = $line;
96277 } else {
96278 if (str_starts_with($line, '-')) {
96279 $line = Color::colorize('fg-red', Color::visualizeWhitespace($line, \true));
96280 } elseif (str_starts_with($line, '+')) {
96281 $line = Color::colorize('fg-green', Color::visualizeWhitespace($line, \true));
96282 } elseif ($line === '@@ @@') {
96283 $line = Color::colorize('fg-cyan', $line);
96284 }
96285 $diff[] = $line;
96286 }
96287 }
96288 $message = implode(PHP_EOL, $message);
96289 $diff = implode(PHP_EOL, $diff);
96290 if (!empty($message)) {
96291 $message = Color::colorizeTextBox($style, $message);
96292 }
96293 return ['message' => $message, 'diff' => $diff];
96294 }
96295 private function formatStackTrace(string $stackTrace): string
96296 {
96297 if (!$this->colors) {
96298 return rtrim($stackTrace);
96299 }
96300 $lines = [];
96301 $previousPath = '';
96302 foreach (explode(PHP_EOL, $stackTrace) as $line) {
96303 if (preg_match('/^(.*):(\d+)$/', $line, $matches)) {
96304 $lines[] = Color::colorizePath($matches[1], $previousPath) . Color::dim(':') . Color::colorize('fg-blue', $matches[2]) . "\n";
96305 $previousPath = $matches[1];
96306 continue;
96307 }
96308 $lines[] = $line;
96309 $previousPath = '';
96310 }
96311 return rtrim(implode('', $lines));
96312 }
96313 private function prefixLines(string $prefix, string $message): string
96314 {
96315 return implode(PHP_EOL, array_map(static fn(string $line) => ' ' . $prefix . ($line ? ' ' . $line : ''), preg_split('/\r\n|\r|\n/', $message)));
96316 }
96317 /**
96318 * @psalm-param 'default'|'start'|'message'|'diff'|'trace'|'last' $type
96319 */
96320 private function prefixFor(string $type, TestStatus $status): string
96321 {
96322 if (!$this->colors) {
96323 return '│';
96324 }
96325 return Color::colorize($this->colorFor($status), match ($type) {
96326 'default' => '│',
96327 'start' => '┐',
96328 'message' => '├',
96329 'diff' => '┊',
96330 'trace' => '╵',
96331 'last' => '┴',
96332 });
96333 }
96334 private function colorFor(TestStatus $status): string
96335 {
96336 if ($status->isSuccess()) {
96337 return 'fg-green';
96338 }
96339 if ($status->isError()) {
96340 return 'fg-yellow';
96341 }
96342 if ($status->isFailure()) {
96343 return 'fg-red';
96344 }
96345 if ($status->isSkipped()) {
96346 return 'fg-cyan';
96347 }
96348 if ($status->isIncomplete() || $status->isDeprecation() || $status->isNotice() || $status->isRisky() || $status->isWarning()) {
96349 return 'fg-yellow';
96350 }
96351 return 'fg-blue';
96352 }
96353 private function messageColorFor(TestStatus $status): string
96354 {
96355 if ($status->isSuccess()) {
96356 return '';
96357 }
96358 if ($status->isError()) {
96359 return 'bg-yellow,fg-black';
96360 }
96361 if ($status->isFailure()) {
96362 return 'bg-red,fg-white';
96363 }
96364 if ($status->isSkipped()) {
96365 return 'fg-cyan';
96366 }
96367 if ($status->isIncomplete() || $status->isDeprecation() || $status->isNotice() || $status->isRisky() || $status->isWarning()) {
96368 return 'fg-yellow';
96369 }
96370 return 'fg-white,bg-blue';
96371 }
96372 private function symbolFor(TestStatus $status): string
96373 {
96374 if ($status->isSuccess()) {
96375 return '✔';
96376 }
96377 if ($status->isError() || $status->isFailure()) {
96378 return '✘';
96379 }
96380 if ($status->isSkipped()) {
96381 return '↩';
96382 }
96383 if ($status->isDeprecation() || $status->isNotice() || $status->isRisky() || $status->isWarning()) {
96384 return '⚠';
96385 }
96386 if ($status->isIncomplete()) {
96387 return '∅';
96388 }
96389 return '?';
96390 }
96391 }
96392 <?php
96393
96394 declare (strict_types=1);
96395 /*
96396 * This file is part of PHPUnit.
96397 *
96398 * (c) Sebastian Bergmann <sebastian@phpunit.de>
96399 *
96400 * For the full copyright and license information, please view the LICENSE
96401 * file that was distributed with this source code.
96402 */
96403 namespace PHPUnit\TextUI;
96404
96405 use PHPUnit\TestRunner\TestResult\TestResult;
96406 use PHPUnit\TextUI\Configuration\Configuration;
96407 /**
96408 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
96409 *
96410 * @internal This class is not covered by the backward compatibility promise for PHPUnit
96411 */
96412 final class ShellExitCodeCalculator
96413 {
96414 private const SUCCESS_EXIT = 0;
96415 private const FAILURE_EXIT = 1;
96416 private const EXCEPTION_EXIT = 2;
96417 public function calculate(Configuration $configuration, TestResult $result): int
96418 {
96419 $failOnDeprecation = \false;
96420 $failOnPhpunitDeprecation = \false;
96421 $failOnPhpunitWarning = \false;
96422 $failOnEmptyTestSuite = \false;
96423 $failOnIncomplete = \false;
96424 $failOnNotice = \false;
96425 $failOnRisky = \false;
96426 $failOnSkipped = \false;
96427 $failOnWarning = \false;
96428 if ($configuration->failOnAllIssues()) {
96429 $failOnDeprecation = \true;
96430 $failOnPhpunitDeprecation = \true;
96431 $failOnPhpunitWarning = \true;
96432 $failOnEmptyTestSuite = \true;
96433 $failOnIncomplete = \true;
96434 $failOnNotice = \true;
96435 $failOnRisky = \true;
96436 $failOnSkipped = \true;
96437 $failOnWarning = \true;
96438 }
96439 if ($configuration->failOnDeprecation()) {
96440 $failOnDeprecation = \true;
96441 }
96442 if ($configuration->doNotFailOnDeprecation()) {
96443 $failOnDeprecation = \false;
96444 }
96445 if ($configuration->failOnPhpunitDeprecation()) {
96446 $failOnPhpunitDeprecation = \true;
96447 }
96448 if ($configuration->doNotFailOnPhpunitDeprecation()) {
96449 $failOnPhpunitDeprecation = \false;
96450 }
96451 if ($configuration->failOnPhpunitWarning()) {
96452 $failOnPhpunitWarning = \true;
96453 }
96454 if ($configuration->doNotFailOnPhpunitWarning()) {
96455 $failOnPhpunitWarning = \false;
96456 }
96457 if ($configuration->failOnEmptyTestSuite()) {
96458 $failOnEmptyTestSuite = \true;
96459 }
96460 if ($configuration->doNotFailOnEmptyTestSuite()) {
96461 $failOnEmptyTestSuite = \false;
96462 }
96463 if ($configuration->failOnIncomplete()) {
96464 $failOnIncomplete = \true;
96465 }
96466 if ($configuration->doNotFailOnIncomplete()) {
96467 $failOnIncomplete = \false;
96468 }
96469 if ($configuration->failOnNotice()) {
96470 $failOnNotice = \true;
96471 }
96472 if ($configuration->doNotFailOnNotice()) {
96473 $failOnNotice = \false;
96474 }
96475 if ($configuration->failOnRisky()) {
96476 $failOnRisky = \true;
96477 }
96478 if ($configuration->doNotFailOnRisky()) {
96479 $failOnRisky = \false;
96480 }
96481 if ($configuration->failOnSkipped()) {
96482 $failOnSkipped = \true;
96483 }
96484 if ($configuration->doNotFailOnSkipped()) {
96485 $failOnSkipped = \false;
96486 }
96487 if ($configuration->failOnWarning()) {
96488 $failOnWarning = \true;
96489 }
96490 if ($configuration->doNotFailOnWarning()) {
96491 $failOnWarning = \false;
96492 }
96493 $returnCode = self::FAILURE_EXIT;
96494 if ($result->wasSuccessful()) {
96495 $returnCode = self::SUCCESS_EXIT;
96496 }
96497 if ($failOnEmptyTestSuite && !$result->hasTests()) {
96498 $returnCode = self::FAILURE_EXIT;
96499 }
96500 if ($failOnDeprecation && $result->hasPhpOrUserDeprecations()) {
96501 $returnCode = self::FAILURE_EXIT;
96502 }
96503 if ($failOnPhpunitDeprecation && $result->hasPhpunitDeprecations()) {
96504 $returnCode = self::FAILURE_EXIT;
96505 }
96506 if ($failOnPhpunitWarning && $result->hasPhpunitWarnings()) {
96507 $returnCode = self::FAILURE_EXIT;
96508 }
96509 if ($failOnIncomplete && $result->hasIncompleteTests()) {
96510 $returnCode = self::FAILURE_EXIT;
96511 }
96512 if ($failOnNotice && $result->hasNotices()) {
96513 $returnCode = self::FAILURE_EXIT;
96514 }
96515 if ($failOnRisky && $result->hasRiskyTests()) {
96516 $returnCode = self::FAILURE_EXIT;
96517 }
96518 if ($failOnSkipped && $result->hasSkippedTests()) {
96519 $returnCode = self::FAILURE_EXIT;
96520 }
96521 if ($failOnWarning && $result->hasWarnings()) {
96522 $returnCode = self::FAILURE_EXIT;
96523 }
96524 if ($result->hasErrors()) {
96525 $returnCode = self::EXCEPTION_EXIT;
96526 }
96527 return $returnCode;
96528 }
96529 }
96530 <?php
96531
96532 declare (strict_types=1);
96533 /*
96534 * This file is part of PHPUnit.
96535 *
96536 * (c) Sebastian Bergmann <sebastian@phpunit.de>
96537 *
96538 * For the full copyright and license information, please view the LICENSE
96539 * file that was distributed with this source code.
96540 */
96541 namespace PHPUnit\TextUI;
96542
96543 use function mt_srand;
96544 use PHPUnit\Event;
96545 use PHPUnit\Framework\TestSuite;
96546 use PHPUnit\Runner\ResultCache\ResultCache;
96547 use PHPUnit\Runner\TestSuiteSorter;
96548 use PHPUnit\TextUI\Configuration\Configuration;
96549 use Throwable;
96550 /**
96551 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
96552 *
96553 * @internal This class is not covered by the backward compatibility promise for PHPUnit
96554 */
96555 final class TestRunner
96556 {
96557 /**
96558 * @throws RuntimeException
96559 */
96560 public function run(Configuration $configuration, ResultCache $resultCache, TestSuite $suite): void
96561 {
96562 try {
96563 Event\Facade::emitter()->testRunnerStarted();
96564 if ($configuration->executionOrder() === TestSuiteSorter::ORDER_RANDOMIZED) {
96565 mt_srand($configuration->randomOrderSeed());
96566 }
96567 if ($configuration->executionOrder() !== TestSuiteSorter::ORDER_DEFAULT || $configuration->executionOrderDefects() !== TestSuiteSorter::ORDER_DEFAULT || $configuration->resolveDependencies()) {
96568 $resultCache->load();
96569 (new TestSuiteSorter($resultCache))->reorderTestsInSuite($suite, $configuration->executionOrder(), $configuration->resolveDependencies(), $configuration->executionOrderDefects());
96570 Event\Facade::emitter()->testSuiteSorted($configuration->executionOrder(), $configuration->executionOrderDefects(), $configuration->resolveDependencies());
96571 }
96572 (new \PHPUnit\TextUI\TestSuiteFilterProcessor())->process($configuration, $suite);
96573 Event\Facade::emitter()->testRunnerExecutionStarted(Event\TestSuite\TestSuiteBuilder::from($suite));
96574 $suite->run();
96575 Event\Facade::emitter()->testRunnerExecutionFinished();
96576 Event\Facade::emitter()->testRunnerFinished();
96577 } catch (Throwable $t) {
96578 throw new \PHPUnit\TextUI\RuntimeException($t->getMessage(), (int) $t->getCode(), $t);
96579 }
96580 }
96581 }
96582 <?php
96583
96584 declare (strict_types=1);
96585 /*
96586 * This file is part of PHPUnit.
96587 *
96588 * (c) Sebastian Bergmann <sebastian@phpunit.de>
96589 *
96590 * For the full copyright and license information, please view the LICENSE
96591 * file that was distributed with this source code.
96592 */
96593 namespace PHPUnit\TextUI;
96594
96595 use function array_map;
96596 use PHPUnit\Event;
96597 use PHPUnit\Framework\TestSuite;
96598 use PHPUnit\Runner\Filter\Factory;
96599 use PHPUnit\TextUI\Configuration\Configuration;
96600 use PHPUnit\TextUI\Configuration\FilterNotConfiguredException;
96601 /**
96602 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
96603 *
96604 * @internal This class is not covered by the backward compatibility promise for PHPUnit
96605 */
96606 final class TestSuiteFilterProcessor
96607 {
96608 /**
96609 * @throws Event\RuntimeException
96610 * @throws FilterNotConfiguredException
96611 */
96612 public function process(Configuration $configuration, TestSuite $suite): void
96613 {
96614 $factory = new Factory();
96615 if (!$configuration->hasFilter() && !$configuration->hasGroups() && !$configuration->hasExcludeGroups() && !$configuration->hasTestsCovering() && !$configuration->hasTestsUsing()) {
96616 return;
96617 }
96618 if ($configuration->hasExcludeGroups()) {
96619 $factory->addExcludeGroupFilter($configuration->excludeGroups());
96620 }
96621 if ($configuration->hasGroups()) {
96622 $factory->addIncludeGroupFilter($configuration->groups());
96623 }
96624 if ($configuration->hasTestsCovering()) {
96625 $factory->addIncludeGroupFilter(array_map(static fn(string $name): string => '__phpunit_covers_' . $name, $configuration->testsCovering()));
96626 }
96627 if ($configuration->hasTestsUsing()) {
96628 $factory->addIncludeGroupFilter(array_map(static fn(string $name): string => '__phpunit_uses_' . $name, $configuration->testsUsing()));
96629 }
96630 if ($configuration->hasFilter()) {
96631 $factory->addNameFilter($configuration->filter());
96632 }
96633 $suite->injectFilter($factory);
96634 Event\Facade::emitter()->testSuiteFiltered(Event\TestSuite\TestSuiteBuilder::from($suite));
96635 }
96636 }
96637 <?php
96638
96639 declare (strict_types=1);
96640 /*
96641 * This file is part of PHPUnit.
96642 *
96643 * (c) Sebastian Bergmann <sebastian@phpunit.de>
96644 *
96645 * For the full copyright and license information, please view the LICENSE
96646 * file that was distributed with this source code.
96647 */
96648 namespace PHPUnit\Util;
96649
96650 use Throwable;
96651 /**
96652 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
96653 *
96654 * @internal This class is not covered by the backward compatibility promise for PHPUnit
96655 */
96656 final class Cloner
96657 {
96658 /**
96659 * @psalm-template OriginalType of object
96660 *
96661 * @psalm-param OriginalType $original
96662 *
96663 * @psalm-return OriginalType
96664 */
96665 public static function clone(object $original): object
96666 {
96667 try {
96668 return clone $original;
96669 } catch (Throwable) {
96670 return $original;
96671 }
96672 }
96673 }
96674 <?php
96675
96676 declare (strict_types=1);
96677 /*
96678 * This file is part of PHPUnit.
96679 *
96680 * (c) Sebastian Bergmann <sebastian@phpunit.de>
96681 *
96682 * For the full copyright and license information, please view the LICENSE
96683 * file that was distributed with this source code.
96684 */
96685 namespace PHPUnit\Util;
96686
96687 use const DIRECTORY_SEPARATOR;
96688 use const PHP_EOL;
96689 use function array_map;
96690 use function count;
96691 use function explode;
96692 use function implode;
96693 use function max;
96694 use function min;
96695 use function preg_replace;
96696 use function preg_replace_callback;
96697 use function preg_split;
96698 use function sprintf;
96699 use function str_pad;
96700 use function strtr;
96701 use function trim;
96702 /**
96703 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
96704 *
96705 * @internal This class is not covered by the backward compatibility promise for PHPUnit
96706 */
96707 final class Color
96708 {
96709 /**
96710 * @psalm-var array<string,string>
96711 */
96712 private const WHITESPACE_MAP = [' ' => '·', "\t" => '⇥'];
96713 /**
96714 * @psalm-var array<string,string>
96715 */
96716 private const WHITESPACE_EOL_MAP = [' ' => '·', "\t" => '⇥', "\n" => '↵', "\r" => '⟵'];
96717 /**
96718 * @psalm-var array<string,string>
96719 */
96720 private static array $ansiCodes = ['reset' => '0', 'bold' => '1', 'dim' => '2', 'dim-reset' => '22', 'underlined' => '4', 'fg-default' => '39', 'fg-black' => '30', 'fg-red' => '31', 'fg-green' => '32', 'fg-yellow' => '33', 'fg-blue' => '34', 'fg-magenta' => '35', 'fg-cyan' => '36', 'fg-white' => '37', 'bg-default' => '49', 'bg-black' => '40', 'bg-red' => '41', 'bg-green' => '42', 'bg-yellow' => '43', 'bg-blue' => '44', 'bg-magenta' => '45', 'bg-cyan' => '46', 'bg-white' => '47'];
96721 public static function colorize(string $color, string $buffer): string
96722 {
96723 if (trim($buffer) === '') {
96724 return $buffer;
96725 }
96726 $codes = array_map('\trim', explode(',', $color));
96727 $styles = [];
96728 foreach ($codes as $code) {
96729 if (isset(self::$ansiCodes[$code])) {
96730 $styles[] = self::$ansiCodes[$code] ?? '';
96731 }
96732 }
96733 if (empty($styles)) {
96734 return $buffer;
96735 }
96736 return self::optimizeColor(sprintf("\x1b[%sm", implode(';', $styles)) . $buffer . "\x1b[0m");
96737 }
96738 public static function colorizeTextBox(string $color, string $buffer): string
96739 {
96740 $lines = preg_split('/\r\n|\r|\n/', $buffer);
96741 $padding = max(array_map('\strlen', $lines));
96742 $styledLines = [];
96743 foreach ($lines as $line) {
96744 $styledLines[] = self::colorize($color, str_pad($line, $padding));
96745 }
96746 return implode(PHP_EOL, $styledLines);
96747 }
96748 public static function colorizePath(string $path, ?string $previousPath = null, bool $colorizeFilename = \false): string
96749 {
96750 if ($previousPath === null) {
96751 $previousPath = '';
96752 }
96753 $path = explode(DIRECTORY_SEPARATOR, $path);
96754 $previousPath = explode(DIRECTORY_SEPARATOR, $previousPath);
96755 for ($i = 0; $i < min(count($path), count($previousPath)); $i++) {
96756 if ($path[$i] === $previousPath[$i]) {
96757 $path[$i] = self::dim($path[$i]);
96758 }
96759 }
96760 if ($colorizeFilename) {
96761 $last = count($path) - 1;
96762 $path[$last] = preg_replace_callback('/([\-_.]+|phpt$)/', static fn($matches) => self::dim($matches[0]), $path[$last]);
96763 }
96764 return self::optimizeColor(implode(self::dim(DIRECTORY_SEPARATOR), $path));
96765 }
96766 public static function dim(string $buffer): string
96767 {
96768 if (trim($buffer) === '') {
96769 return $buffer;
96770 }
96771 return "\x1b[2m{$buffer}\x1b[22m";
96772 }
96773 public static function visualizeWhitespace(string $buffer, bool $visualizeEOL = \false): string
96774 {
96775 $replaceMap = $visualizeEOL ? self::WHITESPACE_EOL_MAP : self::WHITESPACE_MAP;
96776 return preg_replace_callback('/\s+/', static fn($matches) => self::dim(strtr($matches[0], $replaceMap)), $buffer);
96777 }
96778 private static function optimizeColor(string $buffer): string
96779 {
96780 return preg_replace(["/\x1b\\[22m\x1b\\[2m/", "/\x1b\\[([^m]*)m\x1b\\[([1-9][0-9;]*)m/", "/(\x1b\\[[^m]*m)+(\x1b\\[0m)/"], ['', "\x1b[\$1;\$2m", '$2'], $buffer);
96781 }
96782 }
96783 <?php
96784
96785 declare (strict_types=1);
96786 /*
96787 * This file is part of PHPUnit.
96788 *
96789 * (c) Sebastian Bergmann <sebastian@phpunit.de>
96790 *
96791 * For the full copyright and license information, please view the LICENSE
96792 * file that was distributed with this source code.
96793 */
96794 namespace PHPUnit\Util;
96795
96796 use Throwable;
96797 /**
96798 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
96799 *
96800 * @internal This interface is not covered by the backward compatibility promise for PHPUnit
96801 */
96802 interface Exception extends Throwable
96803 {
96804 }
96805 <?php
96806
96807 declare (strict_types=1);
96808 /*
96809 * This file is part of PHPUnit.
96810 *
96811 * (c) Sebastian Bergmann <sebastian@phpunit.de>
96812 *
96813 * For the full copyright and license information, please view the LICENSE
96814 * file that was distributed with this source code.
96815 */
96816 namespace PHPUnit\Util;
96817
96818 use function sprintf;
96819 use RuntimeException;
96820 /**
96821 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
96822 *
96823 * @internal This class is not covered by the backward compatibility promise for PHPUnit
96824 */
96825 final class InvalidDirectoryException extends RuntimeException implements \PHPUnit\Util\Exception
96826 {
96827 public function __construct(string $directory)
96828 {
96829 parent::__construct(sprintf('"%s" is not a directory', $directory));
96830 }
96831 }
96832 <?php
96833
96834 declare (strict_types=1);
96835 /*
96836 * This file is part of PHPUnit.
96837 *
96838 * (c) Sebastian Bergmann <sebastian@phpunit.de>
96839 *
96840 * For the full copyright and license information, please view the LICENSE
96841 * file that was distributed with this source code.
96842 */
96843 namespace PHPUnit\Util;
96844
96845 use RuntimeException;
96846 /**
96847 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
96848 *
96849 * @internal This class is not covered by the backward compatibility promise for PHPUnit
96850 */
96851 final class InvalidJsonException extends RuntimeException implements \PHPUnit\Util\Exception
96852 {
96853 }
96854 <?php
96855
96856 declare (strict_types=1);
96857 /*
96858 * This file is part of PHPUnit.
96859 *
96860 * (c) Sebastian Bergmann <sebastian@phpunit.de>
96861 *
96862 * For the full copyright and license information, please view the LICENSE
96863 * file that was distributed with this source code.
96864 */
96865 namespace PHPUnit\Util;
96866
96867 use function sprintf;
96868 use RuntimeException;
96869 /**
96870 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
96871 *
96872 * @internal This class is not covered by the backward compatibility promise for PHPUnit
96873 */
96874 final class InvalidVersionOperatorException extends RuntimeException implements \PHPUnit\Util\Exception
96875 {
96876 public function __construct(string $operator)
96877 {
96878 parent::__construct(sprintf('"%s" is not a valid version_compare() operator', $operator));
96879 }
96880 }
96881 <?php
96882
96883 declare (strict_types=1);
96884 /*
96885 * This file is part of PHPUnit.
96886 *
96887 * (c) Sebastian Bergmann <sebastian@phpunit.de>
96888 *
96889 * For the full copyright and license information, please view the LICENSE
96890 * file that was distributed with this source code.
96891 */
96892 namespace PHPUnit\Util\PHP;
96893
96894 use PHPUnit\Util\Exception;
96895 use RuntimeException;
96896 /**
96897 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
96898 *
96899 * @internal This class is not covered by the backward compatibility promise for PHPUnit
96900 */
96901 final class PhpProcessException extends RuntimeException implements Exception
96902 {
96903 }
96904 <?php
96905
96906 declare (strict_types=1);
96907 /*
96908 * This file is part of PHPUnit.
96909 *
96910 * (c) Sebastian Bergmann <sebastian@phpunit.de>
96911 *
96912 * For the full copyright and license information, please view the LICENSE
96913 * file that was distributed with this source code.
96914 */
96915 namespace PHPUnit\Util\Xml;
96916
96917 use PHPUnit\Util\Exception;
96918 use RuntimeException;
96919 /**
96920 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
96921 *
96922 * @internal This class is not covered by the backward compatibility promise for PHPUnit
96923 */
96924 final class XmlException extends RuntimeException implements Exception
96925 {
96926 }
96927 <?php
96928
96929 declare (strict_types=1);
96930 /*
96931 * This file is part of PHPUnit.
96932 *
96933 * (c) Sebastian Bergmann <sebastian@phpunit.de>
96934 *
96935 * For the full copyright and license information, please view the LICENSE
96936 * file that was distributed with this source code.
96937 */
96938 namespace PHPUnit\Util;
96939
96940 use const PHP_OS_FAMILY;
96941 use function class_exists;
96942 use function defined;
96943 use function dirname;
96944 use function is_dir;
96945 use function realpath;
96946 use function str_starts_with;
96947 use function sys_get_temp_dir;
96948 use PHPUnitPHAR\Composer\Autoload\ClassLoader;
96949 use PHPUnitPHAR\DeepCopy\DeepCopy;
96950 use PHPUnitPHAR\PharIo\Manifest\Manifest;
96951 use PHPUnitPHAR\PharIo\Version\Version as PharIoVersion;
96952 use PHPUnitPHAR\PhpParser\Parser;
96953 use PHPUnit\Framework\TestCase;
96954 use ReflectionClass;
96955 use PHPUnitPHAR\SebastianBergmann\CliParser\Parser as CliParser;
96956 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\CodeCoverage;
96957 use PHPUnitPHAR\SebastianBergmann\CodeUnit\CodeUnit;
96958 use PHPUnitPHAR\SebastianBergmann\CodeUnitReverseLookup\Wizard;
96959 use PHPUnitPHAR\SebastianBergmann\Comparator\Comparator;
96960 use PHPUnitPHAR\SebastianBergmann\Complexity\Calculator;
96961 use PHPUnitPHAR\SebastianBergmann\Diff\Diff;
96962 use PHPUnitPHAR\SebastianBergmann\Environment\Runtime;
96963 use PHPUnitPHAR\SebastianBergmann\Exporter\Exporter;
96964 use PHPUnitPHAR\SebastianBergmann\FileIterator\Facade as FileIteratorFacade;
96965 use PHPUnitPHAR\SebastianBergmann\GlobalState\Snapshot;
96966 use PHPUnitPHAR\SebastianBergmann\Invoker\Invoker;
96967 use PHPUnitPHAR\SebastianBergmann\LinesOfCode\Counter;
96968 use PHPUnitPHAR\SebastianBergmann\ObjectEnumerator\Enumerator;
96969 use PHPUnitPHAR\SebastianBergmann\ObjectReflector\ObjectReflector;
96970 use PHPUnitPHAR\SebastianBergmann\RecursionContext\Context;
96971 use PHPUnitPHAR\SebastianBergmann\Template\Template;
96972 use PHPUnitPHAR\SebastianBergmann\Timer\Timer;
96973 use PHPUnitPHAR\SebastianBergmann\Type\TypeName;
96974 use PHPUnitPHAR\SebastianBergmann\Version;
96975 use PHPUnitPHAR\TheSeer\Tokenizer\Tokenizer;
96976 /**
96977 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
96978 */
96979 final class ExcludeList
96980 {
96981 /**
96982 * @psalm-var array<string,int>
96983 */
96984 private const EXCLUDED_CLASS_NAMES = [
96985 // composer
96986 ClassLoader::class => 1,
96987 // myclabs/deepcopy
96988 DeepCopy::class => 1,
96989 // nikic/php-parser
96990 Parser::class => 1,
96991 // phar-io/manifest
96992 Manifest::class => 1,
96993 // phar-io/version
96994 PharIoVersion::class => 1,
96995 // phpunit/phpunit
96996 TestCase::class => 2,
96997 // phpunit/php-code-coverage
96998 CodeCoverage::class => 1,
96999 // phpunit/php-file-iterator
97000 FileIteratorFacade::class => 1,
97001 // phpunit/php-invoker
97002 Invoker::class => 1,
97003 // phpunit/php-text-template
97004 Template::class => 1,
97005 // phpunit/php-timer
97006 Timer::class => 1,
97007 // sebastian/cli-parser
97008 CliParser::class => 1,
97009 // sebastian/code-unit
97010 CodeUnit::class => 1,
97011 // sebastian/code-unit-reverse-lookup
97012 Wizard::class => 1,
97013 // sebastian/comparator
97014 Comparator::class => 1,
97015 // sebastian/complexity
97016 Calculator::class => 1,
97017 // sebastian/diff
97018 Diff::class => 1,
97019 // sebastian/environment
97020 Runtime::class => 1,
97021 // sebastian/exporter
97022 Exporter::class => 1,
97023 // sebastian/global-state
97024 Snapshot::class => 1,
97025 // sebastian/lines-of-code
97026 Counter::class => 1,
97027 // sebastian/object-enumerator
97028 Enumerator::class => 1,
97029 // sebastian/object-reflector
97030 ObjectReflector::class => 1,
97031 // sebastian/recursion-context
97032 Context::class => 1,
97033 // sebastian/type
97034 TypeName::class => 1,
97035 // sebastian/version
97036 Version::class => 1,
97037 // theseer/tokenizer
97038 Tokenizer::class => 1,
97039 ];
97040 /**
97041 * @psalm-var list<string>
97042 */
97043 private static array $directories = [];
97044 private static bool $initialized = \false;
97045 private readonly bool $enabled;
97046 /**
97047 * @psalm-param non-empty-string $directory
97048 *
97049 * @throws InvalidDirectoryException
97050 */
97051 public static function addDirectory(string $directory): void
97052 {
97053 if (!is_dir($directory)) {
97054 throw new \PHPUnit\Util\InvalidDirectoryException($directory);
97055 }
97056 self::$directories[] = realpath($directory);
97057 }
97058 public function __construct(?bool $enabled = null)
97059 {
97060 if ($enabled === null) {
97061 $enabled = !defined('PHPUNIT_TESTSUITE');
97062 }
97063 $this->enabled = $enabled;
97064 }
97065 /**
97066 * @psalm-return list<string>
97067 */
97068 public function getExcludedDirectories(): array
97069 {
97070 self::initialize();
97071 return self::$directories;
97072 }
97073 public function isExcluded(string $file): bool
97074 {
97075 if (!$this->enabled) {
97076 return \false;
97077 }
97078 self::initialize();
97079 foreach (self::$directories as $directory) {
97080 if (str_starts_with($file, $directory)) {
97081 return \true;
97082 }
97083 }
97084 return \false;
97085 }
97086 private static function initialize(): void
97087 {
97088 if (self::$initialized) {
97089 return;
97090 }
97091 foreach (self::EXCLUDED_CLASS_NAMES as $className => $parent) {
97092 if (!class_exists($className)) {
97093 continue;
97094 }
97095 $directory = (new ReflectionClass($className))->getFileName();
97096 for ($i = 0; $i < $parent; $i++) {
97097 $directory = dirname($directory);
97098 }
97099 self::$directories[] = $directory;
97100 }
97101 /**
97102 * Hide process isolation workaround on Windows:
97103 * tempnam() prefix is limited to first 3 characters.
97104 *
97105 * @see https://php.net/manual/en/function.tempnam.php
97106 */
97107 if (PHP_OS_FAMILY === 'Windows') {
97108 // @codeCoverageIgnoreStart
97109 self::$directories[] = sys_get_temp_dir() . '\PHP';
97110 // @codeCoverageIgnoreEnd
97111 }
97112 self::$initialized = \true;
97113 }
97114 }
97115 <?php
97116
97117 declare (strict_types=1);
97118 /*
97119 * This file is part of PHPUnit.
97120 *
97121 * (c) Sebastian Bergmann <sebastian@phpunit.de>
97122 *
97123 * For the full copyright and license information, please view the LICENSE
97124 * file that was distributed with this source code.
97125 */
97126 namespace PHPUnit\Util;
97127
97128 use function is_array;
97129 use function is_scalar;
97130 use PHPUnitPHAR\SebastianBergmann\RecursionContext\Context;
97131 /**
97132 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
97133 *
97134 * @internal This class is not covered by the backward compatibility promise for PHPUnit
97135 *
97136 * @deprecated
97137 */
97138 final class Exporter
97139 {
97140 public static function export(mixed $value, bool $exportObjects = \false): string
97141 {
97142 if (self::isExportable($value) || $exportObjects) {
97143 return (new \PHPUnitPHAR\SebastianBergmann\Exporter\Exporter())->export($value);
97144 }
97145 return '{enable export of objects to see this value}';
97146 }
97147 private static function isExportable(mixed &$value, ?Context $context = null): bool
97148 {
97149 if (is_scalar($value) || $value === null) {
97150 return \true;
97151 }
97152 if (!is_array($value)) {
97153 return \false;
97154 }
97155 if (!$context) {
97156 $context = new Context();
97157 }
97158 if ($context->contains($value) !== \false) {
97159 return \true;
97160 }
97161 $array = $value;
97162 $context->add($value);
97163 foreach ($array as &$_value) {
97164 if (!self::isExportable($_value, $context)) {
97165 return \false;
97166 }
97167 }
97168 return \true;
97169 }
97170 }
97171 <?php
97172
97173 declare (strict_types=1);
97174 /*
97175 * This file is part of PHPUnit.
97176 *
97177 * (c) Sebastian Bergmann <sebastian@phpunit.de>
97178 *
97179 * For the full copyright and license information, please view the LICENSE
97180 * file that was distributed with this source code.
97181 */
97182 namespace PHPUnit\Util;
97183
97184 use const DIRECTORY_SEPARATOR;
97185 use function basename;
97186 use function dirname;
97187 use function is_dir;
97188 use function mkdir;
97189 use function realpath;
97190 use function str_starts_with;
97191 /**
97192 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
97193 *
97194 * @internal This class is not covered by the backward compatibility promise for PHPUnit
97195 */
97196 final class Filesystem
97197 {
97198 public static function createDirectory(string $directory): bool
97199 {
97200 return !(!is_dir($directory) && !@mkdir($directory, 0777, \true) && !is_dir($directory));
97201 }
97202 /**
97203 * @psalm-param non-empty-string $path
97204 *
97205 * @return false|non-empty-string
97206 */
97207 public static function resolveStreamOrFile(string $path): false|string
97208 {
97209 if (str_starts_with($path, 'php://') || str_starts_with($path, 'socket://')) {
97210 return $path;
97211 }
97212 $directory = dirname($path);
97213 if (is_dir($directory)) {
97214 return realpath($directory) . DIRECTORY_SEPARATOR . basename($path);
97215 }
97216 return \false;
97217 }
97218 }
97219 <?php
97220
97221 declare (strict_types=1);
97222 /*
97223 * This file is part of PHPUnit.
97224 *
97225 * (c) Sebastian Bergmann <sebastian@phpunit.de>
97226 *
97227 * For the full copyright and license information, please view the LICENSE
97228 * file that was distributed with this source code.
97229 */
97230 namespace PHPUnit\Util;
97231
97232 use function array_unshift;
97233 use function defined;
97234 use function in_array;
97235 use function is_file;
97236 use function realpath;
97237 use function sprintf;
97238 use function str_starts_with;
97239 use PHPUnit\Framework\Exception;
97240 use PHPUnit\Framework\PhptAssertionFailedError;
97241 use Throwable;
97242 /**
97243 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
97244 *
97245 * @internal This class is not covered by the backward compatibility promise for PHPUnit
97246 */
97247 final class Filter
97248 {
97249 /**
97250 * @throws Exception
97251 */
97252 public static function getFilteredStacktrace(Throwable $t, bool $unwrap = \true): string
97253 {
97254 $filteredStacktrace = '';
97255 if ($t instanceof PhptAssertionFailedError) {
97256 $eTrace = $t->syntheticTrace();
97257 $eFile = $t->syntheticFile();
97258 $eLine = $t->syntheticLine();
97259 } elseif ($t instanceof Exception) {
97260 $eTrace = $t->getSerializableTrace();
97261 $eFile = $t->getFile();
97262 $eLine = $t->getLine();
97263 } else {
97264 if ($unwrap && $t->getPrevious()) {
97265 $t = $t->getPrevious();
97266 }
97267 $eTrace = $t->getTrace();
97268 $eFile = $t->getFile();
97269 $eLine = $t->getLine();
97270 }
97271 if (!self::frameExists($eTrace, $eFile, $eLine)) {
97272 array_unshift($eTrace, ['file' => $eFile, 'line' => $eLine]);
97273 }
97274 $prefix = defined('__PHPUNIT_PHAR_ROOT__') ? __PHPUNIT_PHAR_ROOT__ : \false;
97275 $excludeList = new \PHPUnit\Util\ExcludeList();
97276 foreach ($eTrace as $frame) {
97277 if (self::shouldPrintFrame($frame, $prefix, $excludeList)) {
97278 $filteredStacktrace .= sprintf("%s:%s\n", $frame['file'], $frame['line'] ?? '?');
97279 }
97280 }
97281 return $filteredStacktrace;
97282 }
97283 private static function shouldPrintFrame(array $frame, false|string $prefix, \PHPUnit\Util\ExcludeList $excludeList): bool
97284 {
97285 if (!isset($frame['file'])) {
97286 return \false;
97287 }
97288 $file = $frame['file'];
97289 $fileIsNotPrefixed = $prefix === \false || !str_starts_with($file, $prefix);
97290 // @see https://github.com/sebastianbergmann/phpunit/issues/4033
97291 if (isset($GLOBALS['_SERVER']['SCRIPT_NAME'])) {
97292 $script = realpath($GLOBALS['_SERVER']['SCRIPT_NAME']);
97293 } else {
97294 $script = '';
97295 }
97296 return $fileIsNotPrefixed && $file !== $script && self::fileIsExcluded($file, $excludeList) && is_file($file);
97297 }
97298 private static function fileIsExcluded(string $file, \PHPUnit\Util\ExcludeList $excludeList): bool
97299 {
97300 return (empty($GLOBALS['__PHPUNIT_ISOLATION_EXCLUDE_LIST']) || !in_array($file, $GLOBALS['__PHPUNIT_ISOLATION_EXCLUDE_LIST'], \true)) && !$excludeList->isExcluded($file);
97301 }
97302 private static function frameExists(array $trace, string $file, int $line): bool
97303 {
97304 foreach ($trace as $frame) {
97305 if (isset($frame['file'], $frame['line']) && $frame['file'] === $file && $frame['line'] === $line) {
97306 return \true;
97307 }
97308 }
97309 return \false;
97310 }
97311 }
97312 <?php
97313
97314 declare (strict_types=1);
97315 /*
97316 * This file is part of PHPUnit.
97317 *
97318 * (c) Sebastian Bergmann <sebastian@phpunit.de>
97319 *
97320 * For the full copyright and license information, please view the LICENSE
97321 * file that was distributed with this source code.
97322 */
97323 namespace PHPUnit\Util;
97324
97325 use const PHP_MAJOR_VERSION;
97326 use const PHP_MINOR_VERSION;
97327 use function array_keys;
97328 use function array_reverse;
97329 use function array_shift;
97330 use function defined;
97331 use function get_defined_constants;
97332 use function get_included_files;
97333 use function in_array;
97334 use function ini_get_all;
97335 use function is_array;
97336 use function is_file;
97337 use function is_scalar;
97338 use function preg_match;
97339 use function serialize;
97340 use function sprintf;
97341 use function str_ends_with;
97342 use function str_starts_with;
97343 use function strtr;
97344 use function var_export;
97345 use Closure;
97346 /**
97347 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
97348 *
97349 * @internal This class is not covered by the backward compatibility promise for PHPUnit
97350 */
97351 final class GlobalState
97352 {
97353 /**
97354 * @psalm-var list<string>
97355 */
97356 private const SUPER_GLOBAL_ARRAYS = ['_ENV', '_POST', '_GET', '_COOKIE', '_SERVER', '_FILES', '_REQUEST'];
97357 /**
97358 * @psalm-var array<string, array<string, true>>
97359 */
97360 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], '8.4' => ['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.5' => ['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.6' => ['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]];
97361 /**
97362 * @throws Exception
97363 */
97364 public static function getIncludedFilesAsString(): string
97365 {
97366 return self::processIncludedFilesAsString(get_included_files());
97367 }
97368 /**
97369 * @psalm-param list<string> $files
97370 *
97371 * @throws Exception
97372 */
97373 public static function processIncludedFilesAsString(array $files): string
97374 {
97375 $excludeList = new \PHPUnit\Util\ExcludeList();
97376 $prefix = \false;
97377 $result = '';
97378 if (defined('__PHPUNIT_PHAR__')) {
97379 $prefix = 'phar://' . __PHPUNIT_PHAR__ . '/';
97380 }
97381 // Do not process bootstrap script
97382 array_shift($files);
97383 // If bootstrap script was a Composer bin proxy, skip the second entry as well
97384 if (str_ends_with(strtr($files[0], '\\', '/'), '/phpunit/phpunit/phpunit')) {
97385 array_shift($files);
97386 }
97387 foreach (array_reverse($files) as $file) {
97388 if (!empty($GLOBALS['__PHPUNIT_ISOLATION_EXCLUDE_LIST']) && in_array($file, $GLOBALS['__PHPUNIT_ISOLATION_EXCLUDE_LIST'], \true)) {
97389 continue;
97390 }
97391 if ($prefix !== \false && str_starts_with($file, $prefix)) {
97392 continue;
97393 }
97394 // Skip virtual file system protocols
97395 if (preg_match('/^(vfs|phpvfs[a-z0-9]+):/', $file)) {
97396 continue;
97397 }
97398 if (!$excludeList->isExcluded($file) && is_file($file)) {
97399 $result = 'require_once \'' . $file . "';\n" . $result;
97400 }
97401 }
97402 return $result;
97403 }
97404 public static function getIniSettingsAsString(): string
97405 {
97406 $result = '';
97407 foreach (ini_get_all(null, \false) as $key => $value) {
97408 if (self::isIniSettingDeprecated($key)) {
97409 continue;
97410 }
97411 $result .= sprintf('@ini_set(%s, %s);' . "\n", self::exportVariable($key), self::exportVariable((string) $value));
97412 }
97413 return $result;
97414 }
97415 public static function getConstantsAsString(): string
97416 {
97417 $constants = get_defined_constants(\true);
97418 $result = '';
97419 if (isset($constants['user'])) {
97420 foreach ($constants['user'] as $name => $value) {
97421 $result .= sprintf('if (!defined(\'%s\')) define(\'%s\', %s);' . "\n", $name, $name, self::exportVariable($value));
97422 }
97423 }
97424 return $result;
97425 }
97426 public static function getGlobalsAsString(): string
97427 {
97428 $result = '';
97429 foreach (self::SUPER_GLOBAL_ARRAYS as $superGlobalArray) {
97430 if (isset($GLOBALS[$superGlobalArray]) && is_array($GLOBALS[$superGlobalArray])) {
97431 foreach (array_keys($GLOBALS[$superGlobalArray]) as $key) {
97432 if ($GLOBALS[$superGlobalArray][$key] instanceof Closure) {
97433 continue;
97434 }
97435 $result .= sprintf('$GLOBALS[\'%s\'][\'%s\'] = %s;' . "\n", $superGlobalArray, $key, self::exportVariable($GLOBALS[$superGlobalArray][$key]));
97436 }
97437 }
97438 }
97439 $excludeList = self::SUPER_GLOBAL_ARRAYS;
97440 $excludeList[] = 'GLOBALS';
97441 foreach (array_keys($GLOBALS) as $key) {
97442 if (!$GLOBALS[$key] instanceof Closure && !in_array($key, $excludeList, \true)) {
97443 $result .= sprintf('$GLOBALS[\'%s\'] = %s;' . "\n", $key, self::exportVariable($GLOBALS[$key]));
97444 }
97445 }
97446 return $result;
97447 }
97448 private static function exportVariable(mixed $variable): string
97449 {
97450 if (is_scalar($variable) || $variable === null || is_array($variable) && self::arrayOnlyContainsScalars($variable)) {
97451 return var_export($variable, \true);
97452 }
97453 return 'unserialize(' . var_export(serialize($variable), \true) . ')';
97454 }
97455 private static function arrayOnlyContainsScalars(array $array): bool
97456 {
97457 $result = \true;
97458 foreach ($array as $element) {
97459 if (is_array($element)) {
97460 $result = self::arrayOnlyContainsScalars($element);
97461 } elseif (!is_scalar($element) && $element !== null) {
97462 $result = \false;
97463 }
97464 if (!$result) {
97465 break;
97466 }
97467 }
97468 return $result;
97469 }
97470 private static function isIniSettingDeprecated(string $iniSetting): bool
97471 {
97472 return isset(self::DEPRECATED_INI_SETTINGS[PHP_MAJOR_VERSION . '.' . PHP_MINOR_VERSION][$iniSetting]);
97473 }
97474 }
97475 <?php
97476
97477 declare (strict_types=1);
97478 /*
97479 * This file is part of PHPUnit.
97480 *
97481 * (c) Sebastian Bergmann <sebastian@phpunit.de>
97482 *
97483 * For the full copyright and license information, please view the LICENSE
97484 * file that was distributed with this source code.
97485 */
97486 namespace PHPUnit\Util\Http;
97487
97488 /**
97489 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
97490 *
97491 * @internal This interface is not covered by the backward compatibility promise for PHPUnit
97492 */
97493 interface Downloader
97494 {
97495 /**
97496 * @param non-empty-string $url
97497 */
97498 public function download(string $url): false|string;
97499 }
97500 <?php
97501
97502 declare (strict_types=1);
97503 /*
97504 * This file is part of PHPUnit.
97505 *
97506 * (c) Sebastian Bergmann <sebastian@phpunit.de>
97507 *
97508 * For the full copyright and license information, please view the LICENSE
97509 * file that was distributed with this source code.
97510 */
97511 namespace PHPUnit\Util\Http;
97512
97513 use function file_get_contents;
97514 /**
97515 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
97516 *
97517 * @internal This class is not covered by the backward compatibility promise for PHPUnit
97518 *
97519 * @codeCoverageIgnore
97520 */
97521 final class PhpDownloader implements \PHPUnit\Util\Http\Downloader
97522 {
97523 /**
97524 * @param non-empty-string $url
97525 */
97526 public function download(string $url): false|string
97527 {
97528 return file_get_contents($url);
97529 }
97530 }
97531 <?php
97532
97533 declare (strict_types=1);
97534 /*
97535 * This file is part of PHPUnit.
97536 *
97537 * (c) Sebastian Bergmann <sebastian@phpunit.de>
97538 *
97539 * For the full copyright and license information, please view the LICENSE
97540 * file that was distributed with this source code.
97541 */
97542 namespace PHPUnit\Util;
97543
97544 use const JSON_PRETTY_PRINT;
97545 use const JSON_UNESCAPED_SLASHES;
97546 use const JSON_UNESCAPED_UNICODE;
97547 use const SORT_STRING;
97548 use function is_object;
97549 use function is_scalar;
97550 use function json_decode;
97551 use function json_encode;
97552 use function json_last_error;
97553 use function ksort;
97554 /**
97555 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
97556 *
97557 * @internal This class is not covered by the backward compatibility promise for PHPUnit
97558 */
97559 final class Json
97560 {
97561 /**
97562 * @throws InvalidJsonException
97563 */
97564 public static function prettify(string $json): string
97565 {
97566 $decodedJson = json_decode($json, \false);
97567 if (json_last_error()) {
97568 throw new \PHPUnit\Util\InvalidJsonException();
97569 }
97570 return json_encode($decodedJson, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
97571 }
97572 /**
97573 * To allow comparison of JSON strings, first process them into a consistent
97574 * format so that they can be compared as strings.
97575 *
97576 * @return array ($error, $canonicalized_json) The $error parameter is used
97577 * to indicate an error decoding the json. This is used to avoid ambiguity
97578 * with JSON strings consisting entirely of 'null' or 'false'.
97579 */
97580 public static function canonicalize(string $json): array
97581 {
97582 $decodedJson = json_decode($json);
97583 if (json_last_error()) {
97584 return [\true, null];
97585 }
97586 self::recursiveSort($decodedJson);
97587 $reencodedJson = json_encode($decodedJson);
97588 return [\false, $reencodedJson];
97589 }
97590 /**
97591 * JSON object keys are unordered while PHP array keys are ordered.
97592 *
97593 * Sort all array keys to ensure both the expected and actual values have
97594 * their keys in the same order.
97595 */
97596 private static function recursiveSort(mixed &$json): void
97597 {
97598 // Nulls, empty arrays, and scalars need no further handling.
97599 if (!$json || is_scalar($json)) {
97600 return;
97601 }
97602 $isObject = is_object($json);
97603 if ($isObject) {
97604 // Objects need to be sorted during canonicalization to ensure
97605 // correct comparsion since JSON objects are unordered. It must be
97606 // kept as an object so that the value correctly stays as a JSON
97607 // object instead of potentially being converted to an array. This
97608 // approach ensures that numeric string JSON keys are preserved and
97609 // don't risk being flattened due to PHP's array semantics.
97610 // See #2919, #4584, #4674
97611 $json = (array) $json;
97612 ksort($json, SORT_STRING);
97613 }
97614 foreach ($json as &$value) {
97615 self::recursiveSort($value);
97616 }
97617 if ($isObject) {
97618 $json = (object) $json;
97619 }
97620 }
97621 }
97622 <?php
97623
97624 declare (strict_types=1);
97625 /*
97626 * This file is part of PHPUnit.
97627 *
97628 * (c) Sebastian Bergmann <sebastian@phpunit.de>
97629 *
97630 * For the full copyright and license information, please view the LICENSE
97631 * file that was distributed with this source code.
97632 */
97633 namespace PHPUnit\Util\PHP;
97634
97635 use const PHP_BINARY;
97636 use const PHP_SAPI;
97637 use function array_keys;
97638 use function array_merge;
97639 use function assert;
97640 use function explode;
97641 use function file_get_contents;
97642 use function ini_get_all;
97643 use function is_file;
97644 use function restore_error_handler;
97645 use function set_error_handler;
97646 use function trim;
97647 use function unlink;
97648 use function unserialize;
97649 use ErrorException;
97650 use PHPUnit\Event\Code\TestMethodBuilder;
97651 use PHPUnit\Event\Code\ThrowableBuilder;
97652 use PHPUnit\Event\Facade;
97653 use PHPUnit\Event\NoPreviousThrowableException;
97654 use PHPUnit\Event\TestData\MoreThanOneDataSetFromDataProviderException;
97655 use PHPUnit\Framework\AssertionFailedError;
97656 use PHPUnit\Framework\Exception;
97657 use PHPUnit\Framework\Test;
97658 use PHPUnit\Framework\TestCase;
97659 use PHPUnit\Runner\CodeCoverage;
97660 use PHPUnit\TestRunner\TestResult\PassedTests;
97661 use PHPUnitPHAR\SebastianBergmann\Environment\Runtime;
97662 /**
97663 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
97664 *
97665 * @internal This class is not covered by the backward compatibility promise for PHPUnit
97666 */
97667 abstract class AbstractPhpProcess
97668 {
97669 protected bool $stderrRedirection = \false;
97670 protected string $stdin = '';
97671 protected string $arguments = '';
97672 /**
97673 * @psalm-var array<string, string>
97674 */
97675 protected array $env = [];
97676 public static function factory(): self
97677 {
97678 return new \PHPUnit\Util\PHP\DefaultPhpProcess();
97679 }
97680 /**
97681 * Defines if should use STDERR redirection or not.
97682 *
97683 * Then $stderrRedirection is TRUE, STDERR is redirected to STDOUT.
97684 */
97685 public function setUseStderrRedirection(bool $stderrRedirection): void
97686 {
97687 $this->stderrRedirection = $stderrRedirection;
97688 }
97689 /**
97690 * Returns TRUE if uses STDERR redirection or FALSE if not.
97691 */
97692 public function useStderrRedirection(): bool
97693 {
97694 return $this->stderrRedirection;
97695 }
97696 /**
97697 * Sets the input string to be sent via STDIN.
97698 */
97699 public function setStdin(string $stdin): void
97700 {
97701 $this->stdin = $stdin;
97702 }
97703 /**
97704 * Returns the input string to be sent via STDIN.
97705 */
97706 public function getStdin(): string
97707 {
97708 return $this->stdin;
97709 }
97710 /**
97711 * Sets the string of arguments to pass to the php job.
97712 */
97713 public function setArgs(string $arguments): void
97714 {
97715 $this->arguments = $arguments;
97716 }
97717 /**
97718 * Returns the string of arguments to pass to the php job.
97719 */
97720 public function getArgs(): string
97721 {
97722 return $this->arguments;
97723 }
97724 /**
97725 * Sets the array of environment variables to start the child process with.
97726 *
97727 * @psalm-param array<string, string> $env
97728 */
97729 public function setEnv(array $env): void
97730 {
97731 $this->env = $env;
97732 }
97733 /**
97734 * Returns the array of environment variables to start the child process with.
97735 */
97736 public function getEnv(): array
97737 {
97738 return $this->env;
97739 }
97740 /**
97741 * Runs a single test in a separate PHP process.
97742 *
97743 * @throws \PHPUnit\Runner\Exception
97744 * @throws Exception
97745 * @throws MoreThanOneDataSetFromDataProviderException
97746 * @throws NoPreviousThrowableException
97747 */
97748 public function runTestJob(string $job, Test $test, string $processResultFile): void
97749 {
97750 $_result = $this->runJob($job);
97751 $processResult = '';
97752 if (is_file($processResultFile)) {
97753 $processResult = file_get_contents($processResultFile);
97754 @unlink($processResultFile);
97755 }
97756 $this->processChildResult($test, $processResult, $_result['stderr']);
97757 }
97758 /**
97759 * Returns the command based into the configurations.
97760 *
97761 * @return string[]
97762 */
97763 public function getCommand(array $settings, ?string $file = null): array
97764 {
97765 $runtime = new Runtime();
97766 $command = [];
97767 $command[] = PHP_BINARY;
97768 if ($runtime->hasPCOV()) {
97769 $settings = array_merge($settings, $runtime->getCurrentSettings(array_keys(ini_get_all('pcov'))));
97770 } elseif ($runtime->hasXdebug()) {
97771 $settings = array_merge($settings, $runtime->getCurrentSettings(array_keys(ini_get_all('xdebug'))));
97772 }
97773 $command = array_merge($command, $this->settingsToParameters($settings));
97774 if (PHP_SAPI === 'phpdbg') {
97775 $command[] = '-qrr';
97776 if (!$file) {
97777 $command[] = 's=';
97778 }
97779 }
97780 if ($file) {
97781 $command[] = '-f';
97782 $command[] = $file;
97783 }
97784 if ($this->arguments) {
97785 if (!$file) {
97786 $command[] = '--';
97787 }
97788 foreach (explode(' ', $this->arguments) as $arg) {
97789 $command[] = trim($arg);
97790 }
97791 }
97792 return $command;
97793 }
97794 /**
97795 * Runs a single job (PHP code) using a separate PHP process.
97796 */
97797 abstract public function runJob(string $job, array $settings = []): array;
97798 /**
97799 * @return list<string>
97800 */
97801 protected function settingsToParameters(array $settings): array
97802 {
97803 $buffer = [];
97804 foreach ($settings as $setting) {
97805 $buffer[] = '-d';
97806 $buffer[] = $setting;
97807 }
97808 return $buffer;
97809 }
97810 /**
97811 * @throws \PHPUnit\Runner\Exception
97812 * @throws Exception
97813 * @throws MoreThanOneDataSetFromDataProviderException
97814 * @throws NoPreviousThrowableException
97815 */
97816 private function processChildResult(Test $test, string $stdout, string $stderr): void
97817 {
97818 if (!empty($stderr)) {
97819 $exception = new Exception(trim($stderr));
97820 assert($test instanceof TestCase);
97821 Facade::emitter()->testErrored(TestMethodBuilder::fromTestCase($test), ThrowableBuilder::from($exception));
97822 return;
97823 }
97824 set_error_handler(
97825 /**
97826 * @throws ErrorException
97827 */
97828 static function (int $errno, string $errstr, string $errfile, int $errline): never {
97829 throw new ErrorException($errstr, $errno, $errno, $errfile, $errline);
97830 }
97831 );
97832 try {
97833 $childResult = unserialize($stdout);
97834 restore_error_handler();
97835 if ($childResult === \false) {
97836 $exception = new AssertionFailedError('Test was run in child process and ended unexpectedly');
97837 assert($test instanceof TestCase);
97838 Facade::emitter()->testErrored(TestMethodBuilder::fromTestCase($test), ThrowableBuilder::from($exception));
97839 Facade::emitter()->testFinished(TestMethodBuilder::fromTestCase($test), 0);
97840 }
97841 } catch (ErrorException $e) {
97842 restore_error_handler();
97843 $childResult = \false;
97844 $exception = new Exception(trim($stdout), 0, $e);
97845 assert($test instanceof TestCase);
97846 Facade::emitter()->testErrored(TestMethodBuilder::fromTestCase($test), ThrowableBuilder::from($exception));
97847 }
97848 if ($childResult !== \false) {
97849 Facade::instance()->forward($childResult['events']);
97850 PassedTests::instance()->import($childResult['passedTests']);
97851 assert($test instanceof TestCase);
97852 $test->setResult($childResult['testResult']);
97853 $test->addToAssertionCount($childResult['numAssertions']);
97854 if (CodeCoverage::instance()->isActive() && $childResult['codeCoverage'] instanceof \PHPUnitPHAR\SebastianBergmann\CodeCoverage\CodeCoverage) {
97855 CodeCoverage::instance()->codeCoverage()->merge($childResult['codeCoverage']);
97856 }
97857 }
97858 }
97859 }
97860 <?php
97861
97862 declare (strict_types=1);
97863 /*
97864 * This file is part of PHPUnit.
97865 *
97866 * (c) Sebastian Bergmann <sebastian@phpunit.de>
97867 *
97868 * For the full copyright and license information, please view the LICENSE
97869 * file that was distributed with this source code.
97870 */
97871 namespace PHPUnit\Util\PHP;
97872
97873 use function array_merge;
97874 use function fclose;
97875 use function file_put_contents;
97876 use function fwrite;
97877 use function is_array;
97878 use function is_resource;
97879 use function proc_close;
97880 use function proc_open;
97881 use function stream_get_contents;
97882 use function sys_get_temp_dir;
97883 use function tempnam;
97884 use function unlink;
97885 use PHPUnit\Framework\Exception;
97886 /**
97887 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
97888 *
97889 * @internal This class is not covered by the backward compatibility promise for PHPUnit
97890 */
97891 class DefaultPhpProcess extends \PHPUnit\Util\PHP\AbstractPhpProcess
97892 {
97893 private ?string $tempFile = null;
97894 /**
97895 * Runs a single job (PHP code) using a separate PHP process.
97896 *
97897 * @throws Exception
97898 * @throws PhpProcessException
97899 *
97900 * @psalm-return array{stdout: string, stderr: string}
97901 */
97902 public function runJob(string $job, array $settings = []): array
97903 {
97904 if ($this->stdin) {
97905 if (!($this->tempFile = tempnam(sys_get_temp_dir(), 'phpunit_')) || file_put_contents($this->tempFile, $job) === \false) {
97906 throw new \PHPUnit\Util\PHP\PhpProcessException('Unable to write temporary file');
97907 }
97908 $job = $this->stdin;
97909 }
97910 return $this->runProcess($job, $settings);
97911 }
97912 /**
97913 * Handles creating the child process and returning the STDOUT and STDERR.
97914 *
97915 * @throws Exception
97916 * @throws PhpProcessException
97917 *
97918 * @psalm-return array{stdout: string, stderr: string}
97919 */
97920 protected function runProcess(string $job, array $settings): array
97921 {
97922 $env = null;
97923 if ($this->env) {
97924 $env = $_SERVER ?? [];
97925 unset($env['argv'], $env['argc']);
97926 $env = array_merge($env, $this->env);
97927 foreach ($env as $envKey => $envVar) {
97928 if (is_array($envVar)) {
97929 unset($env[$envKey]);
97930 }
97931 }
97932 }
97933 $pipeSpec = [0 => ['pipe', 'r'], 1 => ['pipe', 'w'], 2 => ['pipe', 'w']];
97934 if ($this->stderrRedirection) {
97935 $pipeSpec[2] = ['redirect', 1];
97936 }
97937 $process = proc_open($this->getCommand($settings, $this->tempFile), $pipeSpec, $pipes, null, $env);
97938 if (!is_resource($process)) {
97939 throw new \PHPUnit\Util\PHP\PhpProcessException('Unable to spawn worker process');
97940 }
97941 if ($job) {
97942 $this->process($pipes[0], $job);
97943 }
97944 fclose($pipes[0]);
97945 $stderr = $stdout = '';
97946 if (isset($pipes[1])) {
97947 $stdout = stream_get_contents($pipes[1]);
97948 fclose($pipes[1]);
97949 }
97950 if (isset($pipes[2])) {
97951 $stderr = stream_get_contents($pipes[2]);
97952 fclose($pipes[2]);
97953 }
97954 proc_close($process);
97955 $this->cleanup();
97956 return ['stdout' => $stdout, 'stderr' => $stderr];
97957 }
97958 /**
97959 * @param resource $pipe
97960 */
97961 protected function process($pipe, string $job): void
97962 {
97963 fwrite($pipe, $job);
97964 }
97965 protected function cleanup(): void
97966 {
97967 if ($this->tempFile) {
97968 unlink($this->tempFile);
97969 }
97970 }
97971 }
97972 <?php declare(strict_types=1);
97973 use PHPUnit\Event\Facade;
97974 use PHPUnit\Runner\CodeCoverage;
97975 use PHPUnit\TextUI\Configuration\Registry as ConfigurationRegistry;
97976 use PHPUnit\TextUI\Configuration\CodeCoverageFilterRegistry;
97977 use PHPUnit\TextUI\Configuration\PhpHandler;
97978 use PHPUnit\TestRunner\TestResult\PassedTests;
97979
97980 // php://stdout does not obey output buffering. Any output would break
97981 // unserialization of child process results in the parent process.
97982 if (!defined('STDOUT')) {
97983 define('STDOUT', fopen('php://temp', 'w+b'));
97984 define('STDERR', fopen('php://stderr', 'wb'));
97985 }
97986
97987 {iniSettings}
97988 ini_set('display_errors', 'stderr');
97989 set_include_path('{include_path}');
97990
97991 $composerAutoload = {composerAutoload};
97992 $phar = {phar};
97993
97994 ob_start();
97995
97996 if ($composerAutoload) {
97997 require_once $composerAutoload;
97998
97999 define('PHPUNIT_COMPOSER_INSTALL', $composerAutoload);
98000 } else if ($phar) {
98001 require $phar;
98002 }
98003
98004 function __phpunit_run_isolated_test()
98005 {
98006 $dispatcher = Facade::instance()->initForIsolation(
98007 PHPUnit\Event\Telemetry\HRTime::fromSecondsAndNanoseconds(
98008 {offsetSeconds},
98009 {offsetNanoseconds}
98010 ),
98011 {exportObjects},
98012 );
98013
98014 require_once '{filename}';
98015
98016 if ({collectCodeCoverageInformation}) {
98017 CodeCoverage::instance()->init(ConfigurationRegistry::get(), CodeCoverageFilterRegistry::instance(), true);
98018 CodeCoverage::instance()->ignoreLines({linesToBeIgnored});
98019 }
98020
98021 $test = new {className}('{name}');
98022
98023 $test->setData('{dataName}', unserialize('{data}'));
98024 $test->setDependencyInput(unserialize('{dependencyInput}'));
98025 $test->setInIsolation(true);
98026
98027 ob_end_clean();
98028
98029 $test->run();
98030
98031 $output = '';
98032
98033 if (!$test->expectsOutput()) {
98034 $output = $test->output();
98035 }
98036
98037 ini_set('xdebug.scream', '0');
98038
98039 // Not every STDOUT target stream is rewindable
98040 @rewind(STDOUT);
98041
98042 if ($stdout = @stream_get_contents(STDOUT)) {
98043 $output = $stdout . $output;
98044 $streamMetaData = stream_get_meta_data(STDOUT);
98045
98046 if (!empty($streamMetaData['stream_type']) && 'STDIO' === $streamMetaData['stream_type']) {
98047 @ftruncate(STDOUT, 0);
98048 @rewind(STDOUT);
98049 }
98050 }
98051
98052 file_put_contents(
98053 '{processResultFile}',
98054 serialize(
98055 [
98056 'testResult' => $test->result(),
98057 'codeCoverage' => {collectCodeCoverageInformation} ? CodeCoverage::instance()->codeCoverage() : null,
98058 'numAssertions' => $test->numberOfAssertionsPerformed(),
98059 'output' => $output,
98060 'events' => $dispatcher->flush(),
98061 'passedTests' => PassedTests::instance()
98062 ]
98063 )
98064 );
98065 }
98066
98067 function __phpunit_error_handler($errno, $errstr, $errfile, $errline)
98068 {
98069 return true;
98070 }
98071
98072 set_error_handler('__phpunit_error_handler');
98073
98074 {constants}
98075 {included_files}
98076 {globals}
98077
98078 restore_error_handler();
98079
98080 ConfigurationRegistry::loadFrom('{serializedConfiguration}');
98081 (new PhpHandler)->handle(ConfigurationRegistry::get()->php());
98082
98083 if ('{bootstrap}' !== '') {
98084 require_once '{bootstrap}';
98085 }
98086
98087 __phpunit_run_isolated_test();
98088 <?php declare(strict_types=1);
98089 use PHPUnit\Event\Facade;
98090 use PHPUnit\Runner\CodeCoverage;
98091 use PHPUnit\TextUI\Configuration\Registry as ConfigurationRegistry;
98092 use PHPUnit\TextUI\Configuration\CodeCoverageFilterRegistry;
98093 use PHPUnit\TextUI\Configuration\PhpHandler;
98094 use PHPUnit\TestRunner\TestResult\PassedTests;
98095
98096 // php://stdout does not obey output buffering. Any output would break
98097 // unserialization of child process results in the parent process.
98098 if (!defined('STDOUT')) {
98099 define('STDOUT', fopen('php://temp', 'w+b'));
98100 define('STDERR', fopen('php://stderr', 'wb'));
98101 }
98102
98103 {iniSettings}
98104 ini_set('display_errors', 'stderr');
98105 set_include_path('{include_path}');
98106
98107 $composerAutoload = {composerAutoload};
98108 $phar = {phar};
98109
98110 ob_start();
98111
98112 if ($composerAutoload) {
98113 require_once $composerAutoload;
98114
98115 define('PHPUNIT_COMPOSER_INSTALL', $composerAutoload);
98116 } else if ($phar) {
98117 require $phar;
98118 }
98119
98120 function __phpunit_run_isolated_test()
98121 {
98122 $dispatcher = Facade::instance()->initForIsolation(
98123 PHPUnit\Event\Telemetry\HRTime::fromSecondsAndNanoseconds(
98124 {offsetSeconds},
98125 {offsetNanoseconds}
98126 ),
98127 {exportObjects},
98128 );
98129
98130 require_once '{filename}';
98131
98132 if ({collectCodeCoverageInformation}) {
98133 CodeCoverage::instance()->init(ConfigurationRegistry::get(), CodeCoverageFilterRegistry::instance(), true);
98134 CodeCoverage::instance()->ignoreLines({linesToBeIgnored});
98135 }
98136
98137 $test = new {className}('{methodName}');
98138
98139 $test->setData('{dataName}', unserialize('{data}'));
98140 $test->setDependencyInput(unserialize('{dependencyInput}'));
98141 $test->setInIsolation(true);
98142
98143 ob_end_clean();
98144
98145 $test->run();
98146
98147 $output = '';
98148
98149 if (!$test->expectsOutput()) {
98150 $output = $test->output();
98151 }
98152
98153 ini_set('xdebug.scream', '0');
98154
98155 // Not every STDOUT target stream is rewindable
98156 @rewind(STDOUT);
98157
98158 if ($stdout = @stream_get_contents(STDOUT)) {
98159 $output = $stdout . $output;
98160 $streamMetaData = stream_get_meta_data(STDOUT);
98161
98162 if (!empty($streamMetaData['stream_type']) && 'STDIO' === $streamMetaData['stream_type']) {
98163 @ftruncate(STDOUT, 0);
98164 @rewind(STDOUT);
98165 }
98166 }
98167
98168 file_put_contents(
98169 '{processResultFile}',
98170 serialize(
98171 [
98172 'testResult' => $test->result(),
98173 'codeCoverage' => {collectCodeCoverageInformation} ? CodeCoverage::instance()->codeCoverage() : null,
98174 'numAssertions' => $test->numberOfAssertionsPerformed(),
98175 'output' => $output,
98176 'events' => $dispatcher->flush(),
98177 'passedTests' => PassedTests::instance()
98178 ]
98179 )
98180 );
98181 }
98182
98183 function __phpunit_error_handler($errno, $errstr, $errfile, $errline)
98184 {
98185 return true;
98186 }
98187
98188 set_error_handler('__phpunit_error_handler');
98189
98190 {constants}
98191 {included_files}
98192 {globals}
98193
98194 restore_error_handler();
98195
98196 ConfigurationRegistry::loadFrom('{serializedConfiguration}');
98197 (new PhpHandler)->handle(ConfigurationRegistry::get()->php());
98198
98199 if ('{bootstrap}' !== '') {
98200 require_once '{bootstrap}';
98201 }
98202
98203 __phpunit_run_isolated_test();
98204 <?php declare(strict_types=1);
98205 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\CodeCoverage;
98206 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Driver\Selector;
98207 use PHPUnitPHAR\SebastianBergmann\CodeCoverage\Filter;
98208
98209 $composerAutoload = {composerAutoload};
98210 $phar = {phar};
98211
98212 ob_start();
98213
98214 $GLOBALS['__PHPUNIT_ISOLATION_EXCLUDE_LIST'][] = '{job}';
98215
98216 if ($composerAutoload) {
98217 require_once $composerAutoload;
98218
98219 define('PHPUNIT_COMPOSER_INSTALL', $composerAutoload);
98220 } else if ($phar) {
98221 require $phar;
98222 }
98223
98224 $coverage = null;
98225
98226 if ('{bootstrap}' !== '') {
98227 require_once '{bootstrap}';
98228 }
98229
98230 if (class_exists('PHPUnitPHAR\SebastianBergmann\CodeCoverage\CodeCoverage')) {
98231 $filter = new Filter;
98232
98233 $coverage = new CodeCoverage(
98234 (new Selector)->{driverMethod}($filter),
98235 $filter
98236 );
98237
98238 if ({codeCoverageCacheDirectory}) {
98239 $coverage->cacheStaticAnalysis({codeCoverageCacheDirectory});
98240 }
98241
98242 $coverage->start(__FILE__);
98243 }
98244
98245 register_shutdown_function(
98246 function() use ($coverage) {
98247 $output = null;
98248
98249 if ($coverage) {
98250 $output = $coverage->stop();
98251 }
98252
98253 file_put_contents('{coverageFile}', serialize($output));
98254 }
98255 );
98256
98257 ob_end_clean();
98258
98259 require '{job}';
98260 <?php
98261
98262 declare (strict_types=1);
98263 /*
98264 * This file is part of PHPUnit.
98265 *
98266 * (c) Sebastian Bergmann <sebastian@phpunit.de>
98267 *
98268 * For the full copyright and license information, please view the LICENSE
98269 * file that was distributed with this source code.
98270 */
98271 namespace PHPUnit\Util;
98272
98273 use function array_keys;
98274 use function array_merge;
98275 use function array_reverse;
98276 use PHPUnit\Framework\Assert;
98277 use PHPUnit\Framework\TestCase;
98278 use ReflectionClass;
98279 use ReflectionException;
98280 use ReflectionMethod;
98281 /**
98282 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
98283 *
98284 * @internal This class is not covered by the backward compatibility promise for PHPUnit
98285 */
98286 final class Reflection
98287 {
98288 /**
98289 * @psalm-param class-string $className
98290 * @psalm-param non-empty-string $methodName
98291 *
98292 * @psalm-return array{file: non-empty-string, line: non-negative-int}
98293 */
98294 public static function sourceLocationFor(string $className, string $methodName): array
98295 {
98296 try {
98297 $reflector = new ReflectionMethod($className, $methodName);
98298 $file = $reflector->getFileName();
98299 $line = $reflector->getStartLine();
98300 } catch (ReflectionException) {
98301 $file = 'unknown';
98302 $line = 0;
98303 }
98304 return ['file' => $file, 'line' => $line];
98305 }
98306 /**
98307 * @psalm-return list<ReflectionMethod>
98308 */
98309 public static function publicMethodsInTestClass(ReflectionClass $class): array
98310 {
98311 return self::filterAndSortMethods($class, ReflectionMethod::IS_PUBLIC, \true);
98312 }
98313 /**
98314 * @psalm-return list<ReflectionMethod>
98315 */
98316 public static function methodsInTestClass(ReflectionClass $class): array
98317 {
98318 return self::filterAndSortMethods($class, null, \false);
98319 }
98320 /**
98321 * @psalm-return list<ReflectionMethod>
98322 */
98323 private static function filterAndSortMethods(ReflectionClass $class, ?int $filter, bool $sortHighestToLowest): array
98324 {
98325 $methodsByClass = [];
98326 foreach ($class->getMethods($filter) as $method) {
98327 $declaringClassName = $method->getDeclaringClass()->getName();
98328 if ($declaringClassName === TestCase::class) {
98329 continue;
98330 }
98331 if ($declaringClassName === Assert::class) {
98332 continue;
98333 }
98334 if (!isset($methodsByClass[$declaringClassName])) {
98335 $methodsByClass[$declaringClassName] = [];
98336 }
98337 $methodsByClass[$declaringClassName][] = $method;
98338 }
98339 $classNames = array_keys($methodsByClass);
98340 if ($sortHighestToLowest) {
98341 $classNames = array_reverse($classNames);
98342 }
98343 $methods = [];
98344 foreach ($classNames as $className) {
98345 $methods = array_merge($methods, $methodsByClass[$className]);
98346 }
98347 return $methods;
98348 }
98349 }
98350 <?php
98351
98352 declare (strict_types=1);
98353 /*
98354 * This file is part of PHPUnit.
98355 *
98356 * (c) Sebastian Bergmann <sebastian@phpunit.de>
98357 *
98358 * For the full copyright and license information, please view the LICENSE
98359 * file that was distributed with this source code.
98360 */
98361 namespace PHPUnit\Util;
98362
98363 use function str_starts_with;
98364 use PHPUnit\Metadata\Parser\Registry;
98365 use ReflectionMethod;
98366 /**
98367 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
98368 *
98369 * @internal This class is not covered by the backward compatibility promise for PHPUnit
98370 */
98371 final class Test
98372 {
98373 public static function isTestMethod(ReflectionMethod $method): bool
98374 {
98375 if (!$method->isPublic()) {
98376 return \false;
98377 }
98378 if (str_starts_with($method->getName(), 'test')) {
98379 return \true;
98380 }
98381 $metadata = Registry::parser()->forMethod($method->getDeclaringClass()->getName(), $method->getName());
98382 return $metadata->isTest()->isNotEmpty();
98383 }
98384 }
98385 <?php
98386
98387 declare (strict_types=1);
98388 /*
98389 * This file is part of PHPUnit.
98390 *
98391 * (c) Sebastian Bergmann <sebastian@phpunit.de>
98392 *
98393 * For the full copyright and license information, please view the LICENSE
98394 * file that was distributed with this source code.
98395 */
98396 namespace PHPUnit\Util;
98397
98398 use function trim;
98399 use PHPUnit\Framework\ExpectationFailedException;
98400 use PHPUnit\Framework\PhptAssertionFailedError;
98401 use PHPUnit\Framework\SelfDescribing;
98402 use PHPUnit\Runner\ErrorException;
98403 use Throwable;
98404 /**
98405 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
98406 *
98407 * @internal This class is not covered by the backward compatibility promise for PHPUnit
98408 */
98409 final class ThrowableToStringMapper
98410 {
98411 public static function map(Throwable $t): string
98412 {
98413 if ($t instanceof ErrorException) {
98414 return $t->getMessage();
98415 }
98416 if ($t instanceof SelfDescribing) {
98417 $buffer = $t->toString();
98418 if ($t instanceof ExpectationFailedException && $t->getComparisonFailure()) {
98419 $buffer .= $t->getComparisonFailure()->getDiff();
98420 }
98421 if ($t instanceof PhptAssertionFailedError) {
98422 $buffer .= $t->diff();
98423 }
98424 if (!empty($buffer)) {
98425 $buffer = trim($buffer) . "\n";
98426 }
98427 return $buffer;
98428 }
98429 return $t::class . ': ' . $t->getMessage() . "\n";
98430 }
98431 }
98432 <?php
98433
98434 declare (strict_types=1);
98435 /*
98436 * This file is part of PHPUnit.
98437 *
98438 * (c) Sebastian Bergmann <sebastian@phpunit.de>
98439 *
98440 * For the full copyright and license information, please view the LICENSE
98441 * file that was distributed with this source code.
98442 */
98443 namespace PHPUnit\Util;
98444
98445 use function in_array;
98446 /**
98447 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
98448 *
98449 * @psalm-immutable
98450 */
98451 final class VersionComparisonOperator
98452 {
98453 /**
98454 * @psalm-var '<'|'lt'|'<='|'le'|'>'|'gt'|'>='|'ge'|'=='|'='|'eq'|'!='|'<>'|'ne'
98455 */
98456 private readonly string $operator;
98457 /**
98458 * @psalm-param '<'|'lt'|'<='|'le'|'>'|'gt'|'>='|'ge'|'=='|'='|'eq'|'!='|'<>'|'ne' $operator
98459 *
98460 * @throws InvalidVersionOperatorException
98461 */
98462 public function __construct(string $operator)
98463 {
98464 $this->ensureOperatorIsValid($operator);
98465 $this->operator = $operator;
98466 }
98467 /**
98468 * @psalm-return '<'|'lt'|'<='|'le'|'>'|'gt'|'>='|'ge'|'=='|'='|'eq'|'!='|'<>'|'ne'
98469 */
98470 public function asString(): string
98471 {
98472 return $this->operator;
98473 }
98474 /**
98475 * @psalm-param '<'|'lt'|'<='|'le'|'>'|'gt'|'>='|'ge'|'=='|'='|'eq'|'!='|'<>'|'ne' $operator
98476 *
98477 * @throws InvalidVersionOperatorException
98478 */
98479 private function ensureOperatorIsValid(string $operator): void
98480 {
98481 if (!in_array($operator, ['<', 'lt', '<=', 'le', '>', 'gt', '>=', 'ge', '==', '=', 'eq', '!=', '<>', 'ne'], \true)) {
98482 throw new \PHPUnit\Util\InvalidVersionOperatorException($operator);
98483 }
98484 }
98485 }
98486 <?php
98487
98488 declare (strict_types=1);
98489 /*
98490 * This file is part of PHPUnit.
98491 *
98492 * (c) Sebastian Bergmann <sebastian@phpunit.de>
98493 *
98494 * For the full copyright and license information, please view the LICENSE
98495 * file that was distributed with this source code.
98496 */
98497 namespace PHPUnit\Util\Xml;
98498
98499 use const PHP_OS_FAMILY;
98500 use function chdir;
98501 use function dirname;
98502 use function error_reporting;
98503 use function file_get_contents;
98504 use function getcwd;
98505 use function libxml_get_errors;
98506 use function libxml_use_internal_errors;
98507 use function sprintf;
98508 use DOMDocument;
98509 /**
98510 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
98511 *
98512 * @internal This class is not covered by the backward compatibility promise for PHPUnit
98513 */
98514 final class Loader
98515 {
98516 /**
98517 * @throws XmlException
98518 */
98519 public function loadFile(string $filename): DOMDocument
98520 {
98521 $reporting = error_reporting(0);
98522 $contents = file_get_contents($filename);
98523 error_reporting($reporting);
98524 if ($contents === \false) {
98525 throw new \PHPUnit\Util\Xml\XmlException(sprintf('Could not read XML from file "%s"', $filename));
98526 }
98527 return $this->load($contents, $filename);
98528 }
98529 /**
98530 * @throws XmlException
98531 */
98532 public function load(string $actual, ?string $filename = null): DOMDocument
98533 {
98534 if ($actual === '') {
98535 if ($filename === null) {
98536 throw new \PHPUnit\Util\Xml\XmlException('Could not parse XML from empty string');
98537 }
98538 throw new \PHPUnit\Util\Xml\XmlException(sprintf('Could not parse XML from empty file "%s"', $filename));
98539 }
98540 $document = new DOMDocument();
98541 $document->preserveWhiteSpace = \false;
98542 $internal = libxml_use_internal_errors(\true);
98543 $message = '';
98544 $reporting = error_reporting(0);
98545 // Required for XInclude
98546 if ($filename !== null) {
98547 // Required for XInclude on Windows
98548 if (PHP_OS_FAMILY === 'Windows') {
98549 $cwd = getcwd();
98550 @chdir(dirname($filename));
98551 }
98552 $document->documentURI = $filename;
98553 }
98554 $loaded = $document->loadXML($actual);
98555 if ($filename !== null) {
98556 $document->xinclude();
98557 }
98558 foreach (libxml_get_errors() as $error) {
98559 $message .= "\n" . $error->message;
98560 }
98561 libxml_use_internal_errors($internal);
98562 error_reporting($reporting);
98563 if (isset($cwd)) {
98564 @chdir($cwd);
98565 }
98566 if ($loaded === \false || $message !== '') {
98567 if ($filename !== null) {
98568 throw new \PHPUnit\Util\Xml\XmlException(sprintf('Could not load "%s"%s', $filename, $message !== '' ? ":\n" . $message : ''));
98569 }
98570 if ($message === '') {
98571 // @codeCoverageIgnoreStart
98572 $message = 'Could not load XML for unknown reason';
98573 // @codeCoverageIgnoreEnd
98574 }
98575 throw new \PHPUnit\Util\Xml\XmlException($message);
98576 }
98577 return $document;
98578 }
98579 }
98580 <?php
98581
98582 declare (strict_types=1);
98583 /*
98584 * This file is part of PHPUnit.
98585 *
98586 * (c) Sebastian Bergmann <sebastian@phpunit.de>
98587 *
98588 * For the full copyright and license information, please view the LICENSE
98589 * file that was distributed with this source code.
98590 */
98591 namespace PHPUnit\Util;
98592
98593 use const ENT_QUOTES;
98594 use function htmlspecialchars;
98595 use function mb_convert_encoding;
98596 use function ord;
98597 use function preg_replace;
98598 use function strlen;
98599 /**
98600 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
98601 *
98602 * @internal This class is not covered by the backward compatibility promise for PHPUnit
98603 */
98604 final class Xml
98605 {
98606 /**
98607 * Escapes a string for the use in XML documents.
98608 *
98609 * Any Unicode character is allowed, excluding the surrogate blocks, FFFE,
98610 * and FFFF (not even as character reference).
98611 *
98612 * @see https://www.w3.org/TR/xml/#charsets
98613 */
98614 public static function prepareString(string $string): string
98615 {
98616 return preg_replace('/[\x00-\x08\x0b\x0c\x0e-\x1f\x7f]/', '', htmlspecialchars(self::convertToUtf8($string), ENT_QUOTES));
98617 }
98618 private static function convertToUtf8(string $string): string
98619 {
98620 if (!self::isUtf8($string)) {
98621 $string = mb_convert_encoding($string, 'UTF-8');
98622 }
98623 return $string;
98624 }
98625 private static function isUtf8(string $string): bool
98626 {
98627 $length = strlen($string);
98628 for ($i = 0; $i < $length; $i++) {
98629 if (ord($string[$i]) < 0x80) {
98630 $n = 0;
98631 } elseif ((ord($string[$i]) & 0xe0) === 0xc0) {
98632 $n = 1;
98633 } elseif ((ord($string[$i]) & 0xf0) === 0xe0) {
98634 $n = 2;
98635 } elseif ((ord($string[$i]) & 0xf0) === 0xf0) {
98636 $n = 3;
98637 } else {
98638 return \false;
98639 }
98640 for ($j = 0; $j < $n; $j++) {
98641 if (++$i === $length || (ord($string[$i]) & 0xc0) !== 0x80) {
98642 return \false;
98643 }
98644 }
98645 }
98646 return \true;
98647 }
98648 }
98649 <?xml version="1.0"?>
98650 <bom xmlns="http://cyclonedx.org/schema/bom/1.4">
98651 <components>
98652 <component type="library">
98653 <group>phpunit</group>
98654 <name>phpunit</name>
98655 <version>10.5.63</version>
98656 <description>The PHP Unit Testing framework.</description>
98657 <licenses>
98658 <license>
98659 <id>BSD-3-Clause</id>
98660 </license>
98661 </licenses>
98662 <purl>pkg:composer/phpunit/phpunit@10.5.63</purl>
98663 </component>
98664 <component type="library">
98665 <group>myclabs</group>
98666 <name>deep-copy</name>
98667 <version>1.13.4</version>
98668 <description>Create deep copies (clones) of your objects</description>
98669 <licenses>
98670 <license>
98671 <id>MIT</id>
98672 </license>
98673 </licenses>
98674 <purl>pkg:composer/myclabs/deep-copy@1.13.4</purl>
98675 </component>
98676 <component type="library">
98677 <group>nikic</group>
98678 <name>php-parser</name>
98679 <version>v5.7.0</version>
98680 <description>A PHP parser written in PHP</description>
98681 <licenses>
98682 <license>
98683 <id>BSD-3-Clause</id>
98684 </license>
98685 </licenses>
98686 <purl>pkg:composer/nikic/php-parser@v5.7.0</purl>
98687 </component>
98688 <component type="library">
98689 <group>phar-io</group>
98690 <name>manifest</name>
98691 <version>2.0.4</version>
98692 <description>Component for reading phar.io manifest information from a PHP Archive (PHAR)</description>
98693 <licenses>
98694 <license>
98695 <id>BSD-3-Clause</id>
98696 </license>
98697 </licenses>
98698 <purl>pkg:composer/phar-io/manifest@2.0.4</purl>
98699 </component>
98700 <component type="library">
98701 <group>phar-io</group>
98702 <name>version</name>
98703 <version>3.2.1</version>
98704 <description>Library for handling version information and constraints</description>
98705 <licenses>
98706 <license>
98707 <id>BSD-3-Clause</id>
98708 </license>
98709 </licenses>
98710 <purl>pkg:composer/phar-io/version@3.2.1</purl>
98711 </component>
98712 <component type="library">
98713 <group>phpunit</group>
98714 <name>php-code-coverage</name>
98715 <version>10.1.16</version>
98716 <description>Library that provides collection, processing, and rendering functionality for PHP code coverage information.</description>
98717 <licenses>
98718 <license>
98719 <id>BSD-3-Clause</id>
98720 </license>
98721 </licenses>
98722 <purl>pkg:composer/phpunit/php-code-coverage@10.1.16</purl>
98723 </component>
98724 <component type="library">
98725 <group>phpunit</group>
98726 <name>php-file-iterator</name>
98727 <version>4.1.0</version>
98728 <description>FilterIterator implementation that filters files based on a list of suffixes.</description>
98729 <licenses>
98730 <license>
98731 <id>BSD-3-Clause</id>
98732 </license>
98733 </licenses>
98734 <purl>pkg:composer/phpunit/php-file-iterator@4.1.0</purl>
98735 </component>
98736 <component type="library">
98737 <group>phpunit</group>
98738 <name>php-invoker</name>
98739 <version>4.0.0</version>
98740 <description>Invoke callables with a timeout</description>
98741 <licenses>
98742 <license>
98743 <id>BSD-3-Clause</id>
98744 </license>
98745 </licenses>
98746 <purl>pkg:composer/phpunit/php-invoker@4.0.0</purl>
98747 </component>
98748 <component type="library">
98749 <group>phpunit</group>
98750 <name>php-text-template</name>
98751 <version>3.0.1</version>
98752 <description>Simple template engine.</description>
98753 <licenses>
98754 <license>
98755 <id>BSD-3-Clause</id>
98756 </license>
98757 </licenses>
98758 <purl>pkg:composer/phpunit/php-text-template@3.0.1</purl>
98759 </component>
98760 <component type="library">
98761 <group>phpunit</group>
98762 <name>php-timer</name>
98763 <version>6.0.0</version>
98764 <description>Utility class for timing</description>
98765 <licenses>
98766 <license>
98767 <id>BSD-3-Clause</id>
98768 </license>
98769 </licenses>
98770 <purl>pkg:composer/phpunit/php-timer@6.0.0</purl>
98771 </component>
98772 <component type="library">
98773 <group>sebastian</group>
98774 <name>cli-parser</name>
98775 <version>2.0.1</version>
98776 <description>Library for parsing CLI options</description>
98777 <licenses>
98778 <license>
98779 <id>BSD-3-Clause</id>
98780 </license>
98781 </licenses>
98782 <purl>pkg:composer/sebastian/cli-parser@2.0.1</purl>
98783 </component>
98784 <component type="library">
98785 <group>sebastian</group>
98786 <name>code-unit</name>
98787 <version>2.0.0</version>
98788 <description>Collection of value objects that represent the PHP code units</description>
98789 <licenses>
98790 <license>
98791 <id>BSD-3-Clause</id>
98792 </license>
98793 </licenses>
98794 <purl>pkg:composer/sebastian/code-unit@2.0.0</purl>
98795 </component>
98796 <component type="library">
98797 <group>sebastian</group>
98798 <name>code-unit-reverse-lookup</name>
98799 <version>3.0.0</version>
98800 <description>Looks up which function or method a line of code belongs to</description>
98801 <licenses>
98802 <license>
98803 <id>BSD-3-Clause</id>
98804 </license>
98805 </licenses>
98806 <purl>pkg:composer/sebastian/code-unit-reverse-lookup@3.0.0</purl>
98807 </component>
98808 <component type="library">
98809 <group>sebastian</group>
98810 <name>comparator</name>
98811 <version>5.0.5</version>
98812 <description>Provides the functionality to compare PHP values for equality</description>
98813 <licenses>
98814 <license>
98815 <id>BSD-3-Clause</id>
98816 </license>
98817 </licenses>
98818 <purl>pkg:composer/sebastian/comparator@5.0.5</purl>
98819 </component>
98820 <component type="library">
98821 <group>sebastian</group>
98822 <name>complexity</name>
98823 <version>3.2.0</version>
98824 <description>Library for calculating the complexity of PHP code units</description>
98825 <licenses>
98826 <license>
98827 <id>BSD-3-Clause</id>
98828 </license>
98829 </licenses>
98830 <purl>pkg:composer/sebastian/complexity@3.2.0</purl>
98831 </component>
98832 <component type="library">
98833 <group>sebastian</group>
98834 <name>diff</name>
98835 <version>5.1.1</version>
98836 <description>Diff implementation</description>
98837 <licenses>
98838 <license>
98839 <id>BSD-3-Clause</id>
98840 </license>
98841 </licenses>
98842 <purl>pkg:composer/sebastian/diff@5.1.1</purl>
98843 </component>
98844 <component type="library">
98845 <group>sebastian</group>
98846 <name>environment</name>
98847 <version>6.1.0</version>
98848 <description>Provides functionality to handle HHVM/PHP environments</description>
98849 <licenses>
98850 <license>
98851 <id>BSD-3-Clause</id>
98852 </license>
98853 </licenses>
98854 <purl>pkg:composer/sebastian/environment@6.1.0</purl>
98855 </component>
98856 <component type="library">
98857 <group>sebastian</group>
98858 <name>exporter</name>
98859 <version>5.1.4</version>
98860 <description>Provides the functionality to export PHP variables for visualization</description>
98861 <licenses>
98862 <license>
98863 <id>BSD-3-Clause</id>
98864 </license>
98865 </licenses>
98866 <purl>pkg:composer/sebastian/exporter@5.1.4</purl>
98867 </component>
98868 <component type="library">
98869 <group>sebastian</group>
98870 <name>global-state</name>
98871 <version>6.0.2</version>
98872 <description>Snapshotting of global state</description>
98873 <licenses>
98874 <license>
98875 <id>BSD-3-Clause</id>
98876 </license>
98877 </licenses>
98878 <purl>pkg:composer/sebastian/global-state@6.0.2</purl>
98879 </component>
98880 <component type="library">
98881 <group>sebastian</group>
98882 <name>lines-of-code</name>
98883 <version>2.0.2</version>
98884 <description>Library for counting the lines of code in PHP source code</description>
98885 <licenses>
98886 <license>
98887 <id>BSD-3-Clause</id>
98888 </license>
98889 </licenses>
98890 <purl>pkg:composer/sebastian/lines-of-code@2.0.2</purl>
98891 </component>
98892 <component type="library">
98893 <group>sebastian</group>
98894 <name>object-enumerator</name>
98895 <version>5.0.0</version>
98896 <description>Traverses array structures and object graphs to enumerate all referenced objects</description>
98897 <licenses>
98898 <license>
98899 <id>BSD-3-Clause</id>
98900 </license>
98901 </licenses>
98902 <purl>pkg:composer/sebastian/object-enumerator@5.0.0</purl>
98903 </component>
98904 <component type="library">
98905 <group>sebastian</group>
98906 <name>object-reflector</name>
98907 <version>3.0.0</version>
98908 <description>Allows reflection of object attributes, including inherited and non-public ones</description>
98909 <licenses>
98910 <license>
98911 <id>BSD-3-Clause</id>
98912 </license>
98913 </licenses>
98914 <purl>pkg:composer/sebastian/object-reflector@3.0.0</purl>
98915 </component>
98916 <component type="library">
98917 <group>sebastian</group>
98918 <name>recursion-context</name>
98919 <version>5.0.1</version>
98920 <description>Provides functionality to recursively process PHP variables</description>
98921 <licenses>
98922 <license>
98923 <id>BSD-3-Clause</id>
98924 </license>
98925 </licenses>
98926 <purl>pkg:composer/sebastian/recursion-context@5.0.1</purl>
98927 </component>
98928 <component type="library">
98929 <group>sebastian</group>
98930 <name>type</name>
98931 <version>4.0.0</version>
98932 <description>Collection of value objects that represent the types of the PHP type system</description>
98933 <licenses>
98934 <license>
98935 <id>BSD-3-Clause</id>
98936 </license>
98937 </licenses>
98938 <purl>pkg:composer/sebastian/type@4.0.0</purl>
98939 </component>
98940 <component type="library">
98941 <group>sebastian</group>
98942 <name>version</name>
98943 <version>4.0.1</version>
98944 <description>Library that helps with managing the version number of Git-hosted PHP projects</description>
98945 <licenses>
98946 <license>
98947 <id>BSD-3-Clause</id>
98948 </license>
98949 </licenses>
98950 <purl>pkg:composer/sebastian/version@4.0.1</purl>
98951 </component>
98952 <component type="library">
98953 <group>theseer</group>
98954 <name>tokenizer</name>
98955 <version>1.3.1</version>
98956 <description>A small library for converting tokenized PHP source code into XML and potentially other formats</description>
98957 <licenses>
98958 <license>
98959 <id>BSD-3-Clause</id>
98960 </license>
98961 </licenses>
98962 <purl>pkg:composer/theseer/tokenizer@1.3.1</purl>
98963 </component>
98964 </components>
98965 </bom>
98966 <?xml version="1.0" encoding="UTF-8"?>
98967 <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
98968 <xs:annotation>
98969 <xs:documentation source="https://phpunit.de/documentation.html">
98970 This Schema file defines the rules by which the XML configuration file of PHPUnit 10.0 may be structured.
98971 </xs:documentation>
98972 <xs:appinfo source="https://phpunit.de/documentation.html"/>
98973 </xs:annotation>
98974 <xs:element name="phpunit" type="phpUnitType">
98975 <xs:annotation>
98976 <xs:documentation>Root Element</xs:documentation>
98977 </xs:annotation>
98978 </xs:element>
98979 <xs:complexType name="coverageType">
98980 <xs:all>
98981 <xs:element name="include" minOccurs="0" maxOccurs="1">
98982 <xs:complexType>
98983 <xs:group ref="pathGroup"/>
98984 </xs:complexType>
98985 </xs:element>
98986 <xs:element name="exclude" minOccurs="0" maxOccurs="1">
98987 <xs:complexType>
98988 <xs:group ref="pathGroup"/>
98989 </xs:complexType>
98990 </xs:element>
98991 <xs:element name="report" minOccurs="0" maxOccurs="1">
98992 <xs:complexType>
98993 <xs:group ref="coverageReportGroup"/>
98994 </xs:complexType>
98995 </xs:element>
98996 </xs:all>
98997 <xs:attribute name="cacheDirectory" type="xs:anyURI"/>
98998 <xs:attribute name="pathCoverage" type="xs:boolean" default="false"/>
98999 <xs:attribute name="includeUncoveredFiles" type="xs:boolean" default="true"/>
99000 <xs:attribute name="ignoreDeprecatedCodeUnits" type="xs:boolean" default="false"/>
99001 <xs:attribute name="disableCodeCoverageIgnore" type="xs:boolean" default="false"/>
99002 </xs:complexType>
99003 <xs:complexType name="loggingType">
99004 <xs:group ref="loggingGroup"/>
99005 </xs:complexType>
99006 <xs:complexType name="groupsType">
99007 <xs:choice>
99008 <xs:sequence>
99009 <xs:element name="include" type="groupType"/>
99010 <xs:element name="exclude" type="groupType" minOccurs="0"/>
99011 </xs:sequence>
99012 <xs:sequence>
99013 <xs:element name="exclude" type="groupType"/>
99014 </xs:sequence>
99015 </xs:choice>
99016 </xs:complexType>
99017 <xs:complexType name="groupType">
99018 <xs:sequence>
99019 <xs:element name="group" type="xs:string" maxOccurs="unbounded"/>
99020 </xs:sequence>
99021 </xs:complexType>
99022 <xs:complexType name="extensionsType">
99023 <xs:sequence>
99024 <xs:element name="bootstrap" type="bootstrapType" maxOccurs="unbounded"/>
99025 </xs:sequence>
99026 </xs:complexType>
99027 <xs:complexType name="bootstrapType">
99028 <xs:sequence>
99029 <xs:element name="parameter" type="parameterType" minOccurs="0" maxOccurs="unbounded"/>
99030 </xs:sequence>
99031 <xs:attribute name="class" type="xs:string" use="required"/>
99032 </xs:complexType>
99033 <xs:complexType name="parameterType">
99034 <xs:attribute name="name" type="xs:string" use="required"/>
99035 <xs:attribute name="value" type="xs:string" use="required"/>
99036 </xs:complexType>
99037 <xs:simpleType name="columnsType">
99038 <xs:union>
99039 <xs:simpleType>
99040 <xs:restriction base="xs:integer"/>
99041 </xs:simpleType>
99042 <xs:simpleType>
99043 <xs:restriction base="xs:string">
99044 <xs:enumeration value="max"/>
99045 </xs:restriction>
99046 </xs:simpleType>
99047 </xs:union>
99048 </xs:simpleType>
99049 <xs:group name="pathGroup">
99050 <xs:sequence>
99051 <xs:choice minOccurs="0" maxOccurs="unbounded">
99052 <xs:element name="directory" type="directoryFilterType"/>
99053 <xs:element name="file" type="fileFilterType"/>
99054 </xs:choice>
99055 </xs:sequence>
99056 </xs:group>
99057 <xs:complexType name="directoryFilterType">
99058 <xs:simpleContent>
99059 <xs:extension base="xs:string">
99060 <xs:attribute type="xs:string" name="prefix" default=""/>
99061 <xs:attribute type="xs:string" name="suffix" default="Test.php"/>
99062 <xs:attributeGroup ref="phpVersionGroup"/>
99063 </xs:extension>
99064 </xs:simpleContent>
99065 </xs:complexType>
99066 <xs:simpleType name="executionOrderType">
99067 <xs:restriction base="xs:string">
99068 <xs:enumeration value="default"/>
99069 <xs:enumeration value="defects"/>
99070 <xs:enumeration value="depends"/>
99071 <xs:enumeration value="depends,defects"/>
99072 <xs:enumeration value="depends,duration"/>
99073 <xs:enumeration value="depends,random"/>
99074 <xs:enumeration value="depends,reverse"/>
99075 <xs:enumeration value="depends,size"/>
99076 <xs:enumeration value="duration"/>
99077 <xs:enumeration value="no-depends"/>
99078 <xs:enumeration value="no-depends,defects"/>
99079 <xs:enumeration value="no-depends,duration"/>
99080 <xs:enumeration value="no-depends,random"/>
99081 <xs:enumeration value="no-depends,reverse"/>
99082 <xs:enumeration value="no-depends,size"/>
99083 <xs:enumeration value="random"/>
99084 <xs:enumeration value="reverse"/>
99085 <xs:enumeration value="size"/>
99086 </xs:restriction>
99087 </xs:simpleType>
99088 <xs:complexType name="fileFilterType">
99089 <xs:simpleContent>
99090 <xs:extension base="xs:anyURI">
99091 <xs:attributeGroup ref="phpVersionGroup"/>
99092 </xs:extension>
99093 </xs:simpleContent>
99094 </xs:complexType>
99095 <xs:attributeGroup name="phpVersionGroup">
99096 <xs:attribute name="phpVersion" type="xs:string" default="5.3.0"/>
99097 <xs:attribute name="phpVersionOperator" type="xs:string" default="&gt;="/>
99098 </xs:attributeGroup>
99099 <xs:complexType name="phpType">
99100 <xs:sequence>
99101 <xs:choice maxOccurs="unbounded">
99102 <xs:element name="includePath" type="xs:anyURI" minOccurs="0" maxOccurs="unbounded"/>
99103 <xs:element name="ini" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
99104 <xs:element name="const" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
99105 <xs:element name="var" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
99106 <xs:element name="env" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
99107 <xs:element name="post" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
99108 <xs:element name="get" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
99109 <xs:element name="cookie" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
99110 <xs:element name="server" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
99111 <xs:element name="files" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
99112 <xs:element name="request" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
99113 </xs:choice>
99114 </xs:sequence>
99115 </xs:complexType>
99116 <xs:complexType name="namedValueType">
99117 <xs:attribute name="name" use="required" type="xs:string"/>
99118 <xs:attribute name="value" use="required" type="xs:anySimpleType"/>
99119 <xs:attribute name="verbatim" use="optional" type="xs:boolean"/>
99120 <xs:attribute name="force" use="optional" type="xs:boolean"/>
99121 </xs:complexType>
99122 <xs:complexType name="phpUnitType">
99123 <xs:annotation>
99124 <xs:documentation>The main type specifying the document structure</xs:documentation>
99125 </xs:annotation>
99126 <xs:group ref="configGroup"/>
99127 <xs:attributeGroup ref="configAttributeGroup"/>
99128 </xs:complexType>
99129 <xs:attributeGroup name="configAttributeGroup">
99130 <xs:attribute name="backupGlobals" type="xs:boolean" default="false"/>
99131 <xs:attribute name="backupStaticProperties" type="xs:boolean" default="false"/>
99132 <xs:attribute name="bootstrap" type="xs:anyURI"/>
99133 <xs:attribute name="cacheDirectory" type="xs:anyURI"/>
99134 <xs:attribute name="cacheResult" type="xs:boolean" default="true"/>
99135 <xs:attribute name="cacheResultFile" type="xs:anyURI"/>
99136 <xs:attribute name="colors" type="xs:boolean" default="false"/>
99137 <xs:attribute name="columns" type="columnsType" default="80"/>
99138 <xs:attribute name="requireCoverageMetadata" type="xs:boolean" default="false"/>
99139 <xs:attribute name="processIsolation" type="xs:boolean" default="false"/>
99140 <xs:attribute name="stopOnDefect" type="xs:boolean" default="false"/>
99141 <xs:attribute name="stopOnError" type="xs:boolean" default="false"/>
99142 <xs:attribute name="stopOnFailure" type="xs:boolean" default="false"/>
99143 <xs:attribute name="stopOnWarning" type="xs:boolean" default="false"/>
99144 <xs:attribute name="stopOnIncomplete" type="xs:boolean" default="false"/>
99145 <xs:attribute name="stopOnRisky" type="xs:boolean" default="false"/>
99146 <xs:attribute name="stopOnSkipped" type="xs:boolean" default="false"/>
99147 <xs:attribute name="failOnEmptyTestSuite" type="xs:boolean" default="false"/>
99148 <xs:attribute name="failOnIncomplete" type="xs:boolean" default="false"/>
99149 <xs:attribute name="failOnRisky" type="xs:boolean" default="false"/>
99150 <xs:attribute name="failOnSkipped" type="xs:boolean" default="false"/>
99151 <xs:attribute name="failOnWarning" type="xs:boolean" default="false"/>
99152 <xs:attribute name="beStrictAboutChangesToGlobalState" type="xs:boolean" default="false"/>
99153 <xs:attribute name="beStrictAboutOutputDuringTests" type="xs:boolean" default="false"/>
99154 <xs:attribute name="beStrictAboutTestsThatDoNotTestAnything" type="xs:boolean" default="true"/>
99155 <xs:attribute name="beStrictAboutTodoAnnotatedTests" type="xs:boolean" default="false"/>
99156 <xs:attribute name="beStrictAboutCoverageMetadata" type="xs:boolean" default="false"/>
99157 <xs:attribute name="defaultTimeLimit" type="xs:integer" default="0"/>
99158 <xs:attribute name="enforceTimeLimit" type="xs:boolean" default="false"/>
99159 <xs:attribute name="timeoutForSmallTests" type="xs:integer" default="1"/>
99160 <xs:attribute name="timeoutForMediumTests" type="xs:integer" default="10"/>
99161 <xs:attribute name="timeoutForLargeTests" type="xs:integer" default="60"/>
99162 <xs:attribute name="defaultTestSuite" type="xs:string" default=""/>
99163 <xs:attribute name="testdox" type="xs:boolean" default="false"/>
99164 <xs:attribute name="stderr" type="xs:boolean" default="false"/>
99165 <xs:attribute name="reverseDefectList" type="xs:boolean" default="false"/>
99166 <xs:attribute name="registerMockObjectsFromTestArgumentsRecursively" type="xs:boolean" default="false"/>
99167 <xs:attribute name="extensionsDirectory" type="xs:anyURI"/>
99168 <xs:attribute name="executionOrder" type="executionOrderType" default="default"/>
99169 <xs:attribute name="resolveDependencies" type="xs:boolean" default="true"/>
99170 <xs:attribute name="displayDetailsOnIncompleteTests" type="xs:boolean" default="false"/>
99171 <xs:attribute name="displayDetailsOnSkippedTests" type="xs:boolean" default="false"/>
99172 <xs:attribute name="displayDetailsOnTestsThatTriggerDeprecations" type="xs:boolean" default="false"/>
99173 <xs:attribute name="displayDetailsOnTestsThatTriggerErrors" type="xs:boolean" default="false"/>
99174 <xs:attribute name="displayDetailsOnTestsThatTriggerNotices" type="xs:boolean" default="false"/>
99175 <xs:attribute name="displayDetailsOnTestsThatTriggerWarnings" type="xs:boolean" default="false"/>
99176 </xs:attributeGroup>
99177 <xs:group name="configGroup">
99178 <xs:all>
99179 <xs:element ref="testSuiteFacet" minOccurs="0"/>
99180 <xs:element name="groups" type="groupsType" minOccurs="0"/>
99181 <xs:element name="coverage" type="coverageType" minOccurs="0"/>
99182 <xs:element name="logging" type="loggingType" minOccurs="0"/>
99183 <xs:element name="extensions" type="extensionsType" minOccurs="0"/>
99184 <xs:element name="php" type="phpType" minOccurs="0"/>
99185 </xs:all>
99186 </xs:group>
99187 <xs:element name="testSuiteFacet" abstract="true"/>
99188 <xs:element name="testsuite" type="testSuiteType" substitutionGroup="testSuiteFacet"/>
99189 <xs:element name="testsuites" type="testSuitesType" substitutionGroup="testSuiteFacet"/>
99190 <xs:complexType name="testSuitesType">
99191 <xs:sequence>
99192 <xs:element name="testsuite" type="testSuiteType" maxOccurs="unbounded"/>
99193 </xs:sequence>
99194 </xs:complexType>
99195 <xs:complexType name="testSuiteType">
99196 <xs:sequence>
99197 <xs:choice minOccurs="0" maxOccurs="unbounded">
99198 <xs:group ref="pathGroup"/>
99199 <xs:element name="exclude" type="xs:string"/>
99200 </xs:choice>
99201 </xs:sequence>
99202 <xs:attribute name="name" type="xs:string" use="required"/>
99203 </xs:complexType>
99204 <xs:group name="coverageReportGroup">
99205 <xs:all>
99206 <xs:element name="clover" type="logToFileType" minOccurs="0"/>
99207 <xs:element name="cobertura" type="logToFileType" minOccurs="0"/>
99208 <xs:element name="crap4j" type="coverageReportCrap4JType" minOccurs="0" />
99209 <xs:element name="html" type="coverageReportHtmlType" minOccurs="0" />
99210 <xs:element name="php" type="logToFileType" minOccurs="0" />
99211 <xs:element name="text" type="coverageReportTextType" minOccurs="0" />
99212 <xs:element name="xml" type="logToDirectoryType" minOccurs="0" />
99213 </xs:all>
99214 </xs:group>
99215 <xs:group name="loggingGroup">
99216 <xs:all>
99217 <xs:element name="junit" type="logToFileType" minOccurs="0" />
99218 <xs:element name="teamcity" type="logToFileType" minOccurs="0" />
99219 <xs:element name="testdoxHtml" type="logToFileType" minOccurs="0" />
99220 <xs:element name="testdoxText" type="logToFileType" minOccurs="0" />
99221 </xs:all>
99222 </xs:group>
99223 <xs:complexType name="logToFileType">
99224 <xs:attribute name="outputFile" type="xs:anyURI" use="required"/>
99225 </xs:complexType>
99226 <xs:complexType name="logToDirectoryType">
99227 <xs:attribute name="outputDirectory" type="xs:anyURI" use="required"/>
99228 </xs:complexType>
99229 <xs:complexType name="coverageReportCrap4JType">
99230 <xs:attribute name="outputFile" type="xs:anyURI" use="required"/>
99231 <xs:attribute name="threshold" type="xs:integer"/>
99232 </xs:complexType>
99233 <xs:complexType name="coverageReportHtmlType">
99234 <xs:attribute name="outputDirectory" type="xs:anyURI" use="required"/>
99235 <xs:attribute name="lowUpperBound" type="xs:integer" default="50"/>
99236 <xs:attribute name="highLowerBound" type="xs:integer" default="90"/>
99237 <xs:attribute name="colorSuccessLow" type="xs:string" default="#dff0d8"/>
99238 <xs:attribute name="colorSuccessMedium" type="xs:string" default="#c3e3b5"/>
99239 <xs:attribute name="colorSuccessHigh" type="xs:string" default="#99cb84"/>
99240 <xs:attribute name="colorWarning" type="xs:string" default="#fcf8e3"/>
99241 <xs:attribute name="colorDanger" type="xs:string" default="#f2dede"/>
99242 <xs:attribute name="customCssFile" type="xs:string"/>
99243 </xs:complexType>
99244 <xs:complexType name="coverageReportTextType">
99245 <xs:attribute name="outputFile" type="xs:anyURI" use="required"/>
99246 <xs:attribute name="showUncoveredFiles" type="xs:boolean" default="false"/>
99247 <xs:attribute name="showOnlySummary" type="xs:boolean" default="false"/>
99248 </xs:complexType>
99249 </xs:schema>
99250 <?xml version="1.0" encoding="UTF-8"?>
99251 <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
99252 <xs:annotation>
99253 <xs:documentation source="https://phpunit.de/documentation.html">
99254 This Schema file defines the rules by which the XML configuration file of PHPUnit 10.1 may be structured.
99255 </xs:documentation>
99256 <xs:appinfo source="https://phpunit.de/documentation.html"/>
99257 </xs:annotation>
99258 <xs:element name="phpunit" type="phpUnitType">
99259 <xs:annotation>
99260 <xs:documentation>Root Element</xs:documentation>
99261 </xs:annotation>
99262 </xs:element>
99263 <xs:complexType name="sourceType">
99264 <xs:all>
99265 <xs:element name="include" minOccurs="0" maxOccurs="1">
99266 <xs:complexType>
99267 <xs:group ref="sourcePathGroup"/>
99268 </xs:complexType>
99269 </xs:element>
99270 <xs:element name="exclude" minOccurs="0" maxOccurs="1">
99271 <xs:complexType>
99272 <xs:group ref="sourcePathGroup"/>
99273 </xs:complexType>
99274 </xs:element>
99275 </xs:all>
99276 <xs:attribute name="restrictDeprecations" type="xs:boolean" default="false"/>
99277 <xs:attribute name="restrictNotices" type="xs:boolean" default="false"/>
99278 <xs:attribute name="restrictWarnings" type="xs:boolean" default="false"/>
99279 </xs:complexType>
99280 <xs:group name="sourcePathGroup">
99281 <xs:sequence>
99282 <xs:choice minOccurs="0" maxOccurs="unbounded">
99283 <xs:element name="directory" type="sourceDirectoryType"/>
99284 <xs:element name="file" type="xs:anyURI"/>
99285 </xs:choice>
99286 </xs:sequence>
99287 </xs:group>
99288 <xs:complexType name="sourceDirectoryType">
99289 <xs:simpleContent>
99290 <xs:extension base="xs:string">
99291 <xs:attribute type="xs:string" name="prefix" default=""/>
99292 <xs:attribute type="xs:string" name="suffix" default=".php"/>
99293 </xs:extension>
99294 </xs:simpleContent>
99295 </xs:complexType>
99296 <xs:complexType name="coverageType">
99297 <xs:all>
99298 <xs:element name="report" minOccurs="0" maxOccurs="1">
99299 <xs:complexType>
99300 <xs:group ref="coverageReportGroup"/>
99301 </xs:complexType>
99302 </xs:element>
99303 </xs:all>
99304 <xs:attribute name="cacheDirectory" type="xs:anyURI"/>
99305 <xs:attribute name="pathCoverage" type="xs:boolean" default="false"/>
99306 <xs:attribute name="includeUncoveredFiles" type="xs:boolean" default="true"/>
99307 <xs:attribute name="ignoreDeprecatedCodeUnits" type="xs:boolean" default="false"/>
99308 <xs:attribute name="disableCodeCoverageIgnore" type="xs:boolean" default="false"/>
99309 </xs:complexType>
99310 <xs:complexType name="loggingType">
99311 <xs:group ref="loggingGroup"/>
99312 </xs:complexType>
99313 <xs:complexType name="groupsType">
99314 <xs:choice>
99315 <xs:sequence>
99316 <xs:element name="include" type="groupType"/>
99317 <xs:element name="exclude" type="groupType" minOccurs="0"/>
99318 </xs:sequence>
99319 <xs:sequence>
99320 <xs:element name="exclude" type="groupType"/>
99321 </xs:sequence>
99322 </xs:choice>
99323 </xs:complexType>
99324 <xs:complexType name="groupType">
99325 <xs:sequence>
99326 <xs:element name="group" type="xs:string" maxOccurs="unbounded"/>
99327 </xs:sequence>
99328 </xs:complexType>
99329 <xs:complexType name="extensionsType">
99330 <xs:sequence>
99331 <xs:element name="bootstrap" type="bootstrapType" maxOccurs="unbounded"/>
99332 </xs:sequence>
99333 </xs:complexType>
99334 <xs:complexType name="bootstrapType">
99335 <xs:sequence>
99336 <xs:element name="parameter" type="parameterType" minOccurs="0" maxOccurs="unbounded"/>
99337 </xs:sequence>
99338 <xs:attribute name="class" type="xs:string" use="required"/>
99339 </xs:complexType>
99340 <xs:complexType name="parameterType">
99341 <xs:attribute name="name" type="xs:string" use="required"/>
99342 <xs:attribute name="value" type="xs:string" use="required"/>
99343 </xs:complexType>
99344 <xs:simpleType name="columnsType">
99345 <xs:union>
99346 <xs:simpleType>
99347 <xs:restriction base="xs:integer"/>
99348 </xs:simpleType>
99349 <xs:simpleType>
99350 <xs:restriction base="xs:string">
99351 <xs:enumeration value="max"/>
99352 </xs:restriction>
99353 </xs:simpleType>
99354 </xs:union>
99355 </xs:simpleType>
99356 <xs:simpleType name="executionOrderType">
99357 <xs:restriction base="xs:string">
99358 <xs:enumeration value="default"/>
99359 <xs:enumeration value="defects"/>
99360 <xs:enumeration value="depends"/>
99361 <xs:enumeration value="depends,defects"/>
99362 <xs:enumeration value="depends,duration"/>
99363 <xs:enumeration value="depends,random"/>
99364 <xs:enumeration value="depends,reverse"/>
99365 <xs:enumeration value="depends,size"/>
99366 <xs:enumeration value="duration"/>
99367 <xs:enumeration value="no-depends"/>
99368 <xs:enumeration value="no-depends,defects"/>
99369 <xs:enumeration value="no-depends,duration"/>
99370 <xs:enumeration value="no-depends,random"/>
99371 <xs:enumeration value="no-depends,reverse"/>
99372 <xs:enumeration value="no-depends,size"/>
99373 <xs:enumeration value="random"/>
99374 <xs:enumeration value="reverse"/>
99375 <xs:enumeration value="size"/>
99376 </xs:restriction>
99377 </xs:simpleType>
99378 <xs:complexType name="phpType">
99379 <xs:sequence>
99380 <xs:choice maxOccurs="unbounded">
99381 <xs:element name="includePath" type="xs:anyURI" minOccurs="0" maxOccurs="unbounded"/>
99382 <xs:element name="ini" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
99383 <xs:element name="const" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
99384 <xs:element name="var" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
99385 <xs:element name="env" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
99386 <xs:element name="post" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
99387 <xs:element name="get" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
99388 <xs:element name="cookie" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
99389 <xs:element name="server" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
99390 <xs:element name="files" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
99391 <xs:element name="request" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
99392 </xs:choice>
99393 </xs:sequence>
99394 </xs:complexType>
99395 <xs:complexType name="namedValueType">
99396 <xs:attribute name="name" use="required" type="xs:string"/>
99397 <xs:attribute name="value" use="required" type="xs:anySimpleType"/>
99398 <xs:attribute name="verbatim" use="optional" type="xs:boolean"/>
99399 <xs:attribute name="force" use="optional" type="xs:boolean"/>
99400 </xs:complexType>
99401 <xs:complexType name="phpUnitType">
99402 <xs:annotation>
99403 <xs:documentation>The main type specifying the document structure</xs:documentation>
99404 </xs:annotation>
99405 <xs:group ref="configGroup"/>
99406 <xs:attributeGroup ref="configAttributeGroup"/>
99407 </xs:complexType>
99408 <xs:attributeGroup name="configAttributeGroup">
99409 <xs:attribute name="backupGlobals" type="xs:boolean" default="false"/>
99410 <xs:attribute name="backupStaticProperties" type="xs:boolean" default="false"/>
99411 <xs:attribute name="bootstrap" type="xs:anyURI"/>
99412 <xs:attribute name="cacheDirectory" type="xs:anyURI"/>
99413 <xs:attribute name="cacheResult" type="xs:boolean" default="true"/>
99414 <xs:attribute name="cacheResultFile" type="xs:anyURI"/>
99415 <xs:attribute name="colors" type="xs:boolean" default="false"/>
99416 <xs:attribute name="columns" type="columnsType" default="80"/>
99417 <xs:attribute name="requireCoverageMetadata" type="xs:boolean" default="false"/>
99418 <xs:attribute name="processIsolation" type="xs:boolean" default="false"/>
99419 <xs:attribute name="failOnDeprecation" type="xs:boolean" default="false"/>
99420 <xs:attribute name="failOnEmptyTestSuite" type="xs:boolean" default="false"/>
99421 <xs:attribute name="failOnIncomplete" type="xs:boolean" default="false"/>
99422 <xs:attribute name="failOnNotice" type="xs:boolean" default="false"/>
99423 <xs:attribute name="failOnRisky" type="xs:boolean" default="false"/>
99424 <xs:attribute name="failOnSkipped" type="xs:boolean" default="false"/>
99425 <xs:attribute name="failOnWarning" type="xs:boolean" default="false"/>
99426 <xs:attribute name="stopOnDefect" type="xs:boolean" default="false"/>
99427 <xs:attribute name="stopOnDeprecation" type="xs:boolean" default="false"/>
99428 <xs:attribute name="stopOnError" type="xs:boolean" default="false"/>
99429 <xs:attribute name="stopOnFailure" type="xs:boolean" default="false"/>
99430 <xs:attribute name="stopOnIncomplete" type="xs:boolean" default="false"/>
99431 <xs:attribute name="stopOnNotice" type="xs:boolean" default="false"/>
99432 <xs:attribute name="stopOnRisky" type="xs:boolean" default="false"/>
99433 <xs:attribute name="stopOnSkipped" type="xs:boolean" default="false"/>
99434 <xs:attribute name="stopOnWarning" type="xs:boolean" default="false"/>
99435 <xs:attribute name="beStrictAboutChangesToGlobalState" type="xs:boolean" default="false"/>
99436 <xs:attribute name="beStrictAboutOutputDuringTests" type="xs:boolean" default="false"/>
99437 <xs:attribute name="beStrictAboutTestsThatDoNotTestAnything" type="xs:boolean" default="true"/>
99438 <xs:attribute name="beStrictAboutTodoAnnotatedTests" type="xs:boolean" default="false"/>
99439 <xs:attribute name="beStrictAboutCoverageMetadata" type="xs:boolean" default="false"/>
99440 <xs:attribute name="defaultTimeLimit" type="xs:integer" default="0"/>
99441 <xs:attribute name="enforceTimeLimit" type="xs:boolean" default="false"/>
99442 <xs:attribute name="timeoutForSmallTests" type="xs:integer" default="1"/>
99443 <xs:attribute name="timeoutForMediumTests" type="xs:integer" default="10"/>
99444 <xs:attribute name="timeoutForLargeTests" type="xs:integer" default="60"/>
99445 <xs:attribute name="defaultTestSuite" type="xs:string" default=""/>
99446 <xs:attribute name="testdox" type="xs:boolean" default="false"/>
99447 <xs:attribute name="stderr" type="xs:boolean" default="false"/>
99448 <xs:attribute name="reverseDefectList" type="xs:boolean" default="false"/>
99449 <xs:attribute name="registerMockObjectsFromTestArgumentsRecursively" type="xs:boolean" default="false"/>
99450 <xs:attribute name="extensionsDirectory" type="xs:anyURI"/>
99451 <xs:attribute name="executionOrder" type="executionOrderType" default="default"/>
99452 <xs:attribute name="resolveDependencies" type="xs:boolean" default="true"/>
99453 <xs:attribute name="displayDetailsOnIncompleteTests" type="xs:boolean" default="false"/>
99454 <xs:attribute name="displayDetailsOnSkippedTests" type="xs:boolean" default="false"/>
99455 <xs:attribute name="displayDetailsOnTestsThatTriggerDeprecations" type="xs:boolean" default="false"/>
99456 <xs:attribute name="displayDetailsOnTestsThatTriggerErrors" type="xs:boolean" default="false"/>
99457 <xs:attribute name="displayDetailsOnTestsThatTriggerNotices" type="xs:boolean" default="false"/>
99458 <xs:attribute name="displayDetailsOnTestsThatTriggerWarnings" type="xs:boolean" default="false"/>
99459 </xs:attributeGroup>
99460 <xs:group name="configGroup">
99461 <xs:all>
99462 <xs:element ref="testSuiteFacet" minOccurs="0"/>
99463 <xs:element name="groups" type="groupsType" minOccurs="0"/>
99464 <xs:element name="source" type="sourceType" minOccurs="0"/>
99465 <xs:element name="coverage" type="coverageType" minOccurs="0"/>
99466 <xs:element name="logging" type="loggingType" minOccurs="0"/>
99467 <xs:element name="extensions" type="extensionsType" minOccurs="0"/>
99468 <xs:element name="php" type="phpType" minOccurs="0"/>
99469 </xs:all>
99470 </xs:group>
99471 <xs:element name="testSuiteFacet" abstract="true"/>
99472 <xs:element name="testsuite" type="testSuiteType" substitutionGroup="testSuiteFacet"/>
99473 <xs:element name="testsuites" type="testSuitesType" substitutionGroup="testSuiteFacet"/>
99474 <xs:complexType name="testSuitesType">
99475 <xs:sequence>
99476 <xs:element name="testsuite" type="testSuiteType" maxOccurs="unbounded"/>
99477 </xs:sequence>
99478 </xs:complexType>
99479 <xs:complexType name="testSuiteType">
99480 <xs:sequence>
99481 <xs:choice minOccurs="0" maxOccurs="unbounded">
99482 <xs:group ref="testSuitePathGroup"/>
99483 <xs:element name="exclude" type="xs:string"/>
99484 </xs:choice>
99485 </xs:sequence>
99486 <xs:attribute name="name" type="xs:string" use="required"/>
99487 </xs:complexType>
99488 <xs:group name="testSuitePathGroup">
99489 <xs:sequence>
99490 <xs:choice minOccurs="0" maxOccurs="unbounded">
99491 <xs:element name="directory" type="testSuiteDirectoryType"/>
99492 <xs:element name="file" type="testSuiteFileType"/>
99493 </xs:choice>
99494 </xs:sequence>
99495 </xs:group>
99496 <xs:complexType name="testSuiteDirectoryType">
99497 <xs:simpleContent>
99498 <xs:extension base="xs:string">
99499 <xs:attribute type="xs:string" name="prefix" default=""/>
99500 <xs:attribute type="xs:string" name="suffix" default="Test.php"/>
99501 <xs:attributeGroup ref="phpVersionGroup"/>
99502 </xs:extension>
99503 </xs:simpleContent>
99504 </xs:complexType>
99505 <xs:complexType name="testSuiteFileType">
99506 <xs:simpleContent>
99507 <xs:extension base="xs:anyURI">
99508 <xs:attributeGroup ref="phpVersionGroup"/>
99509 </xs:extension>
99510 </xs:simpleContent>
99511 </xs:complexType>
99512 <xs:attributeGroup name="phpVersionGroup">
99513 <xs:attribute name="phpVersion" type="xs:string" default="5.3.0"/>
99514 <xs:attribute name="phpVersionOperator" type="xs:string" default="&gt;="/>
99515 </xs:attributeGroup>
99516 <xs:group name="coverageReportGroup">
99517 <xs:all>
99518 <xs:element name="clover" type="logToFileType" minOccurs="0"/>
99519 <xs:element name="cobertura" type="logToFileType" minOccurs="0"/>
99520 <xs:element name="crap4j" type="coverageReportCrap4JType" minOccurs="0" />
99521 <xs:element name="html" type="coverageReportHtmlType" minOccurs="0" />
99522 <xs:element name="php" type="logToFileType" minOccurs="0" />
99523 <xs:element name="text" type="coverageReportTextType" minOccurs="0" />
99524 <xs:element name="xml" type="logToDirectoryType" minOccurs="0" />
99525 </xs:all>
99526 </xs:group>
99527 <xs:group name="loggingGroup">
99528 <xs:all>
99529 <xs:element name="junit" type="logToFileType" minOccurs="0" />
99530 <xs:element name="teamcity" type="logToFileType" minOccurs="0" />
99531 <xs:element name="testdoxHtml" type="logToFileType" minOccurs="0" />
99532 <xs:element name="testdoxText" type="logToFileType" minOccurs="0" />
99533 </xs:all>
99534 </xs:group>
99535 <xs:complexType name="logToFileType">
99536 <xs:attribute name="outputFile" type="xs:anyURI" use="required"/>
99537 </xs:complexType>
99538 <xs:complexType name="logToDirectoryType">
99539 <xs:attribute name="outputDirectory" type="xs:anyURI" use="required"/>
99540 </xs:complexType>
99541 <xs:complexType name="coverageReportCrap4JType">
99542 <xs:attribute name="outputFile" type="xs:anyURI" use="required"/>
99543 <xs:attribute name="threshold" type="xs:integer"/>
99544 </xs:complexType>
99545 <xs:complexType name="coverageReportHtmlType">
99546 <xs:attribute name="outputDirectory" type="xs:anyURI" use="required"/>
99547 <xs:attribute name="lowUpperBound" type="xs:integer" default="50"/>
99548 <xs:attribute name="highLowerBound" type="xs:integer" default="90"/>
99549 <xs:attribute name="colorSuccessLow" type="xs:string" default="#dff0d8"/>
99550 <xs:attribute name="colorSuccessMedium" type="xs:string" default="#c3e3b5"/>
99551 <xs:attribute name="colorSuccessHigh" type="xs:string" default="#99cb84"/>
99552 <xs:attribute name="colorWarning" type="xs:string" default="#fcf8e3"/>
99553 <xs:attribute name="colorDanger" type="xs:string" default="#f2dede"/>
99554 <xs:attribute name="customCssFile" type="xs:string"/>
99555 </xs:complexType>
99556 <xs:complexType name="coverageReportTextType">
99557 <xs:attribute name="outputFile" type="xs:anyURI" use="required"/>
99558 <xs:attribute name="showUncoveredFiles" type="xs:boolean" default="false"/>
99559 <xs:attribute name="showOnlySummary" type="xs:boolean" default="false"/>
99560 </xs:complexType>
99561 </xs:schema>
99562 <?xml version="1.0" encoding="UTF-8"?>
99563 <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
99564 <xs:annotation>
99565 <xs:documentation source="https://phpunit.de/documentation.html">
99566 This Schema file defines the rules by which the XML configuration file of PHPUnit 10.2 may be structured.
99567 </xs:documentation>
99568 <xs:appinfo source="https://phpunit.de/documentation.html"/>
99569 </xs:annotation>
99570 <xs:element name="phpunit" type="phpUnitType">
99571 <xs:annotation>
99572 <xs:documentation>Root Element</xs:documentation>
99573 </xs:annotation>
99574 </xs:element>
99575 <xs:complexType name="sourceType">
99576 <xs:all>
99577 <xs:element name="include" minOccurs="0" maxOccurs="1">
99578 <xs:complexType>
99579 <xs:group ref="sourcePathGroup"/>
99580 </xs:complexType>
99581 </xs:element>
99582 <xs:element name="exclude" minOccurs="0" maxOccurs="1">
99583 <xs:complexType>
99584 <xs:group ref="sourcePathGroup"/>
99585 </xs:complexType>
99586 </xs:element>
99587 </xs:all>
99588 <xs:attribute name="restrictDeprecations" type="xs:boolean" default="false"/>
99589 <xs:attribute name="restrictNotices" type="xs:boolean" default="false"/>
99590 <xs:attribute name="restrictWarnings" type="xs:boolean" default="false"/>
99591 <xs:attribute name="ignoreSuppressionOfDeprecations" type="xs:boolean" default="false"/>
99592 <xs:attribute name="ignoreSuppressionOfPhpDeprecations" type="xs:boolean" default="false"/>
99593 <xs:attribute name="ignoreSuppressionOfErrors" type="xs:boolean" default="false"/>
99594 <xs:attribute name="ignoreSuppressionOfNotices" type="xs:boolean" default="false"/>
99595 <xs:attribute name="ignoreSuppressionOfPhpNotices" type="xs:boolean" default="false"/>
99596 <xs:attribute name="ignoreSuppressionOfWarnings" type="xs:boolean" default="false"/>
99597 <xs:attribute name="ignoreSuppressionOfPhpWarnings" type="xs:boolean" default="false"/>
99598 </xs:complexType>
99599 <xs:group name="sourcePathGroup">
99600 <xs:sequence>
99601 <xs:choice minOccurs="0" maxOccurs="unbounded">
99602 <xs:element name="directory" type="sourceDirectoryType"/>
99603 <xs:element name="file" type="xs:anyURI"/>
99604 </xs:choice>
99605 </xs:sequence>
99606 </xs:group>
99607 <xs:complexType name="sourceDirectoryType">
99608 <xs:simpleContent>
99609 <xs:extension base="xs:string">
99610 <xs:attribute type="xs:string" name="prefix" default=""/>
99611 <xs:attribute type="xs:string" name="suffix" default=".php"/>
99612 </xs:extension>
99613 </xs:simpleContent>
99614 </xs:complexType>
99615 <xs:complexType name="coverageType">
99616 <xs:all>
99617 <xs:element name="report" minOccurs="0" maxOccurs="1">
99618 <xs:complexType>
99619 <xs:group ref="coverageReportGroup"/>
99620 </xs:complexType>
99621 </xs:element>
99622 </xs:all>
99623 <xs:attribute name="cacheDirectory" type="xs:anyURI"/>
99624 <xs:attribute name="pathCoverage" type="xs:boolean" default="false"/>
99625 <xs:attribute name="includeUncoveredFiles" type="xs:boolean" default="true"/>
99626 <xs:attribute name="ignoreDeprecatedCodeUnits" type="xs:boolean" default="false"/>
99627 <xs:attribute name="disableCodeCoverageIgnore" type="xs:boolean" default="false"/>
99628 </xs:complexType>
99629 <xs:complexType name="loggingType">
99630 <xs:group ref="loggingGroup"/>
99631 </xs:complexType>
99632 <xs:complexType name="groupsType">
99633 <xs:choice>
99634 <xs:sequence>
99635 <xs:element name="include" type="groupType"/>
99636 <xs:element name="exclude" type="groupType" minOccurs="0"/>
99637 </xs:sequence>
99638 <xs:sequence>
99639 <xs:element name="exclude" type="groupType"/>
99640 </xs:sequence>
99641 </xs:choice>
99642 </xs:complexType>
99643 <xs:complexType name="groupType">
99644 <xs:sequence>
99645 <xs:element name="group" type="xs:string" maxOccurs="unbounded"/>
99646 </xs:sequence>
99647 </xs:complexType>
99648 <xs:complexType name="extensionsType">
99649 <xs:sequence>
99650 <xs:element name="bootstrap" type="bootstrapType" minOccurs="0" maxOccurs="unbounded"/>
99651 </xs:sequence>
99652 </xs:complexType>
99653 <xs:complexType name="bootstrapType">
99654 <xs:sequence>
99655 <xs:element name="parameter" type="parameterType" minOccurs="0" maxOccurs="unbounded"/>
99656 </xs:sequence>
99657 <xs:attribute name="class" type="xs:string" use="required"/>
99658 </xs:complexType>
99659 <xs:complexType name="parameterType">
99660 <xs:attribute name="name" type="xs:string" use="required"/>
99661 <xs:attribute name="value" type="xs:string" use="required"/>
99662 </xs:complexType>
99663 <xs:simpleType name="columnsType">
99664 <xs:union>
99665 <xs:simpleType>
99666 <xs:restriction base="xs:integer"/>
99667 </xs:simpleType>
99668 <xs:simpleType>
99669 <xs:restriction base="xs:string">
99670 <xs:enumeration value="max"/>
99671 </xs:restriction>
99672 </xs:simpleType>
99673 </xs:union>
99674 </xs:simpleType>
99675 <xs:simpleType name="executionOrderType">
99676 <xs:restriction base="xs:string">
99677 <xs:enumeration value="default"/>
99678 <xs:enumeration value="defects"/>
99679 <xs:enumeration value="depends"/>
99680 <xs:enumeration value="depends,defects"/>
99681 <xs:enumeration value="depends,duration"/>
99682 <xs:enumeration value="depends,random"/>
99683 <xs:enumeration value="depends,reverse"/>
99684 <xs:enumeration value="depends,size"/>
99685 <xs:enumeration value="duration"/>
99686 <xs:enumeration value="no-depends"/>
99687 <xs:enumeration value="no-depends,defects"/>
99688 <xs:enumeration value="no-depends,duration"/>
99689 <xs:enumeration value="no-depends,random"/>
99690 <xs:enumeration value="no-depends,reverse"/>
99691 <xs:enumeration value="no-depends,size"/>
99692 <xs:enumeration value="random"/>
99693 <xs:enumeration value="reverse"/>
99694 <xs:enumeration value="size"/>
99695 </xs:restriction>
99696 </xs:simpleType>
99697 <xs:complexType name="phpType">
99698 <xs:sequence>
99699 <xs:choice maxOccurs="unbounded">
99700 <xs:element name="includePath" type="xs:anyURI" minOccurs="0" maxOccurs="unbounded"/>
99701 <xs:element name="ini" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
99702 <xs:element name="const" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
99703 <xs:element name="var" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
99704 <xs:element name="env" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
99705 <xs:element name="post" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
99706 <xs:element name="get" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
99707 <xs:element name="cookie" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
99708 <xs:element name="server" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
99709 <xs:element name="files" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
99710 <xs:element name="request" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
99711 </xs:choice>
99712 </xs:sequence>
99713 </xs:complexType>
99714 <xs:complexType name="namedValueType">
99715 <xs:attribute name="name" use="required" type="xs:string"/>
99716 <xs:attribute name="value" use="required" type="xs:anySimpleType"/>
99717 <xs:attribute name="verbatim" use="optional" type="xs:boolean"/>
99718 <xs:attribute name="force" use="optional" type="xs:boolean"/>
99719 </xs:complexType>
99720 <xs:complexType name="phpUnitType">
99721 <xs:annotation>
99722 <xs:documentation>The main type specifying the document structure</xs:documentation>
99723 </xs:annotation>
99724 <xs:group ref="configGroup"/>
99725 <xs:attributeGroup ref="configAttributeGroup"/>
99726 </xs:complexType>
99727 <xs:attributeGroup name="configAttributeGroup">
99728 <xs:attribute name="backupGlobals" type="xs:boolean" default="false"/>
99729 <xs:attribute name="backupStaticProperties" type="xs:boolean" default="false"/>
99730 <xs:attribute name="bootstrap" type="xs:anyURI"/>
99731 <xs:attribute name="cacheDirectory" type="xs:anyURI"/>
99732 <xs:attribute name="cacheResult" type="xs:boolean" default="true"/>
99733 <xs:attribute name="cacheResultFile" type="xs:anyURI"/>
99734 <xs:attribute name="colors" type="xs:boolean" default="false"/>
99735 <xs:attribute name="columns" type="columnsType" default="80"/>
99736 <xs:attribute name="requireCoverageMetadata" type="xs:boolean" default="false"/>
99737 <xs:attribute name="processIsolation" type="xs:boolean" default="false"/>
99738 <xs:attribute name="failOnDeprecation" type="xs:boolean" default="false"/>
99739 <xs:attribute name="failOnEmptyTestSuite" type="xs:boolean" default="false"/>
99740 <xs:attribute name="failOnIncomplete" type="xs:boolean" default="false"/>
99741 <xs:attribute name="failOnNotice" type="xs:boolean" default="false"/>
99742 <xs:attribute name="failOnRisky" type="xs:boolean" default="false"/>
99743 <xs:attribute name="failOnSkipped" type="xs:boolean" default="false"/>
99744 <xs:attribute name="failOnWarning" type="xs:boolean" default="false"/>
99745 <xs:attribute name="stopOnDefect" type="xs:boolean" default="false"/>
99746 <xs:attribute name="stopOnDeprecation" type="xs:boolean" default="false"/>
99747 <xs:attribute name="stopOnError" type="xs:boolean" default="false"/>
99748 <xs:attribute name="stopOnFailure" type="xs:boolean" default="false"/>
99749 <xs:attribute name="stopOnIncomplete" type="xs:boolean" default="false"/>
99750 <xs:attribute name="stopOnNotice" type="xs:boolean" default="false"/>
99751 <xs:attribute name="stopOnRisky" type="xs:boolean" default="false"/>
99752 <xs:attribute name="stopOnSkipped" type="xs:boolean" default="false"/>
99753 <xs:attribute name="stopOnWarning" type="xs:boolean" default="false"/>
99754 <xs:attribute name="beStrictAboutChangesToGlobalState" type="xs:boolean" default="false"/>
99755 <xs:attribute name="beStrictAboutOutputDuringTests" type="xs:boolean" default="false"/>
99756 <xs:attribute name="beStrictAboutTestsThatDoNotTestAnything" type="xs:boolean" default="true"/>
99757 <xs:attribute name="beStrictAboutTodoAnnotatedTests" type="xs:boolean" default="false"/>
99758 <xs:attribute name="beStrictAboutCoverageMetadata" type="xs:boolean" default="false"/>
99759 <xs:attribute name="defaultTimeLimit" type="xs:integer" default="0"/>
99760 <xs:attribute name="enforceTimeLimit" type="xs:boolean" default="false"/>
99761 <xs:attribute name="timeoutForSmallTests" type="xs:integer" default="1"/>
99762 <xs:attribute name="timeoutForMediumTests" type="xs:integer" default="10"/>
99763 <xs:attribute name="timeoutForLargeTests" type="xs:integer" default="60"/>
99764 <xs:attribute name="defaultTestSuite" type="xs:string" default=""/>
99765 <xs:attribute name="testdox" type="xs:boolean" default="false"/>
99766 <xs:attribute name="stderr" type="xs:boolean" default="false"/>
99767 <xs:attribute name="reverseDefectList" type="xs:boolean" default="false"/>
99768 <xs:attribute name="registerMockObjectsFromTestArgumentsRecursively" type="xs:boolean" default="false"/>
99769 <xs:attribute name="extensionsDirectory" type="xs:anyURI"/>
99770 <xs:attribute name="executionOrder" type="executionOrderType" default="default"/>
99771 <xs:attribute name="resolveDependencies" type="xs:boolean" default="true"/>
99772 <xs:attribute name="displayDetailsOnIncompleteTests" type="xs:boolean" default="false"/>
99773 <xs:attribute name="displayDetailsOnSkippedTests" type="xs:boolean" default="false"/>
99774 <xs:attribute name="displayDetailsOnTestsThatTriggerDeprecations" type="xs:boolean" default="false"/>
99775 <xs:attribute name="displayDetailsOnTestsThatTriggerErrors" type="xs:boolean" default="false"/>
99776 <xs:attribute name="displayDetailsOnTestsThatTriggerNotices" type="xs:boolean" default="false"/>
99777 <xs:attribute name="displayDetailsOnTestsThatTriggerWarnings" type="xs:boolean" default="false"/>
99778 </xs:attributeGroup>
99779 <xs:group name="configGroup">
99780 <xs:all>
99781 <xs:element ref="testSuiteFacet" minOccurs="0"/>
99782 <xs:element name="groups" type="groupsType" minOccurs="0"/>
99783 <xs:element name="source" type="sourceType" minOccurs="0"/>
99784 <xs:element name="coverage" type="coverageType" minOccurs="0"/>
99785 <xs:element name="logging" type="loggingType" minOccurs="0"/>
99786 <xs:element name="extensions" type="extensionsType" minOccurs="0"/>
99787 <xs:element name="php" type="phpType" minOccurs="0"/>
99788 </xs:all>
99789 </xs:group>
99790 <xs:element name="testSuiteFacet" abstract="true"/>
99791 <xs:element name="testsuite" type="testSuiteType" substitutionGroup="testSuiteFacet"/>
99792 <xs:element name="testsuites" type="testSuitesType" substitutionGroup="testSuiteFacet"/>
99793 <xs:complexType name="testSuitesType">
99794 <xs:sequence>
99795 <xs:element name="testsuite" type="testSuiteType" maxOccurs="unbounded"/>
99796 </xs:sequence>
99797 </xs:complexType>
99798 <xs:complexType name="testSuiteType">
99799 <xs:sequence>
99800 <xs:choice minOccurs="0" maxOccurs="unbounded">
99801 <xs:group ref="testSuitePathGroup"/>
99802 <xs:element name="exclude" type="xs:string"/>
99803 </xs:choice>
99804 </xs:sequence>
99805 <xs:attribute name="name" type="xs:string" use="required"/>
99806 </xs:complexType>
99807 <xs:group name="testSuitePathGroup">
99808 <xs:sequence>
99809 <xs:choice minOccurs="0" maxOccurs="unbounded">
99810 <xs:element name="directory" type="testSuiteDirectoryType"/>
99811 <xs:element name="file" type="testSuiteFileType"/>
99812 </xs:choice>
99813 </xs:sequence>
99814 </xs:group>
99815 <xs:complexType name="testSuiteDirectoryType">
99816 <xs:simpleContent>
99817 <xs:extension base="xs:string">
99818 <xs:attribute type="xs:string" name="prefix" default=""/>
99819 <xs:attribute type="xs:string" name="suffix" default="Test.php"/>
99820 <xs:attributeGroup ref="phpVersionGroup"/>
99821 </xs:extension>
99822 </xs:simpleContent>
99823 </xs:complexType>
99824 <xs:complexType name="testSuiteFileType">
99825 <xs:simpleContent>
99826 <xs:extension base="xs:anyURI">
99827 <xs:attributeGroup ref="phpVersionGroup"/>
99828 </xs:extension>
99829 </xs:simpleContent>
99830 </xs:complexType>
99831 <xs:attributeGroup name="phpVersionGroup">
99832 <xs:attribute name="phpVersion" type="xs:string" default="5.3.0"/>
99833 <xs:attribute name="phpVersionOperator" type="xs:string" default="&gt;="/>
99834 </xs:attributeGroup>
99835 <xs:group name="coverageReportGroup">
99836 <xs:all>
99837 <xs:element name="clover" type="logToFileType" minOccurs="0"/>
99838 <xs:element name="cobertura" type="logToFileType" minOccurs="0"/>
99839 <xs:element name="crap4j" type="coverageReportCrap4JType" minOccurs="0" />
99840 <xs:element name="html" type="coverageReportHtmlType" minOccurs="0" />
99841 <xs:element name="php" type="logToFileType" minOccurs="0" />
99842 <xs:element name="text" type="coverageReportTextType" minOccurs="0" />
99843 <xs:element name="xml" type="logToDirectoryType" minOccurs="0" />
99844 </xs:all>
99845 </xs:group>
99846 <xs:group name="loggingGroup">
99847 <xs:all>
99848 <xs:element name="junit" type="logToFileType" minOccurs="0" />
99849 <xs:element name="teamcity" type="logToFileType" minOccurs="0" />
99850 <xs:element name="testdoxHtml" type="logToFileType" minOccurs="0" />
99851 <xs:element name="testdoxText" type="logToFileType" minOccurs="0" />
99852 </xs:all>
99853 </xs:group>
99854 <xs:complexType name="logToFileType">
99855 <xs:attribute name="outputFile" type="xs:anyURI" use="required"/>
99856 </xs:complexType>
99857 <xs:complexType name="logToDirectoryType">
99858 <xs:attribute name="outputDirectory" type="xs:anyURI" use="required"/>
99859 </xs:complexType>
99860 <xs:complexType name="coverageReportCrap4JType">
99861 <xs:attribute name="outputFile" type="xs:anyURI" use="required"/>
99862 <xs:attribute name="threshold" type="xs:integer"/>
99863 </xs:complexType>
99864 <xs:complexType name="coverageReportHtmlType">
99865 <xs:attribute name="outputDirectory" type="xs:anyURI" use="required"/>
99866 <xs:attribute name="lowUpperBound" type="xs:integer" default="50"/>
99867 <xs:attribute name="highLowerBound" type="xs:integer" default="90"/>
99868 <xs:attribute name="colorSuccessLow" type="xs:string" default="#dff0d8"/>
99869 <xs:attribute name="colorSuccessMedium" type="xs:string" default="#c3e3b5"/>
99870 <xs:attribute name="colorSuccessHigh" type="xs:string" default="#99cb84"/>
99871 <xs:attribute name="colorWarning" type="xs:string" default="#fcf8e3"/>
99872 <xs:attribute name="colorDanger" type="xs:string" default="#f2dede"/>
99873 <xs:attribute name="customCssFile" type="xs:string"/>
99874 </xs:complexType>
99875 <xs:complexType name="coverageReportTextType">
99876 <xs:attribute name="outputFile" type="xs:anyURI" use="required"/>
99877 <xs:attribute name="showUncoveredFiles" type="xs:boolean" default="false"/>
99878 <xs:attribute name="showOnlySummary" type="xs:boolean" default="false"/>
99879 </xs:complexType>
99880 </xs:schema>
99881 <?xml version="1.0" encoding="UTF-8"?>
99882 <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
99883 <xs:annotation>
99884 <xs:documentation source="https://phpunit.de/documentation.html">
99885 This Schema file defines the rules by which the XML configuration file of PHPUnit 10.3 may be structured.
99886 </xs:documentation>
99887 <xs:appinfo source="https://phpunit.de/documentation.html"/>
99888 </xs:annotation>
99889 <xs:element name="phpunit" type="phpUnitType">
99890 <xs:annotation>
99891 <xs:documentation>Root Element</xs:documentation>
99892 </xs:annotation>
99893 </xs:element>
99894 <xs:complexType name="sourceType">
99895 <xs:all>
99896 <xs:element name="include" minOccurs="0" maxOccurs="1">
99897 <xs:complexType>
99898 <xs:group ref="sourcePathGroup"/>
99899 </xs:complexType>
99900 </xs:element>
99901 <xs:element name="exclude" minOccurs="0" maxOccurs="1">
99902 <xs:complexType>
99903 <xs:group ref="sourcePathGroup"/>
99904 </xs:complexType>
99905 </xs:element>
99906 </xs:all>
99907 <xs:attribute name="restrictDeprecations" type="xs:boolean" default="false"/>
99908 <xs:attribute name="restrictNotices" type="xs:boolean" default="false"/>
99909 <xs:attribute name="restrictWarnings" type="xs:boolean" default="false"/>
99910 <xs:attribute name="ignoreSuppressionOfDeprecations" type="xs:boolean" default="false"/>
99911 <xs:attribute name="ignoreSuppressionOfPhpDeprecations" type="xs:boolean" default="false"/>
99912 <xs:attribute name="ignoreSuppressionOfErrors" type="xs:boolean" default="false"/>
99913 <xs:attribute name="ignoreSuppressionOfNotices" type="xs:boolean" default="false"/>
99914 <xs:attribute name="ignoreSuppressionOfPhpNotices" type="xs:boolean" default="false"/>
99915 <xs:attribute name="ignoreSuppressionOfWarnings" type="xs:boolean" default="false"/>
99916 <xs:attribute name="ignoreSuppressionOfPhpWarnings" type="xs:boolean" default="false"/>
99917 </xs:complexType>
99918 <xs:group name="sourcePathGroup">
99919 <xs:sequence>
99920 <xs:choice minOccurs="0" maxOccurs="unbounded">
99921 <xs:element name="directory" type="sourceDirectoryType"/>
99922 <xs:element name="file" type="xs:anyURI"/>
99923 </xs:choice>
99924 </xs:sequence>
99925 </xs:group>
99926 <xs:complexType name="sourceDirectoryType">
99927 <xs:simpleContent>
99928 <xs:extension base="xs:string">
99929 <xs:attribute type="xs:string" name="prefix" default=""/>
99930 <xs:attribute type="xs:string" name="suffix" default=".php"/>
99931 </xs:extension>
99932 </xs:simpleContent>
99933 </xs:complexType>
99934 <xs:complexType name="coverageType">
99935 <xs:all>
99936 <xs:element name="report" minOccurs="0" maxOccurs="1">
99937 <xs:complexType>
99938 <xs:group ref="coverageReportGroup"/>
99939 </xs:complexType>
99940 </xs:element>
99941 </xs:all>
99942 <xs:attribute name="cacheDirectory" type="xs:anyURI"/>
99943 <xs:attribute name="pathCoverage" type="xs:boolean" default="false"/>
99944 <xs:attribute name="includeUncoveredFiles" type="xs:boolean" default="true"/>
99945 <xs:attribute name="ignoreDeprecatedCodeUnits" type="xs:boolean" default="false"/>
99946 <xs:attribute name="disableCodeCoverageIgnore" type="xs:boolean" default="false"/>
99947 </xs:complexType>
99948 <xs:complexType name="loggingType">
99949 <xs:group ref="loggingGroup"/>
99950 </xs:complexType>
99951 <xs:complexType name="groupsType">
99952 <xs:choice>
99953 <xs:sequence>
99954 <xs:element name="include" type="groupType"/>
99955 <xs:element name="exclude" type="groupType" minOccurs="0"/>
99956 </xs:sequence>
99957 <xs:sequence>
99958 <xs:element name="exclude" type="groupType"/>
99959 </xs:sequence>
99960 </xs:choice>
99961 </xs:complexType>
99962 <xs:complexType name="groupType">
99963 <xs:sequence>
99964 <xs:element name="group" type="xs:string" maxOccurs="unbounded"/>
99965 </xs:sequence>
99966 </xs:complexType>
99967 <xs:complexType name="extensionsType">
99968 <xs:sequence>
99969 <xs:element name="bootstrap" type="bootstrapType" minOccurs="0" maxOccurs="unbounded"/>
99970 </xs:sequence>
99971 </xs:complexType>
99972 <xs:complexType name="bootstrapType">
99973 <xs:sequence>
99974 <xs:element name="parameter" type="parameterType" minOccurs="0" maxOccurs="unbounded"/>
99975 </xs:sequence>
99976 <xs:attribute name="class" type="xs:string" use="required"/>
99977 </xs:complexType>
99978 <xs:complexType name="parameterType">
99979 <xs:attribute name="name" type="xs:string" use="required"/>
99980 <xs:attribute name="value" type="xs:string" use="required"/>
99981 </xs:complexType>
99982 <xs:simpleType name="columnsType">
99983 <xs:union>
99984 <xs:simpleType>
99985 <xs:restriction base="xs:integer"/>
99986 </xs:simpleType>
99987 <xs:simpleType>
99988 <xs:restriction base="xs:string">
99989 <xs:enumeration value="max"/>
99990 </xs:restriction>
99991 </xs:simpleType>
99992 </xs:union>
99993 </xs:simpleType>
99994 <xs:simpleType name="executionOrderType">
99995 <xs:restriction base="xs:string">
99996 <xs:enumeration value="default"/>
99997 <xs:enumeration value="defects"/>
99998 <xs:enumeration value="depends"/>
99999 <xs:enumeration value="depends,defects"/>
100000 <xs:enumeration value="depends,duration"/>
100001 <xs:enumeration value="depends,random"/>
100002 <xs:enumeration value="depends,reverse"/>
100003 <xs:enumeration value="depends,size"/>
100004 <xs:enumeration value="duration"/>
100005 <xs:enumeration value="no-depends"/>
100006 <xs:enumeration value="no-depends,defects"/>
100007 <xs:enumeration value="no-depends,duration"/>
100008 <xs:enumeration value="no-depends,random"/>
100009 <xs:enumeration value="no-depends,reverse"/>
100010 <xs:enumeration value="no-depends,size"/>
100011 <xs:enumeration value="random"/>
100012 <xs:enumeration value="reverse"/>
100013 <xs:enumeration value="size"/>
100014 </xs:restriction>
100015 </xs:simpleType>
100016 <xs:complexType name="phpType">
100017 <xs:sequence>
100018 <xs:choice maxOccurs="unbounded">
100019 <xs:element name="includePath" type="xs:anyURI" minOccurs="0" maxOccurs="unbounded"/>
100020 <xs:element name="ini" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
100021 <xs:element name="const" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
100022 <xs:element name="var" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
100023 <xs:element name="env" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
100024 <xs:element name="post" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
100025 <xs:element name="get" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
100026 <xs:element name="cookie" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
100027 <xs:element name="server" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
100028 <xs:element name="files" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
100029 <xs:element name="request" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
100030 </xs:choice>
100031 </xs:sequence>
100032 </xs:complexType>
100033 <xs:complexType name="namedValueType">
100034 <xs:attribute name="name" use="required" type="xs:string"/>
100035 <xs:attribute name="value" use="required" type="xs:anySimpleType"/>
100036 <xs:attribute name="verbatim" use="optional" type="xs:boolean"/>
100037 <xs:attribute name="force" use="optional" type="xs:boolean"/>
100038 </xs:complexType>
100039 <xs:complexType name="phpUnitType">
100040 <xs:annotation>
100041 <xs:documentation>The main type specifying the document structure</xs:documentation>
100042 </xs:annotation>
100043 <xs:group ref="configGroup"/>
100044 <xs:attributeGroup ref="configAttributeGroup"/>
100045 </xs:complexType>
100046 <xs:attributeGroup name="configAttributeGroup">
100047 <xs:attribute name="backupGlobals" type="xs:boolean" default="false"/>
100048 <xs:attribute name="backupStaticProperties" type="xs:boolean" default="false"/>
100049 <xs:attribute name="bootstrap" type="xs:anyURI"/>
100050 <xs:attribute name="cacheDirectory" type="xs:anyURI"/>
100051 <xs:attribute name="cacheResult" type="xs:boolean" default="true"/>
100052 <xs:attribute name="cacheResultFile" type="xs:anyURI"/>
100053 <xs:attribute name="colors" type="xs:boolean" default="false"/>
100054 <xs:attribute name="columns" type="columnsType" default="80"/>
100055 <xs:attribute name="controlGarbageCollector" type="xs:boolean" default="false"/>
100056 <xs:attribute name="numberOfTestsBeforeGarbageCollection" type="xs:integer" default="100"/>
100057 <xs:attribute name="requireCoverageMetadata" type="xs:boolean" default="false"/>
100058 <xs:attribute name="processIsolation" type="xs:boolean" default="false"/>
100059 <xs:attribute name="failOnDeprecation" type="xs:boolean" default="false"/>
100060 <xs:attribute name="failOnEmptyTestSuite" type="xs:boolean" default="false"/>
100061 <xs:attribute name="failOnIncomplete" type="xs:boolean" default="false"/>
100062 <xs:attribute name="failOnNotice" type="xs:boolean" default="false"/>
100063 <xs:attribute name="failOnRisky" type="xs:boolean" default="false"/>
100064 <xs:attribute name="failOnSkipped" type="xs:boolean" default="false"/>
100065 <xs:attribute name="failOnWarning" type="xs:boolean" default="false"/>
100066 <xs:attribute name="stopOnDefect" type="xs:boolean" default="false"/>
100067 <xs:attribute name="stopOnDeprecation" type="xs:boolean" default="false"/>
100068 <xs:attribute name="stopOnError" type="xs:boolean" default="false"/>
100069 <xs:attribute name="stopOnFailure" type="xs:boolean" default="false"/>
100070 <xs:attribute name="stopOnIncomplete" type="xs:boolean" default="false"/>
100071 <xs:attribute name="stopOnNotice" type="xs:boolean" default="false"/>
100072 <xs:attribute name="stopOnRisky" type="xs:boolean" default="false"/>
100073 <xs:attribute name="stopOnSkipped" type="xs:boolean" default="false"/>
100074 <xs:attribute name="stopOnWarning" type="xs:boolean" default="false"/>
100075 <xs:attribute name="beStrictAboutChangesToGlobalState" type="xs:boolean" default="false"/>
100076 <xs:attribute name="beStrictAboutOutputDuringTests" type="xs:boolean" default="false"/>
100077 <xs:attribute name="beStrictAboutTestsThatDoNotTestAnything" type="xs:boolean" default="true"/>
100078 <xs:attribute name="beStrictAboutTodoAnnotatedTests" type="xs:boolean" default="false"/>
100079 <xs:attribute name="beStrictAboutCoverageMetadata" type="xs:boolean" default="false"/>
100080 <xs:attribute name="defaultTimeLimit" type="xs:integer" default="0"/>
100081 <xs:attribute name="enforceTimeLimit" type="xs:boolean" default="false"/>
100082 <xs:attribute name="timeoutForSmallTests" type="xs:integer" default="1"/>
100083 <xs:attribute name="timeoutForMediumTests" type="xs:integer" default="10"/>
100084 <xs:attribute name="timeoutForLargeTests" type="xs:integer" default="60"/>
100085 <xs:attribute name="defaultTestSuite" type="xs:string" default=""/>
100086 <xs:attribute name="testdox" type="xs:boolean" default="false"/>
100087 <xs:attribute name="stderr" type="xs:boolean" default="false"/>
100088 <xs:attribute name="reverseDefectList" type="xs:boolean" default="false"/>
100089 <xs:attribute name="registerMockObjectsFromTestArgumentsRecursively" type="xs:boolean" default="false"/>
100090 <xs:attribute name="extensionsDirectory" type="xs:anyURI"/>
100091 <xs:attribute name="executionOrder" type="executionOrderType" default="default"/>
100092 <xs:attribute name="resolveDependencies" type="xs:boolean" default="true"/>
100093 <xs:attribute name="displayDetailsOnIncompleteTests" type="xs:boolean" default="false"/>
100094 <xs:attribute name="displayDetailsOnSkippedTests" type="xs:boolean" default="false"/>
100095 <xs:attribute name="displayDetailsOnTestsThatTriggerDeprecations" type="xs:boolean" default="false"/>
100096 <xs:attribute name="displayDetailsOnTestsThatTriggerErrors" type="xs:boolean" default="false"/>
100097 <xs:attribute name="displayDetailsOnTestsThatTriggerNotices" type="xs:boolean" default="false"/>
100098 <xs:attribute name="displayDetailsOnTestsThatTriggerWarnings" type="xs:boolean" default="false"/>
100099 </xs:attributeGroup>
100100 <xs:group name="configGroup">
100101 <xs:all>
100102 <xs:element ref="testSuiteFacet" minOccurs="0"/>
100103 <xs:element name="groups" type="groupsType" minOccurs="0"/>
100104 <xs:element name="source" type="sourceType" minOccurs="0"/>
100105 <xs:element name="coverage" type="coverageType" minOccurs="0"/>
100106 <xs:element name="logging" type="loggingType" minOccurs="0"/>
100107 <xs:element name="extensions" type="extensionsType" minOccurs="0"/>
100108 <xs:element name="php" type="phpType" minOccurs="0"/>
100109 </xs:all>
100110 </xs:group>
100111 <xs:element name="testSuiteFacet" abstract="true"/>
100112 <xs:element name="testsuite" type="testSuiteType" substitutionGroup="testSuiteFacet"/>
100113 <xs:element name="testsuites" type="testSuitesType" substitutionGroup="testSuiteFacet"/>
100114 <xs:complexType name="testSuitesType">
100115 <xs:sequence>
100116 <xs:element name="testsuite" type="testSuiteType" maxOccurs="unbounded"/>
100117 </xs:sequence>
100118 </xs:complexType>
100119 <xs:complexType name="testSuiteType">
100120 <xs:sequence>
100121 <xs:choice minOccurs="0" maxOccurs="unbounded">
100122 <xs:group ref="testSuitePathGroup"/>
100123 <xs:element name="exclude" type="xs:string"/>
100124 </xs:choice>
100125 </xs:sequence>
100126 <xs:attribute name="name" type="xs:string" use="required"/>
100127 </xs:complexType>
100128 <xs:group name="testSuitePathGroup">
100129 <xs:sequence>
100130 <xs:choice minOccurs="0" maxOccurs="unbounded">
100131 <xs:element name="directory" type="testSuiteDirectoryType"/>
100132 <xs:element name="file" type="testSuiteFileType"/>
100133 </xs:choice>
100134 </xs:sequence>
100135 </xs:group>
100136 <xs:complexType name="testSuiteDirectoryType">
100137 <xs:simpleContent>
100138 <xs:extension base="xs:string">
100139 <xs:attribute type="xs:string" name="prefix" default=""/>
100140 <xs:attribute type="xs:string" name="suffix" default="Test.php"/>
100141 <xs:attributeGroup ref="phpVersionGroup"/>
100142 </xs:extension>
100143 </xs:simpleContent>
100144 </xs:complexType>
100145 <xs:complexType name="testSuiteFileType">
100146 <xs:simpleContent>
100147 <xs:extension base="xs:anyURI">
100148 <xs:attributeGroup ref="phpVersionGroup"/>
100149 </xs:extension>
100150 </xs:simpleContent>
100151 </xs:complexType>
100152 <xs:attributeGroup name="phpVersionGroup">
100153 <xs:attribute name="phpVersion" type="xs:string" default="5.3.0"/>
100154 <xs:attribute name="phpVersionOperator" type="xs:string" default="&gt;="/>
100155 </xs:attributeGroup>
100156 <xs:group name="coverageReportGroup">
100157 <xs:all>
100158 <xs:element name="clover" type="logToFileType" minOccurs="0"/>
100159 <xs:element name="cobertura" type="logToFileType" minOccurs="0"/>
100160 <xs:element name="crap4j" type="coverageReportCrap4JType" minOccurs="0" />
100161 <xs:element name="html" type="coverageReportHtmlType" minOccurs="0" />
100162 <xs:element name="php" type="logToFileType" minOccurs="0" />
100163 <xs:element name="text" type="coverageReportTextType" minOccurs="0" />
100164 <xs:element name="xml" type="logToDirectoryType" minOccurs="0" />
100165 </xs:all>
100166 </xs:group>
100167 <xs:group name="loggingGroup">
100168 <xs:all>
100169 <xs:element name="junit" type="logToFileType" minOccurs="0" />
100170 <xs:element name="teamcity" type="logToFileType" minOccurs="0" />
100171 <xs:element name="testdoxHtml" type="logToFileType" minOccurs="0" />
100172 <xs:element name="testdoxText" type="logToFileType" minOccurs="0" />
100173 </xs:all>
100174 </xs:group>
100175 <xs:complexType name="logToFileType">
100176 <xs:attribute name="outputFile" type="xs:anyURI" use="required"/>
100177 </xs:complexType>
100178 <xs:complexType name="logToDirectoryType">
100179 <xs:attribute name="outputDirectory" type="xs:anyURI" use="required"/>
100180 </xs:complexType>
100181 <xs:complexType name="coverageReportCrap4JType">
100182 <xs:attribute name="outputFile" type="xs:anyURI" use="required"/>
100183 <xs:attribute name="threshold" type="xs:integer"/>
100184 </xs:complexType>
100185 <xs:complexType name="coverageReportHtmlType">
100186 <xs:attribute name="outputDirectory" type="xs:anyURI" use="required"/>
100187 <xs:attribute name="lowUpperBound" type="xs:integer" default="50"/>
100188 <xs:attribute name="highLowerBound" type="xs:integer" default="90"/>
100189 <xs:attribute name="colorSuccessLow" type="xs:string" default="#dff0d8"/>
100190 <xs:attribute name="colorSuccessMedium" type="xs:string" default="#c3e3b5"/>
100191 <xs:attribute name="colorSuccessHigh" type="xs:string" default="#99cb84"/>
100192 <xs:attribute name="colorWarning" type="xs:string" default="#fcf8e3"/>
100193 <xs:attribute name="colorDanger" type="xs:string" default="#f2dede"/>
100194 <xs:attribute name="customCssFile" type="xs:string"/>
100195 </xs:complexType>
100196 <xs:complexType name="coverageReportTextType">
100197 <xs:attribute name="outputFile" type="xs:anyURI" use="required"/>
100198 <xs:attribute name="showUncoveredFiles" type="xs:boolean" default="false"/>
100199 <xs:attribute name="showOnlySummary" type="xs:boolean" default="false"/>
100200 </xs:complexType>
100201 </xs:schema>
100202 <?xml version="1.0" encoding="UTF-8"?>
100203 <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
100204 <xs:annotation>
100205 <xs:documentation source="https://phpunit.de/documentation.html">
100206 This Schema file defines the rules by which the XML configuration file of PHPUnit 10.4 may be structured.
100207 </xs:documentation>
100208 <xs:appinfo source="https://phpunit.de/documentation.html"/>
100209 </xs:annotation>
100210 <xs:element name="phpunit" type="phpUnitType">
100211 <xs:annotation>
100212 <xs:documentation>Root Element</xs:documentation>
100213 </xs:annotation>
100214 </xs:element>
100215 <xs:complexType name="sourceType">
100216 <xs:all>
100217 <xs:element name="include" minOccurs="0" maxOccurs="1">
100218 <xs:complexType>
100219 <xs:group ref="sourcePathGroup"/>
100220 </xs:complexType>
100221 </xs:element>
100222 <xs:element name="exclude" minOccurs="0" maxOccurs="1">
100223 <xs:complexType>
100224 <xs:group ref="sourcePathGroup"/>
100225 </xs:complexType>
100226 </xs:element>
100227 </xs:all>
100228 <xs:attribute name="baseline" type="xs:anyURI"/>
100229 <xs:attribute name="restrictDeprecations" type="xs:boolean" default="false"/>
100230 <xs:attribute name="restrictNotices" type="xs:boolean" default="false"/>
100231 <xs:attribute name="restrictWarnings" type="xs:boolean" default="false"/>
100232 <xs:attribute name="ignoreSuppressionOfDeprecations" type="xs:boolean" default="false"/>
100233 <xs:attribute name="ignoreSuppressionOfPhpDeprecations" type="xs:boolean" default="false"/>
100234 <xs:attribute name="ignoreSuppressionOfErrors" type="xs:boolean" default="false"/>
100235 <xs:attribute name="ignoreSuppressionOfNotices" type="xs:boolean" default="false"/>
100236 <xs:attribute name="ignoreSuppressionOfPhpNotices" type="xs:boolean" default="false"/>
100237 <xs:attribute name="ignoreSuppressionOfWarnings" type="xs:boolean" default="false"/>
100238 <xs:attribute name="ignoreSuppressionOfPhpWarnings" type="xs:boolean" default="false"/>
100239 </xs:complexType>
100240 <xs:group name="sourcePathGroup">
100241 <xs:sequence>
100242 <xs:choice minOccurs="0" maxOccurs="unbounded">
100243 <xs:element name="directory" type="sourceDirectoryType"/>
100244 <xs:element name="file" type="xs:anyURI"/>
100245 </xs:choice>
100246 </xs:sequence>
100247 </xs:group>
100248 <xs:complexType name="sourceDirectoryType">
100249 <xs:simpleContent>
100250 <xs:extension base="xs:string">
100251 <xs:attribute type="xs:string" name="prefix" default=""/>
100252 <xs:attribute type="xs:string" name="suffix" default=".php"/>
100253 </xs:extension>
100254 </xs:simpleContent>
100255 </xs:complexType>
100256 <xs:complexType name="coverageType">
100257 <xs:all>
100258 <xs:element name="report" minOccurs="0" maxOccurs="1">
100259 <xs:complexType>
100260 <xs:group ref="coverageReportGroup"/>
100261 </xs:complexType>
100262 </xs:element>
100263 </xs:all>
100264 <xs:attribute name="cacheDirectory" type="xs:anyURI"/>
100265 <xs:attribute name="pathCoverage" type="xs:boolean" default="false"/>
100266 <xs:attribute name="includeUncoveredFiles" type="xs:boolean" default="true"/>
100267 <xs:attribute name="ignoreDeprecatedCodeUnits" type="xs:boolean" default="false"/>
100268 <xs:attribute name="disableCodeCoverageIgnore" type="xs:boolean" default="false"/>
100269 </xs:complexType>
100270 <xs:complexType name="loggingType">
100271 <xs:group ref="loggingGroup"/>
100272 </xs:complexType>
100273 <xs:complexType name="groupsType">
100274 <xs:choice>
100275 <xs:sequence>
100276 <xs:element name="include" type="groupType"/>
100277 <xs:element name="exclude" type="groupType" minOccurs="0"/>
100278 </xs:sequence>
100279 <xs:sequence>
100280 <xs:element name="exclude" type="groupType"/>
100281 </xs:sequence>
100282 </xs:choice>
100283 </xs:complexType>
100284 <xs:complexType name="groupType">
100285 <xs:sequence>
100286 <xs:element name="group" type="xs:string" maxOccurs="unbounded"/>
100287 </xs:sequence>
100288 </xs:complexType>
100289 <xs:complexType name="extensionsType">
100290 <xs:sequence>
100291 <xs:element name="bootstrap" type="bootstrapType" minOccurs="0" maxOccurs="unbounded"/>
100292 </xs:sequence>
100293 </xs:complexType>
100294 <xs:complexType name="bootstrapType">
100295 <xs:sequence>
100296 <xs:element name="parameter" type="parameterType" minOccurs="0" maxOccurs="unbounded"/>
100297 </xs:sequence>
100298 <xs:attribute name="class" type="xs:string" use="required"/>
100299 </xs:complexType>
100300 <xs:complexType name="parameterType">
100301 <xs:attribute name="name" type="xs:string" use="required"/>
100302 <xs:attribute name="value" type="xs:string" use="required"/>
100303 </xs:complexType>
100304 <xs:simpleType name="columnsType">
100305 <xs:union>
100306 <xs:simpleType>
100307 <xs:restriction base="xs:integer"/>
100308 </xs:simpleType>
100309 <xs:simpleType>
100310 <xs:restriction base="xs:string">
100311 <xs:enumeration value="max"/>
100312 </xs:restriction>
100313 </xs:simpleType>
100314 </xs:union>
100315 </xs:simpleType>
100316 <xs:simpleType name="executionOrderType">
100317 <xs:restriction base="xs:string">
100318 <xs:enumeration value="default"/>
100319 <xs:enumeration value="defects"/>
100320 <xs:enumeration value="depends"/>
100321 <xs:enumeration value="depends,defects"/>
100322 <xs:enumeration value="depends,duration"/>
100323 <xs:enumeration value="depends,random"/>
100324 <xs:enumeration value="depends,reverse"/>
100325 <xs:enumeration value="depends,size"/>
100326 <xs:enumeration value="duration"/>
100327 <xs:enumeration value="no-depends"/>
100328 <xs:enumeration value="no-depends,defects"/>
100329 <xs:enumeration value="no-depends,duration"/>
100330 <xs:enumeration value="no-depends,random"/>
100331 <xs:enumeration value="no-depends,reverse"/>
100332 <xs:enumeration value="no-depends,size"/>
100333 <xs:enumeration value="random"/>
100334 <xs:enumeration value="reverse"/>
100335 <xs:enumeration value="size"/>
100336 </xs:restriction>
100337 </xs:simpleType>
100338 <xs:complexType name="phpType">
100339 <xs:sequence>
100340 <xs:choice maxOccurs="unbounded">
100341 <xs:element name="includePath" type="xs:anyURI" minOccurs="0" maxOccurs="unbounded"/>
100342 <xs:element name="ini" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
100343 <xs:element name="const" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
100344 <xs:element name="var" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
100345 <xs:element name="env" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
100346 <xs:element name="post" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
100347 <xs:element name="get" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
100348 <xs:element name="cookie" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
100349 <xs:element name="server" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
100350 <xs:element name="files" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
100351 <xs:element name="request" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
100352 </xs:choice>
100353 </xs:sequence>
100354 </xs:complexType>
100355 <xs:complexType name="namedValueType">
100356 <xs:attribute name="name" use="required" type="xs:string"/>
100357 <xs:attribute name="value" use="required" type="xs:anySimpleType"/>
100358 <xs:attribute name="verbatim" use="optional" type="xs:boolean"/>
100359 <xs:attribute name="force" use="optional" type="xs:boolean"/>
100360 </xs:complexType>
100361 <xs:complexType name="phpUnitType">
100362 <xs:annotation>
100363 <xs:documentation>The main type specifying the document structure</xs:documentation>
100364 </xs:annotation>
100365 <xs:group ref="configGroup"/>
100366 <xs:attributeGroup ref="configAttributeGroup"/>
100367 </xs:complexType>
100368 <xs:attributeGroup name="configAttributeGroup">
100369 <xs:attribute name="backupGlobals" type="xs:boolean" default="false"/>
100370 <xs:attribute name="backupStaticProperties" type="xs:boolean" default="false"/>
100371 <xs:attribute name="bootstrap" type="xs:anyURI"/>
100372 <xs:attribute name="cacheDirectory" type="xs:anyURI"/>
100373 <xs:attribute name="cacheResult" type="xs:boolean" default="true"/>
100374 <xs:attribute name="cacheResultFile" type="xs:anyURI"/>
100375 <xs:attribute name="colors" type="xs:boolean" default="false"/>
100376 <xs:attribute name="columns" type="columnsType" default="80"/>
100377 <xs:attribute name="controlGarbageCollector" type="xs:boolean" default="false"/>
100378 <xs:attribute name="numberOfTestsBeforeGarbageCollection" type="xs:integer" default="100"/>
100379 <xs:attribute name="requireCoverageMetadata" type="xs:boolean" default="false"/>
100380 <xs:attribute name="processIsolation" type="xs:boolean" default="false"/>
100381 <xs:attribute name="failOnDeprecation" type="xs:boolean" default="false"/>
100382 <xs:attribute name="failOnEmptyTestSuite" type="xs:boolean" default="false"/>
100383 <xs:attribute name="failOnIncomplete" type="xs:boolean" default="false"/>
100384 <xs:attribute name="failOnNotice" type="xs:boolean" default="false"/>
100385 <xs:attribute name="failOnRisky" type="xs:boolean" default="false"/>
100386 <xs:attribute name="failOnSkipped" type="xs:boolean" default="false"/>
100387 <xs:attribute name="failOnWarning" type="xs:boolean" default="false"/>
100388 <xs:attribute name="stopOnDefect" type="xs:boolean" default="false"/>
100389 <xs:attribute name="stopOnDeprecation" type="xs:boolean" default="false"/>
100390 <xs:attribute name="stopOnError" type="xs:boolean" default="false"/>
100391 <xs:attribute name="stopOnFailure" type="xs:boolean" default="false"/>
100392 <xs:attribute name="stopOnIncomplete" type="xs:boolean" default="false"/>
100393 <xs:attribute name="stopOnNotice" type="xs:boolean" default="false"/>
100394 <xs:attribute name="stopOnRisky" type="xs:boolean" default="false"/>
100395 <xs:attribute name="stopOnSkipped" type="xs:boolean" default="false"/>
100396 <xs:attribute name="stopOnWarning" type="xs:boolean" default="false"/>
100397 <xs:attribute name="beStrictAboutChangesToGlobalState" type="xs:boolean" default="false"/>
100398 <xs:attribute name="beStrictAboutOutputDuringTests" type="xs:boolean" default="false"/>
100399 <xs:attribute name="beStrictAboutTestsThatDoNotTestAnything" type="xs:boolean" default="true"/>
100400 <xs:attribute name="beStrictAboutTodoAnnotatedTests" type="xs:boolean" default="false"/>
100401 <xs:attribute name="beStrictAboutCoverageMetadata" type="xs:boolean" default="false"/>
100402 <xs:attribute name="defaultTimeLimit" type="xs:integer" default="0"/>
100403 <xs:attribute name="enforceTimeLimit" type="xs:boolean" default="false"/>
100404 <xs:attribute name="timeoutForSmallTests" type="xs:integer" default="1"/>
100405 <xs:attribute name="timeoutForMediumTests" type="xs:integer" default="10"/>
100406 <xs:attribute name="timeoutForLargeTests" type="xs:integer" default="60"/>
100407 <xs:attribute name="defaultTestSuite" type="xs:string" default=""/>
100408 <xs:attribute name="testdox" type="xs:boolean" default="false"/>
100409 <xs:attribute name="stderr" type="xs:boolean" default="false"/>
100410 <xs:attribute name="reverseDefectList" type="xs:boolean" default="false"/>
100411 <xs:attribute name="registerMockObjectsFromTestArgumentsRecursively" type="xs:boolean" default="false"/>
100412 <xs:attribute name="extensionsDirectory" type="xs:anyURI"/>
100413 <xs:attribute name="executionOrder" type="executionOrderType" default="default"/>
100414 <xs:attribute name="resolveDependencies" type="xs:boolean" default="true"/>
100415 <xs:attribute name="displayDetailsOnIncompleteTests" type="xs:boolean" default="false"/>
100416 <xs:attribute name="displayDetailsOnSkippedTests" type="xs:boolean" default="false"/>
100417 <xs:attribute name="displayDetailsOnTestsThatTriggerDeprecations" type="xs:boolean" default="false"/>
100418 <xs:attribute name="displayDetailsOnTestsThatTriggerErrors" type="xs:boolean" default="false"/>
100419 <xs:attribute name="displayDetailsOnTestsThatTriggerNotices" type="xs:boolean" default="false"/>
100420 <xs:attribute name="displayDetailsOnTestsThatTriggerWarnings" type="xs:boolean" default="false"/>
100421 </xs:attributeGroup>
100422 <xs:group name="configGroup">
100423 <xs:all>
100424 <xs:element ref="testSuiteFacet" minOccurs="0"/>
100425 <xs:element name="groups" type="groupsType" minOccurs="0"/>
100426 <xs:element name="source" type="sourceType" minOccurs="0"/>
100427 <xs:element name="coverage" type="coverageType" minOccurs="0"/>
100428 <xs:element name="logging" type="loggingType" minOccurs="0"/>
100429 <xs:element name="extensions" type="extensionsType" minOccurs="0"/>
100430 <xs:element name="php" type="phpType" minOccurs="0"/>
100431 </xs:all>
100432 </xs:group>
100433 <xs:element name="testSuiteFacet" abstract="true"/>
100434 <xs:element name="testsuite" type="testSuiteType" substitutionGroup="testSuiteFacet"/>
100435 <xs:element name="testsuites" type="testSuitesType" substitutionGroup="testSuiteFacet"/>
100436 <xs:complexType name="testSuitesType">
100437 <xs:sequence>
100438 <xs:element name="testsuite" type="testSuiteType" maxOccurs="unbounded"/>
100439 </xs:sequence>
100440 </xs:complexType>
100441 <xs:complexType name="testSuiteType">
100442 <xs:sequence>
100443 <xs:choice minOccurs="0" maxOccurs="unbounded">
100444 <xs:group ref="testSuitePathGroup"/>
100445 <xs:element name="exclude" type="xs:string"/>
100446 </xs:choice>
100447 </xs:sequence>
100448 <xs:attribute name="name" type="xs:string" use="required"/>
100449 </xs:complexType>
100450 <xs:group name="testSuitePathGroup">
100451 <xs:sequence>
100452 <xs:choice minOccurs="0" maxOccurs="unbounded">
100453 <xs:element name="directory" type="testSuiteDirectoryType"/>
100454 <xs:element name="file" type="testSuiteFileType"/>
100455 </xs:choice>
100456 </xs:sequence>
100457 </xs:group>
100458 <xs:complexType name="testSuiteDirectoryType">
100459 <xs:simpleContent>
100460 <xs:extension base="xs:string">
100461 <xs:attribute type="xs:string" name="prefix" default=""/>
100462 <xs:attribute type="xs:string" name="suffix" default="Test.php"/>
100463 <xs:attributeGroup ref="phpVersionGroup"/>
100464 </xs:extension>
100465 </xs:simpleContent>
100466 </xs:complexType>
100467 <xs:complexType name="testSuiteFileType">
100468 <xs:simpleContent>
100469 <xs:extension base="xs:anyURI">
100470 <xs:attributeGroup ref="phpVersionGroup"/>
100471 </xs:extension>
100472 </xs:simpleContent>
100473 </xs:complexType>
100474 <xs:attributeGroup name="phpVersionGroup">
100475 <xs:attribute name="phpVersion" type="xs:string" default="5.3.0"/>
100476 <xs:attribute name="phpVersionOperator" type="xs:string" default="&gt;="/>
100477 </xs:attributeGroup>
100478 <xs:group name="coverageReportGroup">
100479 <xs:all>
100480 <xs:element name="clover" type="logToFileType" minOccurs="0"/>
100481 <xs:element name="cobertura" type="logToFileType" minOccurs="0"/>
100482 <xs:element name="crap4j" type="coverageReportCrap4JType" minOccurs="0" />
100483 <xs:element name="html" type="coverageReportHtmlType" minOccurs="0" />
100484 <xs:element name="php" type="logToFileType" minOccurs="0" />
100485 <xs:element name="text" type="coverageReportTextType" minOccurs="0" />
100486 <xs:element name="xml" type="logToDirectoryType" minOccurs="0" />
100487 </xs:all>
100488 </xs:group>
100489 <xs:group name="loggingGroup">
100490 <xs:all>
100491 <xs:element name="junit" type="logToFileType" minOccurs="0" />
100492 <xs:element name="teamcity" type="logToFileType" minOccurs="0" />
100493 <xs:element name="testdoxHtml" type="logToFileType" minOccurs="0" />
100494 <xs:element name="testdoxText" type="logToFileType" minOccurs="0" />
100495 </xs:all>
100496 </xs:group>
100497 <xs:complexType name="logToFileType">
100498 <xs:attribute name="outputFile" type="xs:anyURI" use="required"/>
100499 </xs:complexType>
100500 <xs:complexType name="logToDirectoryType">
100501 <xs:attribute name="outputDirectory" type="xs:anyURI" use="required"/>
100502 </xs:complexType>
100503 <xs:complexType name="coverageReportCrap4JType">
100504 <xs:attribute name="outputFile" type="xs:anyURI" use="required"/>
100505 <xs:attribute name="threshold" type="xs:integer"/>
100506 </xs:complexType>
100507 <xs:complexType name="coverageReportHtmlType">
100508 <xs:attribute name="outputDirectory" type="xs:anyURI" use="required"/>
100509 <xs:attribute name="lowUpperBound" type="xs:integer" default="50"/>
100510 <xs:attribute name="highLowerBound" type="xs:integer" default="90"/>
100511 <xs:attribute name="colorSuccessLow" type="xs:string" default="#dff0d8"/>
100512 <xs:attribute name="colorSuccessMedium" type="xs:string" default="#c3e3b5"/>
100513 <xs:attribute name="colorSuccessHigh" type="xs:string" default="#99cb84"/>
100514 <xs:attribute name="colorWarning" type="xs:string" default="#fcf8e3"/>
100515 <xs:attribute name="colorDanger" type="xs:string" default="#f2dede"/>
100516 <xs:attribute name="customCssFile" type="xs:string"/>
100517 </xs:complexType>
100518 <xs:complexType name="coverageReportTextType">
100519 <xs:attribute name="outputFile" type="xs:anyURI" use="required"/>
100520 <xs:attribute name="showUncoveredFiles" type="xs:boolean" default="false"/>
100521 <xs:attribute name="showOnlySummary" type="xs:boolean" default="false"/>
100522 </xs:complexType>
100523 </xs:schema>
100524 <?xml version="1.0" encoding="UTF-8"?>
100525 <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
100526 <xs:annotation>
100527 <xs:documentation source="https://phpunit.de/documentation.html">
100528 This Schema file defines the rules by which the XML configuration file of PHPUnit 8.5 may be structured.
100529 </xs:documentation>
100530 <xs:appinfo source="https://phpunit.de/documentation.html"/>
100531 </xs:annotation>
100532 <xs:element name="phpunit" type="phpUnitType">
100533 <xs:annotation>
100534 <xs:documentation>Root Element</xs:documentation>
100535 </xs:annotation>
100536 </xs:element>
100537 <xs:complexType name="filtersType">
100538 <xs:sequence>
100539 <xs:element name="whitelist" type="whiteListType" minOccurs="0"/>
100540 </xs:sequence>
100541 </xs:complexType>
100542 <xs:complexType name="filterType">
100543 <xs:sequence>
100544 <xs:choice maxOccurs="unbounded" minOccurs="0">
100545 <xs:group ref="pathGroup"/>
100546 <xs:element name="exclude">
100547 <xs:complexType>
100548 <xs:group ref="pathGroup"/>
100549 </xs:complexType>
100550 </xs:element>
100551 </xs:choice>
100552 </xs:sequence>
100553 </xs:complexType>
100554 <xs:complexType name="whiteListType">
100555 <xs:complexContent>
100556 <xs:extension base="filterType">
100557 <xs:attribute name="addUncoveredFilesFromWhitelist" default="true" type="xs:boolean"/>
100558 <xs:attribute name="processUncoveredFilesFromWhitelist" default="false" type="xs:boolean"/>
100559 </xs:extension>
100560 </xs:complexContent>
100561 </xs:complexType>
100562 <xs:complexType name="groupsType">
100563 <xs:choice>
100564 <xs:sequence>
100565 <xs:element name="include" type="groupType"/>
100566 <xs:element name="exclude" type="groupType" minOccurs="0"/>
100567 </xs:sequence>
100568 <xs:sequence>
100569 <xs:element name="exclude" type="groupType"/>
100570 </xs:sequence>
100571 </xs:choice>
100572 </xs:complexType>
100573 <xs:complexType name="groupType">
100574 <xs:sequence>
100575 <xs:element name="group" type="xs:string" maxOccurs="unbounded"/>
100576 </xs:sequence>
100577 </xs:complexType>
100578 <xs:complexType name="extensionsType">
100579 <xs:sequence>
100580 <xs:element name="extension" type="objectType" maxOccurs="unbounded"/>
100581 </xs:sequence>
100582 </xs:complexType>
100583 <xs:complexType name="listenersType">
100584 <xs:sequence>
100585 <xs:element name="listener" type="objectType" maxOccurs="unbounded"/>
100586 </xs:sequence>
100587 </xs:complexType>
100588 <xs:complexType name="objectType">
100589 <xs:sequence>
100590 <xs:element name="arguments" minOccurs="0">
100591 <xs:complexType>
100592 <xs:group ref="argumentsGroup"/>
100593 </xs:complexType>
100594 </xs:element>
100595 </xs:sequence>
100596 <xs:attribute name="class" type="xs:string" use="required"/>
100597 <xs:attribute name="file" type="xs:anyURI"/>
100598 </xs:complexType>
100599 <xs:complexType name="arrayType">
100600 <xs:sequence>
100601 <xs:element name="element" type="argumentType" minOccurs="0" maxOccurs="unbounded"/>
100602 </xs:sequence>
100603 </xs:complexType>
100604 <xs:complexType name="argumentType">
100605 <xs:group ref="argumentChoice"/>
100606 <xs:attribute name="key" use="required"/>
100607 </xs:complexType>
100608 <xs:group name="argumentsGroup">
100609 <xs:sequence>
100610 <xs:choice minOccurs="0" maxOccurs="unbounded">
100611 <xs:element name="array" type="arrayType" />
100612 <xs:element name="integer" type="xs:integer" />
100613 <xs:element name="string" type="xs:string" />
100614 <xs:element name="double" type="xs:double" />
100615 <xs:element name="null" />
100616 <xs:element name="object" type="objectType" />
100617 <xs:element name="file" type="xs:anyURI" />
100618 <xs:element name="directory" type="xs:anyURI" />
100619 <xs:element name="boolean" type="xs:boolean" />
100620 </xs:choice>
100621 </xs:sequence>
100622 </xs:group>
100623 <xs:group name="argumentChoice">
100624 <xs:choice>
100625 <xs:element name="array" type="arrayType" minOccurs="0" maxOccurs="unbounded"/>
100626 <xs:element name="integer" type="xs:integer" minOccurs="0" maxOccurs="unbounded"/>
100627 <xs:element name="string" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
100628 <xs:element name="double" type="xs:double" minOccurs="0" maxOccurs="unbounded"/>
100629 <xs:element name="null" minOccurs="0" maxOccurs="unbounded"/>
100630 <xs:element name="object" type="objectType" minOccurs="0" maxOccurs="unbounded"/>
100631 <xs:element name="file" type="xs:anyURI" minOccurs="0" maxOccurs="unbounded"/>
100632 <xs:element name="directory" type="xs:anyURI" minOccurs="0" maxOccurs="unbounded"/>
100633 <xs:element name="boolean" type="xs:boolean" minOccurs="0" maxOccurs="unbounded"/>
100634 </xs:choice>
100635 </xs:group>
100636 <xs:simpleType name="columnsType">
100637 <xs:union>
100638 <xs:simpleType>
100639 <xs:restriction base="xs:integer"/>
100640 </xs:simpleType>
100641 <xs:simpleType>
100642 <xs:restriction base="xs:string">
100643 <xs:enumeration value="max"/>
100644 </xs:restriction>
100645 </xs:simpleType>
100646 </xs:union>
100647 </xs:simpleType>
100648 <xs:complexType name="loggersType">
100649 <xs:sequence>
100650 <xs:element name="log" type="loggerType" maxOccurs="unbounded"/>
100651 </xs:sequence>
100652 </xs:complexType>
100653 <xs:complexType name="loggerType">
100654 <xs:attribute name="type">
100655 <xs:simpleType>
100656 <xs:restriction base="xs:string">
100657 <xs:enumeration value="coverage-html"/>
100658 <xs:enumeration value="coverage-text"/>
100659 <xs:enumeration value="coverage-clover"/>
100660 <xs:enumeration value="coverage-crap4j"/>
100661 <xs:enumeration value="coverage-xml"/>
100662 <xs:enumeration value="coverage-php"/>
100663 <xs:enumeration value="json"/>
100664 <xs:enumeration value="plain"/>
100665 <xs:enumeration value="tap"/>
100666 <xs:enumeration value="teamcity"/>
100667 <xs:enumeration value="junit"/>
100668 <xs:enumeration value="testdox-html"/>
100669 <xs:enumeration value="testdox-text"/>
100670 <xs:enumeration value="testdox-xml"/>
100671 </xs:restriction>
100672 </xs:simpleType>
100673 </xs:attribute>
100674 <xs:attribute name="target" type="xs:anyURI"/>
100675 <xs:attribute name="lowUpperBound" type="xs:nonNegativeInteger" default="50"/>
100676 <xs:attribute name="highLowerBound" type="xs:nonNegativeInteger" default="90"/>
100677 <xs:attribute name="showUncoveredFiles" type="xs:boolean" default="false"/>
100678 <xs:attribute name="showOnlySummary" type="xs:boolean" default="false"/>
100679 <xs:attribute name="threshold" type="xs:nonNegativeInteger" default="30"/>
100680 </xs:complexType>
100681 <xs:group name="pathGroup">
100682 <xs:sequence>
100683 <xs:choice minOccurs="0" maxOccurs="unbounded">
100684 <xs:element name="directory" type="directoryFilterType"/>
100685 <xs:element name="file" type="fileFilterType"/>
100686 </xs:choice>
100687 </xs:sequence>
100688 </xs:group>
100689 <xs:complexType name="directoryFilterType">
100690 <xs:simpleContent>
100691 <xs:extension base="xs:string">
100692 <xs:attribute type="xs:string" name="prefix" default=""/>
100693 <xs:attribute type="xs:string" name="suffix" default="Test.php"/>
100694 <xs:attributeGroup ref="phpVersionGroup"/>
100695 </xs:extension>
100696 </xs:simpleContent>
100697 </xs:complexType>
100698 <xs:simpleType name="executionOrderType">
100699 <xs:restriction base="xs:string">
100700 <xs:enumeration value="default"/>
100701 <xs:enumeration value="defects"/>
100702 <xs:enumeration value="depends"/>
100703 <xs:enumeration value="depends,defects"/>
100704 <xs:enumeration value="depends,duration"/>
100705 <xs:enumeration value="depends,random"/>
100706 <xs:enumeration value="depends,reverse"/>
100707 <xs:enumeration value="depends,size"/>
100708 <xs:enumeration value="duration"/>
100709 <xs:enumeration value="no-depends"/>
100710 <xs:enumeration value="no-depends,defects"/>
100711 <xs:enumeration value="no-depends,duration"/>
100712 <xs:enumeration value="no-depends,random"/>
100713 <xs:enumeration value="no-depends,reverse"/>
100714 <xs:enumeration value="no-depends,size"/>
100715 <xs:enumeration value="random"/>
100716 <xs:enumeration value="reverse"/>
100717 <xs:enumeration value="size"/>
100718 </xs:restriction>
100719 </xs:simpleType>
100720 <xs:complexType name="fileFilterType">
100721 <xs:simpleContent>
100722 <xs:extension base="xs:anyURI">
100723 <xs:attributeGroup ref="phpVersionGroup"/>
100724 </xs:extension>
100725 </xs:simpleContent>
100726 </xs:complexType>
100727 <xs:attributeGroup name="phpVersionGroup">
100728 <xs:attribute name="phpVersion" type="xs:string" default="5.3.0"/>
100729 <xs:attribute name="phpVersionOperator" type="xs:string" default="&gt;="/>
100730 </xs:attributeGroup>
100731 <xs:complexType name="phpType">
100732 <xs:sequence>
100733 <xs:choice maxOccurs="unbounded">
100734 <xs:element name="includePath" type="xs:anyURI" minOccurs="0" maxOccurs="unbounded"/>
100735 <xs:element name="ini" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
100736 <xs:element name="const" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
100737 <xs:element name="var" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
100738 <xs:element name="env" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
100739 <xs:element name="post" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
100740 <xs:element name="get" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
100741 <xs:element name="cookie" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
100742 <xs:element name="server" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
100743 <xs:element name="files" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
100744 <xs:element name="request" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
100745 </xs:choice>
100746 </xs:sequence>
100747 </xs:complexType>
100748 <xs:complexType name="namedValueType">
100749 <xs:attribute name="name" use="required" type="xs:string"/>
100750 <xs:attribute name="value" use="required" type="xs:anySimpleType"/>
100751 <xs:attribute name="verbatim" use="optional" type="xs:boolean"/>
100752 <xs:attribute name="force" use="optional" type="xs:boolean"/>
100753 </xs:complexType>
100754 <xs:complexType name="phpUnitType">
100755 <xs:annotation>
100756 <xs:documentation>The main type specifying the document structure</xs:documentation>
100757 </xs:annotation>
100758 <xs:group ref="configGroup"/>
100759 <xs:attributeGroup ref="configAttributeGroup"/>
100760 </xs:complexType>
100761 <xs:attributeGroup name="configAttributeGroup">
100762 <xs:attribute name="backupGlobals" type="xs:boolean" default="false"/>
100763 <xs:attribute name="backupStaticAttributes" type="xs:boolean" default="false"/>
100764 <xs:attribute name="bootstrap" type="xs:anyURI"/>
100765 <xs:attribute name="cacheResult" type="xs:boolean" default="true"/>
100766 <xs:attribute name="cacheResultFile" type="xs:anyURI"/>
100767 <xs:attribute name="cacheTokens" type="xs:boolean" default="false"/>
100768 <xs:attribute name="colors" type="xs:boolean" default="false"/>
100769 <xs:attribute name="columns" type="columnsType" default="80"/>
100770 <xs:attribute name="convertDeprecationsToExceptions" type="xs:boolean" default="false"/>
100771 <xs:attribute name="convertErrorsToExceptions" type="xs:boolean" default="true"/>
100772 <xs:attribute name="convertNoticesToExceptions" type="xs:boolean" default="true"/>
100773 <xs:attribute name="convertWarningsToExceptions" type="xs:boolean" default="true"/>
100774 <xs:attribute name="disableCodeCoverageIgnore" type="xs:boolean" default="false"/>
100775 <xs:attribute name="forceCoversAnnotation" type="xs:boolean" default="false"/>
100776 <xs:attribute name="printerClass" type="xs:string" default="PHPUnit\TextUI\ResultPrinter"/>
100777 <xs:attribute name="printerFile" type="xs:anyURI"/>
100778 <xs:attribute name="processIsolation" type="xs:boolean" default="false"/>
100779 <xs:attribute name="stopOnDefect" type="xs:boolean" default="false"/>
100780 <xs:attribute name="stopOnError" type="xs:boolean" default="false"/>
100781 <xs:attribute name="stopOnFailure" type="xs:boolean" default="false"/>
100782 <xs:attribute name="stopOnWarning" type="xs:boolean" default="false"/>
100783 <xs:attribute name="stopOnIncomplete" type="xs:boolean" default="false"/>
100784 <xs:attribute name="stopOnRisky" type="xs:boolean" default="false"/>
100785 <xs:attribute name="stopOnSkipped" type="xs:boolean" default="false"/>
100786 <xs:attribute name="failOnRisky" type="xs:boolean" default="false"/>
100787 <xs:attribute name="failOnWarning" type="xs:boolean" default="false"/>
100788 <xs:attribute name="beStrictAboutChangesToGlobalState" type="xs:boolean" default="false"/>
100789 <xs:attribute name="beStrictAboutOutputDuringTests" type="xs:boolean" default="false"/>
100790 <xs:attribute name="beStrictAboutResourceUsageDuringSmallTests" type="xs:boolean" default="false"/>
100791 <xs:attribute name="beStrictAboutTestsThatDoNotTestAnything" type="xs:boolean" default="true"/>
100792 <xs:attribute name="beStrictAboutTodoAnnotatedTests" type="xs:boolean" default="false"/>
100793 <xs:attribute name="beStrictAboutCoversAnnotation" type="xs:boolean" default="false"/>
100794 <xs:attribute name="defaultTimeLimit" type="xs:integer" default="0"/>
100795 <xs:attribute name="enforceTimeLimit" type="xs:boolean" default="false"/>
100796 <xs:attribute name="ignoreDeprecatedCodeUnitsFromCodeCoverage" type="xs:boolean" default="false"/>
100797 <xs:attribute name="timeoutForSmallTests" type="xs:integer" default="1"/>
100798 <xs:attribute name="timeoutForMediumTests" type="xs:integer" default="10"/>
100799 <xs:attribute name="timeoutForLargeTests" type="xs:integer" default="60"/>
100800 <xs:attribute name="testSuiteLoaderClass" type="xs:string" default="PHPUnit\Runner\StandardTestSuiteLoader"/>
100801 <xs:attribute name="testSuiteLoaderFile" type="xs:anyURI"/>
100802 <xs:attribute name="defaultTestSuite" type="xs:string" default=""/>
100803 <xs:attribute name="verbose" type="xs:boolean" default="false"/>
100804 <xs:attribute name="testdox" type="xs:boolean" default="false"/>
100805 <xs:attribute name="stderr" type="xs:boolean" default="false"/>
100806 <xs:attribute name="reverseDefectList" type="xs:boolean" default="false"/>
100807 <xs:attribute name="registerMockObjectsFromTestArgumentsRecursively" type="xs:boolean" default="false"/>
100808 <xs:attribute name="extensionsDirectory" type="xs:anyURI"/>
100809 <xs:attribute name="executionOrder" type="executionOrderType" default="default"/>
100810 <xs:attribute name="resolveDependencies" type="xs:boolean" default="true"/>
100811 <xs:attribute name="noInteraction" type="xs:boolean" default="false"/>
100812 </xs:attributeGroup>
100813 <xs:group name="configGroup">
100814 <xs:all>
100815 <xs:element ref="testSuiteFacet" minOccurs="0"/>
100816 <xs:element name="groups" type="groupsType" minOccurs="0"/>
100817 <xs:element name="testdoxGroups" type="groupsType" minOccurs="0"/>
100818 <xs:element name="filter" type="filtersType" minOccurs="0"/>
100819 <xs:element name="logging" type="loggersType" minOccurs="0"/>
100820 <xs:element name="extensions" type="extensionsType" minOccurs="0"/>
100821 <xs:element name="listeners" type="listenersType" minOccurs="0"/>
100822 <xs:element name="php" type="phpType" minOccurs="0"/>
100823 </xs:all>
100824 </xs:group>
100825 <xs:element name="testSuiteFacet" abstract="true"/>
100826 <xs:element name="testsuite" type="testSuiteType" substitutionGroup="testSuiteFacet"/>
100827 <xs:element name="testsuites" type="testSuitesType" substitutionGroup="testSuiteFacet"/>
100828 <xs:complexType name="testSuitesType">
100829 <xs:sequence>
100830 <xs:element name="testsuite" type="testSuiteType" maxOccurs="unbounded"/>
100831 </xs:sequence>
100832 </xs:complexType>
100833 <xs:complexType name="testSuiteType">
100834 <xs:sequence>
100835 <xs:choice minOccurs="0" maxOccurs="unbounded">
100836 <xs:group ref="pathGroup"/>
100837 <xs:element name="exclude" type="xs:string"/>
100838 </xs:choice>
100839 </xs:sequence>
100840 <xs:attribute name="name" type="xs:string" use="required"/>
100841 </xs:complexType>
100842 </xs:schema>
100843 <?xml version="1.0" encoding="UTF-8"?>
100844 <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
100845 <xs:annotation>
100846 <xs:documentation source="https://phpunit.de/documentation.html">
100847 This Schema file defines the rules by which the XML configuration file of PHPUnit 9.0 may be structured.
100848 </xs:documentation>
100849 <xs:appinfo source="https://phpunit.de/documentation.html"/>
100850 </xs:annotation>
100851 <xs:element name="phpunit" type="phpUnitType">
100852 <xs:annotation>
100853 <xs:documentation>Root Element</xs:documentation>
100854 </xs:annotation>
100855 </xs:element>
100856 <xs:complexType name="filtersType">
100857 <xs:sequence>
100858 <xs:element name="whitelist" type="whiteListType" minOccurs="0"/>
100859 </xs:sequence>
100860 </xs:complexType>
100861 <xs:complexType name="filterType">
100862 <xs:sequence>
100863 <xs:choice maxOccurs="unbounded" minOccurs="0">
100864 <xs:group ref="pathGroup"/>
100865 <xs:element name="exclude">
100866 <xs:complexType>
100867 <xs:group ref="pathGroup"/>
100868 </xs:complexType>
100869 </xs:element>
100870 </xs:choice>
100871 </xs:sequence>
100872 </xs:complexType>
100873 <xs:complexType name="whiteListType">
100874 <xs:complexContent>
100875 <xs:extension base="filterType">
100876 <xs:attribute name="addUncoveredFilesFromWhitelist" default="true" type="xs:boolean"/>
100877 <xs:attribute name="processUncoveredFilesFromWhitelist" default="false" type="xs:boolean"/>
100878 </xs:extension>
100879 </xs:complexContent>
100880 </xs:complexType>
100881 <xs:complexType name="groupsType">
100882 <xs:choice>
100883 <xs:sequence>
100884 <xs:element name="include" type="groupType"/>
100885 <xs:element name="exclude" type="groupType" minOccurs="0"/>
100886 </xs:sequence>
100887 <xs:sequence>
100888 <xs:element name="exclude" type="groupType"/>
100889 </xs:sequence>
100890 </xs:choice>
100891 </xs:complexType>
100892 <xs:complexType name="groupType">
100893 <xs:sequence>
100894 <xs:element name="group" type="xs:string" maxOccurs="unbounded"/>
100895 </xs:sequence>
100896 </xs:complexType>
100897 <xs:complexType name="extensionsType">
100898 <xs:sequence>
100899 <xs:element name="extension" type="objectType" maxOccurs="unbounded"/>
100900 </xs:sequence>
100901 </xs:complexType>
100902 <xs:complexType name="listenersType">
100903 <xs:sequence>
100904 <xs:element name="listener" type="objectType" maxOccurs="unbounded"/>
100905 </xs:sequence>
100906 </xs:complexType>
100907 <xs:complexType name="objectType">
100908 <xs:sequence>
100909 <xs:element name="arguments" minOccurs="0">
100910 <xs:complexType>
100911 <xs:group ref="argumentsGroup"/>
100912 </xs:complexType>
100913 </xs:element>
100914 </xs:sequence>
100915 <xs:attribute name="class" type="xs:string" use="required"/>
100916 <xs:attribute name="file" type="xs:anyURI"/>
100917 </xs:complexType>
100918 <xs:complexType name="arrayType">
100919 <xs:sequence>
100920 <xs:element name="element" type="argumentType" minOccurs="0" maxOccurs="unbounded"/>
100921 </xs:sequence>
100922 </xs:complexType>
100923 <xs:complexType name="argumentType">
100924 <xs:group ref="argumentChoice"/>
100925 <xs:attribute name="key" use="required"/>
100926 </xs:complexType>
100927 <xs:group name="argumentsGroup">
100928 <xs:sequence>
100929 <xs:choice minOccurs="0" maxOccurs="unbounded">
100930 <xs:element name="array" type="arrayType" />
100931 <xs:element name="integer" type="xs:integer" />
100932 <xs:element name="string" type="xs:string" />
100933 <xs:element name="double" type="xs:double" />
100934 <xs:element name="null" />
100935 <xs:element name="object" type="objectType" />
100936 <xs:element name="file" type="xs:anyURI" />
100937 <xs:element name="directory" type="xs:anyURI" />
100938 <xs:element name="boolean" type="xs:boolean" />
100939 </xs:choice>
100940 </xs:sequence>
100941 </xs:group>
100942 <xs:group name="argumentChoice">
100943 <xs:choice>
100944 <xs:element name="array" type="arrayType" minOccurs="0" maxOccurs="unbounded"/>
100945 <xs:element name="integer" type="xs:integer" minOccurs="0" maxOccurs="unbounded"/>
100946 <xs:element name="string" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
100947 <xs:element name="double" type="xs:double" minOccurs="0" maxOccurs="unbounded"/>
100948 <xs:element name="null" minOccurs="0" maxOccurs="unbounded"/>
100949 <xs:element name="object" type="objectType" minOccurs="0" maxOccurs="unbounded"/>
100950 <xs:element name="file" type="xs:anyURI" minOccurs="0" maxOccurs="unbounded"/>
100951 <xs:element name="directory" type="xs:anyURI" minOccurs="0" maxOccurs="unbounded"/>
100952 <xs:element name="boolean" type="xs:boolean" minOccurs="0" maxOccurs="unbounded"/>
100953 </xs:choice>
100954 </xs:group>
100955 <xs:simpleType name="columnsType">
100956 <xs:union>
100957 <xs:simpleType>
100958 <xs:restriction base="xs:integer"/>
100959 </xs:simpleType>
100960 <xs:simpleType>
100961 <xs:restriction base="xs:string">
100962 <xs:enumeration value="max"/>
100963 </xs:restriction>
100964 </xs:simpleType>
100965 </xs:union>
100966 </xs:simpleType>
100967 <xs:complexType name="loggersType">
100968 <xs:sequence>
100969 <xs:element name="log" type="loggerType" maxOccurs="unbounded"/>
100970 </xs:sequence>
100971 </xs:complexType>
100972 <xs:complexType name="loggerType">
100973 <xs:attribute name="type">
100974 <xs:simpleType>
100975 <xs:restriction base="xs:string">
100976 <xs:enumeration value="coverage-html"/>
100977 <xs:enumeration value="coverage-text"/>
100978 <xs:enumeration value="coverage-clover"/>
100979 <xs:enumeration value="coverage-crap4j"/>
100980 <xs:enumeration value="coverage-xml"/>
100981 <xs:enumeration value="coverage-php"/>
100982 <xs:enumeration value="plain"/>
100983 <xs:enumeration value="teamcity"/>
100984 <xs:enumeration value="junit"/>
100985 <xs:enumeration value="testdox-html"/>
100986 <xs:enumeration value="testdox-text"/>
100987 <xs:enumeration value="testdox-xml"/>
100988 </xs:restriction>
100989 </xs:simpleType>
100990 </xs:attribute>
100991 <xs:attribute name="target" type="xs:anyURI"/>
100992 <xs:attribute name="lowUpperBound" type="xs:nonNegativeInteger" default="35"/>
100993 <xs:attribute name="highLowerBound" type="xs:nonNegativeInteger" default="70"/>
100994 <xs:attribute name="showUncoveredFiles" type="xs:boolean" default="false"/>
100995 <xs:attribute name="showOnlySummary" type="xs:boolean" default="false"/>
100996 <xs:attribute name="threshold" type="xs:nonNegativeInteger" default="30"/>
100997 </xs:complexType>
100998 <xs:group name="pathGroup">
100999 <xs:sequence>
101000 <xs:choice minOccurs="0" maxOccurs="unbounded">
101001 <xs:element name="directory" type="directoryFilterType"/>
101002 <xs:element name="file" type="fileFilterType"/>
101003 </xs:choice>
101004 </xs:sequence>
101005 </xs:group>
101006 <xs:complexType name="directoryFilterType">
101007 <xs:simpleContent>
101008 <xs:extension base="xs:anyURI">
101009 <xs:attribute type="xs:string" name="prefix" default=""/>
101010 <xs:attribute type="xs:string" name="suffix" default="Test.php"/>
101011 <xs:attributeGroup ref="phpVersionGroup"/>
101012 </xs:extension>
101013 </xs:simpleContent>
101014 </xs:complexType>
101015 <xs:simpleType name="executionOrderType">
101016 <xs:restriction base="xs:string">
101017 <xs:enumeration value="default"/>
101018 <xs:enumeration value="defects"/>
101019 <xs:enumeration value="depends"/>
101020 <xs:enumeration value="depends,defects"/>
101021 <xs:enumeration value="depends,duration"/>
101022 <xs:enumeration value="depends,random"/>
101023 <xs:enumeration value="depends,reverse"/>
101024 <xs:enumeration value="depends,size"/>
101025 <xs:enumeration value="duration"/>
101026 <xs:enumeration value="no-depends"/>
101027 <xs:enumeration value="no-depends,defects"/>
101028 <xs:enumeration value="no-depends,duration"/>
101029 <xs:enumeration value="no-depends,random"/>
101030 <xs:enumeration value="no-depends,reverse"/>
101031 <xs:enumeration value="no-depends,size"/>
101032 <xs:enumeration value="random"/>
101033 <xs:enumeration value="reverse"/>
101034 <xs:enumeration value="size"/>
101035 </xs:restriction>
101036 </xs:simpleType>
101037 <xs:complexType name="fileFilterType">
101038 <xs:simpleContent>
101039 <xs:extension base="xs:anyURI">
101040 <xs:attributeGroup ref="phpVersionGroup"/>
101041 </xs:extension>
101042 </xs:simpleContent>
101043 </xs:complexType>
101044 <xs:attributeGroup name="phpVersionGroup">
101045 <xs:attribute name="phpVersion" type="xs:string" default="5.3.0"/>
101046 <xs:attribute name="phpVersionOperator" type="xs:string" default="&gt;="/>
101047 </xs:attributeGroup>
101048 <xs:complexType name="phpType">
101049 <xs:sequence>
101050 <xs:choice maxOccurs="unbounded">
101051 <xs:element name="includePath" type="xs:anyURI" minOccurs="0" maxOccurs="unbounded"/>
101052 <xs:element name="ini" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
101053 <xs:element name="const" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
101054 <xs:element name="var" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
101055 <xs:element name="env" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
101056 <xs:element name="post" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
101057 <xs:element name="get" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
101058 <xs:element name="cookie" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
101059 <xs:element name="server" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
101060 <xs:element name="files" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
101061 <xs:element name="request" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
101062 </xs:choice>
101063 </xs:sequence>
101064 </xs:complexType>
101065 <xs:complexType name="namedValueType">
101066 <xs:attribute name="name" use="required" type="xs:string"/>
101067 <xs:attribute name="value" use="required" type="xs:anySimpleType"/>
101068 <xs:attribute name="verbatim" use="optional" type="xs:boolean"/>
101069 <xs:attribute name="force" use="optional" type="xs:boolean"/>
101070 </xs:complexType>
101071 <xs:complexType name="phpUnitType">
101072 <xs:annotation>
101073 <xs:documentation>The main type specifying the document structure</xs:documentation>
101074 </xs:annotation>
101075 <xs:group ref="configGroup"/>
101076 <xs:attributeGroup ref="configAttributeGroup"/>
101077 </xs:complexType>
101078 <xs:attributeGroup name="configAttributeGroup">
101079 <xs:attribute name="backupGlobals" type="xs:boolean" default="false"/>
101080 <xs:attribute name="backupStaticAttributes" type="xs:boolean" default="false"/>
101081 <xs:attribute name="bootstrap" type="xs:anyURI"/>
101082 <xs:attribute name="cacheResult" type="xs:boolean" default="true"/>
101083 <xs:attribute name="cacheResultFile" type="xs:anyURI"/>
101084 <xs:attribute name="cacheTokens" type="xs:boolean" default="false"/>
101085 <xs:attribute name="colors" type="xs:boolean" default="false"/>
101086 <xs:attribute name="columns" type="columnsType" default="80"/>
101087 <xs:attribute name="convertDeprecationsToExceptions" type="xs:boolean" default="true"/>
101088 <xs:attribute name="convertErrorsToExceptions" type="xs:boolean" default="true"/>
101089 <xs:attribute name="convertNoticesToExceptions" type="xs:boolean" default="true"/>
101090 <xs:attribute name="convertWarningsToExceptions" type="xs:boolean" default="true"/>
101091 <xs:attribute name="disableCodeCoverageIgnore" type="xs:boolean" default="false"/>
101092 <xs:attribute name="forceCoversAnnotation" type="xs:boolean" default="false"/>
101093 <xs:attribute name="printerClass" type="xs:string" default="PHPUnit\TextUI\ResultPrinter"/>
101094 <xs:attribute name="printerFile" type="xs:anyURI"/>
101095 <xs:attribute name="processIsolation" type="xs:boolean" default="false"/>
101096 <xs:attribute name="stopOnDefect" type="xs:boolean" default="false"/>
101097 <xs:attribute name="stopOnError" type="xs:boolean" default="false"/>
101098 <xs:attribute name="stopOnFailure" type="xs:boolean" default="false"/>
101099 <xs:attribute name="stopOnWarning" type="xs:boolean" default="false"/>
101100 <xs:attribute name="stopOnIncomplete" type="xs:boolean" default="false"/>
101101 <xs:attribute name="stopOnRisky" type="xs:boolean" default="false"/>
101102 <xs:attribute name="stopOnSkipped" type="xs:boolean" default="false"/>
101103 <xs:attribute name="failOnRisky" type="xs:boolean" default="false"/>
101104 <xs:attribute name="failOnWarning" type="xs:boolean" default="false"/>
101105 <xs:attribute name="beStrictAboutChangesToGlobalState" type="xs:boolean" default="false"/>
101106 <xs:attribute name="beStrictAboutOutputDuringTests" type="xs:boolean" default="false"/>
101107 <xs:attribute name="beStrictAboutResourceUsageDuringSmallTests" type="xs:boolean" default="false"/>
101108 <xs:attribute name="beStrictAboutTestsThatDoNotTestAnything" type="xs:boolean" default="true"/>
101109 <xs:attribute name="beStrictAboutTodoAnnotatedTests" type="xs:boolean" default="false"/>
101110 <xs:attribute name="beStrictAboutCoversAnnotation" type="xs:boolean" default="false"/>
101111 <xs:attribute name="defaultTimeLimit" type="xs:integer" default="0"/>
101112 <xs:attribute name="enforceTimeLimit" type="xs:boolean" default="false"/>
101113 <xs:attribute name="ignoreDeprecatedCodeUnitsFromCodeCoverage" type="xs:boolean" default="false"/>
101114 <xs:attribute name="timeoutForSmallTests" type="xs:integer" default="1"/>
101115 <xs:attribute name="timeoutForMediumTests" type="xs:integer" default="10"/>
101116 <xs:attribute name="timeoutForLargeTests" type="xs:integer" default="60"/>
101117 <xs:attribute name="testSuiteLoaderClass" type="xs:string" default="PHPUnit\Runner\StandardTestSuiteLoader"/>
101118 <xs:attribute name="testSuiteLoaderFile" type="xs:anyURI"/>
101119 <xs:attribute name="defaultTestSuite" type="xs:string" default=""/>
101120 <xs:attribute name="verbose" type="xs:boolean" default="false"/>
101121 <xs:attribute name="testdox" type="xs:boolean" default="false"/>
101122 <xs:attribute name="stderr" type="xs:boolean" default="false"/>
101123 <xs:attribute name="reverseDefectList" type="xs:boolean" default="false"/>
101124 <xs:attribute name="registerMockObjectsFromTestArgumentsRecursively" type="xs:boolean" default="false"/>
101125 <xs:attribute name="extensionsDirectory" type="xs:string"/>
101126 <xs:attribute name="executionOrder" type="executionOrderType" default="default"/>
101127 <xs:attribute name="resolveDependencies" type="xs:boolean" default="true"/>
101128 <xs:attribute name="noInteraction" type="xs:boolean" default="false"/>
101129 </xs:attributeGroup>
101130 <xs:group name="configGroup">
101131 <xs:all>
101132 <xs:element ref="testSuiteFacet" minOccurs="0"/>
101133 <xs:element name="groups" type="groupsType" minOccurs="0"/>
101134 <xs:element name="testdoxGroups" type="groupsType" minOccurs="0"/>
101135 <xs:element name="filter" type="filtersType" minOccurs="0"/>
101136 <xs:element name="logging" type="loggersType" minOccurs="0"/>
101137 <xs:element name="extensions" type="extensionsType" minOccurs="0"/>
101138 <xs:element name="listeners" type="listenersType" minOccurs="0"/>
101139 <xs:element name="php" type="phpType" minOccurs="0"/>
101140 </xs:all>
101141 </xs:group>
101142 <xs:element name="testSuiteFacet" abstract="true"/>
101143 <xs:element name="testsuite" type="testSuiteType" substitutionGroup="testSuiteFacet"/>
101144 <xs:element name="testsuites" type="testSuitesType" substitutionGroup="testSuiteFacet"/>
101145 <xs:complexType name="testSuitesType">
101146 <xs:sequence>
101147 <xs:element name="testsuite" type="testSuiteType" maxOccurs="unbounded"/>
101148 </xs:sequence>
101149 </xs:complexType>
101150 <xs:complexType name="testSuiteType">
101151 <xs:sequence>
101152 <xs:group ref="pathGroup"/>
101153 <xs:element name="exclude" type="xs:anyURI" minOccurs="0" maxOccurs="unbounded"/>
101154 </xs:sequence>
101155 <xs:attribute name="name" type="xs:string" use="required"/>
101156 </xs:complexType>
101157 </xs:schema>
101158 <?xml version="1.0" encoding="UTF-8"?>
101159 <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
101160 <xs:annotation>
101161 <xs:documentation source="https://phpunit.de/documentation.html">
101162 This Schema file defines the rules by which the XML configuration file of PHPUnit 9.0 may be structured.
101163 </xs:documentation>
101164 <xs:appinfo source="https://phpunit.de/documentation.html"/>
101165 </xs:annotation>
101166 <xs:element name="phpunit" type="phpUnitType">
101167 <xs:annotation>
101168 <xs:documentation>Root Element</xs:documentation>
101169 </xs:annotation>
101170 </xs:element>
101171 <xs:complexType name="filtersType">
101172 <xs:sequence>
101173 <xs:element name="whitelist" type="whiteListType" minOccurs="0"/>
101174 </xs:sequence>
101175 </xs:complexType>
101176 <xs:complexType name="filterType">
101177 <xs:sequence>
101178 <xs:choice maxOccurs="unbounded" minOccurs="0">
101179 <xs:group ref="pathGroup"/>
101180 <xs:element name="exclude">
101181 <xs:complexType>
101182 <xs:group ref="pathGroup"/>
101183 </xs:complexType>
101184 </xs:element>
101185 </xs:choice>
101186 </xs:sequence>
101187 </xs:complexType>
101188 <xs:complexType name="whiteListType">
101189 <xs:complexContent>
101190 <xs:extension base="filterType">
101191 <xs:attribute name="addUncoveredFilesFromWhitelist" default="true" type="xs:boolean"/>
101192 <xs:attribute name="processUncoveredFilesFromWhitelist" default="false" type="xs:boolean"/>
101193 </xs:extension>
101194 </xs:complexContent>
101195 </xs:complexType>
101196 <xs:complexType name="groupsType">
101197 <xs:choice>
101198 <xs:sequence>
101199 <xs:element name="include" type="groupType"/>
101200 <xs:element name="exclude" type="groupType" minOccurs="0"/>
101201 </xs:sequence>
101202 <xs:sequence>
101203 <xs:element name="exclude" type="groupType"/>
101204 </xs:sequence>
101205 </xs:choice>
101206 </xs:complexType>
101207 <xs:complexType name="groupType">
101208 <xs:sequence>
101209 <xs:element name="group" type="xs:string" maxOccurs="unbounded"/>
101210 </xs:sequence>
101211 </xs:complexType>
101212 <xs:complexType name="extensionsType">
101213 <xs:sequence>
101214 <xs:element name="extension" type="objectType" maxOccurs="unbounded"/>
101215 </xs:sequence>
101216 </xs:complexType>
101217 <xs:complexType name="listenersType">
101218 <xs:sequence>
101219 <xs:element name="listener" type="objectType" maxOccurs="unbounded"/>
101220 </xs:sequence>
101221 </xs:complexType>
101222 <xs:complexType name="objectType">
101223 <xs:sequence>
101224 <xs:element name="arguments" minOccurs="0">
101225 <xs:complexType>
101226 <xs:group ref="argumentsGroup"/>
101227 </xs:complexType>
101228 </xs:element>
101229 </xs:sequence>
101230 <xs:attribute name="class" type="xs:string" use="required"/>
101231 <xs:attribute name="file" type="xs:anyURI"/>
101232 </xs:complexType>
101233 <xs:complexType name="arrayType">
101234 <xs:sequence>
101235 <xs:element name="element" type="argumentType" minOccurs="0" maxOccurs="unbounded"/>
101236 </xs:sequence>
101237 </xs:complexType>
101238 <xs:complexType name="argumentType">
101239 <xs:group ref="argumentChoice"/>
101240 <xs:attribute name="key" use="required"/>
101241 </xs:complexType>
101242 <xs:group name="argumentsGroup">
101243 <xs:sequence>
101244 <xs:choice minOccurs="0" maxOccurs="unbounded">
101245 <xs:element name="array" type="arrayType" />
101246 <xs:element name="integer" type="xs:integer" />
101247 <xs:element name="string" type="xs:string" />
101248 <xs:element name="double" type="xs:double" />
101249 <xs:element name="null" />
101250 <xs:element name="object" type="objectType" />
101251 <xs:element name="file" type="xs:anyURI" />
101252 <xs:element name="directory" type="xs:anyURI" />
101253 <xs:element name="boolean" type="xs:boolean" />
101254 </xs:choice>
101255 </xs:sequence>
101256 </xs:group>
101257 <xs:group name="argumentChoice">
101258 <xs:choice>
101259 <xs:element name="array" type="arrayType" minOccurs="0" maxOccurs="unbounded"/>
101260 <xs:element name="integer" type="xs:integer" minOccurs="0" maxOccurs="unbounded"/>
101261 <xs:element name="string" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
101262 <xs:element name="double" type="xs:double" minOccurs="0" maxOccurs="unbounded"/>
101263 <xs:element name="null" minOccurs="0" maxOccurs="unbounded"/>
101264 <xs:element name="object" type="objectType" minOccurs="0" maxOccurs="unbounded"/>
101265 <xs:element name="file" type="xs:anyURI" minOccurs="0" maxOccurs="unbounded"/>
101266 <xs:element name="directory" type="xs:anyURI" minOccurs="0" maxOccurs="unbounded"/>
101267 <xs:element name="boolean" type="xs:boolean" minOccurs="0" maxOccurs="unbounded"/>
101268 </xs:choice>
101269 </xs:group>
101270 <xs:simpleType name="columnsType">
101271 <xs:union>
101272 <xs:simpleType>
101273 <xs:restriction base="xs:integer"/>
101274 </xs:simpleType>
101275 <xs:simpleType>
101276 <xs:restriction base="xs:string">
101277 <xs:enumeration value="max"/>
101278 </xs:restriction>
101279 </xs:simpleType>
101280 </xs:union>
101281 </xs:simpleType>
101282 <xs:complexType name="loggersType">
101283 <xs:sequence>
101284 <xs:element name="log" type="loggerType" maxOccurs="unbounded"/>
101285 </xs:sequence>
101286 </xs:complexType>
101287 <xs:complexType name="loggerType">
101288 <xs:attribute name="type">
101289 <xs:simpleType>
101290 <xs:restriction base="xs:string">
101291 <xs:enumeration value="coverage-html"/>
101292 <xs:enumeration value="coverage-text"/>
101293 <xs:enumeration value="coverage-clover"/>
101294 <xs:enumeration value="coverage-crap4j"/>
101295 <xs:enumeration value="coverage-xml"/>
101296 <xs:enumeration value="coverage-php"/>
101297 <xs:enumeration value="plain"/>
101298 <xs:enumeration value="teamcity"/>
101299 <xs:enumeration value="junit"/>
101300 <xs:enumeration value="testdox-html"/>
101301 <xs:enumeration value="testdox-text"/>
101302 <xs:enumeration value="testdox-xml"/>
101303 </xs:restriction>
101304 </xs:simpleType>
101305 </xs:attribute>
101306 <xs:attribute name="target" type="xs:anyURI"/>
101307 <xs:attribute name="lowUpperBound" type="xs:nonNegativeInteger" default="35"/>
101308 <xs:attribute name="highLowerBound" type="xs:nonNegativeInteger" default="70"/>
101309 <xs:attribute name="showUncoveredFiles" type="xs:boolean" default="false"/>
101310 <xs:attribute name="showOnlySummary" type="xs:boolean" default="false"/>
101311 <xs:attribute name="threshold" type="xs:nonNegativeInteger" default="30"/>
101312 </xs:complexType>
101313 <xs:group name="pathGroup">
101314 <xs:sequence>
101315 <xs:choice minOccurs="0" maxOccurs="unbounded">
101316 <xs:element name="directory" type="directoryFilterType"/>
101317 <xs:element name="file" type="fileFilterType"/>
101318 </xs:choice>
101319 </xs:sequence>
101320 </xs:group>
101321 <xs:complexType name="directoryFilterType">
101322 <xs:simpleContent>
101323 <xs:extension base="xs:anyURI">
101324 <xs:attribute type="xs:string" name="prefix" default=""/>
101325 <xs:attribute type="xs:string" name="suffix" default="Test.php"/>
101326 <xs:attributeGroup ref="phpVersionGroup"/>
101327 </xs:extension>
101328 </xs:simpleContent>
101329 </xs:complexType>
101330 <xs:simpleType name="executionOrderType">
101331 <xs:restriction base="xs:string">
101332 <xs:enumeration value="default"/>
101333 <xs:enumeration value="defects"/>
101334 <xs:enumeration value="depends"/>
101335 <xs:enumeration value="depends,defects"/>
101336 <xs:enumeration value="depends,duration"/>
101337 <xs:enumeration value="depends,random"/>
101338 <xs:enumeration value="depends,reverse"/>
101339 <xs:enumeration value="depends,size"/>
101340 <xs:enumeration value="duration"/>
101341 <xs:enumeration value="no-depends"/>
101342 <xs:enumeration value="no-depends,defects"/>
101343 <xs:enumeration value="no-depends,duration"/>
101344 <xs:enumeration value="no-depends,random"/>
101345 <xs:enumeration value="no-depends,reverse"/>
101346 <xs:enumeration value="no-depends,size"/>
101347 <xs:enumeration value="random"/>
101348 <xs:enumeration value="reverse"/>
101349 <xs:enumeration value="size"/>
101350 </xs:restriction>
101351 </xs:simpleType>
101352 <xs:complexType name="fileFilterType">
101353 <xs:simpleContent>
101354 <xs:extension base="xs:anyURI">
101355 <xs:attributeGroup ref="phpVersionGroup"/>
101356 </xs:extension>
101357 </xs:simpleContent>
101358 </xs:complexType>
101359 <xs:attributeGroup name="phpVersionGroup">
101360 <xs:attribute name="phpVersion" type="xs:string" default="5.3.0"/>
101361 <xs:attribute name="phpVersionOperator" type="xs:string" default="&gt;="/>
101362 </xs:attributeGroup>
101363 <xs:complexType name="phpType">
101364 <xs:sequence>
101365 <xs:choice maxOccurs="unbounded">
101366 <xs:element name="includePath" type="xs:anyURI" minOccurs="0" maxOccurs="unbounded"/>
101367 <xs:element name="ini" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
101368 <xs:element name="const" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
101369 <xs:element name="var" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
101370 <xs:element name="env" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
101371 <xs:element name="post" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
101372 <xs:element name="get" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
101373 <xs:element name="cookie" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
101374 <xs:element name="server" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
101375 <xs:element name="files" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
101376 <xs:element name="request" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
101377 </xs:choice>
101378 </xs:sequence>
101379 </xs:complexType>
101380 <xs:complexType name="namedValueType">
101381 <xs:attribute name="name" use="required" type="xs:string"/>
101382 <xs:attribute name="value" use="required" type="xs:anySimpleType"/>
101383 <xs:attribute name="verbatim" use="optional" type="xs:boolean"/>
101384 <xs:attribute name="force" use="optional" type="xs:boolean"/>
101385 </xs:complexType>
101386 <xs:complexType name="phpUnitType">
101387 <xs:annotation>
101388 <xs:documentation>The main type specifying the document structure</xs:documentation>
101389 </xs:annotation>
101390 <xs:group ref="configGroup"/>
101391 <xs:attributeGroup ref="configAttributeGroup"/>
101392 </xs:complexType>
101393 <xs:attributeGroup name="configAttributeGroup">
101394 <xs:attribute name="backupGlobals" type="xs:boolean" default="false"/>
101395 <xs:attribute name="backupStaticAttributes" type="xs:boolean" default="false"/>
101396 <xs:attribute name="bootstrap" type="xs:anyURI"/>
101397 <xs:attribute name="cacheResult" type="xs:boolean" default="true"/>
101398 <xs:attribute name="cacheResultFile" type="xs:anyURI"/>
101399 <xs:attribute name="cacheTokens" type="xs:boolean" default="false"/>
101400 <xs:attribute name="colors" type="xs:boolean" default="false"/>
101401 <xs:attribute name="columns" type="columnsType" default="80"/>
101402 <xs:attribute name="convertDeprecationsToExceptions" type="xs:boolean" default="true"/>
101403 <xs:attribute name="convertErrorsToExceptions" type="xs:boolean" default="true"/>
101404 <xs:attribute name="convertNoticesToExceptions" type="xs:boolean" default="true"/>
101405 <xs:attribute name="convertWarningsToExceptions" type="xs:boolean" default="true"/>
101406 <xs:attribute name="disableCodeCoverageIgnore" type="xs:boolean" default="false"/>
101407 <xs:attribute name="forceCoversAnnotation" type="xs:boolean" default="false"/>
101408 <xs:attribute name="printerClass" type="xs:string" default="PHPUnit\TextUI\ResultPrinter"/>
101409 <xs:attribute name="printerFile" type="xs:anyURI"/>
101410 <xs:attribute name="processIsolation" type="xs:boolean" default="false"/>
101411 <xs:attribute name="stopOnDefect" type="xs:boolean" default="false"/>
101412 <xs:attribute name="stopOnError" type="xs:boolean" default="false"/>
101413 <xs:attribute name="stopOnFailure" type="xs:boolean" default="false"/>
101414 <xs:attribute name="stopOnWarning" type="xs:boolean" default="false"/>
101415 <xs:attribute name="stopOnIncomplete" type="xs:boolean" default="false"/>
101416 <xs:attribute name="stopOnRisky" type="xs:boolean" default="false"/>
101417 <xs:attribute name="stopOnSkipped" type="xs:boolean" default="false"/>
101418 <xs:attribute name="failOnIncomplete" type="xs:boolean" default="false"/>
101419 <xs:attribute name="failOnRisky" type="xs:boolean" default="false"/>
101420 <xs:attribute name="failOnSkipped" type="xs:boolean" default="false"/>
101421 <xs:attribute name="failOnWarning" type="xs:boolean" default="false"/>
101422 <xs:attribute name="beStrictAboutChangesToGlobalState" type="xs:boolean" default="false"/>
101423 <xs:attribute name="beStrictAboutOutputDuringTests" type="xs:boolean" default="false"/>
101424 <xs:attribute name="beStrictAboutResourceUsageDuringSmallTests" type="xs:boolean" default="false"/>
101425 <xs:attribute name="beStrictAboutTestsThatDoNotTestAnything" type="xs:boolean" default="true"/>
101426 <xs:attribute name="beStrictAboutTodoAnnotatedTests" type="xs:boolean" default="false"/>
101427 <xs:attribute name="beStrictAboutCoversAnnotation" type="xs:boolean" default="false"/>
101428 <xs:attribute name="defaultTimeLimit" type="xs:integer" default="0"/>
101429 <xs:attribute name="enforceTimeLimit" type="xs:boolean" default="false"/>
101430 <xs:attribute name="ignoreDeprecatedCodeUnitsFromCodeCoverage" type="xs:boolean" default="false"/>
101431 <xs:attribute name="timeoutForSmallTests" type="xs:integer" default="1"/>
101432 <xs:attribute name="timeoutForMediumTests" type="xs:integer" default="10"/>
101433 <xs:attribute name="timeoutForLargeTests" type="xs:integer" default="60"/>
101434 <xs:attribute name="testSuiteLoaderClass" type="xs:string" default="PHPUnit\Runner\StandardTestSuiteLoader"/>
101435 <xs:attribute name="testSuiteLoaderFile" type="xs:anyURI"/>
101436 <xs:attribute name="defaultTestSuite" type="xs:string" default=""/>
101437 <xs:attribute name="verbose" type="xs:boolean" default="false"/>
101438 <xs:attribute name="testdox" type="xs:boolean" default="false"/>
101439 <xs:attribute name="stderr" type="xs:boolean" default="false"/>
101440 <xs:attribute name="reverseDefectList" type="xs:boolean" default="false"/>
101441 <xs:attribute name="registerMockObjectsFromTestArgumentsRecursively" type="xs:boolean" default="false"/>
101442 <xs:attribute name="extensionsDirectory" type="xs:string"/>
101443 <xs:attribute name="executionOrder" type="executionOrderType" default="default"/>
101444 <xs:attribute name="resolveDependencies" type="xs:boolean" default="true"/>
101445 <xs:attribute name="noInteraction" type="xs:boolean" default="false"/>
101446 </xs:attributeGroup>
101447 <xs:group name="configGroup">
101448 <xs:all>
101449 <xs:element ref="testSuiteFacet" minOccurs="0"/>
101450 <xs:element name="groups" type="groupsType" minOccurs="0"/>
101451 <xs:element name="testdoxGroups" type="groupsType" minOccurs="0"/>
101452 <xs:element name="filter" type="filtersType" minOccurs="0"/>
101453 <xs:element name="logging" type="loggersType" minOccurs="0"/>
101454 <xs:element name="extensions" type="extensionsType" minOccurs="0"/>
101455 <xs:element name="listeners" type="listenersType" minOccurs="0"/>
101456 <xs:element name="php" type="phpType" minOccurs="0"/>
101457 </xs:all>
101458 </xs:group>
101459 <xs:element name="testSuiteFacet" abstract="true"/>
101460 <xs:element name="testsuite" type="testSuiteType" substitutionGroup="testSuiteFacet"/>
101461 <xs:element name="testsuites" type="testSuitesType" substitutionGroup="testSuiteFacet"/>
101462 <xs:complexType name="testSuitesType">
101463 <xs:sequence>
101464 <xs:element name="testsuite" type="testSuiteType" maxOccurs="unbounded"/>
101465 </xs:sequence>
101466 </xs:complexType>
101467 <xs:complexType name="testSuiteType">
101468 <xs:sequence>
101469 <xs:group ref="pathGroup"/>
101470 <xs:element name="exclude" type="xs:anyURI" minOccurs="0" maxOccurs="unbounded"/>
101471 </xs:sequence>
101472 <xs:attribute name="name" type="xs:string" use="required"/>
101473 </xs:complexType>
101474 </xs:schema>
101475 <?xml version="1.0" encoding="UTF-8"?>
101476 <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
101477 <xs:annotation>
101478 <xs:documentation source="https://phpunit.de/documentation.html">
101479 This Schema file defines the rules by which the XML configuration file of PHPUnit 9.2 may be structured.
101480 </xs:documentation>
101481 <xs:appinfo source="https://phpunit.de/documentation.html"/>
101482 </xs:annotation>
101483 <xs:element name="phpunit" type="phpUnitType">
101484 <xs:annotation>
101485 <xs:documentation>Root Element</xs:documentation>
101486 </xs:annotation>
101487 </xs:element>
101488 <xs:complexType name="filtersType">
101489 <xs:sequence>
101490 <xs:element name="whitelist" type="whiteListType" minOccurs="0"/>
101491 </xs:sequence>
101492 </xs:complexType>
101493 <xs:complexType name="filterType">
101494 <xs:sequence>
101495 <xs:choice maxOccurs="unbounded" minOccurs="0">
101496 <xs:group ref="pathGroup"/>
101497 <xs:element name="exclude">
101498 <xs:complexType>
101499 <xs:group ref="pathGroup"/>
101500 </xs:complexType>
101501 </xs:element>
101502 </xs:choice>
101503 </xs:sequence>
101504 </xs:complexType>
101505 <xs:complexType name="whiteListType">
101506 <xs:complexContent>
101507 <xs:extension base="filterType">
101508 <xs:attribute name="addUncoveredFilesFromWhitelist" default="true" type="xs:boolean"/>
101509 <xs:attribute name="processUncoveredFilesFromWhitelist" default="false" type="xs:boolean"/>
101510 </xs:extension>
101511 </xs:complexContent>
101512 </xs:complexType>
101513 <xs:complexType name="groupsType">
101514 <xs:choice>
101515 <xs:sequence>
101516 <xs:element name="include" type="groupType"/>
101517 <xs:element name="exclude" type="groupType" minOccurs="0"/>
101518 </xs:sequence>
101519 <xs:sequence>
101520 <xs:element name="exclude" type="groupType"/>
101521 </xs:sequence>
101522 </xs:choice>
101523 </xs:complexType>
101524 <xs:complexType name="groupType">
101525 <xs:sequence>
101526 <xs:element name="group" type="xs:string" maxOccurs="unbounded"/>
101527 </xs:sequence>
101528 </xs:complexType>
101529 <xs:complexType name="extensionsType">
101530 <xs:sequence>
101531 <xs:element name="extension" type="objectType" maxOccurs="unbounded"/>
101532 </xs:sequence>
101533 </xs:complexType>
101534 <xs:complexType name="listenersType">
101535 <xs:sequence>
101536 <xs:element name="listener" type="objectType" maxOccurs="unbounded"/>
101537 </xs:sequence>
101538 </xs:complexType>
101539 <xs:complexType name="objectType">
101540 <xs:sequence>
101541 <xs:element name="arguments" minOccurs="0">
101542 <xs:complexType>
101543 <xs:group ref="argumentsGroup"/>
101544 </xs:complexType>
101545 </xs:element>
101546 </xs:sequence>
101547 <xs:attribute name="class" type="xs:string" use="required"/>
101548 <xs:attribute name="file" type="xs:anyURI"/>
101549 </xs:complexType>
101550 <xs:complexType name="arrayType">
101551 <xs:sequence>
101552 <xs:element name="element" type="argumentType" minOccurs="0" maxOccurs="unbounded"/>
101553 </xs:sequence>
101554 </xs:complexType>
101555 <xs:complexType name="argumentType">
101556 <xs:group ref="argumentChoice"/>
101557 <xs:attribute name="key" use="required"/>
101558 </xs:complexType>
101559 <xs:group name="argumentsGroup">
101560 <xs:sequence>
101561 <xs:choice minOccurs="0" maxOccurs="unbounded">
101562 <xs:element name="array" type="arrayType" />
101563 <xs:element name="integer" type="xs:integer" />
101564 <xs:element name="string" type="xs:string" />
101565 <xs:element name="double" type="xs:double" />
101566 <xs:element name="null" />
101567 <xs:element name="object" type="objectType" />
101568 <xs:element name="file" type="xs:anyURI" />
101569 <xs:element name="directory" type="xs:anyURI" />
101570 <xs:element name="boolean" type="xs:boolean" />
101571 </xs:choice>
101572 </xs:sequence>
101573 </xs:group>
101574 <xs:group name="argumentChoice">
101575 <xs:choice>
101576 <xs:element name="array" type="arrayType" minOccurs="0" maxOccurs="unbounded"/>
101577 <xs:element name="integer" type="xs:integer" minOccurs="0" maxOccurs="unbounded"/>
101578 <xs:element name="string" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
101579 <xs:element name="double" type="xs:double" minOccurs="0" maxOccurs="unbounded"/>
101580 <xs:element name="null" minOccurs="0" maxOccurs="unbounded"/>
101581 <xs:element name="object" type="objectType" minOccurs="0" maxOccurs="unbounded"/>
101582 <xs:element name="file" type="xs:anyURI" minOccurs="0" maxOccurs="unbounded"/>
101583 <xs:element name="directory" type="xs:anyURI" minOccurs="0" maxOccurs="unbounded"/>
101584 <xs:element name="boolean" type="xs:boolean" minOccurs="0" maxOccurs="unbounded"/>
101585 </xs:choice>
101586 </xs:group>
101587 <xs:simpleType name="columnsType">
101588 <xs:union>
101589 <xs:simpleType>
101590 <xs:restriction base="xs:integer"/>
101591 </xs:simpleType>
101592 <xs:simpleType>
101593 <xs:restriction base="xs:string">
101594 <xs:enumeration value="max"/>
101595 </xs:restriction>
101596 </xs:simpleType>
101597 </xs:union>
101598 </xs:simpleType>
101599 <xs:complexType name="loggersType">
101600 <xs:sequence>
101601 <xs:element name="log" type="loggerType" maxOccurs="unbounded"/>
101602 </xs:sequence>
101603 </xs:complexType>
101604 <xs:complexType name="loggerType">
101605 <xs:attribute name="type">
101606 <xs:simpleType>
101607 <xs:restriction base="xs:string">
101608 <xs:enumeration value="coverage-html"/>
101609 <xs:enumeration value="coverage-text"/>
101610 <xs:enumeration value="coverage-clover"/>
101611 <xs:enumeration value="coverage-crap4j"/>
101612 <xs:enumeration value="coverage-xml"/>
101613 <xs:enumeration value="coverage-php"/>
101614 <xs:enumeration value="plain"/>
101615 <xs:enumeration value="teamcity"/>
101616 <xs:enumeration value="junit"/>
101617 <xs:enumeration value="testdox-html"/>
101618 <xs:enumeration value="testdox-text"/>
101619 <xs:enumeration value="testdox-xml"/>
101620 </xs:restriction>
101621 </xs:simpleType>
101622 </xs:attribute>
101623 <xs:attribute name="target" type="xs:anyURI"/>
101624 <xs:attribute name="lowUpperBound" type="xs:nonNegativeInteger" default="50"/>
101625 <xs:attribute name="highLowerBound" type="xs:nonNegativeInteger" default="90"/>
101626 <xs:attribute name="showUncoveredFiles" type="xs:boolean" default="false"/>
101627 <xs:attribute name="showOnlySummary" type="xs:boolean" default="false"/>
101628 <xs:attribute name="threshold" type="xs:nonNegativeInteger" default="30"/>
101629 </xs:complexType>
101630 <xs:group name="pathGroup">
101631 <xs:sequence>
101632 <xs:choice minOccurs="0" maxOccurs="unbounded">
101633 <xs:element name="directory" type="directoryFilterType"/>
101634 <xs:element name="file" type="fileFilterType"/>
101635 </xs:choice>
101636 </xs:sequence>
101637 </xs:group>
101638 <xs:complexType name="directoryFilterType">
101639 <xs:simpleContent>
101640 <xs:extension base="xs:anyURI">
101641 <xs:attribute type="xs:string" name="prefix" default=""/>
101642 <xs:attribute type="xs:string" name="suffix" default="Test.php"/>
101643 <xs:attributeGroup ref="phpVersionGroup"/>
101644 </xs:extension>
101645 </xs:simpleContent>
101646 </xs:complexType>
101647 <xs:simpleType name="executionOrderType">
101648 <xs:restriction base="xs:string">
101649 <xs:enumeration value="default"/>
101650 <xs:enumeration value="defects"/>
101651 <xs:enumeration value="depends"/>
101652 <xs:enumeration value="depends,defects"/>
101653 <xs:enumeration value="depends,duration"/>
101654 <xs:enumeration value="depends,random"/>
101655 <xs:enumeration value="depends,reverse"/>
101656 <xs:enumeration value="depends,size"/>
101657 <xs:enumeration value="duration"/>
101658 <xs:enumeration value="no-depends"/>
101659 <xs:enumeration value="no-depends,defects"/>
101660 <xs:enumeration value="no-depends,duration"/>
101661 <xs:enumeration value="no-depends,random"/>
101662 <xs:enumeration value="no-depends,reverse"/>
101663 <xs:enumeration value="no-depends,size"/>
101664 <xs:enumeration value="random"/>
101665 <xs:enumeration value="reverse"/>
101666 <xs:enumeration value="size"/>
101667 </xs:restriction>
101668 </xs:simpleType>
101669 <xs:complexType name="fileFilterType">
101670 <xs:simpleContent>
101671 <xs:extension base="xs:anyURI">
101672 <xs:attributeGroup ref="phpVersionGroup"/>
101673 </xs:extension>
101674 </xs:simpleContent>
101675 </xs:complexType>
101676 <xs:attributeGroup name="phpVersionGroup">
101677 <xs:attribute name="phpVersion" type="xs:string" default="5.3.0"/>
101678 <xs:attribute name="phpVersionOperator" type="xs:string" default="&gt;="/>
101679 </xs:attributeGroup>
101680 <xs:complexType name="phpType">
101681 <xs:sequence>
101682 <xs:choice maxOccurs="unbounded">
101683 <xs:element name="includePath" type="xs:anyURI" minOccurs="0" maxOccurs="unbounded"/>
101684 <xs:element name="ini" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
101685 <xs:element name="const" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
101686 <xs:element name="var" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
101687 <xs:element name="env" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
101688 <xs:element name="post" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
101689 <xs:element name="get" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
101690 <xs:element name="cookie" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
101691 <xs:element name="server" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
101692 <xs:element name="files" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
101693 <xs:element name="request" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
101694 </xs:choice>
101695 </xs:sequence>
101696 </xs:complexType>
101697 <xs:complexType name="namedValueType">
101698 <xs:attribute name="name" use="required" type="xs:string"/>
101699 <xs:attribute name="value" use="required" type="xs:anySimpleType"/>
101700 <xs:attribute name="verbatim" use="optional" type="xs:boolean"/>
101701 <xs:attribute name="force" use="optional" type="xs:boolean"/>
101702 </xs:complexType>
101703 <xs:complexType name="phpUnitType">
101704 <xs:annotation>
101705 <xs:documentation>The main type specifying the document structure</xs:documentation>
101706 </xs:annotation>
101707 <xs:group ref="configGroup"/>
101708 <xs:attributeGroup ref="configAttributeGroup"/>
101709 </xs:complexType>
101710 <xs:attributeGroup name="configAttributeGroup">
101711 <xs:attribute name="backupGlobals" type="xs:boolean" default="false"/>
101712 <xs:attribute name="backupStaticAttributes" type="xs:boolean" default="false"/>
101713 <xs:attribute name="bootstrap" type="xs:anyURI"/>
101714 <xs:attribute name="cacheResult" type="xs:boolean" default="true"/>
101715 <xs:attribute name="cacheResultFile" type="xs:anyURI"/>
101716 <xs:attribute name="cacheTokens" type="xs:boolean" default="false"/>
101717 <xs:attribute name="colors" type="xs:boolean" default="false"/>
101718 <xs:attribute name="columns" type="columnsType" default="80"/>
101719 <xs:attribute name="convertDeprecationsToExceptions" type="xs:boolean" default="true"/>
101720 <xs:attribute name="convertErrorsToExceptions" type="xs:boolean" default="true"/>
101721 <xs:attribute name="convertNoticesToExceptions" type="xs:boolean" default="true"/>
101722 <xs:attribute name="convertWarningsToExceptions" type="xs:boolean" default="true"/>
101723 <xs:attribute name="disableCodeCoverageIgnore" type="xs:boolean" default="false"/>
101724 <xs:attribute name="forceCoversAnnotation" type="xs:boolean" default="false"/>
101725 <xs:attribute name="printerClass" type="xs:string" default="PHPUnit\TextUI\DefaultResultPrinter"/>
101726 <xs:attribute name="printerFile" type="xs:anyURI"/>
101727 <xs:attribute name="processIsolation" type="xs:boolean" default="false"/>
101728 <xs:attribute name="stopOnDefect" type="xs:boolean" default="false"/>
101729 <xs:attribute name="stopOnError" type="xs:boolean" default="false"/>
101730 <xs:attribute name="stopOnFailure" type="xs:boolean" default="false"/>
101731 <xs:attribute name="stopOnWarning" type="xs:boolean" default="false"/>
101732 <xs:attribute name="stopOnIncomplete" type="xs:boolean" default="false"/>
101733 <xs:attribute name="stopOnRisky" type="xs:boolean" default="false"/>
101734 <xs:attribute name="stopOnSkipped" type="xs:boolean" default="false"/>
101735 <xs:attribute name="failOnIncomplete" type="xs:boolean" default="false"/>
101736 <xs:attribute name="failOnRisky" type="xs:boolean" default="false"/>
101737 <xs:attribute name="failOnSkipped" type="xs:boolean" default="false"/>
101738 <xs:attribute name="failOnWarning" type="xs:boolean" default="false"/>
101739 <xs:attribute name="beStrictAboutChangesToGlobalState" type="xs:boolean" default="false"/>
101740 <xs:attribute name="beStrictAboutOutputDuringTests" type="xs:boolean" default="false"/>
101741 <xs:attribute name="beStrictAboutResourceUsageDuringSmallTests" type="xs:boolean" default="false"/>
101742 <xs:attribute name="beStrictAboutTestsThatDoNotTestAnything" type="xs:boolean" default="true"/>
101743 <xs:attribute name="beStrictAboutTodoAnnotatedTests" type="xs:boolean" default="false"/>
101744 <xs:attribute name="beStrictAboutCoversAnnotation" type="xs:boolean" default="false"/>
101745 <xs:attribute name="defaultTimeLimit" type="xs:integer" default="0"/>
101746 <xs:attribute name="enforceTimeLimit" type="xs:boolean" default="false"/>
101747 <xs:attribute name="ignoreDeprecatedCodeUnitsFromCodeCoverage" type="xs:boolean" default="false"/>
101748 <xs:attribute name="timeoutForSmallTests" type="xs:integer" default="1"/>
101749 <xs:attribute name="timeoutForMediumTests" type="xs:integer" default="10"/>
101750 <xs:attribute name="timeoutForLargeTests" type="xs:integer" default="60"/>
101751 <xs:attribute name="testSuiteLoaderClass" type="xs:string" default="PHPUnit\Runner\StandardTestSuiteLoader"/>
101752 <xs:attribute name="testSuiteLoaderFile" type="xs:anyURI"/>
101753 <xs:attribute name="defaultTestSuite" type="xs:string" default=""/>
101754 <xs:attribute name="verbose" type="xs:boolean" default="false"/>
101755 <xs:attribute name="testdox" type="xs:boolean" default="false"/>
101756 <xs:attribute name="stderr" type="xs:boolean" default="false"/>
101757 <xs:attribute name="reverseDefectList" type="xs:boolean" default="false"/>
101758 <xs:attribute name="registerMockObjectsFromTestArgumentsRecursively" type="xs:boolean" default="false"/>
101759 <xs:attribute name="extensionsDirectory" type="xs:string"/>
101760 <xs:attribute name="executionOrder" type="executionOrderType" default="default"/>
101761 <xs:attribute name="resolveDependencies" type="xs:boolean" default="true"/>
101762 <xs:attribute name="noInteraction" type="xs:boolean" default="false"/>
101763 </xs:attributeGroup>
101764 <xs:group name="configGroup">
101765 <xs:all>
101766 <xs:element ref="testSuiteFacet" minOccurs="0"/>
101767 <xs:element name="groups" type="groupsType" minOccurs="0"/>
101768 <xs:element name="testdoxGroups" type="groupsType" minOccurs="0"/>
101769 <xs:element name="filter" type="filtersType" minOccurs="0"/>
101770 <xs:element name="logging" type="loggersType" minOccurs="0"/>
101771 <xs:element name="extensions" type="extensionsType" minOccurs="0"/>
101772 <xs:element name="listeners" type="listenersType" minOccurs="0"/>
101773 <xs:element name="php" type="phpType" minOccurs="0"/>
101774 </xs:all>
101775 </xs:group>
101776 <xs:element name="testSuiteFacet" abstract="true"/>
101777 <xs:element name="testsuite" type="testSuiteType" substitutionGroup="testSuiteFacet"/>
101778 <xs:element name="testsuites" type="testSuitesType" substitutionGroup="testSuiteFacet"/>
101779 <xs:complexType name="testSuitesType">
101780 <xs:sequence>
101781 <xs:element name="testsuite" type="testSuiteType" maxOccurs="unbounded"/>
101782 </xs:sequence>
101783 </xs:complexType>
101784 <xs:complexType name="testSuiteType">
101785 <xs:sequence>
101786 <xs:group ref="pathGroup"/>
101787 <xs:element name="exclude" type="xs:anyURI" minOccurs="0" maxOccurs="unbounded"/>
101788 </xs:sequence>
101789 <xs:attribute name="name" type="xs:string" use="required"/>
101790 </xs:complexType>
101791 </xs:schema>
101792 <?xml version="1.0" encoding="UTF-8"?>
101793 <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
101794 <xs:annotation>
101795 <xs:documentation source="https://phpunit.de/documentation.html">
101796 This Schema file defines the rules by which the XML configuration file of PHPUnit 9.3 may be structured.
101797 </xs:documentation>
101798 <xs:appinfo source="https://phpunit.de/documentation.html"/>
101799 </xs:annotation>
101800 <xs:element name="phpunit" type="phpUnitType">
101801 <xs:annotation>
101802 <xs:documentation>Root Element</xs:documentation>
101803 </xs:annotation>
101804 </xs:element>
101805 <xs:complexType name="coverageType">
101806 <xs:all>
101807 <xs:element name="include" minOccurs="0" maxOccurs="1">
101808 <xs:complexType>
101809 <xs:group ref="pathGroup"/>
101810 </xs:complexType>
101811 </xs:element>
101812 <xs:element name="exclude" minOccurs="0" maxOccurs="1">
101813 <xs:complexType>
101814 <xs:group ref="pathGroup"/>
101815 </xs:complexType>
101816 </xs:element>
101817 <xs:element name="report" minOccurs="0" maxOccurs="1">
101818 <xs:complexType>
101819 <xs:group ref="coverageReportGroup"/>
101820 </xs:complexType>
101821 </xs:element>
101822 </xs:all>
101823 <xs:attribute name="cacheDirectory" type="xs:anyURI"/>
101824 <xs:attribute name="pathCoverage" type="xs:boolean" default="false"/>
101825 <xs:attribute name="includeUncoveredFiles" type="xs:boolean" default="true"/>
101826 <xs:attribute name="processUncoveredFiles" type="xs:boolean" default="false"/>
101827 <xs:attribute name="ignoreDeprecatedCodeUnits" type="xs:boolean" default="false"/>
101828 <xs:attribute name="disableCodeCoverageIgnore" type="xs:boolean" default="false"/>
101829 </xs:complexType>
101830 <xs:complexType name="loggingType">
101831 <xs:group ref="loggingGroup"/>
101832 </xs:complexType>
101833 <xs:complexType name="groupsType">
101834 <xs:choice>
101835 <xs:sequence>
101836 <xs:element name="include" type="groupType"/>
101837 <xs:element name="exclude" type="groupType" minOccurs="0"/>
101838 </xs:sequence>
101839 <xs:sequence>
101840 <xs:element name="exclude" type="groupType"/>
101841 </xs:sequence>
101842 </xs:choice>
101843 </xs:complexType>
101844 <xs:complexType name="groupType">
101845 <xs:sequence>
101846 <xs:element name="group" type="xs:string" maxOccurs="unbounded"/>
101847 </xs:sequence>
101848 </xs:complexType>
101849 <xs:complexType name="extensionsType">
101850 <xs:sequence>
101851 <xs:element name="extension" type="objectType" maxOccurs="unbounded"/>
101852 </xs:sequence>
101853 </xs:complexType>
101854 <xs:complexType name="listenersType">
101855 <xs:sequence>
101856 <xs:element name="listener" type="objectType" maxOccurs="unbounded"/>
101857 </xs:sequence>
101858 </xs:complexType>
101859 <xs:complexType name="objectType">
101860 <xs:sequence>
101861 <xs:element name="arguments" minOccurs="0">
101862 <xs:complexType>
101863 <xs:group ref="argumentsGroup"/>
101864 </xs:complexType>
101865 </xs:element>
101866 </xs:sequence>
101867 <xs:attribute name="class" type="xs:string" use="required"/>
101868 <xs:attribute name="file" type="xs:anyURI"/>
101869 </xs:complexType>
101870 <xs:complexType name="arrayType">
101871 <xs:sequence>
101872 <xs:element name="element" type="argumentType" minOccurs="0" maxOccurs="unbounded"/>
101873 </xs:sequence>
101874 </xs:complexType>
101875 <xs:complexType name="argumentType">
101876 <xs:group ref="argumentChoice"/>
101877 <xs:attribute name="key" use="required"/>
101878 </xs:complexType>
101879 <xs:group name="argumentsGroup">
101880 <xs:sequence>
101881 <xs:choice minOccurs="0" maxOccurs="unbounded">
101882 <xs:element name="array" type="arrayType" />
101883 <xs:element name="integer" type="xs:integer" />
101884 <xs:element name="string" type="xs:string" />
101885 <xs:element name="double" type="xs:double" />
101886 <xs:element name="null" />
101887 <xs:element name="object" type="objectType" />
101888 <xs:element name="file" type="xs:anyURI" />
101889 <xs:element name="directory" type="xs:anyURI" />
101890 <xs:element name="boolean" type="xs:boolean" />
101891 </xs:choice>
101892 </xs:sequence>
101893 </xs:group>
101894 <xs:group name="argumentChoice">
101895 <xs:choice>
101896 <xs:element name="array" type="arrayType" minOccurs="0" maxOccurs="unbounded"/>
101897 <xs:element name="integer" type="xs:integer" minOccurs="0" maxOccurs="unbounded"/>
101898 <xs:element name="string" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
101899 <xs:element name="double" type="xs:double" minOccurs="0" maxOccurs="unbounded"/>
101900 <xs:element name="null" minOccurs="0" maxOccurs="unbounded"/>
101901 <xs:element name="object" type="objectType" minOccurs="0" maxOccurs="unbounded"/>
101902 <xs:element name="file" type="xs:anyURI" minOccurs="0" maxOccurs="unbounded"/>
101903 <xs:element name="directory" type="xs:anyURI" minOccurs="0" maxOccurs="unbounded"/>
101904 <xs:element name="boolean" type="xs:boolean" minOccurs="0" maxOccurs="unbounded"/>
101905 </xs:choice>
101906 </xs:group>
101907 <xs:simpleType name="columnsType">
101908 <xs:union>
101909 <xs:simpleType>
101910 <xs:restriction base="xs:integer"/>
101911 </xs:simpleType>
101912 <xs:simpleType>
101913 <xs:restriction base="xs:string">
101914 <xs:enumeration value="max"/>
101915 </xs:restriction>
101916 </xs:simpleType>
101917 </xs:union>
101918 </xs:simpleType>
101919 <xs:group name="pathGroup">
101920 <xs:sequence>
101921 <xs:choice minOccurs="0" maxOccurs="unbounded">
101922 <xs:element name="directory" type="directoryFilterType"/>
101923 <xs:element name="file" type="fileFilterType"/>
101924 </xs:choice>
101925 </xs:sequence>
101926 </xs:group>
101927 <xs:complexType name="directoryFilterType">
101928 <xs:simpleContent>
101929 <xs:extension base="xs:anyURI">
101930 <xs:attribute type="xs:string" name="prefix" default=""/>
101931 <xs:attribute type="xs:string" name="suffix" default="Test.php"/>
101932 <xs:attributeGroup ref="phpVersionGroup"/>
101933 </xs:extension>
101934 </xs:simpleContent>
101935 </xs:complexType>
101936 <xs:simpleType name="executionOrderType">
101937 <xs:restriction base="xs:string">
101938 <xs:enumeration value="default"/>
101939 <xs:enumeration value="defects"/>
101940 <xs:enumeration value="depends"/>
101941 <xs:enumeration value="depends,defects"/>
101942 <xs:enumeration value="depends,duration"/>
101943 <xs:enumeration value="depends,random"/>
101944 <xs:enumeration value="depends,reverse"/>
101945 <xs:enumeration value="depends,size"/>
101946 <xs:enumeration value="duration"/>
101947 <xs:enumeration value="no-depends"/>
101948 <xs:enumeration value="no-depends,defects"/>
101949 <xs:enumeration value="no-depends,duration"/>
101950 <xs:enumeration value="no-depends,random"/>
101951 <xs:enumeration value="no-depends,reverse"/>
101952 <xs:enumeration value="no-depends,size"/>
101953 <xs:enumeration value="random"/>
101954 <xs:enumeration value="reverse"/>
101955 <xs:enumeration value="size"/>
101956 </xs:restriction>
101957 </xs:simpleType>
101958 <xs:complexType name="fileFilterType">
101959 <xs:simpleContent>
101960 <xs:extension base="xs:anyURI">
101961 <xs:attributeGroup ref="phpVersionGroup"/>
101962 </xs:extension>
101963 </xs:simpleContent>
101964 </xs:complexType>
101965 <xs:attributeGroup name="phpVersionGroup">
101966 <xs:attribute name="phpVersion" type="xs:string" default="5.3.0"/>
101967 <xs:attribute name="phpVersionOperator" type="xs:string" default="&gt;="/>
101968 </xs:attributeGroup>
101969 <xs:complexType name="phpType">
101970 <xs:sequence>
101971 <xs:choice maxOccurs="unbounded">
101972 <xs:element name="includePath" type="xs:anyURI" minOccurs="0" maxOccurs="unbounded"/>
101973 <xs:element name="ini" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
101974 <xs:element name="const" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
101975 <xs:element name="var" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
101976 <xs:element name="env" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
101977 <xs:element name="post" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
101978 <xs:element name="get" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
101979 <xs:element name="cookie" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
101980 <xs:element name="server" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
101981 <xs:element name="files" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
101982 <xs:element name="request" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
101983 </xs:choice>
101984 </xs:sequence>
101985 </xs:complexType>
101986 <xs:complexType name="namedValueType">
101987 <xs:attribute name="name" use="required" type="xs:string"/>
101988 <xs:attribute name="value" use="required" type="xs:anySimpleType"/>
101989 <xs:attribute name="verbatim" use="optional" type="xs:boolean"/>
101990 <xs:attribute name="force" use="optional" type="xs:boolean"/>
101991 </xs:complexType>
101992 <xs:complexType name="phpUnitType">
101993 <xs:annotation>
101994 <xs:documentation>The main type specifying the document structure</xs:documentation>
101995 </xs:annotation>
101996 <xs:group ref="configGroup"/>
101997 <xs:attributeGroup ref="configAttributeGroup"/>
101998 </xs:complexType>
101999 <xs:attributeGroup name="configAttributeGroup">
102000 <xs:attribute name="backupGlobals" type="xs:boolean" default="false"/>
102001 <xs:attribute name="backupStaticAttributes" type="xs:boolean" default="false"/>
102002 <xs:attribute name="bootstrap" type="xs:anyURI"/>
102003 <xs:attribute name="cacheResult" type="xs:boolean" default="true"/>
102004 <xs:attribute name="cacheResultFile" type="xs:anyURI"/>
102005 <xs:attribute name="colors" type="xs:boolean" default="false"/>
102006 <xs:attribute name="columns" type="columnsType" default="80"/>
102007 <xs:attribute name="convertDeprecationsToExceptions" type="xs:boolean" default="true"/>
102008 <xs:attribute name="convertErrorsToExceptions" type="xs:boolean" default="true"/>
102009 <xs:attribute name="convertNoticesToExceptions" type="xs:boolean" default="true"/>
102010 <xs:attribute name="convertWarningsToExceptions" type="xs:boolean" default="true"/>
102011 <xs:attribute name="forceCoversAnnotation" type="xs:boolean" default="false"/>
102012 <xs:attribute name="printerClass" type="xs:string" default="PHPUnit\TextUI\DefaultResultPrinter"/>
102013 <xs:attribute name="printerFile" type="xs:anyURI"/>
102014 <xs:attribute name="processIsolation" type="xs:boolean" default="false"/>
102015 <xs:attribute name="stopOnDefect" type="xs:boolean" default="false"/>
102016 <xs:attribute name="stopOnError" type="xs:boolean" default="false"/>
102017 <xs:attribute name="stopOnFailure" type="xs:boolean" default="false"/>
102018 <xs:attribute name="stopOnWarning" type="xs:boolean" default="false"/>
102019 <xs:attribute name="stopOnIncomplete" type="xs:boolean" default="false"/>
102020 <xs:attribute name="stopOnRisky" type="xs:boolean" default="false"/>
102021 <xs:attribute name="stopOnSkipped" type="xs:boolean" default="false"/>
102022 <xs:attribute name="failOnEmptyTestSuite" type="xs:boolean" default="false"/>
102023 <xs:attribute name="failOnIncomplete" type="xs:boolean" default="false"/>
102024 <xs:attribute name="failOnRisky" type="xs:boolean" default="false"/>
102025 <xs:attribute name="failOnSkipped" type="xs:boolean" default="false"/>
102026 <xs:attribute name="failOnWarning" type="xs:boolean" default="false"/>
102027 <xs:attribute name="beStrictAboutChangesToGlobalState" type="xs:boolean" default="false"/>
102028 <xs:attribute name="beStrictAboutOutputDuringTests" type="xs:boolean" default="false"/>
102029 <xs:attribute name="beStrictAboutResourceUsageDuringSmallTests" type="xs:boolean" default="false"/>
102030 <xs:attribute name="beStrictAboutTestsThatDoNotTestAnything" type="xs:boolean" default="true"/>
102031 <xs:attribute name="beStrictAboutTodoAnnotatedTests" type="xs:boolean" default="false"/>
102032 <xs:attribute name="beStrictAboutCoversAnnotation" type="xs:boolean" default="false"/>
102033 <xs:attribute name="defaultTimeLimit" type="xs:integer" default="0"/>
102034 <xs:attribute name="enforceTimeLimit" type="xs:boolean" default="false"/>
102035 <xs:attribute name="timeoutForSmallTests" type="xs:integer" default="1"/>
102036 <xs:attribute name="timeoutForMediumTests" type="xs:integer" default="10"/>
102037 <xs:attribute name="timeoutForLargeTests" type="xs:integer" default="60"/>
102038 <xs:attribute name="testSuiteLoaderClass" type="xs:string" default="PHPUnit\Runner\StandardTestSuiteLoader"/>
102039 <xs:attribute name="testSuiteLoaderFile" type="xs:anyURI"/>
102040 <xs:attribute name="defaultTestSuite" type="xs:string" default=""/>
102041 <xs:attribute name="verbose" type="xs:boolean" default="false"/>
102042 <xs:attribute name="testdox" type="xs:boolean" default="false"/>
102043 <xs:attribute name="stderr" type="xs:boolean" default="false"/>
102044 <xs:attribute name="reverseDefectList" type="xs:boolean" default="false"/>
102045 <xs:attribute name="registerMockObjectsFromTestArgumentsRecursively" type="xs:boolean" default="false"/>
102046 <xs:attribute name="extensionsDirectory" type="xs:string"/>
102047 <xs:attribute name="executionOrder" type="executionOrderType" default="default"/>
102048 <xs:attribute name="resolveDependencies" type="xs:boolean" default="true"/>
102049 <xs:attribute name="noInteraction" type="xs:boolean" default="false"/>
102050 </xs:attributeGroup>
102051 <xs:group name="configGroup">
102052 <xs:all>
102053 <xs:element ref="testSuiteFacet" minOccurs="0"/>
102054 <xs:element name="groups" type="groupsType" minOccurs="0"/>
102055 <xs:element name="testdoxGroups" type="groupsType" minOccurs="0"/>
102056 <xs:element name="coverage" type="coverageType" minOccurs="0"/>
102057 <xs:element name="logging" type="loggingType" minOccurs="0"/>
102058 <xs:element name="extensions" type="extensionsType" minOccurs="0"/>
102059 <xs:element name="listeners" type="listenersType" minOccurs="0"/>
102060 <xs:element name="php" type="phpType" minOccurs="0"/>
102061 </xs:all>
102062 </xs:group>
102063 <xs:element name="testSuiteFacet" abstract="true"/>
102064 <xs:element name="testsuite" type="testSuiteType" substitutionGroup="testSuiteFacet"/>
102065 <xs:element name="testsuites" type="testSuitesType" substitutionGroup="testSuiteFacet"/>
102066 <xs:complexType name="testSuitesType">
102067 <xs:sequence>
102068 <xs:element name="testsuite" type="testSuiteType" maxOccurs="unbounded"/>
102069 </xs:sequence>
102070 </xs:complexType>
102071 <xs:complexType name="testSuiteType">
102072 <xs:sequence>
102073 <xs:group ref="pathGroup"/>
102074 <xs:element name="exclude" type="xs:anyURI" minOccurs="0" maxOccurs="unbounded"/>
102075 </xs:sequence>
102076 <xs:attribute name="name" type="xs:string" use="required"/>
102077 </xs:complexType>
102078 <xs:group name="coverageReportGroup">
102079 <xs:all>
102080 <xs:element name="clover" type="logToFileType" minOccurs="0"/>
102081 <xs:element name="crap4j" type="coverageReportCrap4JType" minOccurs="0" />
102082 <xs:element name="html" type="coverageReportHtmlType" minOccurs="0" />
102083 <xs:element name="php" type="logToFileType" minOccurs="0" />
102084 <xs:element name="text" type="coverageReportTextType" minOccurs="0" />
102085 <xs:element name="xml" type="logToDirectoryType" minOccurs="0" />
102086 </xs:all>
102087 </xs:group>
102088 <xs:group name="loggingGroup">
102089 <xs:all>
102090 <xs:element name="junit" type="logToFileType" minOccurs="0" />
102091 <xs:element name="teamcity" type="logToFileType" minOccurs="0" />
102092 <xs:element name="testdoxHtml" type="logToFileType" minOccurs="0" />
102093 <xs:element name="testdoxText" type="logToFileType" minOccurs="0" />
102094 <xs:element name="testdoxXml" type="logToFileType" minOccurs="0" />
102095 <xs:element name="text" type="logToFileType" minOccurs="0"/>
102096 </xs:all>
102097 </xs:group>
102098 <xs:complexType name="logToFileType">
102099 <xs:attribute name="outputFile" type="xs:anyURI" use="required"/>
102100 </xs:complexType>
102101 <xs:complexType name="logToDirectoryType">
102102 <xs:attribute name="outputDirectory" type="xs:anyURI" use="required"/>
102103 </xs:complexType>
102104 <xs:complexType name="coverageReportCrap4JType">
102105 <xs:attribute name="outputFile" type="xs:anyURI" use="required"/>
102106 <xs:attribute name="threshold" type="xs:integer"/>
102107 </xs:complexType>
102108 <xs:complexType name="coverageReportHtmlType">
102109 <xs:attribute name="outputDirectory" type="xs:anyURI" use="required"/>
102110 <xs:attribute name="lowUpperBound" type="xs:integer" default="50"/>
102111 <xs:attribute name="highLowerBound" type="xs:integer" default="90"/>
102112 </xs:complexType>
102113 <xs:complexType name="coverageReportTextType">
102114 <xs:attribute name="outputFile" type="xs:anyURI" use="required"/>
102115 <xs:attribute name="showUncoveredFiles" type="xs:boolean" default="false"/>
102116 <xs:attribute name="showOnlySummary" type="xs:boolean" default="false"/>
102117 </xs:complexType>
102118 </xs:schema>
102119 <?xml version="1.0" encoding="UTF-8"?>
102120 <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
102121 <xs:annotation>
102122 <xs:documentation source="https://phpunit.de/documentation.html">
102123 This Schema file defines the rules by which the XML configuration file of PHPUnit 9.4 may be structured.
102124 </xs:documentation>
102125 <xs:appinfo source="https://phpunit.de/documentation.html"/>
102126 </xs:annotation>
102127 <xs:element name="phpunit" type="phpUnitType">
102128 <xs:annotation>
102129 <xs:documentation>Root Element</xs:documentation>
102130 </xs:annotation>
102131 </xs:element>
102132 <xs:complexType name="coverageType">
102133 <xs:all>
102134 <xs:element name="include" minOccurs="0" maxOccurs="1">
102135 <xs:complexType>
102136 <xs:group ref="pathGroup"/>
102137 </xs:complexType>
102138 </xs:element>
102139 <xs:element name="exclude" minOccurs="0" maxOccurs="1">
102140 <xs:complexType>
102141 <xs:group ref="pathGroup"/>
102142 </xs:complexType>
102143 </xs:element>
102144 <xs:element name="report" minOccurs="0" maxOccurs="1">
102145 <xs:complexType>
102146 <xs:group ref="coverageReportGroup"/>
102147 </xs:complexType>
102148 </xs:element>
102149 </xs:all>
102150 <xs:attribute name="cacheDirectory" type="xs:anyURI"/>
102151 <xs:attribute name="pathCoverage" type="xs:boolean" default="false"/>
102152 <xs:attribute name="includeUncoveredFiles" type="xs:boolean" default="true"/>
102153 <xs:attribute name="processUncoveredFiles" type="xs:boolean" default="false"/>
102154 <xs:attribute name="ignoreDeprecatedCodeUnits" type="xs:boolean" default="false"/>
102155 <xs:attribute name="disableCodeCoverageIgnore" type="xs:boolean" default="false"/>
102156 </xs:complexType>
102157 <xs:complexType name="loggingType">
102158 <xs:group ref="loggingGroup"/>
102159 </xs:complexType>
102160 <xs:complexType name="groupsType">
102161 <xs:choice>
102162 <xs:sequence>
102163 <xs:element name="include" type="groupType"/>
102164 <xs:element name="exclude" type="groupType" minOccurs="0"/>
102165 </xs:sequence>
102166 <xs:sequence>
102167 <xs:element name="exclude" type="groupType"/>
102168 </xs:sequence>
102169 </xs:choice>
102170 </xs:complexType>
102171 <xs:complexType name="groupType">
102172 <xs:sequence>
102173 <xs:element name="group" type="xs:string" maxOccurs="unbounded"/>
102174 </xs:sequence>
102175 </xs:complexType>
102176 <xs:complexType name="extensionsType">
102177 <xs:sequence>
102178 <xs:element name="extension" type="objectType" maxOccurs="unbounded"/>
102179 </xs:sequence>
102180 </xs:complexType>
102181 <xs:complexType name="listenersType">
102182 <xs:sequence>
102183 <xs:element name="listener" type="objectType" maxOccurs="unbounded"/>
102184 </xs:sequence>
102185 </xs:complexType>
102186 <xs:complexType name="objectType">
102187 <xs:sequence>
102188 <xs:element name="arguments" minOccurs="0">
102189 <xs:complexType>
102190 <xs:group ref="argumentsGroup"/>
102191 </xs:complexType>
102192 </xs:element>
102193 </xs:sequence>
102194 <xs:attribute name="class" type="xs:string" use="required"/>
102195 <xs:attribute name="file" type="xs:anyURI"/>
102196 </xs:complexType>
102197 <xs:complexType name="arrayType">
102198 <xs:sequence>
102199 <xs:element name="element" type="argumentType" minOccurs="0" maxOccurs="unbounded"/>
102200 </xs:sequence>
102201 </xs:complexType>
102202 <xs:complexType name="argumentType">
102203 <xs:group ref="argumentChoice"/>
102204 <xs:attribute name="key" use="required"/>
102205 </xs:complexType>
102206 <xs:group name="argumentsGroup">
102207 <xs:sequence>
102208 <xs:choice minOccurs="0" maxOccurs="unbounded">
102209 <xs:element name="array" type="arrayType" />
102210 <xs:element name="integer" type="xs:integer" />
102211 <xs:element name="string" type="xs:string" />
102212 <xs:element name="double" type="xs:double" />
102213 <xs:element name="null" />
102214 <xs:element name="object" type="objectType" />
102215 <xs:element name="file" type="xs:anyURI" />
102216 <xs:element name="directory" type="xs:anyURI" />
102217 <xs:element name="boolean" type="xs:boolean" />
102218 </xs:choice>
102219 </xs:sequence>
102220 </xs:group>
102221 <xs:group name="argumentChoice">
102222 <xs:choice>
102223 <xs:element name="array" type="arrayType" minOccurs="0" maxOccurs="unbounded"/>
102224 <xs:element name="integer" type="xs:integer" minOccurs="0" maxOccurs="unbounded"/>
102225 <xs:element name="string" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
102226 <xs:element name="double" type="xs:double" minOccurs="0" maxOccurs="unbounded"/>
102227 <xs:element name="null" minOccurs="0" maxOccurs="unbounded"/>
102228 <xs:element name="object" type="objectType" minOccurs="0" maxOccurs="unbounded"/>
102229 <xs:element name="file" type="xs:anyURI" minOccurs="0" maxOccurs="unbounded"/>
102230 <xs:element name="directory" type="xs:anyURI" minOccurs="0" maxOccurs="unbounded"/>
102231 <xs:element name="boolean" type="xs:boolean" minOccurs="0" maxOccurs="unbounded"/>
102232 </xs:choice>
102233 </xs:group>
102234 <xs:simpleType name="columnsType">
102235 <xs:union>
102236 <xs:simpleType>
102237 <xs:restriction base="xs:integer"/>
102238 </xs:simpleType>
102239 <xs:simpleType>
102240 <xs:restriction base="xs:string">
102241 <xs:enumeration value="max"/>
102242 </xs:restriction>
102243 </xs:simpleType>
102244 </xs:union>
102245 </xs:simpleType>
102246 <xs:group name="pathGroup">
102247 <xs:sequence>
102248 <xs:choice minOccurs="0" maxOccurs="unbounded">
102249 <xs:element name="directory" type="directoryFilterType"/>
102250 <xs:element name="file" type="fileFilterType"/>
102251 </xs:choice>
102252 </xs:sequence>
102253 </xs:group>
102254 <xs:complexType name="directoryFilterType">
102255 <xs:simpleContent>
102256 <xs:extension base="xs:anyURI">
102257 <xs:attribute type="xs:string" name="prefix" default=""/>
102258 <xs:attribute type="xs:string" name="suffix" default="Test.php"/>
102259 <xs:attributeGroup ref="phpVersionGroup"/>
102260 </xs:extension>
102261 </xs:simpleContent>
102262 </xs:complexType>
102263 <xs:simpleType name="executionOrderType">
102264 <xs:restriction base="xs:string">
102265 <xs:enumeration value="default"/>
102266 <xs:enumeration value="defects"/>
102267 <xs:enumeration value="depends"/>
102268 <xs:enumeration value="depends,defects"/>
102269 <xs:enumeration value="depends,duration"/>
102270 <xs:enumeration value="depends,random"/>
102271 <xs:enumeration value="depends,reverse"/>
102272 <xs:enumeration value="depends,size"/>
102273 <xs:enumeration value="duration"/>
102274 <xs:enumeration value="no-depends"/>
102275 <xs:enumeration value="no-depends,defects"/>
102276 <xs:enumeration value="no-depends,duration"/>
102277 <xs:enumeration value="no-depends,random"/>
102278 <xs:enumeration value="no-depends,reverse"/>
102279 <xs:enumeration value="no-depends,size"/>
102280 <xs:enumeration value="random"/>
102281 <xs:enumeration value="reverse"/>
102282 <xs:enumeration value="size"/>
102283 </xs:restriction>
102284 </xs:simpleType>
102285 <xs:complexType name="fileFilterType">
102286 <xs:simpleContent>
102287 <xs:extension base="xs:anyURI">
102288 <xs:attributeGroup ref="phpVersionGroup"/>
102289 </xs:extension>
102290 </xs:simpleContent>
102291 </xs:complexType>
102292 <xs:attributeGroup name="phpVersionGroup">
102293 <xs:attribute name="phpVersion" type="xs:string" default="5.3.0"/>
102294 <xs:attribute name="phpVersionOperator" type="xs:string" default="&gt;="/>
102295 </xs:attributeGroup>
102296 <xs:complexType name="phpType">
102297 <xs:sequence>
102298 <xs:choice maxOccurs="unbounded">
102299 <xs:element name="includePath" type="xs:anyURI" minOccurs="0" maxOccurs="unbounded"/>
102300 <xs:element name="ini" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
102301 <xs:element name="const" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
102302 <xs:element name="var" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
102303 <xs:element name="env" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
102304 <xs:element name="post" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
102305 <xs:element name="get" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
102306 <xs:element name="cookie" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
102307 <xs:element name="server" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
102308 <xs:element name="files" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
102309 <xs:element name="request" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
102310 </xs:choice>
102311 </xs:sequence>
102312 </xs:complexType>
102313 <xs:complexType name="namedValueType">
102314 <xs:attribute name="name" use="required" type="xs:string"/>
102315 <xs:attribute name="value" use="required" type="xs:anySimpleType"/>
102316 <xs:attribute name="verbatim" use="optional" type="xs:boolean"/>
102317 <xs:attribute name="force" use="optional" type="xs:boolean"/>
102318 </xs:complexType>
102319 <xs:complexType name="phpUnitType">
102320 <xs:annotation>
102321 <xs:documentation>The main type specifying the document structure</xs:documentation>
102322 </xs:annotation>
102323 <xs:group ref="configGroup"/>
102324 <xs:attributeGroup ref="configAttributeGroup"/>
102325 </xs:complexType>
102326 <xs:attributeGroup name="configAttributeGroup">
102327 <xs:attribute name="backupGlobals" type="xs:boolean" default="false"/>
102328 <xs:attribute name="backupStaticAttributes" type="xs:boolean" default="false"/>
102329 <xs:attribute name="bootstrap" type="xs:anyURI"/>
102330 <xs:attribute name="cacheResult" type="xs:boolean" default="true"/>
102331 <xs:attribute name="cacheResultFile" type="xs:anyURI"/>
102332 <xs:attribute name="colors" type="xs:boolean" default="false"/>
102333 <xs:attribute name="columns" type="columnsType" default="80"/>
102334 <xs:attribute name="convertDeprecationsToExceptions" type="xs:boolean" default="true"/>
102335 <xs:attribute name="convertErrorsToExceptions" type="xs:boolean" default="true"/>
102336 <xs:attribute name="convertNoticesToExceptions" type="xs:boolean" default="true"/>
102337 <xs:attribute name="convertWarningsToExceptions" type="xs:boolean" default="true"/>
102338 <xs:attribute name="forceCoversAnnotation" type="xs:boolean" default="false"/>
102339 <xs:attribute name="printerClass" type="xs:string" default="PHPUnit\TextUI\DefaultResultPrinter"/>
102340 <xs:attribute name="printerFile" type="xs:anyURI"/>
102341 <xs:attribute name="processIsolation" type="xs:boolean" default="false"/>
102342 <xs:attribute name="stopOnDefect" type="xs:boolean" default="false"/>
102343 <xs:attribute name="stopOnError" type="xs:boolean" default="false"/>
102344 <xs:attribute name="stopOnFailure" type="xs:boolean" default="false"/>
102345 <xs:attribute name="stopOnWarning" type="xs:boolean" default="false"/>
102346 <xs:attribute name="stopOnIncomplete" type="xs:boolean" default="false"/>
102347 <xs:attribute name="stopOnRisky" type="xs:boolean" default="false"/>
102348 <xs:attribute name="stopOnSkipped" type="xs:boolean" default="false"/>
102349 <xs:attribute name="failOnEmptyTestSuite" type="xs:boolean" default="false"/>
102350 <xs:attribute name="failOnIncomplete" type="xs:boolean" default="false"/>
102351 <xs:attribute name="failOnRisky" type="xs:boolean" default="false"/>
102352 <xs:attribute name="failOnSkipped" type="xs:boolean" default="false"/>
102353 <xs:attribute name="failOnWarning" type="xs:boolean" default="false"/>
102354 <xs:attribute name="beStrictAboutChangesToGlobalState" type="xs:boolean" default="false"/>
102355 <xs:attribute name="beStrictAboutOutputDuringTests" type="xs:boolean" default="false"/>
102356 <xs:attribute name="beStrictAboutResourceUsageDuringSmallTests" type="xs:boolean" default="false"/>
102357 <xs:attribute name="beStrictAboutTestsThatDoNotTestAnything" type="xs:boolean" default="true"/>
102358 <xs:attribute name="beStrictAboutTodoAnnotatedTests" type="xs:boolean" default="false"/>
102359 <xs:attribute name="beStrictAboutCoversAnnotation" type="xs:boolean" default="false"/>
102360 <xs:attribute name="defaultTimeLimit" type="xs:integer" default="0"/>
102361 <xs:attribute name="enforceTimeLimit" type="xs:boolean" default="false"/>
102362 <xs:attribute name="timeoutForSmallTests" type="xs:integer" default="1"/>
102363 <xs:attribute name="timeoutForMediumTests" type="xs:integer" default="10"/>
102364 <xs:attribute name="timeoutForLargeTests" type="xs:integer" default="60"/>
102365 <xs:attribute name="testSuiteLoaderClass" type="xs:string" default="PHPUnit\Runner\StandardTestSuiteLoader"/>
102366 <xs:attribute name="testSuiteLoaderFile" type="xs:anyURI"/>
102367 <xs:attribute name="defaultTestSuite" type="xs:string" default=""/>
102368 <xs:attribute name="verbose" type="xs:boolean" default="false"/>
102369 <xs:attribute name="testdox" type="xs:boolean" default="false"/>
102370 <xs:attribute name="stderr" type="xs:boolean" default="false"/>
102371 <xs:attribute name="reverseDefectList" type="xs:boolean" default="false"/>
102372 <xs:attribute name="registerMockObjectsFromTestArgumentsRecursively" type="xs:boolean" default="false"/>
102373 <xs:attribute name="extensionsDirectory" type="xs:string"/>
102374 <xs:attribute name="executionOrder" type="executionOrderType" default="default"/>
102375 <xs:attribute name="resolveDependencies" type="xs:boolean" default="true"/>
102376 <xs:attribute name="noInteraction" type="xs:boolean" default="false"/>
102377 </xs:attributeGroup>
102378 <xs:group name="configGroup">
102379 <xs:all>
102380 <xs:element ref="testSuiteFacet" minOccurs="0"/>
102381 <xs:element name="groups" type="groupsType" minOccurs="0"/>
102382 <xs:element name="testdoxGroups" type="groupsType" minOccurs="0"/>
102383 <xs:element name="coverage" type="coverageType" minOccurs="0"/>
102384 <xs:element name="logging" type="loggingType" minOccurs="0"/>
102385 <xs:element name="extensions" type="extensionsType" minOccurs="0"/>
102386 <xs:element name="listeners" type="listenersType" minOccurs="0"/>
102387 <xs:element name="php" type="phpType" minOccurs="0"/>
102388 </xs:all>
102389 </xs:group>
102390 <xs:element name="testSuiteFacet" abstract="true"/>
102391 <xs:element name="testsuite" type="testSuiteType" substitutionGroup="testSuiteFacet"/>
102392 <xs:element name="testsuites" type="testSuitesType" substitutionGroup="testSuiteFacet"/>
102393 <xs:complexType name="testSuitesType">
102394 <xs:sequence>
102395 <xs:element name="testsuite" type="testSuiteType" maxOccurs="unbounded"/>
102396 </xs:sequence>
102397 </xs:complexType>
102398 <xs:complexType name="testSuiteType">
102399 <xs:sequence>
102400 <xs:group ref="pathGroup"/>
102401 <xs:element name="exclude" type="xs:anyURI" minOccurs="0" maxOccurs="unbounded"/>
102402 </xs:sequence>
102403 <xs:attribute name="name" type="xs:string" use="required"/>
102404 </xs:complexType>
102405 <xs:group name="coverageReportGroup">
102406 <xs:all>
102407 <xs:element name="clover" type="logToFileType" minOccurs="0"/>
102408 <xs:element name="cobertura" type="logToFileType" minOccurs="0"/>
102409 <xs:element name="crap4j" type="coverageReportCrap4JType" minOccurs="0" />
102410 <xs:element name="html" type="coverageReportHtmlType" minOccurs="0" />
102411 <xs:element name="php" type="logToFileType" minOccurs="0" />
102412 <xs:element name="text" type="coverageReportTextType" minOccurs="0" />
102413 <xs:element name="xml" type="logToDirectoryType" minOccurs="0" />
102414 </xs:all>
102415 </xs:group>
102416 <xs:group name="loggingGroup">
102417 <xs:all>
102418 <xs:element name="junit" type="logToFileType" minOccurs="0" />
102419 <xs:element name="teamcity" type="logToFileType" minOccurs="0" />
102420 <xs:element name="testdoxHtml" type="logToFileType" minOccurs="0" />
102421 <xs:element name="testdoxText" type="logToFileType" minOccurs="0" />
102422 <xs:element name="testdoxXml" type="logToFileType" minOccurs="0" />
102423 <xs:element name="text" type="logToFileType" minOccurs="0"/>
102424 </xs:all>
102425 </xs:group>
102426 <xs:complexType name="logToFileType">
102427 <xs:attribute name="outputFile" type="xs:anyURI" use="required"/>
102428 </xs:complexType>
102429 <xs:complexType name="logToDirectoryType">
102430 <xs:attribute name="outputDirectory" type="xs:anyURI" use="required"/>
102431 </xs:complexType>
102432 <xs:complexType name="coverageReportCrap4JType">
102433 <xs:attribute name="outputFile" type="xs:anyURI" use="required"/>
102434 <xs:attribute name="threshold" type="xs:integer"/>
102435 </xs:complexType>
102436 <xs:complexType name="coverageReportHtmlType">
102437 <xs:attribute name="outputDirectory" type="xs:anyURI" use="required"/>
102438 <xs:attribute name="lowUpperBound" type="xs:integer" default="50"/>
102439 <xs:attribute name="highLowerBound" type="xs:integer" default="90"/>
102440 </xs:complexType>
102441 <xs:complexType name="coverageReportTextType">
102442 <xs:attribute name="outputFile" type="xs:anyURI" use="required"/>
102443 <xs:attribute name="showUncoveredFiles" type="xs:boolean" default="false"/>
102444 <xs:attribute name="showOnlySummary" type="xs:boolean" default="false"/>
102445 </xs:complexType>
102446 </xs:schema>
102447 <?xml version="1.0" encoding="UTF-8"?>
102448 <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
102449 <xs:annotation>
102450 <xs:documentation source="https://phpunit.de/documentation.html">
102451 This Schema file defines the rules by which the XML configuration file of PHPUnit 9.5 may be structured.
102452 </xs:documentation>
102453 <xs:appinfo source="https://phpunit.de/documentation.html"/>
102454 </xs:annotation>
102455 <xs:element name="phpunit" type="phpUnitType">
102456 <xs:annotation>
102457 <xs:documentation>Root Element</xs:documentation>
102458 </xs:annotation>
102459 </xs:element>
102460 <xs:complexType name="coverageType">
102461 <xs:all>
102462 <xs:element name="include" minOccurs="0" maxOccurs="1">
102463 <xs:complexType>
102464 <xs:group ref="pathGroup"/>
102465 </xs:complexType>
102466 </xs:element>
102467 <xs:element name="exclude" minOccurs="0" maxOccurs="1">
102468 <xs:complexType>
102469 <xs:group ref="pathGroup"/>
102470 </xs:complexType>
102471 </xs:element>
102472 <xs:element name="report" minOccurs="0" maxOccurs="1">
102473 <xs:complexType>
102474 <xs:group ref="coverageReportGroup"/>
102475 </xs:complexType>
102476 </xs:element>
102477 </xs:all>
102478 <xs:attribute name="cacheDirectory" type="xs:anyURI"/>
102479 <xs:attribute name="pathCoverage" type="xs:boolean" default="false"/>
102480 <xs:attribute name="includeUncoveredFiles" type="xs:boolean" default="true"/>
102481 <xs:attribute name="processUncoveredFiles" type="xs:boolean" default="false"/>
102482 <xs:attribute name="ignoreDeprecatedCodeUnits" type="xs:boolean" default="false"/>
102483 <xs:attribute name="disableCodeCoverageIgnore" type="xs:boolean" default="false"/>
102484 </xs:complexType>
102485 <xs:complexType name="loggingType">
102486 <xs:group ref="loggingGroup"/>
102487 </xs:complexType>
102488 <xs:complexType name="groupsType">
102489 <xs:choice>
102490 <xs:sequence>
102491 <xs:element name="include" type="groupType"/>
102492 <xs:element name="exclude" type="groupType" minOccurs="0"/>
102493 </xs:sequence>
102494 <xs:sequence>
102495 <xs:element name="exclude" type="groupType"/>
102496 </xs:sequence>
102497 </xs:choice>
102498 </xs:complexType>
102499 <xs:complexType name="groupType">
102500 <xs:sequence>
102501 <xs:element name="group" type="xs:string" maxOccurs="unbounded"/>
102502 </xs:sequence>
102503 </xs:complexType>
102504 <xs:complexType name="extensionsType">
102505 <xs:sequence>
102506 <xs:element name="extension" type="objectType" maxOccurs="unbounded"/>
102507 </xs:sequence>
102508 </xs:complexType>
102509 <xs:complexType name="listenersType">
102510 <xs:sequence>
102511 <xs:element name="listener" type="objectType" maxOccurs="unbounded"/>
102512 </xs:sequence>
102513 </xs:complexType>
102514 <xs:complexType name="objectType">
102515 <xs:sequence>
102516 <xs:element name="arguments" minOccurs="0">
102517 <xs:complexType>
102518 <xs:group ref="argumentsGroup"/>
102519 </xs:complexType>
102520 </xs:element>
102521 </xs:sequence>
102522 <xs:attribute name="class" type="xs:string" use="required"/>
102523 <xs:attribute name="file" type="xs:anyURI"/>
102524 </xs:complexType>
102525 <xs:complexType name="arrayType">
102526 <xs:sequence>
102527 <xs:element name="element" type="argumentType" minOccurs="0" maxOccurs="unbounded"/>
102528 </xs:sequence>
102529 </xs:complexType>
102530 <xs:complexType name="argumentType">
102531 <xs:group ref="argumentChoice"/>
102532 <xs:attribute name="key" use="required"/>
102533 </xs:complexType>
102534 <xs:group name="argumentsGroup">
102535 <xs:sequence>
102536 <xs:choice minOccurs="0" maxOccurs="unbounded">
102537 <xs:element name="array" type="arrayType" />
102538 <xs:element name="integer" type="xs:integer" />
102539 <xs:element name="string" type="xs:string" />
102540 <xs:element name="double" type="xs:double" />
102541 <xs:element name="null" />
102542 <xs:element name="object" type="objectType" />
102543 <xs:element name="file" type="xs:anyURI" />
102544 <xs:element name="directory" type="xs:anyURI" />
102545 <xs:element name="boolean" type="xs:boolean" />
102546 </xs:choice>
102547 </xs:sequence>
102548 </xs:group>
102549 <xs:group name="argumentChoice">
102550 <xs:choice>
102551 <xs:element name="array" type="arrayType" minOccurs="0" maxOccurs="unbounded"/>
102552 <xs:element name="integer" type="xs:integer" minOccurs="0" maxOccurs="unbounded"/>
102553 <xs:element name="string" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
102554 <xs:element name="double" type="xs:double" minOccurs="0" maxOccurs="unbounded"/>
102555 <xs:element name="null" minOccurs="0" maxOccurs="unbounded"/>
102556 <xs:element name="object" type="objectType" minOccurs="0" maxOccurs="unbounded"/>
102557 <xs:element name="file" type="xs:anyURI" minOccurs="0" maxOccurs="unbounded"/>
102558 <xs:element name="directory" type="xs:anyURI" minOccurs="0" maxOccurs="unbounded"/>
102559 <xs:element name="boolean" type="xs:boolean" minOccurs="0" maxOccurs="unbounded"/>
102560 </xs:choice>
102561 </xs:group>
102562 <xs:simpleType name="columnsType">
102563 <xs:union>
102564 <xs:simpleType>
102565 <xs:restriction base="xs:integer"/>
102566 </xs:simpleType>
102567 <xs:simpleType>
102568 <xs:restriction base="xs:string">
102569 <xs:enumeration value="max"/>
102570 </xs:restriction>
102571 </xs:simpleType>
102572 </xs:union>
102573 </xs:simpleType>
102574 <xs:group name="pathGroup">
102575 <xs:sequence>
102576 <xs:choice minOccurs="0" maxOccurs="unbounded">
102577 <xs:element name="directory" type="directoryFilterType"/>
102578 <xs:element name="file" type="fileFilterType"/>
102579 </xs:choice>
102580 </xs:sequence>
102581 </xs:group>
102582 <xs:complexType name="directoryFilterType">
102583 <xs:simpleContent>
102584 <xs:extension base="xs:string">
102585 <xs:attribute type="xs:string" name="prefix" default=""/>
102586 <xs:attribute type="xs:string" name="suffix" default="Test.php"/>
102587 <xs:attributeGroup ref="phpVersionGroup"/>
102588 </xs:extension>
102589 </xs:simpleContent>
102590 </xs:complexType>
102591 <xs:simpleType name="executionOrderType">
102592 <xs:restriction base="xs:string">
102593 <xs:enumeration value="default"/>
102594 <xs:enumeration value="defects"/>
102595 <xs:enumeration value="depends"/>
102596 <xs:enumeration value="depends,defects"/>
102597 <xs:enumeration value="depends,duration"/>
102598 <xs:enumeration value="depends,random"/>
102599 <xs:enumeration value="depends,reverse"/>
102600 <xs:enumeration value="depends,size"/>
102601 <xs:enumeration value="duration"/>
102602 <xs:enumeration value="no-depends"/>
102603 <xs:enumeration value="no-depends,defects"/>
102604 <xs:enumeration value="no-depends,duration"/>
102605 <xs:enumeration value="no-depends,random"/>
102606 <xs:enumeration value="no-depends,reverse"/>
102607 <xs:enumeration value="no-depends,size"/>
102608 <xs:enumeration value="random"/>
102609 <xs:enumeration value="reverse"/>
102610 <xs:enumeration value="size"/>
102611 </xs:restriction>
102612 </xs:simpleType>
102613 <xs:complexType name="fileFilterType">
102614 <xs:simpleContent>
102615 <xs:extension base="xs:anyURI">
102616 <xs:attributeGroup ref="phpVersionGroup"/>
102617 </xs:extension>
102618 </xs:simpleContent>
102619 </xs:complexType>
102620 <xs:attributeGroup name="phpVersionGroup">
102621 <xs:attribute name="phpVersion" type="xs:string" default="5.3.0"/>
102622 <xs:attribute name="phpVersionOperator" type="xs:string" default="&gt;="/>
102623 </xs:attributeGroup>
102624 <xs:complexType name="phpType">
102625 <xs:sequence>
102626 <xs:choice maxOccurs="unbounded">
102627 <xs:element name="includePath" type="xs:anyURI" minOccurs="0" maxOccurs="unbounded"/>
102628 <xs:element name="ini" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
102629 <xs:element name="const" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
102630 <xs:element name="var" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
102631 <xs:element name="env" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
102632 <xs:element name="post" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
102633 <xs:element name="get" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
102634 <xs:element name="cookie" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
102635 <xs:element name="server" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
102636 <xs:element name="files" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
102637 <xs:element name="request" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
102638 </xs:choice>
102639 </xs:sequence>
102640 </xs:complexType>
102641 <xs:complexType name="namedValueType">
102642 <xs:attribute name="name" use="required" type="xs:string"/>
102643 <xs:attribute name="value" use="required" type="xs:anySimpleType"/>
102644 <xs:attribute name="verbatim" use="optional" type="xs:boolean"/>
102645 <xs:attribute name="force" use="optional" type="xs:boolean"/>
102646 </xs:complexType>
102647 <xs:complexType name="phpUnitType">
102648 <xs:annotation>
102649 <xs:documentation>The main type specifying the document structure</xs:documentation>
102650 </xs:annotation>
102651 <xs:group ref="configGroup"/>
102652 <xs:attributeGroup ref="configAttributeGroup"/>
102653 </xs:complexType>
102654 <xs:attributeGroup name="configAttributeGroup">
102655 <xs:attribute name="backupGlobals" type="xs:boolean" default="false"/>
102656 <xs:attribute name="backupStaticAttributes" type="xs:boolean" default="false"/>
102657 <xs:attribute name="bootstrap" type="xs:anyURI"/>
102658 <xs:attribute name="cacheResult" type="xs:boolean" default="true"/>
102659 <xs:attribute name="cacheResultFile" type="xs:anyURI"/>
102660 <xs:attribute name="colors" type="xs:boolean" default="false"/>
102661 <xs:attribute name="columns" type="columnsType" default="80"/>
102662 <xs:attribute name="convertDeprecationsToExceptions" type="xs:boolean" default="false"/>
102663 <xs:attribute name="convertErrorsToExceptions" type="xs:boolean" default="true"/>
102664 <xs:attribute name="convertNoticesToExceptions" type="xs:boolean" default="true"/>
102665 <xs:attribute name="convertWarningsToExceptions" type="xs:boolean" default="true"/>
102666 <xs:attribute name="forceCoversAnnotation" type="xs:boolean" default="false"/>
102667 <xs:attribute name="printerClass" type="xs:string" default="PHPUnit\TextUI\DefaultResultPrinter"/>
102668 <xs:attribute name="printerFile" type="xs:anyURI"/>
102669 <xs:attribute name="processIsolation" type="xs:boolean" default="false"/>
102670 <xs:attribute name="stopOnDefect" type="xs:boolean" default="false"/>
102671 <xs:attribute name="stopOnError" type="xs:boolean" default="false"/>
102672 <xs:attribute name="stopOnFailure" type="xs:boolean" default="false"/>
102673 <xs:attribute name="stopOnWarning" type="xs:boolean" default="false"/>
102674 <xs:attribute name="stopOnIncomplete" type="xs:boolean" default="false"/>
102675 <xs:attribute name="stopOnRisky" type="xs:boolean" default="false"/>
102676 <xs:attribute name="stopOnSkipped" type="xs:boolean" default="false"/>
102677 <xs:attribute name="failOnEmptyTestSuite" type="xs:boolean" default="false"/>
102678 <xs:attribute name="failOnIncomplete" type="xs:boolean" default="false"/>
102679 <xs:attribute name="failOnRisky" type="xs:boolean" default="false"/>
102680 <xs:attribute name="failOnSkipped" type="xs:boolean" default="false"/>
102681 <xs:attribute name="failOnWarning" type="xs:boolean" default="false"/>
102682 <xs:attribute name="beStrictAboutChangesToGlobalState" type="xs:boolean" default="false"/>
102683 <xs:attribute name="beStrictAboutOutputDuringTests" type="xs:boolean" default="false"/>
102684 <xs:attribute name="beStrictAboutResourceUsageDuringSmallTests" type="xs:boolean" default="false"/>
102685 <xs:attribute name="beStrictAboutTestsThatDoNotTestAnything" type="xs:boolean" default="true"/>
102686 <xs:attribute name="beStrictAboutTodoAnnotatedTests" type="xs:boolean" default="false"/>
102687 <xs:attribute name="beStrictAboutCoversAnnotation" type="xs:boolean" default="false"/>
102688 <xs:attribute name="defaultTimeLimit" type="xs:integer" default="0"/>
102689 <xs:attribute name="enforceTimeLimit" type="xs:boolean" default="false"/>
102690 <xs:attribute name="timeoutForSmallTests" type="xs:integer" default="1"/>
102691 <xs:attribute name="timeoutForMediumTests" type="xs:integer" default="10"/>
102692 <xs:attribute name="timeoutForLargeTests" type="xs:integer" default="60"/>
102693 <xs:attribute name="testSuiteLoaderClass" type="xs:string" default="PHPUnit\Runner\StandardTestSuiteLoader"/>
102694 <xs:attribute name="testSuiteLoaderFile" type="xs:anyURI"/>
102695 <xs:attribute name="defaultTestSuite" type="xs:string" default=""/>
102696 <xs:attribute name="verbose" type="xs:boolean" default="false"/>
102697 <xs:attribute name="testdox" type="xs:boolean" default="false"/>
102698 <xs:attribute name="stderr" type="xs:boolean" default="false"/>
102699 <xs:attribute name="reverseDefectList" type="xs:boolean" default="false"/>
102700 <xs:attribute name="registerMockObjectsFromTestArgumentsRecursively" type="xs:boolean" default="false"/>
102701 <xs:attribute name="extensionsDirectory" type="xs:anyURI"/>
102702 <xs:attribute name="executionOrder" type="executionOrderType" default="default"/>
102703 <xs:attribute name="resolveDependencies" type="xs:boolean" default="true"/>
102704 <xs:attribute name="noInteraction" type="xs:boolean" default="false"/>
102705 </xs:attributeGroup>
102706 <xs:group name="configGroup">
102707 <xs:all>
102708 <xs:element ref="testSuiteFacet" minOccurs="0"/>
102709 <xs:element name="groups" type="groupsType" minOccurs="0"/>
102710 <xs:element name="testdoxGroups" type="groupsType" minOccurs="0"/>
102711 <xs:element name="coverage" type="coverageType" minOccurs="0"/>
102712 <xs:element name="logging" type="loggingType" minOccurs="0"/>
102713 <xs:element name="extensions" type="extensionsType" minOccurs="0"/>
102714 <xs:element name="listeners" type="listenersType" minOccurs="0"/>
102715 <xs:element name="php" type="phpType" minOccurs="0"/>
102716 </xs:all>
102717 </xs:group>
102718 <xs:element name="testSuiteFacet" abstract="true"/>
102719 <xs:element name="testsuite" type="testSuiteType" substitutionGroup="testSuiteFacet"/>
102720 <xs:element name="testsuites" type="testSuitesType" substitutionGroup="testSuiteFacet"/>
102721 <xs:complexType name="testSuitesType">
102722 <xs:sequence>
102723 <xs:element name="testsuite" type="testSuiteType" maxOccurs="unbounded"/>
102724 </xs:sequence>
102725 </xs:complexType>
102726 <xs:complexType name="testSuiteType">
102727 <xs:sequence>
102728 <xs:choice minOccurs="0" maxOccurs="unbounded">
102729 <xs:group ref="pathGroup"/>
102730 <xs:element name="exclude" type="xs:string"/>
102731 </xs:choice>
102732 </xs:sequence>
102733 <xs:attribute name="name" type="xs:string" use="required"/>
102734 </xs:complexType>
102735 <xs:group name="coverageReportGroup">
102736 <xs:all>
102737 <xs:element name="clover" type="logToFileType" minOccurs="0"/>
102738 <xs:element name="cobertura" type="logToFileType" minOccurs="0"/>
102739 <xs:element name="crap4j" type="coverageReportCrap4JType" minOccurs="0" />
102740 <xs:element name="html" type="coverageReportHtmlType" minOccurs="0" />
102741 <xs:element name="php" type="logToFileType" minOccurs="0" />
102742 <xs:element name="text" type="coverageReportTextType" minOccurs="0" />
102743 <xs:element name="xml" type="logToDirectoryType" minOccurs="0" />
102744 </xs:all>
102745 </xs:group>
102746 <xs:group name="loggingGroup">
102747 <xs:all>
102748 <xs:element name="junit" type="logToFileType" minOccurs="0" />
102749 <xs:element name="teamcity" type="logToFileType" minOccurs="0" />
102750 <xs:element name="testdoxHtml" type="logToFileType" minOccurs="0" />
102751 <xs:element name="testdoxText" type="logToFileType" minOccurs="0" />
102752 <xs:element name="testdoxXml" type="logToFileType" minOccurs="0" />
102753 <xs:element name="text" type="logToFileType" minOccurs="0"/>
102754 </xs:all>
102755 </xs:group>
102756 <xs:complexType name="logToFileType">
102757 <xs:attribute name="outputFile" type="xs:anyURI" use="required"/>
102758 </xs:complexType>
102759 <xs:complexType name="logToDirectoryType">
102760 <xs:attribute name="outputDirectory" type="xs:anyURI" use="required"/>
102761 </xs:complexType>
102762 <xs:complexType name="coverageReportCrap4JType">
102763 <xs:attribute name="outputFile" type="xs:anyURI" use="required"/>
102764 <xs:attribute name="threshold" type="xs:integer"/>
102765 </xs:complexType>
102766 <xs:complexType name="coverageReportHtmlType">
102767 <xs:attribute name="outputDirectory" type="xs:anyURI" use="required"/>
102768 <xs:attribute name="lowUpperBound" type="xs:integer" default="50"/>
102769 <xs:attribute name="highLowerBound" type="xs:integer" default="90"/>
102770 </xs:complexType>
102771 <xs:complexType name="coverageReportTextType">
102772 <xs:attribute name="outputFile" type="xs:anyURI" use="required"/>
102773 <xs:attribute name="showUncoveredFiles" type="xs:boolean" default="false"/>
102774 <xs:attribute name="showOnlySummary" type="xs:boolean" default="false"/>
102775 </xs:complexType>
102776 </xs:schema>
102777 BSD 3-Clause License
102778
102779 Copyright (c) 2020-2024, Sebastian Bergmann
102780 All rights reserved.
102781
102782 Redistribution and use in source and binary forms, with or without
102783 modification, are permitted provided that the following conditions are met:
102784
102785 1. Redistributions of source code must retain the above copyright notice, this
102786 list of conditions and the following disclaimer.
102787
102788 2. Redistributions in binary form must reproduce the above copyright notice,
102789 this list of conditions and the following disclaimer in the documentation
102790 and/or other materials provided with the distribution.
102791
102792 3. Neither the name of the copyright holder nor the names of its
102793 contributors may be used to endorse or promote products derived from
102794 this software without specific prior written permission.
102795
102796 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
102797 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
102798 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
102799 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
102800 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
102801 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
102802 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
102803 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
102804 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
102805 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
102806 <?php
102807
102808 declare (strict_types=1);
102809 /*
102810 * This file is part of sebastian/cli-parser.
102811 *
102812 * (c) Sebastian Bergmann <sebastian@phpunit.de>
102813 *
102814 * For the full copyright and license information, please view the LICENSE
102815 * file that was distributed with this source code.
102816 */
102817 namespace PHPUnitPHAR\SebastianBergmann\CliParser;
102818
102819 use function array_map;
102820 use function array_merge;
102821 use function array_shift;
102822 use function array_slice;
102823 use function assert;
102824 use function count;
102825 use function current;
102826 use function explode;
102827 use function is_array;
102828 use function is_int;
102829 use function is_string;
102830 use function key;
102831 use function next;
102832 use function preg_replace;
102833 use function reset;
102834 use function sort;
102835 use function str_ends_with;
102836 use function str_starts_with;
102837 use function strlen;
102838 use function strstr;
102839 use function substr;
102840 final class Parser
102841 {
102842 /**
102843 * @psalm-param list<string> $argv
102844 * @psalm-param list<string> $longOptions
102845 *
102846 * @psalm-return array{0: array, 1: array}
102847 *
102848 * @throws AmbiguousOptionException
102849 * @throws OptionDoesNotAllowArgumentException
102850 * @throws RequiredOptionArgumentMissingException
102851 * @throws UnknownOptionException
102852 */
102853 public function parse(array $argv, string $shortOptions, ?array $longOptions = null): array
102854 {
102855 if (empty($argv)) {
102856 return [[], []];
102857 }
102858 $options = [];
102859 $nonOptions = [];
102860 if ($longOptions) {
102861 sort($longOptions);
102862 }
102863 if (isset($argv[0][0]) && $argv[0][0] !== '-') {
102864 array_shift($argv);
102865 }
102866 reset($argv);
102867 $argv = array_map('trim', $argv);
102868 while (\false !== $arg = current($argv)) {
102869 $i = key($argv);
102870 assert(is_int($i));
102871 next($argv);
102872 if ($arg === '') {
102873 continue;
102874 }
102875 if ($arg === '--') {
102876 $nonOptions = array_merge($nonOptions, array_slice($argv, $i + 1));
102877 break;
102878 }
102879 if ($arg[0] !== '-' || strlen($arg) > 1 && $arg[1] === '-' && !$longOptions) {
102880 $nonOptions[] = $arg;
102881 continue;
102882 }
102883 if (strlen($arg) > 1 && $arg[1] === '-' && is_array($longOptions)) {
102884 $this->parseLongOption(substr($arg, 2), $longOptions, $options, $argv);
102885 continue;
102886 }
102887 $this->parseShortOption(substr($arg, 1), $shortOptions, $options, $argv);
102888 }
102889 return [$options, $nonOptions];
102890 }
102891 /**
102892 * @throws RequiredOptionArgumentMissingException
102893 */
102894 private function parseShortOption(string $argument, string $shortOptions, array &$options, array &$argv): void
102895 {
102896 $argumentLength = strlen($argument);
102897 for ($i = 0; $i < $argumentLength; $i++) {
102898 $option = $argument[$i];
102899 $optionArgument = null;
102900 if ($argument[$i] === ':' || ($spec = strstr($shortOptions, $option)) === \false) {
102901 throw new UnknownOptionException('-' . $option);
102902 }
102903 if (strlen($spec) > 1 && $spec[1] === ':') {
102904 if ($i + 1 < $argumentLength) {
102905 $options[] = [$option, substr($argument, $i + 1)];
102906 break;
102907 }
102908 if (!(strlen($spec) > 2 && $spec[2] === ':')) {
102909 $optionArgument = current($argv);
102910 if (!$optionArgument) {
102911 throw new RequiredOptionArgumentMissingException('-' . $option);
102912 }
102913 assert(is_string($optionArgument));
102914 next($argv);
102915 }
102916 }
102917 $options[] = [$option, $optionArgument];
102918 }
102919 }
102920 /**
102921 * @psalm-param list<string> $longOptions
102922 *
102923 * @throws AmbiguousOptionException
102924 * @throws OptionDoesNotAllowArgumentException
102925 * @throws RequiredOptionArgumentMissingException
102926 * @throws UnknownOptionException
102927 */
102928 private function parseLongOption(string $argument, array $longOptions, array &$options, array &$argv): void
102929 {
102930 $count = count($longOptions);
102931 $list = explode('=', $argument);
102932 $option = $list[0];
102933 $optionArgument = null;
102934 if (count($list) > 1) {
102935 $optionArgument = $list[1];
102936 }
102937 $optionLength = strlen($option);
102938 foreach ($longOptions as $i => $longOption) {
102939 $opt_start = substr($longOption, 0, $optionLength);
102940 if ($opt_start !== $option) {
102941 continue;
102942 }
102943 $opt_rest = substr($longOption, $optionLength);
102944 if ($opt_rest !== '' && $i + 1 < $count && $option[0] !== '=' && str_starts_with($longOptions[$i + 1], $option)) {
102945 throw new AmbiguousOptionException('--' . $option);
102946 }
102947 if (str_ends_with($longOption, '=')) {
102948 if (!str_ends_with($longOption, '==') && !strlen((string) $optionArgument)) {
102949 if (\false === $optionArgument = current($argv)) {
102950 throw new RequiredOptionArgumentMissingException('--' . $option);
102951 }
102952 next($argv);
102953 }
102954 } elseif ($optionArgument) {
102955 throw new OptionDoesNotAllowArgumentException('--' . $option);
102956 }
102957 $fullOption = '--' . preg_replace('/={1,2}$/', '', $longOption);
102958 $options[] = [$fullOption, $optionArgument];
102959 return;
102960 }
102961 throw new UnknownOptionException('--' . $option);
102962 }
102963 }
102964 <?php
102965
102966 declare (strict_types=1);
102967 /*
102968 * This file is part of sebastian/cli-parser.
102969 *
102970 * (c) Sebastian Bergmann <sebastian@phpunit.de>
102971 *
102972 * For the full copyright and license information, please view the LICENSE
102973 * file that was distributed with this source code.
102974 */
102975 namespace PHPUnitPHAR\SebastianBergmann\CliParser;
102976
102977 use function sprintf;
102978 use RuntimeException;
102979 final class AmbiguousOptionException extends RuntimeException implements Exception
102980 {
102981 public function __construct(string $option)
102982 {
102983 parent::__construct(sprintf('Option "%s" is ambiguous', $option));
102984 }
102985 }
102986 <?php
102987
102988 declare (strict_types=1);
102989 /*
102990 * This file is part of sebastian/cli-parser.
102991 *
102992 * (c) Sebastian Bergmann <sebastian@phpunit.de>
102993 *
102994 * For the full copyright and license information, please view the LICENSE
102995 * file that was distributed with this source code.
102996 */
102997 namespace PHPUnitPHAR\SebastianBergmann\CliParser;
102998
102999 use Throwable;
103000 interface Exception extends Throwable
103001 {
103002 }
103003 <?php
103004
103005 declare (strict_types=1);
103006 /*
103007 * This file is part of sebastian/cli-parser.
103008 *
103009 * (c) Sebastian Bergmann <sebastian@phpunit.de>
103010 *
103011 * For the full copyright and license information, please view the LICENSE
103012 * file that was distributed with this source code.
103013 */
103014 namespace PHPUnitPHAR\SebastianBergmann\CliParser;
103015
103016 use function sprintf;
103017 use RuntimeException;
103018 final class OptionDoesNotAllowArgumentException extends RuntimeException implements Exception
103019 {
103020 public function __construct(string $option)
103021 {
103022 parent::__construct(sprintf('Option "%s" does not allow an argument', $option));
103023 }
103024 }
103025 <?php
103026
103027 declare (strict_types=1);
103028 /*
103029 * This file is part of sebastian/cli-parser.
103030 *
103031 * (c) Sebastian Bergmann <sebastian@phpunit.de>
103032 *
103033 * For the full copyright and license information, please view the LICENSE
103034 * file that was distributed with this source code.
103035 */
103036 namespace PHPUnitPHAR\SebastianBergmann\CliParser;
103037
103038 use function sprintf;
103039 use RuntimeException;
103040 final class RequiredOptionArgumentMissingException extends RuntimeException implements Exception
103041 {
103042 public function __construct(string $option)
103043 {
103044 parent::__construct(sprintf('Required argument for option "%s" is missing', $option));
103045 }
103046 }
103047 <?php
103048
103049 declare (strict_types=1);
103050 /*
103051 * This file is part of sebastian/cli-parser.
103052 *
103053 * (c) Sebastian Bergmann <sebastian@phpunit.de>
103054 *
103055 * For the full copyright and license information, please view the LICENSE
103056 * file that was distributed with this source code.
103057 */
103058 namespace PHPUnitPHAR\SebastianBergmann\CliParser;
103059
103060 use function sprintf;
103061 use RuntimeException;
103062 final class UnknownOptionException extends RuntimeException implements Exception
103063 {
103064 public function __construct(string $option)
103065 {
103066 parent::__construct(sprintf('Unknown option "%s"', $option));
103067 }
103068 }
103069 BSD 3-Clause License
103070
103071 Copyright (c) 2016-2023, Sebastian Bergmann
103072 All rights reserved.
103073
103074 Redistribution and use in source and binary forms, with or without
103075 modification, are permitted provided that the following conditions are met:
103076
103077 1. Redistributions of source code must retain the above copyright notice, this
103078 list of conditions and the following disclaimer.
103079
103080 2. Redistributions in binary form must reproduce the above copyright notice,
103081 this list of conditions and the following disclaimer in the documentation
103082 and/or other materials provided with the distribution.
103083
103084 3. Neither the name of the copyright holder nor the names of its
103085 contributors may be used to endorse or promote products derived from
103086 this software without specific prior written permission.
103087
103088 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
103089 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
103090 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
103091 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
103092 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
103093 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
103094 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
103095 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
103096 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
103097 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
103098 <?php
103099
103100 declare (strict_types=1);
103101 /*
103102 * This file is part of sebastian/code-unit-reverse-lookup.
103103 *
103104 * (c) Sebastian Bergmann <sebastian@phpunit.de>
103105 *
103106 * For the full copyright and license information, please view the LICENSE
103107 * file that was distributed with this source code.
103108 */
103109 namespace PHPUnitPHAR\SebastianBergmann\CodeUnitReverseLookup;
103110
103111 use function array_merge;
103112 use function assert;
103113 use function get_declared_classes;
103114 use function get_declared_traits;
103115 use function get_defined_functions;
103116 use function is_array;
103117 use function range;
103118 use ReflectionClass;
103119 use ReflectionFunction;
103120 use ReflectionFunctionAbstract;
103121 use ReflectionMethod;
103122 class Wizard
103123 {
103124 /**
103125 * @psalm-var array<string,array<int,string>>
103126 */
103127 private array $lookupTable = [];
103128 /**
103129 * @psalm-var array<class-string,true>
103130 */
103131 private array $processedClasses = [];
103132 /**
103133 * @psalm-var array<string,true>
103134 */
103135 private array $processedFunctions = [];
103136 public function lookup(string $filename, int $lineNumber): string
103137 {
103138 if (!isset($this->lookupTable[$filename][$lineNumber])) {
103139 $this->updateLookupTable();
103140 }
103141 if (isset($this->lookupTable[$filename][$lineNumber])) {
103142 return $this->lookupTable[$filename][$lineNumber];
103143 }
103144 return $filename . ':' . $lineNumber;
103145 }
103146 private function updateLookupTable(): void
103147 {
103148 $this->processClassesAndTraits();
103149 $this->processFunctions();
103150 }
103151 private function processClassesAndTraits(): void
103152 {
103153 $classes = get_declared_classes();
103154 $traits = get_declared_traits();
103155 /* @noinspection PhpConditionAlreadyCheckedInspection */
103156 assert(is_array($traits));
103157 foreach (array_merge($classes, $traits) as $classOrTrait) {
103158 if (isset($this->processedClasses[$classOrTrait])) {
103159 continue;
103160 }
103161 foreach ((new ReflectionClass($classOrTrait))->getMethods() as $method) {
103162 $this->processFunctionOrMethod($method);
103163 }
103164 $this->processedClasses[$classOrTrait] = \true;
103165 }
103166 }
103167 private function processFunctions(): void
103168 {
103169 foreach (get_defined_functions()['user'] as $function) {
103170 if (isset($this->processedFunctions[$function])) {
103171 continue;
103172 }
103173 $this->processFunctionOrMethod(new ReflectionFunction($function));
103174 $this->processedFunctions[$function] = \true;
103175 }
103176 }
103177 private function processFunctionOrMethod(ReflectionFunctionAbstract $functionOrMethod): void
103178 {
103179 if ($functionOrMethod->isInternal()) {
103180 return;
103181 }
103182 $name = $functionOrMethod->getName();
103183 if ($functionOrMethod instanceof ReflectionMethod) {
103184 $name = $functionOrMethod->getDeclaringClass()->getName() . '::' . $name;
103185 }
103186 if (!isset($this->lookupTable[$functionOrMethod->getFileName()])) {
103187 $this->lookupTable[$functionOrMethod->getFileName()] = [];
103188 }
103189 foreach (range($functionOrMethod->getStartLine(), $functionOrMethod->getEndLine()) as $line) {
103190 $this->lookupTable[$functionOrMethod->getFileName()][$line] = $name;
103191 }
103192 }
103193 }
103194 <?php
103195
103196 declare (strict_types=1);
103197 /*
103198 * This file is part of sebastian/code-unit.
103199 *
103200 * (c) Sebastian Bergmann <sebastian@phpunit.de>
103201 *
103202 * For the full copyright and license information, please view the LICENSE
103203 * file that was distributed with this source code.
103204 */
103205 namespace PHPUnitPHAR\SebastianBergmann\CodeUnit;
103206
103207 /**
103208 * @psalm-immutable
103209 */
103210 final class ClassMethodUnit extends CodeUnit
103211 {
103212 /**
103213 * @psalm-assert-if-true ClassMethodUnit $this
103214 */
103215 public function isClassMethod(): bool
103216 {
103217 return \true;
103218 }
103219 }
103220 <?php
103221
103222 declare (strict_types=1);
103223 /*
103224 * This file is part of sebastian/code-unit.
103225 *
103226 * (c) Sebastian Bergmann <sebastian@phpunit.de>
103227 *
103228 * For the full copyright and license information, please view the LICENSE
103229 * file that was distributed with this source code.
103230 */
103231 namespace PHPUnitPHAR\SebastianBergmann\CodeUnit;
103232
103233 /**
103234 * @psalm-immutable
103235 */
103236 final class ClassUnit extends CodeUnit
103237 {
103238 /**
103239 * @psalm-assert-if-true ClassUnit $this
103240 */
103241 public function isClass(): bool
103242 {
103243 return \true;
103244 }
103245 }
103246 <?php
103247
103248 declare (strict_types=1);
103249 /*
103250 * This file is part of sebastian/code-unit.
103251 *
103252 * (c) Sebastian Bergmann <sebastian@phpunit.de>
103253 *
103254 * For the full copyright and license information, please view the LICENSE
103255 * file that was distributed with this source code.
103256 */
103257 namespace PHPUnitPHAR\SebastianBergmann\CodeUnit;
103258
103259 use function count;
103260 use function file;
103261 use function file_exists;
103262 use function is_readable;
103263 use function range;
103264 use function sprintf;
103265 use ReflectionClass;
103266 use ReflectionFunction;
103267 use ReflectionMethod;
103268 /**
103269 * @psalm-immutable
103270 */
103271 abstract class CodeUnit
103272 {
103273 private readonly string $name;
103274 private readonly string $sourceFileName;
103275 /**
103276 * @psalm-var list<int>
103277 */
103278 private readonly array $sourceLines;
103279 /**
103280 * @psalm-param class-string $className
103281 *
103282 * @throws InvalidCodeUnitException
103283 * @throws ReflectionException
103284 */
103285 public static function forClass(string $className): ClassUnit
103286 {
103287 self::ensureUserDefinedClass($className);
103288 $reflector = self::reflectorForClass($className);
103289 return new ClassUnit($className, $reflector->getFileName(), range($reflector->getStartLine(), $reflector->getEndLine()));
103290 }
103291 /**
103292 * @psalm-param class-string $className
103293 *
103294 * @throws InvalidCodeUnitException
103295 * @throws ReflectionException
103296 */
103297 public static function forClassMethod(string $className, string $methodName): ClassMethodUnit
103298 {
103299 self::ensureUserDefinedClass($className);
103300 $reflector = self::reflectorForClassMethod($className, $methodName);
103301 return new ClassMethodUnit($className . '::' . $methodName, $reflector->getFileName(), range($reflector->getStartLine(), $reflector->getEndLine()));
103302 }
103303 /**
103304 * @throws InvalidCodeUnitException
103305 */
103306 public static function forFileWithAbsolutePath(string $path): FileUnit
103307 {
103308 self::ensureFileExistsAndIsReadable($path);
103309 return new FileUnit($path, $path, range(1, count(file($path))));
103310 }
103311 /**
103312 * @psalm-param class-string $interfaceName
103313 *
103314 * @throws InvalidCodeUnitException
103315 * @throws ReflectionException
103316 */
103317 public static function forInterface(string $interfaceName): InterfaceUnit
103318 {
103319 self::ensureUserDefinedInterface($interfaceName);
103320 $reflector = self::reflectorForClass($interfaceName);
103321 return new InterfaceUnit($interfaceName, $reflector->getFileName(), range($reflector->getStartLine(), $reflector->getEndLine()));
103322 }
103323 /**
103324 * @psalm-param class-string $interfaceName
103325 *
103326 * @throws InvalidCodeUnitException
103327 * @throws ReflectionException
103328 */
103329 public static function forInterfaceMethod(string $interfaceName, string $methodName): InterfaceMethodUnit
103330 {
103331 self::ensureUserDefinedInterface($interfaceName);
103332 $reflector = self::reflectorForClassMethod($interfaceName, $methodName);
103333 return new InterfaceMethodUnit($interfaceName . '::' . $methodName, $reflector->getFileName(), range($reflector->getStartLine(), $reflector->getEndLine()));
103334 }
103335 /**
103336 * @psalm-param class-string $traitName
103337 *
103338 * @throws InvalidCodeUnitException
103339 * @throws ReflectionException
103340 */
103341 public static function forTrait(string $traitName): TraitUnit
103342 {
103343 self::ensureUserDefinedTrait($traitName);
103344 $reflector = self::reflectorForClass($traitName);
103345 return new TraitUnit($traitName, $reflector->getFileName(), range($reflector->getStartLine(), $reflector->getEndLine()));
103346 }
103347 /**
103348 * @psalm-param class-string $traitName
103349 *
103350 * @throws InvalidCodeUnitException
103351 * @throws ReflectionException
103352 */
103353 public static function forTraitMethod(string $traitName, string $methodName): TraitMethodUnit
103354 {
103355 self::ensureUserDefinedTrait($traitName);
103356 $reflector = self::reflectorForClassMethod($traitName, $methodName);
103357 return new TraitMethodUnit($traitName . '::' . $methodName, $reflector->getFileName(), range($reflector->getStartLine(), $reflector->getEndLine()));
103358 }
103359 /**
103360 * @psalm-param callable-string $functionName
103361 *
103362 * @throws InvalidCodeUnitException
103363 * @throws ReflectionException
103364 */
103365 public static function forFunction(string $functionName): FunctionUnit
103366 {
103367 $reflector = self::reflectorForFunction($functionName);
103368 if (!$reflector->isUserDefined()) {
103369 throw new InvalidCodeUnitException(sprintf('"%s" is not a user-defined function', $functionName));
103370 }
103371 return new FunctionUnit($functionName, $reflector->getFileName(), range($reflector->getStartLine(), $reflector->getEndLine()));
103372 }
103373 /**
103374 * @psalm-param list<int> $sourceLines
103375 */
103376 private function __construct(string $name, string $sourceFileName, array $sourceLines)
103377 {
103378 $this->name = $name;
103379 $this->sourceFileName = $sourceFileName;
103380 $this->sourceLines = $sourceLines;
103381 }
103382 public function name(): string
103383 {
103384 return $this->name;
103385 }
103386 public function sourceFileName(): string
103387 {
103388 return $this->sourceFileName;
103389 }
103390 /**
103391 * @psalm-return list<int>
103392 */
103393 public function sourceLines(): array
103394 {
103395 return $this->sourceLines;
103396 }
103397 public function isClass(): bool
103398 {
103399 return \false;
103400 }
103401 public function isClassMethod(): bool
103402 {
103403 return \false;
103404 }
103405 public function isInterface(): bool
103406 {
103407 return \false;
103408 }
103409 public function isInterfaceMethod(): bool
103410 {
103411 return \false;
103412 }
103413 public function isTrait(): bool
103414 {
103415 return \false;
103416 }
103417 public function isTraitMethod(): bool
103418 {
103419 return \false;
103420 }
103421 public function isFunction(): bool
103422 {
103423 return \false;
103424 }
103425 public function isFile(): bool
103426 {
103427 return \false;
103428 }
103429 /**
103430 * @throws InvalidCodeUnitException
103431 */
103432 private static function ensureFileExistsAndIsReadable(string $path): void
103433 {
103434 if (!(file_exists($path) && is_readable($path))) {
103435 throw new InvalidCodeUnitException(sprintf('File "%s" does not exist or is not readable', $path));
103436 }
103437 }
103438 /**
103439 * @psalm-param class-string $className
103440 *
103441 * @throws InvalidCodeUnitException
103442 */
103443 private static function ensureUserDefinedClass(string $className): void
103444 {
103445 try {
103446 $reflector = new ReflectionClass($className);
103447 if ($reflector->isInterface()) {
103448 throw new InvalidCodeUnitException(sprintf('"%s" is an interface and not a class', $className));
103449 }
103450 if ($reflector->isTrait()) {
103451 throw new InvalidCodeUnitException(sprintf('"%s" is a trait and not a class', $className));
103452 }
103453 if (!$reflector->isUserDefined()) {
103454 throw new InvalidCodeUnitException(sprintf('"%s" is not a user-defined class', $className));
103455 }
103456 // @codeCoverageIgnoreStart
103457 } catch (\ReflectionException $e) {
103458 throw new ReflectionException($e->getMessage(), $e->getCode(), $e);
103459 }
103460 // @codeCoverageIgnoreEnd
103461 }
103462 /**
103463 * @psalm-param class-string $interfaceName
103464 *
103465 * @throws InvalidCodeUnitException
103466 */
103467 private static function ensureUserDefinedInterface(string $interfaceName): void
103468 {
103469 try {
103470 $reflector = new ReflectionClass($interfaceName);
103471 if (!$reflector->isInterface()) {
103472 throw new InvalidCodeUnitException(sprintf('"%s" is not an interface', $interfaceName));
103473 }
103474 if (!$reflector->isUserDefined()) {
103475 throw new InvalidCodeUnitException(sprintf('"%s" is not a user-defined interface', $interfaceName));
103476 }
103477 // @codeCoverageIgnoreStart
103478 } catch (\ReflectionException $e) {
103479 throw new ReflectionException($e->getMessage(), $e->getCode(), $e);
103480 }
103481 // @codeCoverageIgnoreEnd
103482 }
103483 /**
103484 * @psalm-param class-string $traitName
103485 *
103486 * @throws InvalidCodeUnitException
103487 */
103488 private static function ensureUserDefinedTrait(string $traitName): void
103489 {
103490 try {
103491 $reflector = new ReflectionClass($traitName);
103492 if (!$reflector->isTrait()) {
103493 throw new InvalidCodeUnitException(sprintf('"%s" is not a trait', $traitName));
103494 }
103495 // @codeCoverageIgnoreStart
103496 if (!$reflector->isUserDefined()) {
103497 throw new InvalidCodeUnitException(sprintf('"%s" is not a user-defined trait', $traitName));
103498 }
103499 } catch (\ReflectionException $e) {
103500 throw new ReflectionException($e->getMessage(), $e->getCode(), $e);
103501 }
103502 // @codeCoverageIgnoreEnd
103503 }
103504 /**
103505 * @psalm-param class-string $className
103506 *
103507 * @throws ReflectionException
103508 */
103509 private static function reflectorForClass(string $className): ReflectionClass
103510 {
103511 try {
103512 return new ReflectionClass($className);
103513 // @codeCoverageIgnoreStart
103514 } catch (\ReflectionException $e) {
103515 throw new ReflectionException($e->getMessage(), $e->getCode(), $e);
103516 }
103517 // @codeCoverageIgnoreEnd
103518 }
103519 /**
103520 * @psalm-param class-string $className
103521 *
103522 * @throws ReflectionException
103523 */
103524 private static function reflectorForClassMethod(string $className, string $methodName): ReflectionMethod
103525 {
103526 try {
103527 return new ReflectionMethod($className, $methodName);
103528 // @codeCoverageIgnoreStart
103529 } catch (\ReflectionException $e) {
103530 throw new ReflectionException($e->getMessage(), $e->getCode(), $e);
103531 }
103532 // @codeCoverageIgnoreEnd
103533 }
103534 /**
103535 * @psalm-param callable-string $functionName
103536 *
103537 * @throws ReflectionException
103538 */
103539 private static function reflectorForFunction(string $functionName): ReflectionFunction
103540 {
103541 try {
103542 return new ReflectionFunction($functionName);
103543 // @codeCoverageIgnoreStart
103544 } catch (\ReflectionException $e) {
103545 throw new ReflectionException($e->getMessage(), $e->getCode(), $e);
103546 }
103547 // @codeCoverageIgnoreEnd
103548 }
103549 }
103550 <?php
103551
103552 declare (strict_types=1);
103553 /*
103554 * This file is part of sebastian/code-unit.
103555 *
103556 * (c) Sebastian Bergmann <sebastian@phpunit.de>
103557 *
103558 * For the full copyright and license information, please view the LICENSE
103559 * file that was distributed with this source code.
103560 */
103561 namespace PHPUnitPHAR\SebastianBergmann\CodeUnit;
103562
103563 use function array_merge;
103564 use function count;
103565 use Countable;
103566 use IteratorAggregate;
103567 /**
103568 * @template-implements IteratorAggregate<int, CodeUnit>
103569 *
103570 * @psalm-immutable
103571 */
103572 final class CodeUnitCollection implements Countable, IteratorAggregate
103573 {
103574 /**
103575 * @psalm-var list<CodeUnit>
103576 */
103577 private readonly array $codeUnits;
103578 public static function fromList(CodeUnit ...$codeUnits): self
103579 {
103580 return new self($codeUnits);
103581 }
103582 /**
103583 * @psalm-param list<CodeUnit> $codeUnits
103584 */
103585 private function __construct(array $codeUnits)
103586 {
103587 $this->codeUnits = $codeUnits;
103588 }
103589 /**
103590 * @psalm-return list<CodeUnit>
103591 */
103592 public function asArray(): array
103593 {
103594 return $this->codeUnits;
103595 }
103596 public function getIterator(): CodeUnitCollectionIterator
103597 {
103598 return new CodeUnitCollectionIterator($this);
103599 }
103600 public function count(): int
103601 {
103602 return count($this->codeUnits);
103603 }
103604 public function isEmpty(): bool
103605 {
103606 return empty($this->codeUnits);
103607 }
103608 public function mergeWith(self $other): self
103609 {
103610 return new self(array_merge($this->asArray(), $other->asArray()));
103611 }
103612 }
103613 <?php
103614
103615 declare (strict_types=1);
103616 /*
103617 * This file is part of sebastian/code-unit.
103618 *
103619 * (c) Sebastian Bergmann <sebastian@phpunit.de>
103620 *
103621 * For the full copyright and license information, please view the LICENSE
103622 * file that was distributed with this source code.
103623 */
103624 namespace PHPUnitPHAR\SebastianBergmann\CodeUnit;
103625
103626 use Iterator;
103627 /**
103628 * @template-implements Iterator<int, CodeUnit>
103629 */
103630 final class CodeUnitCollectionIterator implements Iterator
103631 {
103632 /**
103633 * @psalm-var list<CodeUnit>
103634 */
103635 private array $codeUnits;
103636 private int $position = 0;
103637 public function __construct(CodeUnitCollection $collection)
103638 {
103639 $this->codeUnits = $collection->asArray();
103640 }
103641 public function rewind(): void
103642 {
103643 $this->position = 0;
103644 }
103645 public function valid(): bool
103646 {
103647 return isset($this->codeUnits[$this->position]);
103648 }
103649 public function key(): int
103650 {
103651 return $this->position;
103652 }
103653 public function current(): CodeUnit
103654 {
103655 return $this->codeUnits[$this->position];
103656 }
103657 public function next(): void
103658 {
103659 $this->position++;
103660 }
103661 }
103662 <?php
103663
103664 declare (strict_types=1);
103665 /*
103666 * This file is part of sebastian/code-unit.
103667 *
103668 * (c) Sebastian Bergmann <sebastian@phpunit.de>
103669 *
103670 * For the full copyright and license information, please view the LICENSE
103671 * file that was distributed with this source code.
103672 */
103673 namespace PHPUnitPHAR\SebastianBergmann\CodeUnit;
103674
103675 /**
103676 * @psalm-immutable
103677 */
103678 final class FileUnit extends CodeUnit
103679 {
103680 /**
103681 * @psalm-assert-if-true FileUnit $this
103682 */
103683 public function isFile(): bool
103684 {
103685 return \true;
103686 }
103687 }
103688 <?php
103689
103690 declare (strict_types=1);
103691 /*
103692 * This file is part of sebastian/code-unit.
103693 *
103694 * (c) Sebastian Bergmann <sebastian@phpunit.de>
103695 *
103696 * For the full copyright and license information, please view the LICENSE
103697 * file that was distributed with this source code.
103698 */
103699 namespace PHPUnitPHAR\SebastianBergmann\CodeUnit;
103700
103701 /**
103702 * @psalm-immutable
103703 */
103704 final class FunctionUnit extends CodeUnit
103705 {
103706 /**
103707 * @psalm-assert-if-true FunctionUnit $this
103708 */
103709 public function isFunction(): bool
103710 {
103711 return \true;
103712 }
103713 }
103714 <?php
103715
103716 declare (strict_types=1);
103717 /*
103718 * This file is part of sebastian/code-unit.
103719 *
103720 * (c) Sebastian Bergmann <sebastian@phpunit.de>
103721 *
103722 * For the full copyright and license information, please view the LICENSE
103723 * file that was distributed with this source code.
103724 */
103725 namespace PHPUnitPHAR\SebastianBergmann\CodeUnit;
103726
103727 /**
103728 * @psalm-immutable
103729 */
103730 final class InterfaceMethodUnit extends CodeUnit
103731 {
103732 /**
103733 * @psalm-assert-if-true InterfaceMethod $this
103734 */
103735 public function isInterfaceMethod(): bool
103736 {
103737 return \true;
103738 }
103739 }
103740 <?php
103741
103742 declare (strict_types=1);
103743 /*
103744 * This file is part of sebastian/code-unit.
103745 *
103746 * (c) Sebastian Bergmann <sebastian@phpunit.de>
103747 *
103748 * For the full copyright and license information, please view the LICENSE
103749 * file that was distributed with this source code.
103750 */
103751 namespace PHPUnitPHAR\SebastianBergmann\CodeUnit;
103752
103753 /**
103754 * @psalm-immutable
103755 */
103756 final class InterfaceUnit extends CodeUnit
103757 {
103758 /**
103759 * @psalm-assert-if-true InterfaceUnit $this
103760 */
103761 public function isInterface(): bool
103762 {
103763 return \true;
103764 }
103765 }
103766 BSD 3-Clause License
103767
103768 Copyright (c) 2020-2023, Sebastian Bergmann
103769 All rights reserved.
103770
103771 Redistribution and use in source and binary forms, with or without
103772 modification, are permitted provided that the following conditions are met:
103773
103774 1. Redistributions of source code must retain the above copyright notice, this
103775 list of conditions and the following disclaimer.
103776
103777 2. Redistributions in binary form must reproduce the above copyright notice,
103778 this list of conditions and the following disclaimer in the documentation
103779 and/or other materials provided with the distribution.
103780
103781 3. Neither the name of the copyright holder nor the names of its
103782 contributors may be used to endorse or promote products derived from
103783 this software without specific prior written permission.
103784
103785 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
103786 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
103787 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
103788 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
103789 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
103790 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
103791 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
103792 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
103793 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
103794 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
103795 <?php
103796
103797 declare (strict_types=1);
103798 /*
103799 * This file is part of sebastian/code-unit.
103800 *
103801 * (c) Sebastian Bergmann <sebastian@phpunit.de>
103802 *
103803 * For the full copyright and license information, please view the LICENSE
103804 * file that was distributed with this source code.
103805 */
103806 namespace PHPUnitPHAR\SebastianBergmann\CodeUnit;
103807
103808 use function array_keys;
103809 use function array_merge;
103810 use function array_unique;
103811 use function array_values;
103812 use function class_exists;
103813 use function explode;
103814 use function function_exists;
103815 use function interface_exists;
103816 use function ksort;
103817 use function method_exists;
103818 use function sort;
103819 use function sprintf;
103820 use function str_contains;
103821 use function trait_exists;
103822 use ReflectionClass;
103823 use ReflectionFunction;
103824 use ReflectionMethod;
103825 final class Mapper
103826 {
103827 /**
103828 * @psalm-return array<string,list<int>>
103829 */
103830 public function codeUnitsToSourceLines(CodeUnitCollection $codeUnits): array
103831 {
103832 $result = [];
103833 foreach ($codeUnits as $codeUnit) {
103834 $sourceFileName = $codeUnit->sourceFileName();
103835 if (!isset($result[$sourceFileName])) {
103836 $result[$sourceFileName] = [];
103837 }
103838 $result[$sourceFileName] = array_merge($result[$sourceFileName], $codeUnit->sourceLines());
103839 }
103840 foreach (array_keys($result) as $sourceFileName) {
103841 $result[$sourceFileName] = array_values(array_unique($result[$sourceFileName]));
103842 sort($result[$sourceFileName]);
103843 }
103844 ksort($result);
103845 return $result;
103846 }
103847 /**
103848 * @throws InvalidCodeUnitException
103849 * @throws ReflectionException
103850 */
103851 public function stringToCodeUnits(string $unit): CodeUnitCollection
103852 {
103853 if (str_contains($unit, '::')) {
103854 [$firstPart, $secondPart] = explode('::', $unit);
103855 if ($this->isUserDefinedFunction($secondPart)) {
103856 return CodeUnitCollection::fromList(CodeUnit::forFunction($secondPart));
103857 }
103858 if ($this->isUserDefinedMethod($firstPart, $secondPart)) {
103859 return CodeUnitCollection::fromList(CodeUnit::forClassMethod($firstPart, $secondPart));
103860 }
103861 if ($this->isUserDefinedInterface($firstPart)) {
103862 return CodeUnitCollection::fromList(CodeUnit::forInterfaceMethod($firstPart, $secondPart));
103863 }
103864 if ($this->isUserDefinedTrait($firstPart)) {
103865 return CodeUnitCollection::fromList(CodeUnit::forTraitMethod($firstPart, $secondPart));
103866 }
103867 } else {
103868 if ($this->isUserDefinedClass($unit)) {
103869 $units = [CodeUnit::forClass($unit)];
103870 foreach ($this->reflectorForClass($unit)->getTraits() as $trait) {
103871 if (!$trait->isUserDefined()) {
103872 // @codeCoverageIgnoreStart
103873 continue;
103874 // @codeCoverageIgnoreEnd
103875 }
103876 $units[] = CodeUnit::forTrait($trait->getName());
103877 }
103878 return CodeUnitCollection::fromList(...$units);
103879 }
103880 if ($this->isUserDefinedInterface($unit)) {
103881 return CodeUnitCollection::fromList(CodeUnit::forInterface($unit));
103882 }
103883 if ($this->isUserDefinedTrait($unit)) {
103884 return CodeUnitCollection::fromList(CodeUnit::forTrait($unit));
103885 }
103886 if ($this->isUserDefinedFunction($unit)) {
103887 return CodeUnitCollection::fromList(CodeUnit::forFunction($unit));
103888 }
103889 }
103890 throw new InvalidCodeUnitException(sprintf('"%s" is not a valid code unit', $unit));
103891 }
103892 /**
103893 * @psalm-param class-string $className
103894 *
103895 * @throws ReflectionException
103896 */
103897 private function reflectorForClass(string $className): ReflectionClass
103898 {
103899 try {
103900 return new ReflectionClass($className);
103901 // @codeCoverageIgnoreStart
103902 } catch (\ReflectionException $e) {
103903 throw new ReflectionException($e->getMessage(), $e->getCode(), $e);
103904 }
103905 // @codeCoverageIgnoreEnd
103906 }
103907 /**
103908 * @throws ReflectionException
103909 */
103910 private function isUserDefinedFunction(string $functionName): bool
103911 {
103912 if (!function_exists($functionName)) {
103913 return \false;
103914 }
103915 try {
103916 return (new ReflectionFunction($functionName))->isUserDefined();
103917 // @codeCoverageIgnoreStart
103918 } catch (\ReflectionException $e) {
103919 throw new ReflectionException($e->getMessage(), $e->getCode(), $e);
103920 }
103921 // @codeCoverageIgnoreEnd
103922 }
103923 /**
103924 * @throws ReflectionException
103925 */
103926 private function isUserDefinedClass(string $className): bool
103927 {
103928 if (!class_exists($className)) {
103929 return \false;
103930 }
103931 try {
103932 return (new ReflectionClass($className))->isUserDefined();
103933 // @codeCoverageIgnoreStart
103934 } catch (\ReflectionException $e) {
103935 throw new ReflectionException($e->getMessage(), $e->getCode(), $e);
103936 }
103937 // @codeCoverageIgnoreEnd
103938 }
103939 /**
103940 * @throws ReflectionException
103941 */
103942 private function isUserDefinedInterface(string $interfaceName): bool
103943 {
103944 if (!interface_exists($interfaceName)) {
103945 return \false;
103946 }
103947 try {
103948 return (new ReflectionClass($interfaceName))->isUserDefined();
103949 // @codeCoverageIgnoreStart
103950 } catch (\ReflectionException $e) {
103951 throw new ReflectionException($e->getMessage(), $e->getCode(), $e);
103952 }
103953 // @codeCoverageIgnoreEnd
103954 }
103955 /**
103956 * @throws ReflectionException
103957 */
103958 private function isUserDefinedTrait(string $traitName): bool
103959 {
103960 if (!trait_exists($traitName)) {
103961 return \false;
103962 }
103963 try {
103964 return (new ReflectionClass($traitName))->isUserDefined();
103965 // @codeCoverageIgnoreStart
103966 } catch (\ReflectionException $e) {
103967 throw new ReflectionException($e->getMessage(), $e->getCode(), $e);
103968 }
103969 // @codeCoverageIgnoreEnd
103970 }
103971 /**
103972 * @throws ReflectionException
103973 */
103974 private function isUserDefinedMethod(string $className, string $methodName): bool
103975 {
103976 if (!class_exists($className)) {
103977 // @codeCoverageIgnoreStart
103978 return \false;
103979 // @codeCoverageIgnoreEnd
103980 }
103981 if (!method_exists($className, $methodName)) {
103982 // @codeCoverageIgnoreStart
103983 return \false;
103984 // @codeCoverageIgnoreEnd
103985 }
103986 try {
103987 return (new ReflectionMethod($className, $methodName))->isUserDefined();
103988 // @codeCoverageIgnoreStart
103989 } catch (\ReflectionException $e) {
103990 throw new ReflectionException($e->getMessage(), $e->getCode(), $e);
103991 }
103992 // @codeCoverageIgnoreEnd
103993 }
103994 }
103995 <?php
103996
103997 declare (strict_types=1);
103998 /*
103999 * This file is part of sebastian/code-unit.
104000 *
104001 * (c) Sebastian Bergmann <sebastian@phpunit.de>
104002 *
104003 * For the full copyright and license information, please view the LICENSE
104004 * file that was distributed with this source code.
104005 */
104006 namespace PHPUnitPHAR\SebastianBergmann\CodeUnit;
104007
104008 /**
104009 * @psalm-immutable
104010 */
104011 final class TraitMethodUnit extends CodeUnit
104012 {
104013 /**
104014 * @psalm-assert-if-true TraitMethodUnit $this
104015 */
104016 public function isTraitMethod(): bool
104017 {
104018 return \true;
104019 }
104020 }
104021 <?php
104022
104023 declare (strict_types=1);
104024 /*
104025 * This file is part of sebastian/code-unit.
104026 *
104027 * (c) Sebastian Bergmann <sebastian@phpunit.de>
104028 *
104029 * For the full copyright and license information, please view the LICENSE
104030 * file that was distributed with this source code.
104031 */
104032 namespace PHPUnitPHAR\SebastianBergmann\CodeUnit;
104033
104034 /**
104035 * @psalm-immutable
104036 */
104037 final class TraitUnit extends CodeUnit
104038 {
104039 /**
104040 * @psalm-assert-if-true TraitUnit $this
104041 */
104042 public function isTrait(): bool
104043 {
104044 return \true;
104045 }
104046 }
104047 <?php
104048
104049 declare (strict_types=1);
104050 /*
104051 * This file is part of sebastian/code-unit.
104052 *
104053 * (c) Sebastian Bergmann <sebastian@phpunit.de>
104054 *
104055 * For the full copyright and license information, please view the LICENSE
104056 * file that was distributed with this source code.
104057 */
104058 namespace PHPUnitPHAR\SebastianBergmann\CodeUnit;
104059
104060 use Throwable;
104061 interface Exception extends Throwable
104062 {
104063 }
104064 <?php
104065
104066 declare (strict_types=1);
104067 /*
104068 * This file is part of sebastian/code-unit.
104069 *
104070 * (c) Sebastian Bergmann <sebastian@phpunit.de>
104071 *
104072 * For the full copyright and license information, please view the LICENSE
104073 * file that was distributed with this source code.
104074 */
104075 namespace PHPUnitPHAR\SebastianBergmann\CodeUnit;
104076
104077 use RuntimeException;
104078 final class InvalidCodeUnitException extends RuntimeException implements Exception
104079 {
104080 }
104081 <?php
104082
104083 declare (strict_types=1);
104084 /*
104085 * This file is part of sebastian/code-unit.
104086 *
104087 * (c) Sebastian Bergmann <sebastian@phpunit.de>
104088 *
104089 * For the full copyright and license information, please view the LICENSE
104090 * file that was distributed with this source code.
104091 */
104092 namespace PHPUnitPHAR\SebastianBergmann\CodeUnit;
104093
104094 use RuntimeException;
104095 final class NoTraitException extends RuntimeException implements Exception
104096 {
104097 }
104098 <?php
104099
104100 declare (strict_types=1);
104101 /*
104102 * This file is part of sebastian/code-unit.
104103 *
104104 * (c) Sebastian Bergmann <sebastian@phpunit.de>
104105 *
104106 * For the full copyright and license information, please view the LICENSE
104107 * file that was distributed with this source code.
104108 */
104109 namespace PHPUnitPHAR\SebastianBergmann\CodeUnit;
104110
104111 use RuntimeException;
104112 final class ReflectionException extends RuntimeException implements Exception
104113 {
104114 }
104115 <?php
104116
104117 declare (strict_types=1);
104118 /*
104119 * This file is part of sebastian/comparator.
104120 *
104121 * (c) Sebastian Bergmann <sebastian@phpunit.de>
104122 *
104123 * For the full copyright and license information, please view the LICENSE
104124 * file that was distributed with this source code.
104125 */
104126 namespace PHPUnitPHAR\SebastianBergmann\Comparator;
104127
104128 use function array_key_exists;
104129 use function assert;
104130 use function is_array;
104131 use function sort;
104132 use function sprintf;
104133 use function str_replace;
104134 use function trim;
104135 use PHPUnitPHAR\SebastianBergmann\Exporter\Exporter;
104136 /**
104137 * Arrays are equal if they contain the same key-value pairs.
104138 * The order of the keys does not matter.
104139 * The types of key-value pairs do not matter.
104140 */
104141 class ArrayComparator extends Comparator
104142 {
104143 public function accepts(mixed $expected, mixed $actual): bool
104144 {
104145 return is_array($expected) && is_array($actual);
104146 }
104147 /**
104148 * @throws ComparisonFailure
104149 */
104150 public function assertEquals(mixed $expected, mixed $actual, float $delta = 0.0, bool $canonicalize = \false, bool $ignoreCase = \false, array &$processed = []): void
104151 {
104152 assert(is_array($expected));
104153 assert(is_array($actual));
104154 if ($canonicalize) {
104155 sort($expected);
104156 sort($actual);
104157 }
104158 $remaining = $actual;
104159 $actualAsString = "Array (\n";
104160 $expectedAsString = "Array (\n";
104161 $equal = \true;
104162 $exporter = new Exporter();
104163 foreach ($expected as $key => $value) {
104164 unset($remaining[$key]);
104165 if (!array_key_exists($key, $actual)) {
104166 $expectedAsString .= sprintf(" %s => %s\n", $exporter->export($key), $exporter->shortenedExport($value));
104167 $equal = \false;
104168 continue;
104169 }
104170 try {
104171 $comparator = $this->factory()->getComparatorFor($value, $actual[$key]);
104172 $comparator->assertEquals($value, $actual[$key], $delta, $canonicalize, $ignoreCase, $processed);
104173 $expectedAsString .= sprintf(" %s => %s\n", $exporter->export($key), $exporter->shortenedExport($value));
104174 $actualAsString .= sprintf(" %s => %s\n", $exporter->export($key), $exporter->shortenedExport($actual[$key]));
104175 } catch (ComparisonFailure $e) {
104176 $expectedAsString .= sprintf(" %s => %s\n", $exporter->export($key), $e->getExpectedAsString() ? $this->indent($e->getExpectedAsString()) : $exporter->shortenedExport($e->getExpected()));
104177 $actualAsString .= sprintf(" %s => %s\n", $exporter->export($key), $e->getActualAsString() ? $this->indent($e->getActualAsString()) : $exporter->shortenedExport($e->getActual()));
104178 $equal = \false;
104179 }
104180 }
104181 foreach ($remaining as $key => $value) {
104182 $actualAsString .= sprintf(" %s => %s\n", $exporter->export($key), $exporter->shortenedExport($value));
104183 $equal = \false;
104184 }
104185 $expectedAsString .= ')';
104186 $actualAsString .= ')';
104187 if (!$equal) {
104188 throw new ComparisonFailure($expected, $actual, $expectedAsString, $actualAsString, 'Failed asserting that two arrays are equal.');
104189 }
104190 }
104191 private function indent(string $lines): string
104192 {
104193 return trim(str_replace("\n", "\n ", $lines));
104194 }
104195 }
104196 <?php
104197
104198 declare (strict_types=1);
104199 /*
104200 * This file is part of sebastian/comparator.
104201 *
104202 * (c) Sebastian Bergmann <sebastian@phpunit.de>
104203 *
104204 * For the full copyright and license information, please view the LICENSE
104205 * file that was distributed with this source code.
104206 */
104207 namespace PHPUnitPHAR\SebastianBergmann\Comparator;
104208
104209 abstract class Comparator
104210 {
104211 private Factory $factory;
104212 public function setFactory(Factory $factory): void
104213 {
104214 $this->factory = $factory;
104215 }
104216 abstract public function accepts(mixed $expected, mixed $actual): bool;
104217 /**
104218 * @throws ComparisonFailure
104219 */
104220 abstract public function assertEquals(mixed $expected, mixed $actual, float $delta = 0.0, bool $canonicalize = \false, bool $ignoreCase = \false): void;
104221 protected function factory(): Factory
104222 {
104223 return $this->factory;
104224 }
104225 }
104226 <?php
104227
104228 declare (strict_types=1);
104229 /*
104230 * This file is part of sebastian/comparator.
104231 *
104232 * (c) Sebastian Bergmann <sebastian@phpunit.de>
104233 *
104234 * For the full copyright and license information, please view the LICENSE
104235 * file that was distributed with this source code.
104236 */
104237 namespace PHPUnitPHAR\SebastianBergmann\Comparator;
104238
104239 use RuntimeException;
104240 use PHPUnitPHAR\SebastianBergmann\Diff\Differ;
104241 use PHPUnitPHAR\SebastianBergmann\Diff\Output\UnifiedDiffOutputBuilder;
104242 final class ComparisonFailure extends RuntimeException
104243 {
104244 private mixed $expected;
104245 private mixed $actual;
104246 private string $expectedAsString;
104247 private string $actualAsString;
104248 public function __construct(mixed $expected, mixed $actual, string $expectedAsString, string $actualAsString, string $message = '')
104249 {
104250 parent::__construct($message);
104251 $this->expected = $expected;
104252 $this->actual = $actual;
104253 $this->expectedAsString = $expectedAsString;
104254 $this->actualAsString = $actualAsString;
104255 }
104256 public function getActual(): mixed
104257 {
104258 return $this->actual;
104259 }
104260 public function getExpected(): mixed
104261 {
104262 return $this->expected;
104263 }
104264 public function getActualAsString(): string
104265 {
104266 return $this->actualAsString;
104267 }
104268 public function getExpectedAsString(): string
104269 {
104270 return $this->expectedAsString;
104271 }
104272 public function getDiff(): string
104273 {
104274 if (!$this->actualAsString && !$this->expectedAsString) {
104275 return '';
104276 }
104277 $differ = new Differ(new UnifiedDiffOutputBuilder("\n--- Expected\n+++ Actual\n"));
104278 return $differ->diff($this->expectedAsString, $this->actualAsString);
104279 }
104280 public function toString(): string
104281 {
104282 return $this->getMessage() . $this->getDiff();
104283 }
104284 }
104285 <?php
104286
104287 declare (strict_types=1);
104288 /*
104289 * This file is part of sebastian/comparator.
104290 *
104291 * (c) Sebastian Bergmann <sebastian@phpunit.de>
104292 *
104293 * For the full copyright and license information, please view the LICENSE
104294 * file that was distributed with this source code.
104295 */
104296 namespace PHPUnitPHAR\SebastianBergmann\Comparator;
104297
104298 use function assert;
104299 use function mb_strtolower;
104300 use function sprintf;
104301 use DOMDocument;
104302 use DOMNode;
104303 use ValueError;
104304 final class DOMNodeComparator extends ObjectComparator
104305 {
104306 public function accepts(mixed $expected, mixed $actual): bool
104307 {
104308 return $expected instanceof DOMNode && $actual instanceof DOMNode;
104309 }
104310 /**
104311 * @throws ComparisonFailure
104312 */
104313 public function assertEquals(mixed $expected, mixed $actual, float $delta = 0.0, bool $canonicalize = \false, bool $ignoreCase = \false, array &$processed = []): void
104314 {
104315 assert($expected instanceof DOMNode);
104316 assert($actual instanceof DOMNode);
104317 $expectedAsString = $this->nodeToText($expected, \true, $ignoreCase);
104318 $actualAsString = $this->nodeToText($actual, \true, $ignoreCase);
104319 if ($expectedAsString !== $actualAsString) {
104320 $type = $expected instanceof DOMDocument ? 'documents' : 'nodes';
104321 throw new ComparisonFailure($expected, $actual, $expectedAsString, $actualAsString, sprintf("Failed asserting that two DOM %s are equal.\n", $type));
104322 }
104323 }
104324 /**
104325 * Returns the normalized, whitespace-cleaned, and indented textual
104326 * representation of a DOMNode.
104327 */
104328 private function nodeToText(DOMNode $node, bool $canonicalize, bool $ignoreCase): string
104329 {
104330 if ($canonicalize) {
104331 $document = new DOMDocument();
104332 try {
104333 $c14n = $node->C14N();
104334 assert(!empty($c14n));
104335 @$document->loadXML($c14n);
104336 } catch (ValueError) {
104337 }
104338 $node = $document;
104339 }
104340 $document = $node instanceof DOMDocument ? $node : $node->ownerDocument;
104341 $document->formatOutput = \true;
104342 $document->normalizeDocument();
104343 $text = $node instanceof DOMDocument ? $node->saveXML() : $document->saveXML($node);
104344 return $ignoreCase ? mb_strtolower($text, 'UTF-8') : $text;
104345 }
104346 }
104347 <?php
104348
104349 declare (strict_types=1);
104350 /*
104351 * This file is part of sebastian/comparator.
104352 *
104353 * (c) Sebastian Bergmann <sebastian@phpunit.de>
104354 *
104355 * For the full copyright and license information, please view the LICENSE
104356 * file that was distributed with this source code.
104357 */
104358 namespace PHPUnitPHAR\SebastianBergmann\Comparator;
104359
104360 use function abs;
104361 use function assert;
104362 use function floor;
104363 use function sprintf;
104364 use DateInterval;
104365 use DateTimeInterface;
104366 use DateTimeZone;
104367 final class DateTimeComparator extends ObjectComparator
104368 {
104369 public function accepts(mixed $expected, mixed $actual): bool
104370 {
104371 return $expected instanceof DateTimeInterface && $actual instanceof DateTimeInterface;
104372 }
104373 /**
104374 * @throws ComparisonFailure
104375 */
104376 public function assertEquals(mixed $expected, mixed $actual, float $delta = 0.0, bool $canonicalize = \false, bool $ignoreCase = \false, array &$processed = []): void
104377 {
104378 assert($expected instanceof DateTimeInterface);
104379 assert($actual instanceof DateTimeInterface);
104380 $absDelta = abs($delta);
104381 $delta = new DateInterval(sprintf('PT%dS', $absDelta));
104382 $delta->f = $absDelta - floor($absDelta);
104383 $actualClone = (clone $actual)->setTimezone(new DateTimeZone('UTC'));
104384 $expectedLower = (clone $expected)->setTimezone(new DateTimeZone('UTC'))->sub($delta);
104385 $expectedUpper = (clone $expected)->setTimezone(new DateTimeZone('UTC'))->add($delta);
104386 if ($actualClone < $expectedLower || $actualClone > $expectedUpper) {
104387 throw new ComparisonFailure($expected, $actual, $this->dateTimeToString($expected), $this->dateTimeToString($actual), 'Failed asserting that two DateTime objects are equal.');
104388 }
104389 }
104390 /**
104391 * Returns an ISO 8601 formatted string representation of a datetime or
104392 * 'Invalid DateTimeInterface object' if the provided DateTimeInterface was not properly
104393 * initialized.
104394 */
104395 private function dateTimeToString(DateTimeInterface $datetime): string
104396 {
104397 $string = $datetime->format('Y-m-d\TH:i:s.uO');
104398 return $string ?: 'Invalid DateTimeInterface object';
104399 }
104400 }
104401 <?php
104402
104403 declare (strict_types=1);
104404 /*
104405 * This file is part of sebastian/comparator.
104406 *
104407 * (c) Sebastian Bergmann <sebastian@phpunit.de>
104408 *
104409 * For the full copyright and license information, please view the LICENSE
104410 * file that was distributed with this source code.
104411 */
104412 namespace PHPUnitPHAR\SebastianBergmann\Comparator;
104413
104414 use function assert;
104415 use Exception;
104416 /**
104417 * Compares Exception instances for equality.
104418 */
104419 final class ExceptionComparator extends ObjectComparator
104420 {
104421 public function accepts(mixed $expected, mixed $actual): bool
104422 {
104423 return $expected instanceof Exception && $actual instanceof Exception;
104424 }
104425 protected function toArray(object $object): array
104426 {
104427 assert($object instanceof Exception);
104428 $array = parent::toArray($object);
104429 unset($array['file'], $array['line'], $array['trace'], $array['string'], $array['xdebug_message']);
104430 return $array;
104431 }
104432 }
104433 <?php
104434
104435 declare (strict_types=1);
104436 /*
104437 * This file is part of sebastian/comparator.
104438 *
104439 * (c) Sebastian Bergmann <sebastian@phpunit.de>
104440 *
104441 * For the full copyright and license information, please view the LICENSE
104442 * file that was distributed with this source code.
104443 */
104444 namespace PHPUnitPHAR\SebastianBergmann\Comparator;
104445
104446 use function array_unshift;
104447 final class Factory
104448 {
104449 private static ?Factory $instance = null;
104450 /**
104451 * @psalm-var list<Comparator>
104452 */
104453 private array $customComparators = [];
104454 /**
104455 * @psalm-var list<Comparator>
104456 */
104457 private array $defaultComparators = [];
104458 public static function getInstance(): self
104459 {
104460 if (self::$instance === null) {
104461 self::$instance = new self();
104462 // @codeCoverageIgnore
104463 }
104464 return self::$instance;
104465 }
104466 public function __construct()
104467 {
104468 $this->registerDefaultComparators();
104469 }
104470 public function getComparatorFor(mixed $expected, mixed $actual): Comparator
104471 {
104472 foreach ($this->customComparators as $comparator) {
104473 if ($comparator->accepts($expected, $actual)) {
104474 return $comparator;
104475 }
104476 }
104477 foreach ($this->defaultComparators as $comparator) {
104478 if ($comparator->accepts($expected, $actual)) {
104479 return $comparator;
104480 }
104481 }
104482 throw new RuntimeException('No suitable Comparator implementation found');
104483 }
104484 /**
104485 * Registers a new comparator.
104486 *
104487 * This comparator will be returned by getComparatorFor() if its accept() method
104488 * returns TRUE for the compared values. It has higher priority than the
104489 * existing comparators, meaning that its accept() method will be invoked
104490 * before those of the other comparators.
104491 */
104492 public function register(Comparator $comparator): void
104493 {
104494 array_unshift($this->customComparators, $comparator);
104495 $comparator->setFactory($this);
104496 }
104497 /**
104498 * Unregisters a comparator.
104499 *
104500 * This comparator will no longer be considered by getComparatorFor().
104501 */
104502 public function unregister(Comparator $comparator): void
104503 {
104504 foreach ($this->customComparators as $key => $_comparator) {
104505 if ($comparator === $_comparator) {
104506 unset($this->customComparators[$key]);
104507 }
104508 }
104509 }
104510 public function reset(): void
104511 {
104512 $this->customComparators = [];
104513 }
104514 private function registerDefaultComparators(): void
104515 {
104516 $this->registerDefaultComparator(new MockObjectComparator());
104517 $this->registerDefaultComparator(new DateTimeComparator());
104518 $this->registerDefaultComparator(new DOMNodeComparator());
104519 $this->registerDefaultComparator(new SplObjectStorageComparator());
104520 $this->registerDefaultComparator(new ExceptionComparator());
104521 $this->registerDefaultComparator(new ObjectComparator());
104522 $this->registerDefaultComparator(new ResourceComparator());
104523 $this->registerDefaultComparator(new ArrayComparator());
104524 $this->registerDefaultComparator(new NumericComparator());
104525 $this->registerDefaultComparator(new ScalarComparator());
104526 $this->registerDefaultComparator(new TypeComparator());
104527 }
104528 private function registerDefaultComparator(Comparator $comparator): void
104529 {
104530 $this->defaultComparators[] = $comparator;
104531 $comparator->setFactory($this);
104532 }
104533 }
104534 BSD 3-Clause License
104535
104536 Copyright (c) 2002-2025, Sebastian Bergmann
104537 All rights reserved.
104538
104539 Redistribution and use in source and binary forms, with or without
104540 modification, are permitted provided that the following conditions are met:
104541
104542 1. Redistributions of source code must retain the above copyright notice, this
104543 list of conditions and the following disclaimer.
104544
104545 2. Redistributions in binary form must reproduce the above copyright notice,
104546 this list of conditions and the following disclaimer in the documentation
104547 and/or other materials provided with the distribution.
104548
104549 3. Neither the name of the copyright holder nor the names of its
104550 contributors may be used to endorse or promote products derived from
104551 this software without specific prior written permission.
104552
104553 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
104554 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
104555 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
104556 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
104557 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
104558 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
104559 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
104560 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
104561 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
104562 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
104563 <?php
104564
104565 declare (strict_types=1);
104566 /*
104567 * This file is part of sebastian/comparator.
104568 *
104569 * (c) Sebastian Bergmann <sebastian@phpunit.de>
104570 *
104571 * For the full copyright and license information, please view the LICENSE
104572 * file that was distributed with this source code.
104573 */
104574 namespace PHPUnitPHAR\SebastianBergmann\Comparator;
104575
104576 use function array_keys;
104577 use function assert;
104578 use function str_starts_with;
104579 use PHPUnit\Framework\MockObject\Stub;
104580 /**
104581 * Compares PHPUnit\Framework\MockObject\MockObject instances for equality.
104582 */
104583 final class MockObjectComparator extends ObjectComparator
104584 {
104585 public function accepts(mixed $expected, mixed $actual): bool
104586 {
104587 return $expected instanceof Stub && $actual instanceof Stub;
104588 }
104589 protected function toArray(object $object): array
104590 {
104591 assert($object instanceof Stub);
104592 $array = parent::toArray($object);
104593 foreach (array_keys($array) as $key) {
104594 if (!str_starts_with($key, '__phpunit_')) {
104595 continue;
104596 }
104597 unset($array[$key]);
104598 }
104599 return $array;
104600 }
104601 }
104602 <?php
104603
104604 declare (strict_types=1);
104605 /*
104606 * This file is part of sebastian/comparator.
104607 *
104608 * (c) Sebastian Bergmann <sebastian@phpunit.de>
104609 *
104610 * For the full copyright and license information, please view the LICENSE
104611 * file that was distributed with this source code.
104612 */
104613 namespace PHPUnitPHAR\SebastianBergmann\Comparator;
104614
104615 use function abs;
104616 use function is_float;
104617 use function is_infinite;
104618 use function is_nan;
104619 use function is_numeric;
104620 use function is_string;
104621 use function sprintf;
104622 use PHPUnitPHAR\SebastianBergmann\Exporter\Exporter;
104623 final class NumericComparator extends ScalarComparator
104624 {
104625 public function accepts(mixed $expected, mixed $actual): bool
104626 {
104627 // all numerical values, but not if both of them are strings
104628 return is_numeric($expected) && is_numeric($actual) && !(is_string($expected) && is_string($actual));
104629 }
104630 /**
104631 * @throws ComparisonFailure
104632 */
104633 public function assertEquals(mixed $expected, mixed $actual, float $delta = 0.0, bool $canonicalize = \false, bool $ignoreCase = \false): void
104634 {
104635 if ($this->isInfinite($actual) && $this->isInfinite($expected)) {
104636 return;
104637 }
104638 if (($this->isInfinite($actual) xor $this->isInfinite($expected)) || ($this->isNan($actual) || $this->isNan($expected)) || abs($actual - $expected) > $delta) {
104639 $exporter = new Exporter();
104640 throw new ComparisonFailure($expected, $actual, '', '', sprintf('Failed asserting that %s matches expected %s.', $exporter->export($actual), $exporter->export($expected)));
104641 }
104642 }
104643 private function isInfinite(mixed $value): bool
104644 {
104645 return is_float($value) && is_infinite($value);
104646 }
104647 private function isNan(mixed $value): bool
104648 {
104649 return is_float($value) && is_nan($value);
104650 }
104651 }
104652 <?php
104653
104654 declare (strict_types=1);
104655 /*
104656 * This file is part of sebastian/comparator.
104657 *
104658 * (c) Sebastian Bergmann <sebastian@phpunit.de>
104659 *
104660 * For the full copyright and license information, please view the LICENSE
104661 * file that was distributed with this source code.
104662 */
104663 namespace PHPUnitPHAR\SebastianBergmann\Comparator;
104664
104665 use function assert;
104666 use function in_array;
104667 use function is_object;
104668 use function sprintf;
104669 use function substr_replace;
104670 use PHPUnitPHAR\SebastianBergmann\Exporter\Exporter;
104671 class ObjectComparator extends ArrayComparator
104672 {
104673 public function accepts(mixed $expected, mixed $actual): bool
104674 {
104675 return is_object($expected) && is_object($actual);
104676 }
104677 /**
104678 * @throws ComparisonFailure
104679 */
104680 public function assertEquals(mixed $expected, mixed $actual, float $delta = 0.0, bool $canonicalize = \false, bool $ignoreCase = \false, array &$processed = []): void
104681 {
104682 assert(is_object($expected));
104683 assert(is_object($actual));
104684 if ($actual::class !== $expected::class) {
104685 $exporter = new Exporter();
104686 throw new ComparisonFailure($expected, $actual, $exporter->export($expected), $exporter->export($actual), sprintf('%s is not instance of expected class "%s".', $exporter->export($actual), $expected::class));
104687 }
104688 // don't compare twice to allow for cyclic dependencies
104689 if (in_array([$actual, $expected], $processed, \true) || in_array([$expected, $actual], $processed, \true)) {
104690 return;
104691 }
104692 $processed[] = [$actual, $expected];
104693 // don't compare objects if they are identical
104694 // this helps to avoid the error "maximum function nesting level reached"
104695 // CAUTION: this conditional clause is not tested
104696 if ($actual !== $expected) {
104697 try {
104698 parent::assertEquals($this->toArray($expected), $this->toArray($actual), $delta, $canonicalize, $ignoreCase, $processed);
104699 } catch (ComparisonFailure $e) {
104700 throw new ComparisonFailure(
104701 $expected,
104702 $actual,
104703 // replace "Array" with "MyClass object"
104704 substr_replace($e->getExpectedAsString(), $expected::class . ' Object', 0, 5),
104705 substr_replace($e->getActualAsString(), $actual::class . ' Object', 0, 5),
104706 'Failed asserting that two objects are equal.'
104707 );
104708 }
104709 }
104710 }
104711 protected function toArray(object $object): array
104712 {
104713 return (new Exporter())->toArray($object);
104714 }
104715 }
104716 <?php
104717
104718 declare (strict_types=1);
104719 /*
104720 * This file is part of sebastian/comparator.
104721 *
104722 * (c) Sebastian Bergmann <sebastian@phpunit.de>
104723 *
104724 * For the full copyright and license information, please view the LICENSE
104725 * file that was distributed with this source code.
104726 */
104727 namespace PHPUnitPHAR\SebastianBergmann\Comparator;
104728
104729 use function assert;
104730 use function is_resource;
104731 use PHPUnitPHAR\SebastianBergmann\Exporter\Exporter;
104732 final class ResourceComparator extends Comparator
104733 {
104734 public function accepts(mixed $expected, mixed $actual): bool
104735 {
104736 return is_resource($expected) && is_resource($actual);
104737 }
104738 /**
104739 * @throws ComparisonFailure
104740 */
104741 public function assertEquals(mixed $expected, mixed $actual, float $delta = 0.0, bool $canonicalize = \false, bool $ignoreCase = \false): void
104742 {
104743 assert(is_resource($expected));
104744 assert(is_resource($actual));
104745 $exporter = new Exporter();
104746 if ($actual != $expected) {
104747 throw new ComparisonFailure($expected, $actual, $exporter->export($expected), $exporter->export($actual));
104748 }
104749 }
104750 }
104751 <?php
104752
104753 declare (strict_types=1);
104754 /*
104755 * This file is part of sebastian/comparator.
104756 *
104757 * (c) Sebastian Bergmann <sebastian@phpunit.de>
104758 *
104759 * For the full copyright and license information, please view the LICENSE
104760 * file that was distributed with this source code.
104761 */
104762 namespace PHPUnitPHAR\SebastianBergmann\Comparator;
104763
104764 use function is_bool;
104765 use function is_object;
104766 use function is_scalar;
104767 use function is_string;
104768 use function mb_strtolower;
104769 use function method_exists;
104770 use function sprintf;
104771 use PHPUnitPHAR\SebastianBergmann\Exporter\Exporter;
104772 /**
104773 * Compares scalar or NULL values for equality.
104774 */
104775 class ScalarComparator extends Comparator
104776 {
104777 public function accepts(mixed $expected, mixed $actual): bool
104778 {
104779 return (is_scalar($expected) xor null === $expected) && (is_scalar($actual) xor null === $actual) || is_string($expected) && is_object($actual) && method_exists($actual, '__toString') || is_object($expected) && method_exists($expected, '__toString') && is_string($actual);
104780 }
104781 /**
104782 * @throws ComparisonFailure
104783 */
104784 public function assertEquals(mixed $expected, mixed $actual, float $delta = 0.0, bool $canonicalize = \false, bool $ignoreCase = \false): void
104785 {
104786 $expectedToCompare = $expected;
104787 $actualToCompare = $actual;
104788 $exporter = new Exporter();
104789 // always compare as strings to avoid strange behaviour
104790 // otherwise 0 == 'Foobar'
104791 if (is_string($expected) && !is_bool($actual) || is_string($actual) && !is_bool($expected)) {
104792 $expectedToCompare = @(string) $expectedToCompare;
104793 $actualToCompare = @(string) $actualToCompare;
104794 if ($ignoreCase) {
104795 $expectedToCompare = mb_strtolower($expectedToCompare, 'UTF-8');
104796 $actualToCompare = mb_strtolower($actualToCompare, 'UTF-8');
104797 }
104798 }
104799 if ($expectedToCompare !== $actualToCompare && is_string($expected) && is_string($actual)) {
104800 throw new ComparisonFailure($expected, $actual, $exporter->export($expected), $exporter->export($actual), 'Failed asserting that two strings are equal.');
104801 }
104802 if ($expectedToCompare != $actualToCompare) {
104803 throw new ComparisonFailure(
104804 $expected,
104805 $actual,
104806 // no diff is required
104807 '',
104808 '',
104809 sprintf('Failed asserting that %s matches expected %s.', $exporter->export($actual), $exporter->export($expected))
104810 );
104811 }
104812 }
104813 }
104814 <?php
104815
104816 declare (strict_types=1);
104817 /*
104818 * This file is part of sebastian/comparator.
104819 *
104820 * (c) Sebastian Bergmann <sebastian@phpunit.de>
104821 *
104822 * For the full copyright and license information, please view the LICENSE
104823 * file that was distributed with this source code.
104824 */
104825 namespace PHPUnitPHAR\SebastianBergmann\Comparator;
104826
104827 use function assert;
104828 use PHPUnitPHAR\SebastianBergmann\Exporter\Exporter;
104829 use SplObjectStorage;
104830 final class SplObjectStorageComparator extends Comparator
104831 {
104832 public function accepts(mixed $expected, mixed $actual): bool
104833 {
104834 return $expected instanceof SplObjectStorage && $actual instanceof SplObjectStorage;
104835 }
104836 /**
104837 * @throws ComparisonFailure
104838 */
104839 public function assertEquals(mixed $expected, mixed $actual, float $delta = 0.0, bool $canonicalize = \false, bool $ignoreCase = \false): void
104840 {
104841 assert($expected instanceof SplObjectStorage);
104842 assert($actual instanceof SplObjectStorage);
104843 $exporter = new Exporter();
104844 foreach ($actual as $object) {
104845 if (!$expected->offsetExists($object)) {
104846 throw new ComparisonFailure($expected, $actual, $exporter->export($expected), $exporter->export($actual), 'Failed asserting that two objects are equal.');
104847 }
104848 }
104849 foreach ($expected as $object) {
104850 if (!$actual->offsetExists($object)) {
104851 throw new ComparisonFailure($expected, $actual, $exporter->export($expected), $exporter->export($actual), 'Failed asserting that two objects are equal.');
104852 }
104853 }
104854 }
104855 }
104856 <?php
104857
104858 declare (strict_types=1);
104859 /*
104860 * This file is part of sebastian/comparator.
104861 *
104862 * (c) Sebastian Bergmann <sebastian@phpunit.de>
104863 *
104864 * For the full copyright and license information, please view the LICENSE
104865 * file that was distributed with this source code.
104866 */
104867 namespace PHPUnitPHAR\SebastianBergmann\Comparator;
104868
104869 use function gettype;
104870 use function sprintf;
104871 use PHPUnitPHAR\SebastianBergmann\Exporter\Exporter;
104872 final class TypeComparator extends Comparator
104873 {
104874 public function accepts(mixed $expected, mixed $actual): bool
104875 {
104876 return \true;
104877 }
104878 /**
104879 * @throws ComparisonFailure
104880 */
104881 public function assertEquals(mixed $expected, mixed $actual, float $delta = 0.0, bool $canonicalize = \false, bool $ignoreCase = \false): void
104882 {
104883 if (gettype($expected) != gettype($actual)) {
104884 throw new ComparisonFailure(
104885 $expected,
104886 $actual,
104887 // we don't need a diff
104888 '',
104889 '',
104890 sprintf('%s does not match expected type "%s".', (new Exporter())->shortenedExport($actual), gettype($expected))
104891 );
104892 }
104893 }
104894 }
104895 <?php
104896
104897 declare (strict_types=1);
104898 /*
104899 * This file is part of sebastian/comparator.
104900 *
104901 * (c) Sebastian Bergmann <sebastian@phpunit.de>
104902 *
104903 * For the full copyright and license information, please view the LICENSE
104904 * file that was distributed with this source code.
104905 */
104906 namespace PHPUnitPHAR\SebastianBergmann\Comparator;
104907
104908 use Throwable;
104909 interface Exception extends Throwable
104910 {
104911 }
104912 <?php
104913
104914 declare (strict_types=1);
104915 /*
104916 * This file is part of sebastian/comparator.
104917 *
104918 * (c) Sebastian Bergmann <sebastian@phpunit.de>
104919 *
104920 * For the full copyright and license information, please view the LICENSE
104921 * file that was distributed with this source code.
104922 */
104923 namespace PHPUnitPHAR\SebastianBergmann\Comparator;
104924
104925 final class RuntimeException extends \RuntimeException implements Exception
104926 {
104927 }
104928 <?php
104929
104930 declare (strict_types=1);
104931 /*
104932 * This file is part of sebastian/complexity.
104933 *
104934 * (c) Sebastian Bergmann <sebastian@phpunit.de>
104935 *
104936 * For the full copyright and license information, please view the LICENSE
104937 * file that was distributed with this source code.
104938 */
104939 namespace PHPUnitPHAR\SebastianBergmann\Complexity;
104940
104941 use function assert;
104942 use function file_get_contents;
104943 use PHPUnitPHAR\PhpParser\Error;
104944 use PHPUnitPHAR\PhpParser\Node;
104945 use PHPUnitPHAR\PhpParser\NodeTraverser;
104946 use PHPUnitPHAR\PhpParser\NodeVisitor\NameResolver;
104947 use PHPUnitPHAR\PhpParser\NodeVisitor\ParentConnectingVisitor;
104948 use PHPUnitPHAR\PhpParser\ParserFactory;
104949 final class Calculator
104950 {
104951 /**
104952 * @throws RuntimeException
104953 */
104954 public function calculateForSourceFile(string $sourceFile): ComplexityCollection
104955 {
104956 return $this->calculateForSourceString(file_get_contents($sourceFile));
104957 }
104958 /**
104959 * @throws RuntimeException
104960 */
104961 public function calculateForSourceString(string $source): ComplexityCollection
104962 {
104963 try {
104964 $nodes = (new ParserFactory())->createForHostVersion()->parse($source);
104965 assert($nodes !== null);
104966 return $this->calculateForAbstractSyntaxTree($nodes);
104967 // @codeCoverageIgnoreStart
104968 } catch (Error $error) {
104969 throw new RuntimeException($error->getMessage(), $error->getCode(), $error);
104970 }
104971 // @codeCoverageIgnoreEnd
104972 }
104973 /**
104974 * @param Node[] $nodes
104975 *
104976 * @throws RuntimeException
104977 */
104978 public function calculateForAbstractSyntaxTree(array $nodes): ComplexityCollection
104979 {
104980 $traverser = new NodeTraverser();
104981 $complexityCalculatingVisitor = new ComplexityCalculatingVisitor(\true);
104982 $traverser->addVisitor(new NameResolver());
104983 $traverser->addVisitor(new ParentConnectingVisitor());
104984 $traverser->addVisitor($complexityCalculatingVisitor);
104985 try {
104986 /* @noinspection UnusedFunctionResultInspection */
104987 $traverser->traverse($nodes);
104988 // @codeCoverageIgnoreStart
104989 } catch (Error $error) {
104990 throw new RuntimeException($error->getMessage(), $error->getCode(), $error);
104991 }
104992 // @codeCoverageIgnoreEnd
104993 return $complexityCalculatingVisitor->result();
104994 }
104995 }
104996 <?php
104997
104998 declare (strict_types=1);
104999 /*
105000 * This file is part of sebastian/complexity.
105001 *
105002 * (c) Sebastian Bergmann <sebastian@phpunit.de>
105003 *
105004 * For the full copyright and license information, please view the LICENSE
105005 * file that was distributed with this source code.
105006 */
105007 namespace PHPUnitPHAR\SebastianBergmann\Complexity;
105008
105009 use function str_contains;
105010 /**
105011 * @psalm-immutable
105012 */
105013 final class Complexity
105014 {
105015 /**
105016 * @psalm-var non-empty-string
105017 */
105018 private readonly string $name;
105019 /**
105020 * @psalm-var positive-int
105021 */
105022 private int $cyclomaticComplexity;
105023 /**
105024 * @psalm-param non-empty-string $name
105025 * @psalm-param positive-int $cyclomaticComplexity
105026 */
105027 public function __construct(string $name, int $cyclomaticComplexity)
105028 {
105029 $this->name = $name;
105030 $this->cyclomaticComplexity = $cyclomaticComplexity;
105031 }
105032 /**
105033 * @psalm-return non-empty-string
105034 */
105035 public function name(): string
105036 {
105037 return $this->name;
105038 }
105039 /**
105040 * @psalm-return positive-int
105041 */
105042 public function cyclomaticComplexity(): int
105043 {
105044 return $this->cyclomaticComplexity;
105045 }
105046 public function isFunction(): bool
105047 {
105048 return !$this->isMethod();
105049 }
105050 public function isMethod(): bool
105051 {
105052 return str_contains($this->name, '::');
105053 }
105054 }
105055 <?php
105056
105057 declare (strict_types=1);
105058 /*
105059 * This file is part of sebastian/complexity.
105060 *
105061 * (c) Sebastian Bergmann <sebastian@phpunit.de>
105062 *
105063 * For the full copyright and license information, please view the LICENSE
105064 * file that was distributed with this source code.
105065 */
105066 namespace PHPUnitPHAR\SebastianBergmann\Complexity;
105067
105068 use function array_filter;
105069 use function array_merge;
105070 use function array_reverse;
105071 use function array_values;
105072 use function count;
105073 use function usort;
105074 use Countable;
105075 use IteratorAggregate;
105076 /**
105077 * @psalm-immutable
105078 */
105079 final class ComplexityCollection implements Countable, IteratorAggregate
105080 {
105081 /**
105082 * @psalm-var list<Complexity>
105083 */
105084 private readonly array $items;
105085 public static function fromList(Complexity ...$items): self
105086 {
105087 return new self($items);
105088 }
105089 /**
105090 * @psalm-param list<Complexity> $items
105091 */
105092 private function __construct(array $items)
105093 {
105094 $this->items = $items;
105095 }
105096 /**
105097 * @psalm-return list<Complexity>
105098 */
105099 public function asArray(): array
105100 {
105101 return $this->items;
105102 }
105103 public function getIterator(): ComplexityCollectionIterator
105104 {
105105 return new ComplexityCollectionIterator($this);
105106 }
105107 /**
105108 * @psalm-return non-negative-int
105109 */
105110 public function count(): int
105111 {
105112 return count($this->items);
105113 }
105114 public function isEmpty(): bool
105115 {
105116 return empty($this->items);
105117 }
105118 /**
105119 * @psalm-return non-negative-int
105120 */
105121 public function cyclomaticComplexity(): int
105122 {
105123 $cyclomaticComplexity = 0;
105124 foreach ($this as $item) {
105125 $cyclomaticComplexity += $item->cyclomaticComplexity();
105126 }
105127 return $cyclomaticComplexity;
105128 }
105129 public function isFunction(): self
105130 {
105131 return new self(array_values(array_filter($this->items, static fn(Complexity $complexity): bool => $complexity->isFunction())));
105132 }
105133 public function isMethod(): self
105134 {
105135 return new self(array_values(array_filter($this->items, static fn(Complexity $complexity): bool => $complexity->isMethod())));
105136 }
105137 public function mergeWith(self $other): self
105138 {
105139 return new self(array_merge($this->asArray(), $other->asArray()));
105140 }
105141 public function sortByDescendingCyclomaticComplexity(): self
105142 {
105143 $items = $this->items;
105144 usort($items, static function (Complexity $a, Complexity $b): int {
105145 return $a->cyclomaticComplexity() <=> $b->cyclomaticComplexity();
105146 });
105147 return new self(array_reverse($items));
105148 }
105149 }
105150 <?php
105151
105152 declare (strict_types=1);
105153 /*
105154 * This file is part of sebastian/complexity.
105155 *
105156 * (c) Sebastian Bergmann <sebastian@phpunit.de>
105157 *
105158 * For the full copyright and license information, please view the LICENSE
105159 * file that was distributed with this source code.
105160 */
105161 namespace PHPUnitPHAR\SebastianBergmann\Complexity;
105162
105163 use Iterator;
105164 final class ComplexityCollectionIterator implements Iterator
105165 {
105166 /**
105167 * @psalm-var list<Complexity>
105168 */
105169 private readonly array $items;
105170 private int $position = 0;
105171 public function __construct(ComplexityCollection $items)
105172 {
105173 $this->items = $items->asArray();
105174 }
105175 public function rewind(): void
105176 {
105177 $this->position = 0;
105178 }
105179 public function valid(): bool
105180 {
105181 return isset($this->items[$this->position]);
105182 }
105183 public function key(): int
105184 {
105185 return $this->position;
105186 }
105187 public function current(): Complexity
105188 {
105189 return $this->items[$this->position];
105190 }
105191 public function next(): void
105192 {
105193 $this->position++;
105194 }
105195 }
105196 <?php
105197
105198 declare (strict_types=1);
105199 /*
105200 * This file is part of sebastian/complexity.
105201 *
105202 * (c) Sebastian Bergmann <sebastian@phpunit.de>
105203 *
105204 * For the full copyright and license information, please view the LICENSE
105205 * file that was distributed with this source code.
105206 */
105207 namespace PHPUnitPHAR\SebastianBergmann\Complexity;
105208
105209 use Throwable;
105210 interface Exception extends Throwable
105211 {
105212 }
105213 <?php
105214
105215 declare (strict_types=1);
105216 /*
105217 * This file is part of sebastian/complexity.
105218 *
105219 * (c) Sebastian Bergmann <sebastian@phpunit.de>
105220 *
105221 * For the full copyright and license information, please view the LICENSE
105222 * file that was distributed with this source code.
105223 */
105224 namespace PHPUnitPHAR\SebastianBergmann\Complexity;
105225
105226 final class RuntimeException extends \RuntimeException implements Exception
105227 {
105228 }
105229 BSD 3-Clause License
105230
105231 Copyright (c) 2020-2023, Sebastian Bergmann
105232 All rights reserved.
105233
105234 Redistribution and use in source and binary forms, with or without
105235 modification, are permitted provided that the following conditions are met:
105236
105237 1. Redistributions of source code must retain the above copyright notice, this
105238 list of conditions and the following disclaimer.
105239
105240 2. Redistributions in binary form must reproduce the above copyright notice,
105241 this list of conditions and the following disclaimer in the documentation
105242 and/or other materials provided with the distribution.
105243
105244 3. Neither the name of the copyright holder nor the names of its
105245 contributors may be used to endorse or promote products derived from
105246 this software without specific prior written permission.
105247
105248 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
105249 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
105250 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
105251 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
105252 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
105253 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
105254 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
105255 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
105256 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
105257 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
105258 <?php
105259
105260 declare (strict_types=1);
105261 /*
105262 * This file is part of sebastian/complexity.
105263 *
105264 * (c) Sebastian Bergmann <sebastian@phpunit.de>
105265 *
105266 * For the full copyright and license information, please view the LICENSE
105267 * file that was distributed with this source code.
105268 */
105269 namespace PHPUnitPHAR\SebastianBergmann\Complexity;
105270
105271 use function assert;
105272 use function is_array;
105273 use PHPUnitPHAR\PhpParser\Node;
105274 use PHPUnitPHAR\PhpParser\Node\Expr\New_;
105275 use PHPUnitPHAR\PhpParser\Node\Name;
105276 use PHPUnitPHAR\PhpParser\Node\Stmt;
105277 use PHPUnitPHAR\PhpParser\Node\Stmt\Class_;
105278 use PHPUnitPHAR\PhpParser\Node\Stmt\ClassMethod;
105279 use PHPUnitPHAR\PhpParser\Node\Stmt\Function_;
105280 use PHPUnitPHAR\PhpParser\Node\Stmt\Interface_;
105281 use PHPUnitPHAR\PhpParser\Node\Stmt\Trait_;
105282 use PHPUnitPHAR\PhpParser\NodeTraverser;
105283 use PHPUnitPHAR\PhpParser\NodeVisitorAbstract;
105284 final class ComplexityCalculatingVisitor extends NodeVisitorAbstract
105285 {
105286 /**
105287 * @psalm-var list<Complexity>
105288 */
105289 private array $result = [];
105290 private bool $shortCircuitTraversal;
105291 public function __construct(bool $shortCircuitTraversal)
105292 {
105293 $this->shortCircuitTraversal = $shortCircuitTraversal;
105294 }
105295 public function enterNode(Node $node): ?int
105296 {
105297 if (!$node instanceof ClassMethod && !$node instanceof Function_) {
105298 return null;
105299 }
105300 if ($node instanceof ClassMethod) {
105301 if ($node->getAttribute('parent') instanceof Interface_) {
105302 return null;
105303 }
105304 if ($node->isAbstract()) {
105305 return null;
105306 }
105307 $name = $this->classMethodName($node);
105308 } else {
105309 $name = $this->functionName($node);
105310 }
105311 $statements = $node->getStmts();
105312 assert(is_array($statements));
105313 $this->result[] = new Complexity($name, $this->cyclomaticComplexity($statements));
105314 if ($this->shortCircuitTraversal) {
105315 return NodeTraverser::DONT_TRAVERSE_CHILDREN;
105316 }
105317 return null;
105318 }
105319 public function result(): ComplexityCollection
105320 {
105321 return ComplexityCollection::fromList(...$this->result);
105322 }
105323 /**
105324 * @param Stmt[] $statements
105325 *
105326 * @psalm-return positive-int
105327 */
105328 private function cyclomaticComplexity(array $statements): int
105329 {
105330 $traverser = new NodeTraverser();
105331 $cyclomaticComplexityCalculatingVisitor = new CyclomaticComplexityCalculatingVisitor();
105332 $traverser->addVisitor($cyclomaticComplexityCalculatingVisitor);
105333 /* @noinspection UnusedFunctionResultInspection */
105334 $traverser->traverse($statements);
105335 return $cyclomaticComplexityCalculatingVisitor->cyclomaticComplexity();
105336 }
105337 /**
105338 * @psalm-return non-empty-string
105339 */
105340 private function classMethodName(ClassMethod $node): string
105341 {
105342 $parent = $node->getAttribute('parent');
105343 assert($parent instanceof Class_ || $parent instanceof Trait_);
105344 if ($parent->getAttribute('parent') instanceof New_) {
105345 return 'anonymous class';
105346 }
105347 assert(isset($parent->namespacedName));
105348 assert($parent->namespacedName instanceof Name);
105349 return $parent->namespacedName->toString() . '::' . $node->name->toString();
105350 }
105351 /**
105352 * @psalm-return non-empty-string
105353 */
105354 private function functionName(Function_ $node): string
105355 {
105356 assert(isset($node->namespacedName));
105357 assert($node->namespacedName instanceof Name);
105358 $functionName = $node->namespacedName->toString();
105359 assert($functionName !== '');
105360 return $functionName;
105361 }
105362 }
105363 <?php
105364
105365 declare (strict_types=1);
105366 /*
105367 * This file is part of sebastian/complexity.
105368 *
105369 * (c) Sebastian Bergmann <sebastian@phpunit.de>
105370 *
105371 * For the full copyright and license information, please view the LICENSE
105372 * file that was distributed with this source code.
105373 */
105374 namespace PHPUnitPHAR\SebastianBergmann\Complexity;
105375
105376 use PHPUnitPHAR\PhpParser\Node;
105377 use PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp\BooleanAnd;
105378 use PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp\BooleanOr;
105379 use PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp\LogicalAnd;
105380 use PHPUnitPHAR\PhpParser\Node\Expr\BinaryOp\LogicalOr;
105381 use PHPUnitPHAR\PhpParser\Node\Expr\Ternary;
105382 use PHPUnitPHAR\PhpParser\Node\Stmt\Case_;
105383 use PHPUnitPHAR\PhpParser\Node\Stmt\Catch_;
105384 use PHPUnitPHAR\PhpParser\Node\Stmt\ElseIf_;
105385 use PHPUnitPHAR\PhpParser\Node\Stmt\For_;
105386 use PHPUnitPHAR\PhpParser\Node\Stmt\Foreach_;
105387 use PHPUnitPHAR\PhpParser\Node\Stmt\If_;
105388 use PHPUnitPHAR\PhpParser\Node\Stmt\While_;
105389 use PHPUnitPHAR\PhpParser\NodeVisitorAbstract;
105390 final class CyclomaticComplexityCalculatingVisitor extends NodeVisitorAbstract
105391 {
105392 /**
105393 * @psalm-var positive-int
105394 */
105395 private int $cyclomaticComplexity = 1;
105396 public function enterNode(Node $node): void
105397 {
105398 switch ($node::class) {
105399 case BooleanAnd::class:
105400 case BooleanOr::class:
105401 case Case_::class:
105402 case Catch_::class:
105403 case ElseIf_::class:
105404 case For_::class:
105405 case Foreach_::class:
105406 case If_::class:
105407 case LogicalAnd::class:
105408 case LogicalOr::class:
105409 case Ternary::class:
105410 case While_::class:
105411 $this->cyclomaticComplexity++;
105412 }
105413 }
105414 /**
105415 * @psalm-return positive-int
105416 */
105417 public function cyclomaticComplexity(): int
105418 {
105419 return $this->cyclomaticComplexity;
105420 }
105421 }
105422 <?php
105423
105424 declare (strict_types=1);
105425 /*
105426 * This file is part of sebastian/diff.
105427 *
105428 * (c) Sebastian Bergmann <sebastian@phpunit.de>
105429 *
105430 * For the full copyright and license information, please view the LICENSE
105431 * file that was distributed with this source code.
105432 */
105433 namespace PHPUnitPHAR\SebastianBergmann\Diff;
105434
105435 use ArrayIterator;
105436 use IteratorAggregate;
105437 use Traversable;
105438 /**
105439 * @template-implements IteratorAggregate<int, Line>
105440 */
105441 final class Chunk implements IteratorAggregate
105442 {
105443 private int $start;
105444 private int $startRange;
105445 private int $end;
105446 private int $endRange;
105447 private array $lines;
105448 public function __construct(int $start = 0, int $startRange = 1, int $end = 0, int $endRange = 1, array $lines = [])
105449 {
105450 $this->start = $start;
105451 $this->startRange = $startRange;
105452 $this->end = $end;
105453 $this->endRange = $endRange;
105454 $this->lines = $lines;
105455 }
105456 public function start(): int
105457 {
105458 return $this->start;
105459 }
105460 public function startRange(): int
105461 {
105462 return $this->startRange;
105463 }
105464 public function end(): int
105465 {
105466 return $this->end;
105467 }
105468 public function endRange(): int
105469 {
105470 return $this->endRange;
105471 }
105472 /**
105473 * @psalm-return list<Line>
105474 */
105475 public function lines(): array
105476 {
105477 return $this->lines;
105478 }
105479 /**
105480 * @psalm-param list<Line> $lines
105481 */
105482 public function setLines(array $lines): void
105483 {
105484 foreach ($lines as $line) {
105485 if (!$line instanceof Line) {
105486 throw new InvalidArgumentException();
105487 }
105488 }
105489 $this->lines = $lines;
105490 }
105491 /**
105492 * @deprecated Use start() instead
105493 */
105494 public function getStart(): int
105495 {
105496 return $this->start;
105497 }
105498 /**
105499 * @deprecated Use startRange() instead
105500 */
105501 public function getStartRange(): int
105502 {
105503 return $this->startRange;
105504 }
105505 /**
105506 * @deprecated Use end() instead
105507 */
105508 public function getEnd(): int
105509 {
105510 return $this->end;
105511 }
105512 /**
105513 * @deprecated Use endRange() instead
105514 */
105515 public function getEndRange(): int
105516 {
105517 return $this->endRange;
105518 }
105519 /**
105520 * @psalm-return list<Line>
105521 *
105522 * @deprecated Use lines() instead
105523 */
105524 public function getLines(): array
105525 {
105526 return $this->lines;
105527 }
105528 public function getIterator(): Traversable
105529 {
105530 return new ArrayIterator($this->lines);
105531 }
105532 }
105533 <?php
105534
105535 declare (strict_types=1);
105536 /*
105537 * This file is part of sebastian/diff.
105538 *
105539 * (c) Sebastian Bergmann <sebastian@phpunit.de>
105540 *
105541 * For the full copyright and license information, please view the LICENSE
105542 * file that was distributed with this source code.
105543 */
105544 namespace PHPUnitPHAR\SebastianBergmann\Diff;
105545
105546 use ArrayIterator;
105547 use IteratorAggregate;
105548 use Traversable;
105549 /**
105550 * @template-implements IteratorAggregate<int, Chunk>
105551 */
105552 final class Diff implements IteratorAggregate
105553 {
105554 /**
105555 * @psalm-var non-empty-string
105556 */
105557 private string $from;
105558 /**
105559 * @psalm-var non-empty-string
105560 */
105561 private string $to;
105562 /**
105563 * @psalm-var list<Chunk>
105564 */
105565 private array $chunks;
105566 /**
105567 * @psalm-param non-empty-string $from
105568 * @psalm-param non-empty-string $to
105569 * @psalm-param list<Chunk> $chunks
105570 */
105571 public function __construct(string $from, string $to, array $chunks = [])
105572 {
105573 $this->from = $from;
105574 $this->to = $to;
105575 $this->chunks = $chunks;
105576 }
105577 /**
105578 * @psalm-return non-empty-string
105579 */
105580 public function from(): string
105581 {
105582 return $this->from;
105583 }
105584 /**
105585 * @psalm-return non-empty-string
105586 */
105587 public function to(): string
105588 {
105589 return $this->to;
105590 }
105591 /**
105592 * @psalm-return list<Chunk>
105593 */
105594 public function chunks(): array
105595 {
105596 return $this->chunks;
105597 }
105598 /**
105599 * @psalm-param list<Chunk> $chunks
105600 */
105601 public function setChunks(array $chunks): void
105602 {
105603 $this->chunks = $chunks;
105604 }
105605 /**
105606 * @psalm-return non-empty-string
105607 *
105608 * @deprecated
105609 */
105610 public function getFrom(): string
105611 {
105612 return $this->from;
105613 }
105614 /**
105615 * @psalm-return non-empty-string
105616 *
105617 * @deprecated
105618 */
105619 public function getTo(): string
105620 {
105621 return $this->to;
105622 }
105623 /**
105624 * @psalm-return list<Chunk>
105625 *
105626 * @deprecated
105627 */
105628 public function getChunks(): array
105629 {
105630 return $this->chunks;
105631 }
105632 public function getIterator(): Traversable
105633 {
105634 return new ArrayIterator($this->chunks);
105635 }
105636 }
105637 <?php
105638
105639 declare (strict_types=1);
105640 /*
105641 * This file is part of sebastian/diff.
105642 *
105643 * (c) Sebastian Bergmann <sebastian@phpunit.de>
105644 *
105645 * For the full copyright and license information, please view the LICENSE
105646 * file that was distributed with this source code.
105647 */
105648 namespace PHPUnitPHAR\SebastianBergmann\Diff;
105649
105650 use const PHP_INT_SIZE;
105651 use const PREG_SPLIT_DELIM_CAPTURE;
105652 use const PREG_SPLIT_NO_EMPTY;
105653 use function array_shift;
105654 use function array_unshift;
105655 use function array_values;
105656 use function count;
105657 use function current;
105658 use function end;
105659 use function is_string;
105660 use function key;
105661 use function min;
105662 use function preg_split;
105663 use function prev;
105664 use function reset;
105665 use function str_ends_with;
105666 use function substr;
105667 use PHPUnitPHAR\SebastianBergmann\Diff\Output\DiffOutputBuilderInterface;
105668 final class Differ
105669 {
105670 public const OLD = 0;
105671 public const ADDED = 1;
105672 public const REMOVED = 2;
105673 public const DIFF_LINE_END_WARNING = 3;
105674 public const NO_LINE_END_EOF_WARNING = 4;
105675 private DiffOutputBuilderInterface $outputBuilder;
105676 public function __construct(DiffOutputBuilderInterface $outputBuilder)
105677 {
105678 $this->outputBuilder = $outputBuilder;
105679 }
105680 public function diff(array|string $from, array|string $to, ?LongestCommonSubsequenceCalculator $lcs = null): string
105681 {
105682 $diff = $this->diffToArray($from, $to, $lcs);
105683 return $this->outputBuilder->getDiff($diff);
105684 }
105685 public function diffToArray(array|string $from, array|string $to, ?LongestCommonSubsequenceCalculator $lcs = null): array
105686 {
105687 if (is_string($from)) {
105688 $from = $this->splitStringByLines($from);
105689 }
105690 if (is_string($to)) {
105691 $to = $this->splitStringByLines($to);
105692 }
105693 [$from, $to, $start, $end] = self::getArrayDiffParted($from, $to);
105694 if ($lcs === null) {
105695 $lcs = $this->selectLcsImplementation($from, $to);
105696 }
105697 $common = $lcs->calculate(array_values($from), array_values($to));
105698 $diff = [];
105699 foreach ($start as $token) {
105700 $diff[] = [$token, self::OLD];
105701 }
105702 reset($from);
105703 reset($to);
105704 foreach ($common as $token) {
105705 while (($fromToken = reset($from)) !== $token) {
105706 $diff[] = [array_shift($from), self::REMOVED];
105707 }
105708 while (($toToken = reset($to)) !== $token) {
105709 $diff[] = [array_shift($to), self::ADDED];
105710 }
105711 $diff[] = [$token, self::OLD];
105712 array_shift($from);
105713 array_shift($to);
105714 }
105715 while (($token = array_shift($from)) !== null) {
105716 $diff[] = [$token, self::REMOVED];
105717 }
105718 while (($token = array_shift($to)) !== null) {
105719 $diff[] = [$token, self::ADDED];
105720 }
105721 foreach ($end as $token) {
105722 $diff[] = [$token, self::OLD];
105723 }
105724 if ($this->detectUnmatchedLineEndings($diff)) {
105725 array_unshift($diff, ["#Warning: Strings contain different line endings!\n", self::DIFF_LINE_END_WARNING]);
105726 }
105727 return $diff;
105728 }
105729 private function splitStringByLines(string $input): array
105730 {
105731 return preg_split('/(.*\R)/', $input, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
105732 }
105733 private function selectLcsImplementation(array $from, array $to): LongestCommonSubsequenceCalculator
105734 {
105735 // We do not want to use the time-efficient implementation if its memory
105736 // footprint will probably exceed this value. Note that the footprint
105737 // calculation is only an estimation for the matrix and the LCS method
105738 // will typically allocate a bit more memory than this.
105739 $memoryLimit = 100 * 1024 * 1024;
105740 if ($this->calculateEstimatedFootprint($from, $to) > $memoryLimit) {
105741 return new MemoryEfficientLongestCommonSubsequenceCalculator();
105742 }
105743 return new TimeEfficientLongestCommonSubsequenceCalculator();
105744 }
105745 private function calculateEstimatedFootprint(array $from, array $to): float|int
105746 {
105747 $itemSize = PHP_INT_SIZE === 4 ? 76 : 144;
105748 return $itemSize * min(count($from), count($to)) ** 2;
105749 }
105750 private function detectUnmatchedLineEndings(array $diff): bool
105751 {
105752 $newLineBreaks = ['' => \true];
105753 $oldLineBreaks = ['' => \true];
105754 foreach ($diff as $entry) {
105755 if (self::OLD === $entry[1]) {
105756 $ln = $this->getLinebreak($entry[0]);
105757 $oldLineBreaks[$ln] = \true;
105758 $newLineBreaks[$ln] = \true;
105759 } elseif (self::ADDED === $entry[1]) {
105760 $newLineBreaks[$this->getLinebreak($entry[0])] = \true;
105761 } elseif (self::REMOVED === $entry[1]) {
105762 $oldLineBreaks[$this->getLinebreak($entry[0])] = \true;
105763 }
105764 }
105765 // if either input or output is a single line without breaks than no warning should be raised
105766 if (['' => \true] === $newLineBreaks || ['' => \true] === $oldLineBreaks) {
105767 return \false;
105768 }
105769 // two-way compare
105770 foreach ($newLineBreaks as $break => $set) {
105771 if (!isset($oldLineBreaks[$break])) {
105772 return \true;
105773 }
105774 }
105775 foreach ($oldLineBreaks as $break => $set) {
105776 if (!isset($newLineBreaks[$break])) {
105777 return \true;
105778 }
105779 }
105780 return \false;
105781 }
105782 private function getLinebreak($line): string
105783 {
105784 if (!is_string($line)) {
105785 return '';
105786 }
105787 $lc = substr($line, -1);
105788 if ("\r" === $lc) {
105789 return "\r";
105790 }
105791 if ("\n" !== $lc) {
105792 return '';
105793 }
105794 if (str_ends_with($line, "\r\n")) {
105795 return "\r\n";
105796 }
105797 return "\n";
105798 }
105799 private static function getArrayDiffParted(array &$from, array &$to): array
105800 {
105801 $start = [];
105802 $end = [];
105803 reset($to);
105804 foreach ($from as $k => $v) {
105805 $toK = key($to);
105806 if ($toK === $k && $v === $to[$k]) {
105807 $start[$k] = $v;
105808 unset($from[$k], $to[$k]);
105809 } else {
105810 break;
105811 }
105812 }
105813 end($from);
105814 end($to);
105815 do {
105816 $fromK = key($from);
105817 $toK = key($to);
105818 if (null === $fromK || null === $toK || current($from) !== current($to)) {
105819 break;
105820 }
105821 prev($from);
105822 prev($to);
105823 $end = [$fromK => $from[$fromK]] + $end;
105824 unset($from[$fromK], $to[$toK]);
105825 } while (\true);
105826 return [$from, $to, $start, $end];
105827 }
105828 }
105829 <?php
105830
105831 declare (strict_types=1);
105832 /*
105833 * This file is part of sebastian/diff.
105834 *
105835 * (c) Sebastian Bergmann <sebastian@phpunit.de>
105836 *
105837 * For the full copyright and license information, please view the LICENSE
105838 * file that was distributed with this source code.
105839 */
105840 namespace PHPUnitPHAR\SebastianBergmann\Diff;
105841
105842 use function gettype;
105843 use function is_object;
105844 use function sprintf;
105845 use Exception;
105846 final class ConfigurationException extends InvalidArgumentException
105847 {
105848 public function __construct(string $option, string $expected, $value, int $code = 0, ?Exception $previous = null)
105849 {
105850 parent::__construct(sprintf('Option "%s" must be %s, got "%s".', $option, $expected, is_object($value) ? $value::class : (null === $value ? '<null>' : gettype($value) . '#' . $value)), $code, $previous);
105851 }
105852 }
105853 <?php
105854
105855 declare (strict_types=1);
105856 /*
105857 * This file is part of sebastian/diff.
105858 *
105859 * (c) Sebastian Bergmann <sebastian@phpunit.de>
105860 *
105861 * For the full copyright and license information, please view the LICENSE
105862 * file that was distributed with this source code.
105863 */
105864 namespace PHPUnitPHAR\SebastianBergmann\Diff;
105865
105866 use Throwable;
105867 interface Exception extends Throwable
105868 {
105869 }
105870 <?php
105871
105872 declare (strict_types=1);
105873 /*
105874 * This file is part of sebastian/diff.
105875 *
105876 * (c) Sebastian Bergmann <sebastian@phpunit.de>
105877 *
105878 * For the full copyright and license information, please view the LICENSE
105879 * file that was distributed with this source code.
105880 */
105881 namespace PHPUnitPHAR\SebastianBergmann\Diff;
105882
105883 class InvalidArgumentException extends \InvalidArgumentException implements Exception
105884 {
105885 }
105886 BSD 3-Clause License
105887
105888 Copyright (c) 2002-2024, Sebastian Bergmann
105889 All rights reserved.
105890
105891 Redistribution and use in source and binary forms, with or without
105892 modification, are permitted provided that the following conditions are met:
105893
105894 1. Redistributions of source code must retain the above copyright notice, this
105895 list of conditions and the following disclaimer.
105896
105897 2. Redistributions in binary form must reproduce the above copyright notice,
105898 this list of conditions and the following disclaimer in the documentation
105899 and/or other materials provided with the distribution.
105900
105901 3. Neither the name of the copyright holder nor the names of its
105902 contributors may be used to endorse or promote products derived from
105903 this software without specific prior written permission.
105904
105905 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
105906 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
105907 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
105908 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
105909 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
105910 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
105911 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
105912 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
105913 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
105914 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
105915 <?php
105916
105917 declare (strict_types=1);
105918 /*
105919 * This file is part of sebastian/diff.
105920 *
105921 * (c) Sebastian Bergmann <sebastian@phpunit.de>
105922 *
105923 * For the full copyright and license information, please view the LICENSE
105924 * file that was distributed with this source code.
105925 */
105926 namespace PHPUnitPHAR\SebastianBergmann\Diff;
105927
105928 final class Line
105929 {
105930 public const ADDED = 1;
105931 public const REMOVED = 2;
105932 public const UNCHANGED = 3;
105933 private int $type;
105934 private string $content;
105935 public function __construct(int $type = self::UNCHANGED, string $content = '')
105936 {
105937 $this->type = $type;
105938 $this->content = $content;
105939 }
105940 public function content(): string
105941 {
105942 return $this->content;
105943 }
105944 public function type(): int
105945 {
105946 return $this->type;
105947 }
105948 public function isAdded(): bool
105949 {
105950 return $this->type === self::ADDED;
105951 }
105952 public function isRemoved(): bool
105953 {
105954 return $this->type === self::REMOVED;
105955 }
105956 public function isUnchanged(): bool
105957 {
105958 return $this->type === self::UNCHANGED;
105959 }
105960 /**
105961 * @deprecated
105962 */
105963 public function getContent(): string
105964 {
105965 return $this->content;
105966 }
105967 /**
105968 * @deprecated
105969 */
105970 public function getType(): int
105971 {
105972 return $this->type;
105973 }
105974 }
105975 <?php
105976
105977 declare (strict_types=1);
105978 /*
105979 * This file is part of sebastian/diff.
105980 *
105981 * (c) Sebastian Bergmann <sebastian@phpunit.de>
105982 *
105983 * For the full copyright and license information, please view the LICENSE
105984 * file that was distributed with this source code.
105985 */
105986 namespace PHPUnitPHAR\SebastianBergmann\Diff;
105987
105988 interface LongestCommonSubsequenceCalculator
105989 {
105990 /**
105991 * Calculates the longest common subsequence of two arrays.
105992 */
105993 public function calculate(array $from, array $to): array;
105994 }
105995 <?php
105996
105997 declare (strict_types=1);
105998 /*
105999 * This file is part of sebastian/diff.
106000 *
106001 * (c) Sebastian Bergmann <sebastian@phpunit.de>
106002 *
106003 * For the full copyright and license information, please view the LICENSE
106004 * file that was distributed with this source code.
106005 */
106006 namespace PHPUnitPHAR\SebastianBergmann\Diff;
106007
106008 use function array_fill;
106009 use function array_merge;
106010 use function array_reverse;
106011 use function array_slice;
106012 use function count;
106013 use function in_array;
106014 use function max;
106015 final class MemoryEfficientLongestCommonSubsequenceCalculator implements LongestCommonSubsequenceCalculator
106016 {
106017 /**
106018 * @inheritDoc
106019 */
106020 public function calculate(array $from, array $to): array
106021 {
106022 $cFrom = count($from);
106023 $cTo = count($to);
106024 if ($cFrom === 0) {
106025 return [];
106026 }
106027 if ($cFrom === 1) {
106028 if (in_array($from[0], $to, \true)) {
106029 return [$from[0]];
106030 }
106031 return [];
106032 }
106033 $i = (int) ($cFrom / 2);
106034 $fromStart = array_slice($from, 0, $i);
106035 $fromEnd = array_slice($from, $i);
106036 $llB = $this->length($fromStart, $to);
106037 $llE = $this->length(array_reverse($fromEnd), array_reverse($to));
106038 $jMax = 0;
106039 $max = 0;
106040 for ($j = 0; $j <= $cTo; $j++) {
106041 $m = $llB[$j] + $llE[$cTo - $j];
106042 if ($m >= $max) {
106043 $max = $m;
106044 $jMax = $j;
106045 }
106046 }
106047 $toStart = array_slice($to, 0, $jMax);
106048 $toEnd = array_slice($to, $jMax);
106049 return array_merge($this->calculate($fromStart, $toStart), $this->calculate($fromEnd, $toEnd));
106050 }
106051 private function length(array $from, array $to): array
106052 {
106053 $current = array_fill(0, count($to) + 1, 0);
106054 $cFrom = count($from);
106055 $cTo = count($to);
106056 for ($i = 0; $i < $cFrom; $i++) {
106057 $prev = $current;
106058 for ($j = 0; $j < $cTo; $j++) {
106059 if ($from[$i] === $to[$j]) {
106060 $current[$j + 1] = $prev[$j] + 1;
106061 } else if ($current[$j] > $prev[$j + 1]) {
106062 $current[$j + 1] = $current[$j];
106063 } else {
106064 $current[$j + 1] = $prev[$j + 1];
106065 }
106066 }
106067 }
106068 return $current;
106069 }
106070 }
106071 <?php
106072
106073 declare (strict_types=1);
106074 /*
106075 * This file is part of sebastian/diff.
106076 *
106077 * (c) Sebastian Bergmann <sebastian@phpunit.de>
106078 *
106079 * For the full copyright and license information, please view the LICENSE
106080 * file that was distributed with this source code.
106081 */
106082 namespace PHPUnitPHAR\SebastianBergmann\Diff\Output;
106083
106084 use function count;
106085 abstract class AbstractChunkOutputBuilder implements DiffOutputBuilderInterface
106086 {
106087 /**
106088 * Takes input of the diff array and returns the common parts.
106089 * Iterates through diff line by line.
106090 */
106091 protected function getCommonChunks(array $diff, int $lineThreshold = 5): array
106092 {
106093 $diffSize = count($diff);
106094 $capturing = \false;
106095 $chunkStart = 0;
106096 $chunkSize = 0;
106097 $commonChunks = [];
106098 for ($i = 0; $i < $diffSize; $i++) {
106099 if ($diff[$i][1] === 0) {
106100 if ($capturing === \false) {
106101 $capturing = \true;
106102 $chunkStart = $i;
106103 $chunkSize = 0;
106104 } else {
106105 $chunkSize++;
106106 }
106107 } elseif ($capturing !== \false) {
106108 if ($chunkSize >= $lineThreshold) {
106109 $commonChunks[$chunkStart] = $chunkStart + $chunkSize;
106110 }
106111 $capturing = \false;
106112 }
106113 }
106114 if ($capturing !== \false && $chunkSize >= $lineThreshold) {
106115 $commonChunks[$chunkStart] = $chunkStart + $chunkSize;
106116 }
106117 return $commonChunks;
106118 }
106119 }
106120 <?php
106121
106122 declare (strict_types=1);
106123 /*
106124 * This file is part of sebastian/diff.
106125 *
106126 * (c) Sebastian Bergmann <sebastian@phpunit.de>
106127 *
106128 * For the full copyright and license information, please view the LICENSE
106129 * file that was distributed with this source code.
106130 */
106131 namespace PHPUnitPHAR\SebastianBergmann\Diff\Output;
106132
106133 use function fclose;
106134 use function fopen;
106135 use function fwrite;
106136 use function str_ends_with;
106137 use function stream_get_contents;
106138 use function substr;
106139 use PHPUnitPHAR\SebastianBergmann\Diff\Differ;
106140 /**
106141 * Builds a diff string representation in a loose unified diff format
106142 * listing only changes lines. Does not include line numbers.
106143 */
106144 final class DiffOnlyOutputBuilder implements DiffOutputBuilderInterface
106145 {
106146 private string $header;
106147 public function __construct(string $header = "--- Original\n+++ New\n")
106148 {
106149 $this->header = $header;
106150 }
106151 public function getDiff(array $diff): string
106152 {
106153 $buffer = fopen('php://memory', 'r+b');
106154 if ('' !== $this->header) {
106155 fwrite($buffer, $this->header);
106156 if (!str_ends_with($this->header, "\n")) {
106157 fwrite($buffer, "\n");
106158 }
106159 }
106160 foreach ($diff as $diffEntry) {
106161 if ($diffEntry[1] === Differ::ADDED) {
106162 fwrite($buffer, '+' . $diffEntry[0]);
106163 } elseif ($diffEntry[1] === Differ::REMOVED) {
106164 fwrite($buffer, '-' . $diffEntry[0]);
106165 } elseif ($diffEntry[1] === Differ::DIFF_LINE_END_WARNING) {
106166 fwrite($buffer, ' ' . $diffEntry[0]);
106167 continue;
106168 // Warnings should not be tested for line break, it will always be there
106169 } else {
106170 /* Not changed (old) 0 */
106171 continue;
106172 // we didn't write the not-changed line, so do not add a line break either
106173 }
106174 $lc = substr($diffEntry[0], -1);
106175 if ($lc !== "\n" && $lc !== "\r") {
106176 fwrite($buffer, "\n");
106177 // \No newline at end of file
106178 }
106179 }
106180 $diff = stream_get_contents($buffer, -1, 0);
106181 fclose($buffer);
106182 return $diff;
106183 }
106184 }
106185 <?php
106186
106187 declare (strict_types=1);
106188 /*
106189 * This file is part of sebastian/diff.
106190 *
106191 * (c) Sebastian Bergmann <sebastian@phpunit.de>
106192 *
106193 * For the full copyright and license information, please view the LICENSE
106194 * file that was distributed with this source code.
106195 */
106196 namespace PHPUnitPHAR\SebastianBergmann\Diff\Output;
106197
106198 /**
106199 * Defines how an output builder should take a generated
106200 * diff array and return a string representation of that diff.
106201 */
106202 interface DiffOutputBuilderInterface
106203 {
106204 public function getDiff(array $diff): string;
106205 }
106206 <?php
106207
106208 declare (strict_types=1);
106209 /*
106210 * This file is part of sebastian/diff.
106211 *
106212 * (c) Sebastian Bergmann <sebastian@phpunit.de>
106213 *
106214 * For the full copyright and license information, please view the LICENSE
106215 * file that was distributed with this source code.
106216 */
106217 namespace PHPUnitPHAR\SebastianBergmann\Diff\Output;
106218
106219 use function array_merge;
106220 use function array_splice;
106221 use function count;
106222 use function fclose;
106223 use function fopen;
106224 use function fwrite;
106225 use function is_bool;
106226 use function is_int;
106227 use function is_string;
106228 use function max;
106229 use function min;
106230 use function sprintf;
106231 use function stream_get_contents;
106232 use function substr;
106233 use PHPUnitPHAR\SebastianBergmann\Diff\ConfigurationException;
106234 use PHPUnitPHAR\SebastianBergmann\Diff\Differ;
106235 /**
106236 * Strict Unified diff output builder.
106237 *
106238 * Generates (strict) Unified diff's (unidiffs) with hunks.
106239 */
106240 final class StrictUnifiedDiffOutputBuilder implements DiffOutputBuilderInterface
106241 {
106242 private static array $default = [
106243 'collapseRanges' => \true,
106244 // ranges of length one are rendered with the trailing `,1`
106245 'commonLineThreshold' => 6,
106246 // number of same lines before ending a new hunk and creating a new one (if needed)
106247 'contextLines' => 3,
106248 // like `diff: -u, -U NUM, --unified[=NUM]`, for patch/git apply compatibility best to keep at least @ 3
106249 'fromFile' => null,
106250 'fromFileDate' => null,
106251 'toFile' => null,
106252 'toFileDate' => null,
106253 ];
106254 private bool $changed;
106255 private bool $collapseRanges;
106256 /**
106257 * @psalm-var positive-int
106258 */
106259 private int $commonLineThreshold;
106260 private string $header;
106261 /**
106262 * @psalm-var positive-int
106263 */
106264 private int $contextLines;
106265 public function __construct(array $options = [])
106266 {
106267 $options = array_merge(self::$default, $options);
106268 if (!is_bool($options['collapseRanges'])) {
106269 throw new ConfigurationException('collapseRanges', 'a bool', $options['collapseRanges']);
106270 }
106271 if (!is_int($options['contextLines']) || $options['contextLines'] < 0) {
106272 throw new ConfigurationException('contextLines', 'an int >= 0', $options['contextLines']);
106273 }
106274 if (!is_int($options['commonLineThreshold']) || $options['commonLineThreshold'] <= 0) {
106275 throw new ConfigurationException('commonLineThreshold', 'an int > 0', $options['commonLineThreshold']);
106276 }
106277 $this->assertString($options, 'fromFile');
106278 $this->assertString($options, 'toFile');
106279 $this->assertStringOrNull($options, 'fromFileDate');
106280 $this->assertStringOrNull($options, 'toFileDate');
106281 $this->header = sprintf("--- %s%s\n+++ %s%s\n", $options['fromFile'], null === $options['fromFileDate'] ? '' : "\t" . $options['fromFileDate'], $options['toFile'], null === $options['toFileDate'] ? '' : "\t" . $options['toFileDate']);
106282 $this->collapseRanges = $options['collapseRanges'];
106283 $this->commonLineThreshold = $options['commonLineThreshold'];
106284 $this->contextLines = $options['contextLines'];
106285 }
106286 public function getDiff(array $diff): string
106287 {
106288 if (0 === count($diff)) {
106289 return '';
106290 }
106291 $this->changed = \false;
106292 $buffer = fopen('php://memory', 'r+b');
106293 fwrite($buffer, $this->header);
106294 $this->writeDiffHunks($buffer, $diff);
106295 if (!$this->changed) {
106296 fclose($buffer);
106297 return '';
106298 }
106299 $diff = stream_get_contents($buffer, -1, 0);
106300 fclose($buffer);
106301 // If the last char is not a linebreak: add it.
106302 // This might happen when both the `from` and `to` do not have a trailing linebreak
106303 $last = substr($diff, -1);
106304 return "\n" !== $last && "\r" !== $last ? $diff . "\n" : $diff;
106305 }
106306 private function writeDiffHunks($output, array $diff): void
106307 {
106308 // detect "No newline at end of file" and insert into `$diff` if needed
106309 $upperLimit = count($diff);
106310 if (0 === $diff[$upperLimit - 1][1]) {
106311 $lc = substr($diff[$upperLimit - 1][0], -1);
106312 if ("\n" !== $lc) {
106313 array_splice($diff, $upperLimit, 0, [["\n\\ No newline at end of file\n", Differ::NO_LINE_END_EOF_WARNING]]);
106314 }
106315 } else {
106316 // search back for the last `+` and `-` line,
106317 // check if it has a trailing linebreak, else add a warning under it
106318 $toFind = [1 => \true, 2 => \true];
106319 for ($i = $upperLimit - 1; $i >= 0; $i--) {
106320 if (isset($toFind[$diff[$i][1]])) {
106321 unset($toFind[$diff[$i][1]]);
106322 $lc = substr($diff[$i][0], -1);
106323 if ("\n" !== $lc) {
106324 array_splice($diff, $i + 1, 0, [["\n\\ No newline at end of file\n", Differ::NO_LINE_END_EOF_WARNING]]);
106325 }
106326 if (!count($toFind)) {
106327 break;
106328 }
106329 }
106330 }
106331 }
106332 // write hunks to output buffer
106333 $cutOff = max($this->commonLineThreshold, $this->contextLines);
106334 $hunkCapture = \false;
106335 $sameCount = $toRange = $fromRange = 0;
106336 $toStart = $fromStart = 1;
106337 $i = 0;
106338 /** @var int $i */
106339 foreach ($diff as $i => $entry) {
106340 if (0 === $entry[1]) {
106341 // same
106342 if (\false === $hunkCapture) {
106343 $fromStart++;
106344 $toStart++;
106345 continue;
106346 }
106347 $sameCount++;
106348 $toRange++;
106349 $fromRange++;
106350 if ($sameCount === $cutOff) {
106351 $contextStartOffset = $hunkCapture - $this->contextLines < 0 ? $hunkCapture : $this->contextLines;
106352 // note: $contextEndOffset = $this->contextLines;
106353 //
106354 // because we never go beyond the end of the diff.
106355 // with the cutoff/contextlines here the follow is never true;
106356 //
106357 // if ($i - $cutOff + $this->contextLines + 1 > \count($diff)) {
106358 // $contextEndOffset = count($diff) - 1;
106359 // }
106360 //
106361 // ; that would be true for a trailing incomplete hunk case which is dealt with after this loop
106362 $this->writeHunk($diff, $hunkCapture - $contextStartOffset, $i - $cutOff + $this->contextLines + 1, $fromStart - $contextStartOffset, $fromRange - $cutOff + $contextStartOffset + $this->contextLines, $toStart - $contextStartOffset, $toRange - $cutOff + $contextStartOffset + $this->contextLines, $output);
106363 $fromStart += $fromRange;
106364 $toStart += $toRange;
106365 $hunkCapture = \false;
106366 $sameCount = $toRange = $fromRange = 0;
106367 }
106368 continue;
106369 }
106370 $sameCount = 0;
106371 if ($entry[1] === Differ::NO_LINE_END_EOF_WARNING) {
106372 continue;
106373 }
106374 $this->changed = \true;
106375 if (\false === $hunkCapture) {
106376 $hunkCapture = $i;
106377 }
106378 if (Differ::ADDED === $entry[1]) {
106379 // added
106380 $toRange++;
106381 }
106382 if (Differ::REMOVED === $entry[1]) {
106383 // removed
106384 $fromRange++;
106385 }
106386 }
106387 if (\false === $hunkCapture) {
106388 return;
106389 }
106390 // we end here when cutoff (commonLineThreshold) was not reached, but we were capturing a hunk,
106391 // do not render hunk till end automatically because the number of context lines might be less than the commonLineThreshold
106392 $contextStartOffset = $hunkCapture - $this->contextLines < 0 ? $hunkCapture : $this->contextLines;
106393 // prevent trying to write out more common lines than there are in the diff _and_
106394 // do not write more than configured through the context lines
106395 $contextEndOffset = min($sameCount, $this->contextLines);
106396 $fromRange -= $sameCount;
106397 $toRange -= $sameCount;
106398 $this->writeHunk($diff, $hunkCapture - $contextStartOffset, $i - $sameCount + $contextEndOffset + 1, $fromStart - $contextStartOffset, $fromRange + $contextStartOffset + $contextEndOffset, $toStart - $contextStartOffset, $toRange + $contextStartOffset + $contextEndOffset, $output);
106399 }
106400 private function writeHunk(array $diff, int $diffStartIndex, int $diffEndIndex, int $fromStart, int $fromRange, int $toStart, int $toRange, $output): void
106401 {
106402 fwrite($output, '@@ -' . $fromStart);
106403 if (!$this->collapseRanges || 1 !== $fromRange) {
106404 fwrite($output, ',' . $fromRange);
106405 }
106406 fwrite($output, ' +' . $toStart);
106407 if (!$this->collapseRanges || 1 !== $toRange) {
106408 fwrite($output, ',' . $toRange);
106409 }
106410 fwrite($output, " @@\n");
106411 for ($i = $diffStartIndex; $i < $diffEndIndex; $i++) {
106412 if ($diff[$i][1] === Differ::ADDED) {
106413 $this->changed = \true;
106414 fwrite($output, '+' . $diff[$i][0]);
106415 } elseif ($diff[$i][1] === Differ::REMOVED) {
106416 $this->changed = \true;
106417 fwrite($output, '-' . $diff[$i][0]);
106418 } elseif ($diff[$i][1] === Differ::OLD) {
106419 fwrite($output, ' ' . $diff[$i][0]);
106420 } elseif ($diff[$i][1] === Differ::NO_LINE_END_EOF_WARNING) {
106421 $this->changed = \true;
106422 fwrite($output, $diff[$i][0]);
106423 }
106424 // } elseif ($diff[$i][1] === Differ::DIFF_LINE_END_WARNING) { // custom comment inserted by PHPUnit/diff package
106425 // skip
106426 // } else {
106427 // unknown/invalid
106428 // }
106429 }
106430 }
106431 private function assertString(array $options, string $option): void
106432 {
106433 if (!is_string($options[$option])) {
106434 throw new ConfigurationException($option, 'a string', $options[$option]);
106435 }
106436 }
106437 private function assertStringOrNull(array $options, string $option): void
106438 {
106439 if (null !== $options[$option] && !is_string($options[$option])) {
106440 throw new ConfigurationException($option, 'a string or <null>', $options[$option]);
106441 }
106442 }
106443 }
106444 <?php
106445
106446 declare (strict_types=1);
106447 /*
106448 * This file is part of sebastian/diff.
106449 *
106450 * (c) Sebastian Bergmann <sebastian@phpunit.de>
106451 *
106452 * For the full copyright and license information, please view the LICENSE
106453 * file that was distributed with this source code.
106454 */
106455 namespace PHPUnitPHAR\SebastianBergmann\Diff\Output;
106456
106457 use function array_splice;
106458 use function count;
106459 use function fclose;
106460 use function fopen;
106461 use function fwrite;
106462 use function max;
106463 use function min;
106464 use function str_ends_with;
106465 use function stream_get_contents;
106466 use function substr;
106467 use PHPUnitPHAR\SebastianBergmann\Diff\Differ;
106468 /**
106469 * Builds a diff string representation in unified diff format in chunks.
106470 */
106471 final class UnifiedDiffOutputBuilder extends AbstractChunkOutputBuilder
106472 {
106473 private bool $collapseRanges = \true;
106474 private int $commonLineThreshold = 6;
106475 /**
106476 * @psalm-var positive-int
106477 */
106478 private int $contextLines = 3;
106479 private string $header;
106480 private bool $addLineNumbers;
106481 public function __construct(string $header = "--- Original\n+++ New\n", bool $addLineNumbers = \false)
106482 {
106483 $this->header = $header;
106484 $this->addLineNumbers = $addLineNumbers;
106485 }
106486 public function getDiff(array $diff): string
106487 {
106488 $buffer = fopen('php://memory', 'r+b');
106489 if ('' !== $this->header) {
106490 fwrite($buffer, $this->header);
106491 if (!str_ends_with($this->header, "\n")) {
106492 fwrite($buffer, "\n");
106493 }
106494 }
106495 if (0 !== count($diff)) {
106496 $this->writeDiffHunks($buffer, $diff);
106497 }
106498 $diff = stream_get_contents($buffer, -1, 0);
106499 fclose($buffer);
106500 // If the diff is non-empty and last char is not a linebreak: add it.
106501 // This might happen when both the `from` and `to` do not have a trailing linebreak
106502 $last = substr($diff, -1);
106503 return '' !== $diff && "\n" !== $last && "\r" !== $last ? $diff . "\n" : $diff;
106504 }
106505 private function writeDiffHunks($output, array $diff): void
106506 {
106507 // detect "No newline at end of file" and insert into `$diff` if needed
106508 $upperLimit = count($diff);
106509 if (0 === $diff[$upperLimit - 1][1]) {
106510 $lc = substr($diff[$upperLimit - 1][0], -1);
106511 if ("\n" !== $lc) {
106512 array_splice($diff, $upperLimit, 0, [["\n\\ No newline at end of file\n", Differ::NO_LINE_END_EOF_WARNING]]);
106513 }
106514 } else {
106515 // search back for the last `+` and `-` line,
106516 // check if it has trailing linebreak, else add a warning under it
106517 $toFind = [1 => \true, 2 => \true];
106518 for ($i = $upperLimit - 1; $i >= 0; $i--) {
106519 if (isset($toFind[$diff[$i][1]])) {
106520 unset($toFind[$diff[$i][1]]);
106521 $lc = substr($diff[$i][0], -1);
106522 if ("\n" !== $lc) {
106523 array_splice($diff, $i + 1, 0, [["\n\\ No newline at end of file\n", Differ::NO_LINE_END_EOF_WARNING]]);
106524 }
106525 if (!count($toFind)) {
106526 break;
106527 }
106528 }
106529 }
106530 }
106531 // write hunks to output buffer
106532 $cutOff = max($this->commonLineThreshold, $this->contextLines);
106533 $hunkCapture = \false;
106534 $sameCount = $toRange = $fromRange = 0;
106535 $toStart = $fromStart = 1;
106536 $i = 0;
106537 /** @var int $i */
106538 foreach ($diff as $i => $entry) {
106539 if (0 === $entry[1]) {
106540 // same
106541 if (\false === $hunkCapture) {
106542 $fromStart++;
106543 $toStart++;
106544 continue;
106545 }
106546 $sameCount++;
106547 $toRange++;
106548 $fromRange++;
106549 if ($sameCount === $cutOff) {
106550 $contextStartOffset = $hunkCapture - $this->contextLines < 0 ? $hunkCapture : $this->contextLines;
106551 // note: $contextEndOffset = $this->contextLines;
106552 //
106553 // because we never go beyond the end of the diff.
106554 // with the cutoff/contextlines here the follow is never true;
106555 //
106556 // if ($i - $cutOff + $this->contextLines + 1 > \count($diff)) {
106557 // $contextEndOffset = count($diff) - 1;
106558 // }
106559 //
106560 // ; that would be true for a trailing incomplete hunk case which is dealt with after this loop
106561 $this->writeHunk($diff, $hunkCapture - $contextStartOffset, $i - $cutOff + $this->contextLines + 1, $fromStart - $contextStartOffset, $fromRange - $cutOff + $contextStartOffset + $this->contextLines, $toStart - $contextStartOffset, $toRange - $cutOff + $contextStartOffset + $this->contextLines, $output);
106562 $fromStart += $fromRange;
106563 $toStart += $toRange;
106564 $hunkCapture = \false;
106565 $sameCount = $toRange = $fromRange = 0;
106566 }
106567 continue;
106568 }
106569 $sameCount = 0;
106570 if ($entry[1] === Differ::NO_LINE_END_EOF_WARNING) {
106571 continue;
106572 }
106573 if (\false === $hunkCapture) {
106574 $hunkCapture = $i;
106575 }
106576 if (Differ::ADDED === $entry[1]) {
106577 $toRange++;
106578 }
106579 if (Differ::REMOVED === $entry[1]) {
106580 $fromRange++;
106581 }
106582 }
106583 if (\false === $hunkCapture) {
106584 return;
106585 }
106586 // we end here when cutoff (commonLineThreshold) was not reached, but we were capturing a hunk,
106587 // do not render hunk till end automatically because the number of context lines might be less than the commonLineThreshold
106588 $contextStartOffset = $hunkCapture - $this->contextLines < 0 ? $hunkCapture : $this->contextLines;
106589 // prevent trying to write out more common lines than there are in the diff _and_
106590 // do not write more than configured through the context lines
106591 $contextEndOffset = min($sameCount, $this->contextLines);
106592 $fromRange -= $sameCount;
106593 $toRange -= $sameCount;
106594 $this->writeHunk($diff, $hunkCapture - $contextStartOffset, $i - $sameCount + $contextEndOffset + 1, $fromStart - $contextStartOffset, $fromRange + $contextStartOffset + $contextEndOffset, $toStart - $contextStartOffset, $toRange + $contextStartOffset + $contextEndOffset, $output);
106595 }
106596 private function writeHunk(array $diff, int $diffStartIndex, int $diffEndIndex, int $fromStart, int $fromRange, int $toStart, int $toRange, $output): void
106597 {
106598 if ($this->addLineNumbers) {
106599 fwrite($output, '@@ -' . $fromStart);
106600 if (!$this->collapseRanges || 1 !== $fromRange) {
106601 fwrite($output, ',' . $fromRange);
106602 }
106603 fwrite($output, ' +' . $toStart);
106604 if (!$this->collapseRanges || 1 !== $toRange) {
106605 fwrite($output, ',' . $toRange);
106606 }
106607 fwrite($output, " @@\n");
106608 } else {
106609 fwrite($output, "@@ @@\n");
106610 }
106611 for ($i = $diffStartIndex; $i < $diffEndIndex; $i++) {
106612 if ($diff[$i][1] === Differ::ADDED) {
106613 fwrite($output, '+' . $diff[$i][0]);
106614 } elseif ($diff[$i][1] === Differ::REMOVED) {
106615 fwrite($output, '-' . $diff[$i][0]);
106616 } elseif ($diff[$i][1] === Differ::OLD) {
106617 fwrite($output, ' ' . $diff[$i][0]);
106618 } elseif ($diff[$i][1] === Differ::NO_LINE_END_EOF_WARNING) {
106619 fwrite($output, "\n");
106620 // $diff[$i][0]
106621 } else {
106622 /* Not changed (old) Differ::OLD or Warning Differ::DIFF_LINE_END_WARNING */
106623 fwrite($output, ' ' . $diff[$i][0]);
106624 }
106625 }
106626 }
106627 }
106628 <?php
106629
106630 declare (strict_types=1);
106631 /*
106632 * This file is part of sebastian/diff.
106633 *
106634 * (c) Sebastian Bergmann <sebastian@phpunit.de>
106635 *
106636 * For the full copyright and license information, please view the LICENSE
106637 * file that was distributed with this source code.
106638 */
106639 namespace PHPUnitPHAR\SebastianBergmann\Diff;
106640
106641 use function array_pop;
106642 use function assert;
106643 use function count;
106644 use function max;
106645 use function preg_match;
106646 use function preg_split;
106647 /**
106648 * Unified diff parser.
106649 */
106650 final class Parser
106651 {
106652 /**
106653 * @return Diff[]
106654 */
106655 public function parse(string $string): array
106656 {
106657 $lines = preg_split('(\r\n|\r|\n)', $string);
106658 if (!empty($lines) && $lines[count($lines) - 1] === '') {
106659 array_pop($lines);
106660 }
106661 $lineCount = count($lines);
106662 $diffs = [];
106663 $diff = null;
106664 $collected = [];
106665 for ($i = 0; $i < $lineCount; $i++) {
106666 if (preg_match('#^---\h+"?(?P<file>[^\v\t"]+)#', $lines[$i], $fromMatch) && preg_match('#^\+\+\+\h+"?(?P<file>[^\v\t"]+)#', $lines[$i + 1], $toMatch)) {
106667 if ($diff !== null) {
106668 $this->parseFileDiff($diff, $collected);
106669 $diffs[] = $diff;
106670 $collected = [];
106671 }
106672 assert(!empty($fromMatch['file']));
106673 assert(!empty($toMatch['file']));
106674 $diff = new Diff($fromMatch['file'], $toMatch['file']);
106675 $i++;
106676 } else {
106677 if (preg_match('/^(?:diff --git |index [\da-f.]+|[+-]{3} [ab])/', $lines[$i])) {
106678 continue;
106679 }
106680 $collected[] = $lines[$i];
106681 }
106682 }
106683 if ($diff !== null && count($collected)) {
106684 $this->parseFileDiff($diff, $collected);
106685 $diffs[] = $diff;
106686 }
106687 return $diffs;
106688 }
106689 private function parseFileDiff(Diff $diff, array $lines): void
106690 {
106691 $chunks = [];
106692 $chunk = null;
106693 $diffLines = [];
106694 foreach ($lines as $line) {
106695 if (preg_match('/^@@\s+-(?P<start>\d+)(?:,\s*(?P<startrange>\d+))?\s+\+(?P<end>\d+)(?:,\s*(?P<endrange>\d+))?\s+@@/', $line, $match, \PREG_UNMATCHED_AS_NULL)) {
106696 $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);
106697 $chunks[] = $chunk;
106698 $diffLines = [];
106699 continue;
106700 }
106701 if (preg_match('/^(?P<type>[+ -])?(?P<line>.*)/', $line, $match)) {
106702 $type = Line::UNCHANGED;
106703 if ($match['type'] === '+') {
106704 $type = Line::ADDED;
106705 } elseif ($match['type'] === '-') {
106706 $type = Line::REMOVED;
106707 }
106708 $diffLines[] = new Line($type, $match['line']);
106709 $chunk?->setLines($diffLines);
106710 }
106711 }
106712 $diff->setChunks($chunks);
106713 }
106714 }
106715 <?php
106716
106717 declare (strict_types=1);
106718 /*
106719 * This file is part of sebastian/diff.
106720 *
106721 * (c) Sebastian Bergmann <sebastian@phpunit.de>
106722 *
106723 * For the full copyright and license information, please view the LICENSE
106724 * file that was distributed with this source code.
106725 */
106726 namespace PHPUnitPHAR\SebastianBergmann\Diff;
106727
106728 use function array_reverse;
106729 use function count;
106730 use function max;
106731 use SplFixedArray;
106732 final class TimeEfficientLongestCommonSubsequenceCalculator implements LongestCommonSubsequenceCalculator
106733 {
106734 /**
106735 * @inheritDoc
106736 */
106737 public function calculate(array $from, array $to): array
106738 {
106739 $common = [];
106740 $fromLength = count($from);
106741 $toLength = count($to);
106742 $width = $fromLength + 1;
106743 $matrix = new SplFixedArray($width * ($toLength + 1));
106744 for ($i = 0; $i <= $fromLength; $i++) {
106745 $matrix[$i] = 0;
106746 }
106747 for ($j = 0; $j <= $toLength; $j++) {
106748 $matrix[$j * $width] = 0;
106749 }
106750 for ($i = 1; $i <= $fromLength; $i++) {
106751 for ($j = 1; $j <= $toLength; $j++) {
106752 $o = $j * $width + $i;
106753 // don't use max() to avoid function call overhead
106754 $firstOrLast = $from[$i - 1] === $to[$j - 1] ? $matrix[$o - $width - 1] + 1 : 0;
106755 if ($matrix[$o - 1] > $matrix[$o - $width]) {
106756 if ($firstOrLast > $matrix[$o - 1]) {
106757 $matrix[$o] = $firstOrLast;
106758 } else {
106759 $matrix[$o] = $matrix[$o - 1];
106760 }
106761 } else if ($firstOrLast > $matrix[$o - $width]) {
106762 $matrix[$o] = $firstOrLast;
106763 } else {
106764 $matrix[$o] = $matrix[$o - $width];
106765 }
106766 }
106767 }
106768 $i = $fromLength;
106769 $j = $toLength;
106770 while ($i > 0 && $j > 0) {
106771 if ($from[$i - 1] === $to[$j - 1]) {
106772 $common[] = $from[$i - 1];
106773 $i--;
106774 $j--;
106775 } else {
106776 $o = $j * $width + $i;
106777 if ($matrix[$o - $width] > $matrix[$o - 1]) {
106778 $j--;
106779 } else {
106780 $i--;
106781 }
106782 }
106783 }
106784 return array_reverse($common);
106785 }
106786 }
106787 <?php
106788
106789 declare (strict_types=1);
106790 /*
106791 * This file is part of sebastian/environment.
106792 *
106793 * (c) Sebastian Bergmann <sebastian@phpunit.de>
106794 *
106795 * For the full copyright and license information, please view the LICENSE
106796 * file that was distributed with this source code.
106797 */
106798 namespace PHPUnitPHAR\SebastianBergmann\Environment;
106799
106800 use const DIRECTORY_SEPARATOR;
106801 use const STDIN;
106802 use const STDOUT;
106803 use function defined;
106804 use function fclose;
106805 use function fstat;
106806 use function function_exists;
106807 use function getenv;
106808 use function is_resource;
106809 use function is_string;
106810 use function posix_isatty;
106811 use function preg_match;
106812 use function proc_close;
106813 use function proc_open;
106814 use function sapi_windows_vt100_support;
106815 use function shell_exec;
106816 use function stream_get_contents;
106817 use function stream_isatty;
106818 use function trim;
106819 final class Console
106820 {
106821 /**
106822 * @var int
106823 */
106824 public const STDIN = 0;
106825 /**
106826 * @var int
106827 */
106828 public const STDOUT = 1;
106829 /**
106830 * @var int
106831 */
106832 public const STDERR = 2;
106833 /**
106834 * Returns true if STDOUT supports colorization.
106835 *
106836 * This code has been copied and adapted from
106837 * Symfony\Component\Console\Output\StreamOutput.
106838 */
106839 public function hasColorSupport(): bool
106840 {
106841 if ('Hyper' === getenv('TERM_PROGRAM')) {
106842 return \true;
106843 }
106844 if ($this->isWindows()) {
106845 // @codeCoverageIgnoreStart
106846 return defined('STDOUT') && function_exists('sapi_windows_vt100_support') && @sapi_windows_vt100_support(STDOUT) || \false !== getenv('ANSICON') || 'ON' === getenv('ConEmuANSI') || 'xterm' === getenv('TERM');
106847 // @codeCoverageIgnoreEnd
106848 }
106849 if (!defined('STDOUT')) {
106850 // @codeCoverageIgnoreStart
106851 return \false;
106852 // @codeCoverageIgnoreEnd
106853 }
106854 return $this->isInteractive(STDOUT);
106855 }
106856 /**
106857 * Returns the number of columns of the terminal.
106858 *
106859 * @codeCoverageIgnore
106860 */
106861 public function getNumberOfColumns(): int
106862 {
106863 if (!$this->isInteractive(defined('STDIN') ? STDIN : self::STDIN)) {
106864 return 80;
106865 }
106866 if ($this->isWindows()) {
106867 return $this->getNumberOfColumnsWindows();
106868 }
106869 return $this->getNumberOfColumnsInteractive();
106870 }
106871 /**
106872 * Returns if the file descriptor is an interactive terminal or not.
106873 *
106874 * Normally, we want to use a resource as a parameter, yet sadly it's not always available,
106875 * eg when running code in interactive console (`php -a`), STDIN/STDOUT/STDERR constants are not defined.
106876 *
106877 * @param int|resource $fileDescriptor
106878 */
106879 public function isInteractive($fileDescriptor = self::STDOUT): bool
106880 {
106881 if (is_resource($fileDescriptor)) {
106882 if (function_exists('stream_isatty') && @stream_isatty($fileDescriptor)) {
106883 return \true;
106884 }
106885 if (function_exists('fstat')) {
106886 $stat = @fstat(STDOUT);
106887 return $stat && 020000 === ($stat['mode'] & 0170000);
106888 }
106889 return \false;
106890 }
106891 return function_exists('posix_isatty') && @posix_isatty($fileDescriptor);
106892 }
106893 private function isWindows(): bool
106894 {
106895 return DIRECTORY_SEPARATOR === '\\';
106896 }
106897 /**
106898 * @codeCoverageIgnore
106899 */
106900 private function getNumberOfColumnsInteractive(): int
106901 {
106902 if (function_exists('shell_exec') && preg_match('#\d+ (\d+)#', shell_exec('stty size') ?: '', $match) === 1) {
106903 if ((int) $match[1] > 0) {
106904 return (int) $match[1];
106905 }
106906 }
106907 if (function_exists('shell_exec') && preg_match('#columns = (\d+);#', shell_exec('stty') ?: '', $match) === 1) {
106908 if ((int) $match[1] > 0) {
106909 return (int) $match[1];
106910 }
106911 }
106912 return 80;
106913 }
106914 /**
106915 * @codeCoverageIgnore
106916 */
106917 private function getNumberOfColumnsWindows(): int
106918 {
106919 $ansicon = getenv('ANSICON');
106920 $columns = 80;
106921 if (is_string($ansicon) && preg_match('/^(\d+)x\d+ \(\d+x(\d+)\)$/', trim($ansicon), $matches)) {
106922 $columns = (int) $matches[1];
106923 } elseif (function_exists('proc_open')) {
106924 $process = proc_open('mode CON', [1 => ['pipe', 'w'], 2 => ['pipe', 'w']], $pipes, null, null, ['suppress_errors' => \true]);
106925 if (is_resource($process)) {
106926 $info = stream_get_contents($pipes[1]);
106927 fclose($pipes[1]);
106928 fclose($pipes[2]);
106929 proc_close($process);
106930 if (preg_match('/--------+\r?\n.+?(\d+)\r?\n.+?(\d+)\r?\n/', $info, $matches)) {
106931 $columns = (int) $matches[2];
106932 }
106933 }
106934 }
106935 return $columns - 1;
106936 }
106937 }
106938 BSD 3-Clause License
106939
106940 Copyright (c) 2014-2024, Sebastian Bergmann
106941 All rights reserved.
106942
106943 Redistribution and use in source and binary forms, with or without
106944 modification, are permitted provided that the following conditions are met:
106945
106946 1. Redistributions of source code must retain the above copyright notice, this
106947 list of conditions and the following disclaimer.
106948
106949 2. Redistributions in binary form must reproduce the above copyright notice,
106950 this list of conditions and the following disclaimer in the documentation
106951 and/or other materials provided with the distribution.
106952
106953 3. Neither the name of the copyright holder nor the names of its
106954 contributors may be used to endorse or promote products derived from
106955 this software without specific prior written permission.
106956
106957 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
106958 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
106959 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
106960 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
106961 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
106962 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
106963 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
106964 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
106965 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
106966 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
106967 <?php
106968
106969 declare (strict_types=1);
106970 /*
106971 * This file is part of sebastian/environment.
106972 *
106973 * (c) Sebastian Bergmann <sebastian@phpunit.de>
106974 *
106975 * For the full copyright and license information, please view the LICENSE
106976 * file that was distributed with this source code.
106977 */
106978 namespace PHPUnitPHAR\SebastianBergmann\Environment;
106979
106980 use const PHP_BINARY;
106981 use const PHP_BINDIR;
106982 use const PHP_MAJOR_VERSION;
106983 use const PHP_SAPI;
106984 use const PHP_VERSION;
106985 use function array_map;
106986 use function array_merge;
106987 use function escapeshellarg;
106988 use function explode;
106989 use function extension_loaded;
106990 use function ini_get;
106991 use function is_readable;
106992 use function parse_ini_file;
106993 use function php_ini_loaded_file;
106994 use function php_ini_scanned_files;
106995 use function phpversion;
106996 use function sprintf;
106997 use function strrpos;
106998 final class Runtime
106999 {
107000 private static string $rawBinary;
107001 private static bool $initialized = \false;
107002 /**
107003 * Returns true when Xdebug or PCOV is available or
107004 * the runtime used is PHPDBG.
107005 */
107006 public function canCollectCodeCoverage(): bool
107007 {
107008 return $this->hasXdebug() || $this->hasPCOV() || $this->hasPHPDBGCodeCoverage();
107009 }
107010 /**
107011 * Returns true when Zend OPcache is loaded, enabled,
107012 * and is configured to discard comments.
107013 */
107014 public function discardsComments(): bool
107015 {
107016 if (!$this->isOpcacheActive()) {
107017 return \false;
107018 }
107019 if (ini_get('opcache.save_comments') !== '0') {
107020 return \false;
107021 }
107022 return \true;
107023 }
107024 /**
107025 * Returns true when Zend OPcache is loaded, enabled,
107026 * and is configured to perform just-in-time compilation.
107027 */
107028 public function performsJustInTimeCompilation(): bool
107029 {
107030 if (PHP_MAJOR_VERSION < 8) {
107031 return \false;
107032 }
107033 if (!$this->isOpcacheActive()) {
107034 return \false;
107035 }
107036 if (ini_get('opcache.jit_buffer_size') === '0') {
107037 return \false;
107038 }
107039 $jit = ini_get('opcache.jit');
107040 if ($jit === 'disable' || $jit === 'off') {
107041 return \false;
107042 }
107043 if (strrpos($jit, '0') === 3) {
107044 return \false;
107045 }
107046 return \true;
107047 }
107048 /**
107049 * Returns the raw path to the binary of the current runtime.
107050 */
107051 public function getRawBinary(): string
107052 {
107053 if (self::$initialized) {
107054 return self::$rawBinary;
107055 }
107056 if (PHP_BINARY !== '') {
107057 self::$rawBinary = PHP_BINARY;
107058 self::$initialized = \true;
107059 return self::$rawBinary;
107060 }
107061 // @codeCoverageIgnoreStart
107062 $possibleBinaryLocations = [PHP_BINDIR . '/php', PHP_BINDIR . '/php-cli.exe', PHP_BINDIR . '/php.exe'];
107063 foreach ($possibleBinaryLocations as $binary) {
107064 if (is_readable($binary)) {
107065 self::$rawBinary = $binary;
107066 self::$initialized = \true;
107067 return self::$rawBinary;
107068 }
107069 }
107070 self::$rawBinary = 'php';
107071 self::$initialized = \true;
107072 return self::$rawBinary;
107073 // @codeCoverageIgnoreEnd
107074 }
107075 /**
107076 * Returns the escaped path to the binary of the current runtime.
107077 */
107078 public function getBinary(): string
107079 {
107080 return escapeshellarg($this->getRawBinary());
107081 }
107082 public function getNameWithVersion(): string
107083 {
107084 return $this->getName() . ' ' . $this->getVersion();
107085 }
107086 public function getNameWithVersionAndCodeCoverageDriver(): string
107087 {
107088 if ($this->hasPCOV()) {
107089 return sprintf('%s with PCOV %s', $this->getNameWithVersion(), phpversion('pcov'));
107090 }
107091 if ($this->hasXdebug()) {
107092 return sprintf('%s with Xdebug %s', $this->getNameWithVersion(), phpversion('xdebug'));
107093 }
107094 return $this->getNameWithVersion();
107095 }
107096 public function getName(): string
107097 {
107098 if ($this->isPHPDBG()) {
107099 // @codeCoverageIgnoreStart
107100 return 'PHPDBG';
107101 // @codeCoverageIgnoreEnd
107102 }
107103 return 'PHP';
107104 }
107105 public function getVendorUrl(): string
107106 {
107107 return 'https://www.php.net/';
107108 }
107109 public function getVersion(): string
107110 {
107111 return PHP_VERSION;
107112 }
107113 /**
107114 * Returns true when the runtime used is PHP and Xdebug is loaded.
107115 */
107116 public function hasXdebug(): bool
107117 {
107118 return $this->isPHP() && extension_loaded('xdebug');
107119 }
107120 /**
107121 * Returns true when the runtime used is PHP without the PHPDBG SAPI.
107122 */
107123 public function isPHP(): bool
107124 {
107125 return !$this->isPHPDBG();
107126 }
107127 /**
107128 * Returns true when the runtime used is PHP with the PHPDBG SAPI.
107129 */
107130 public function isPHPDBG(): bool
107131 {
107132 return PHP_SAPI === 'phpdbg';
107133 }
107134 /**
107135 * Returns true when the runtime used is PHP with the PHPDBG SAPI
107136 * and the phpdbg_*_oplog() functions are available (PHP >= 7.0).
107137 */
107138 public function hasPHPDBGCodeCoverage(): bool
107139 {
107140 return $this->isPHPDBG();
107141 }
107142 /**
107143 * Returns true when the runtime used is PHP with PCOV loaded and enabled.
107144 */
107145 public function hasPCOV(): bool
107146 {
107147 return $this->isPHP() && extension_loaded('pcov') && ini_get('pcov.enabled');
107148 }
107149 /**
107150 * Parses the loaded php.ini file (if any) as well as all
107151 * additional php.ini files from the additional ini dir for
107152 * a list of all configuration settings loaded from files
107153 * at startup. Then checks for each php.ini setting passed
107154 * via the `$values` parameter whether this setting has
107155 * been changed at runtime. Returns an array of strings
107156 * where each string has the format `key=value` denoting
107157 * the name of a changed php.ini setting with its new value.
107158 *
107159 * @return string[]
107160 */
107161 public function getCurrentSettings(array $values): array
107162 {
107163 $diff = [];
107164 $files = [];
107165 if ($file = php_ini_loaded_file()) {
107166 $files[] = $file;
107167 }
107168 if ($scanned = php_ini_scanned_files()) {
107169 $files = array_merge($files, array_map('trim', explode(",\n", $scanned)));
107170 }
107171 foreach ($files as $ini) {
107172 $config = parse_ini_file($ini, \true);
107173 foreach ($values as $value) {
107174 $set = ini_get($value);
107175 if (empty($set)) {
107176 continue;
107177 }
107178 if (!isset($config[$value]) || $set !== $config[$value]) {
107179 $diff[$value] = sprintf('%s=%s', $value, $set);
107180 }
107181 }
107182 }
107183 return $diff;
107184 }
107185 private function isOpcacheActive(): bool
107186 {
107187 if (!extension_loaded('Zend OPcache')) {
107188 return \false;
107189 }
107190 if ((PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') && ini_get('opcache.enable_cli') === '1') {
107191 return \true;
107192 }
107193 if (PHP_SAPI !== 'cli' && PHP_SAPI !== 'phpdbg' && ini_get('opcache.enable') === '1') {
107194 return \true;
107195 }
107196 return \false;
107197 }
107198 }
107199 <?php
107200
107201 declare (strict_types=1);
107202 /*
107203 * This file is part of sebastian/exporter.
107204 *
107205 * (c) Sebastian Bergmann <sebastian@phpunit.de>
107206 *
107207 * For the full copyright and license information, please view the LICENSE
107208 * file that was distributed with this source code.
107209 */
107210 namespace PHPUnitPHAR\SebastianBergmann\Exporter;
107211
107212 use function bin2hex;
107213 use function count;
107214 use function get_resource_type;
107215 use function gettype;
107216 use function implode;
107217 use function ini_get;
107218 use function ini_set;
107219 use function is_array;
107220 use function is_bool;
107221 use function is_float;
107222 use function is_object;
107223 use function is_resource;
107224 use function is_string;
107225 use function mb_strlen;
107226 use function mb_substr;
107227 use function preg_match;
107228 use function spl_object_id;
107229 use function sprintf;
107230 use function str_repeat;
107231 use function str_replace;
107232 use function var_export;
107233 use BackedEnum;
107234 use PHPUnitPHAR\SebastianBergmann\RecursionContext\Context;
107235 use SplObjectStorage;
107236 use UnitEnum;
107237 final class Exporter
107238 {
107239 /**
107240 * Exports a value as a string.
107241 *
107242 * The output of this method is similar to the output of print_r(), but
107243 * improved in various aspects:
107244 *
107245 * - NULL is rendered as "null" (instead of "")
107246 * - TRUE is rendered as "true" (instead of "1")
107247 * - FALSE is rendered as "false" (instead of "")
107248 * - Strings are always quoted with single quotes
107249 * - Carriage returns and newlines are normalized to \n
107250 * - Recursion and repeated rendering is treated properly
107251 */
107252 public function export(mixed $value, int $indentation = 0): string
107253 {
107254 return $this->recursiveExport($value, $indentation);
107255 }
107256 public function shortenedRecursiveExport(array &$data, ?Context $context = null): string
107257 {
107258 $result = [];
107259 $exporter = new self();
107260 if (!$context) {
107261 $context = new Context();
107262 }
107263 $array = $data;
107264 /* @noinspection UnusedFunctionResultInspection */
107265 $context->add($data);
107266 foreach ($array as $key => $value) {
107267 if (is_array($value)) {
107268 if ($context->contains($data[$key]) !== \false) {
107269 $result[] = '*RECURSION*';
107270 } else {
107271 $result[] = sprintf('[%s]', $this->shortenedRecursiveExport($data[$key], $context));
107272 }
107273 } else {
107274 $result[] = $exporter->shortenedExport($value);
107275 }
107276 }
107277 return implode(', ', $result);
107278 }
107279 /**
107280 * Exports a value into a single-line string.
107281 *
107282 * The output of this method is similar to the output of
107283 * SebastianBergmann\Exporter\Exporter::export().
107284 *
107285 * Newlines are replaced by the visible string '\n'.
107286 * Contents of arrays and objects (if any) are replaced by '...'.
107287 */
107288 public function shortenedExport(mixed $value): string
107289 {
107290 if (is_string($value)) {
107291 $string = str_replace("\n", '', $this->export($value));
107292 if (mb_strlen($string) > 40) {
107293 return mb_substr($string, 0, 30) . '...' . mb_substr($string, -7);
107294 }
107295 return $string;
107296 }
107297 if ($value instanceof BackedEnum) {
107298 return sprintf('%s Enum (%s, %s)', $value::class, $value->name, $this->export($value->value));
107299 }
107300 if ($value instanceof UnitEnum) {
107301 return sprintf('%s Enum (%s)', $value::class, $value->name);
107302 }
107303 if (is_object($value)) {
107304 return sprintf('%s Object (%s)', $value::class, count($this->toArray($value)) > 0 ? '...' : '');
107305 }
107306 if (is_array($value)) {
107307 return sprintf('[%s]', count($value) > 0 ? '...' : '');
107308 }
107309 return $this->export($value);
107310 }
107311 /**
107312 * Converts an object to an array containing all of its private, protected
107313 * and public properties.
107314 */
107315 public function toArray(mixed $value): array
107316 {
107317 if (!is_object($value)) {
107318 return (array) $value;
107319 }
107320 $array = [];
107321 foreach ((array) $value as $key => $val) {
107322 // Exception traces commonly reference hundreds to thousands of
107323 // objects currently loaded in memory. Including them in the result
107324 // has a severe negative performance impact.
107325 if ("\x00Error\x00trace" === $key || "\x00Exception\x00trace" === $key) {
107326 continue;
107327 }
107328 // properties are transformed to keys in the following way:
107329 // private $propertyName => "\0ClassName\0propertyName"
107330 // protected $propertyName => "\0*\0propertyName"
107331 // public $propertyName => "propertyName"
107332 if (preg_match('/\0.+\0(.+)/', (string) $key, $matches)) {
107333 $key = $matches[1];
107334 }
107335 // See https://github.com/php/php-src/commit/5721132
107336 if ($key === "\x00gcdata") {
107337 continue;
107338 }
107339 $array[$key] = $val;
107340 }
107341 // Some internal classes like SplObjectStorage do not work with the
107342 // above (fast) mechanism nor with reflection in Zend.
107343 // Format the output similarly to print_r() in this case
107344 if ($value instanceof SplObjectStorage) {
107345 foreach ($value as $_value) {
107346 $array['Object #' . spl_object_id($_value)] = ['obj' => $_value, 'inf' => $value->getInfo()];
107347 }
107348 $value->rewind();
107349 }
107350 return $array;
107351 }
107352 private function recursiveExport(mixed &$value, int $indentation, ?Context $processed = null): string
107353 {
107354 if ($value === null) {
107355 return 'null';
107356 }
107357 if (is_bool($value)) {
107358 return $value ? 'true' : 'false';
107359 }
107360 if (is_float($value)) {
107361 $precisionBackup = ini_get('precision');
107362 ini_set('precision', '-1');
107363 $valueAsString = @(string) $value;
107364 ini_set('precision', $precisionBackup);
107365 if ((string) @(int) $value === $valueAsString) {
107366 return $valueAsString . '.0';
107367 }
107368 return $valueAsString;
107369 }
107370 if (gettype($value) === 'resource (closed)') {
107371 return 'resource (closed)';
107372 }
107373 if (is_resource($value)) {
107374 return sprintf('resource(%d) of type (%s)', (int) $value, get_resource_type($value));
107375 }
107376 if ($value instanceof BackedEnum) {
107377 return sprintf('%s Enum #%d (%s, %s)', $value::class, spl_object_id($value), $value->name, $this->export($value->value, $indentation));
107378 }
107379 if ($value instanceof UnitEnum) {
107380 return sprintf('%s Enum #%d (%s)', $value::class, spl_object_id($value), $value->name);
107381 }
107382 if (is_string($value)) {
107383 // Match for most non-printable chars somewhat taking multibyte chars into account
107384 if (preg_match('/[^\x09-\x0d\x1b\x20-\xff]/', $value)) {
107385 return 'Binary String: 0x' . bin2hex($value);
107386 }
107387 return "'" . str_replace('<lf>', "\n", str_replace(["\r\n", "\n\r", "\r", "\n"], ['\r\n<lf>', '\n\r<lf>', '\r<lf>', '\n<lf>'], $value)) . "'";
107388 }
107389 $whitespace = str_repeat(' ', 4 * $indentation);
107390 if (!$processed) {
107391 $processed = new Context();
107392 }
107393 if (is_array($value)) {
107394 if (($key = $processed->contains($value)) !== \false) {
107395 return 'Array &' . $key;
107396 }
107397 $array = $value;
107398 $key = $processed->add($value);
107399 $values = '';
107400 if (count($array) > 0) {
107401 foreach ($array as $k => $v) {
107402 $values .= $whitespace . ' ' . $this->recursiveExport($k, $indentation) . ' => ' . $this->recursiveExport($value[$k], $indentation + 1, $processed) . ",\n";
107403 }
107404 $values = "\n" . $values . $whitespace;
107405 }
107406 return 'Array &' . (string) $key . ' [' . $values . ']';
107407 }
107408 if (is_object($value)) {
107409 $class = $value::class;
107410 if ($processed->contains($value) !== \false) {
107411 return $class . ' Object #' . spl_object_id($value);
107412 }
107413 $processed->add($value);
107414 $values = '';
107415 $array = $this->toArray($value);
107416 if (count($array) > 0) {
107417 foreach ($array as $k => $v) {
107418 $values .= $whitespace . ' ' . $this->recursiveExport($k, $indentation) . ' => ' . $this->recursiveExport($v, $indentation + 1, $processed) . ",\n";
107419 }
107420 $values = "\n" . $values . $whitespace;
107421 }
107422 return $class . ' Object #' . spl_object_id($value) . ' (' . $values . ')';
107423 }
107424 return var_export($value, \true);
107425 }
107426 }
107427 BSD 3-Clause License
107428
107429 Copyright (c) 2002-2025, Sebastian Bergmann
107430 All rights reserved.
107431
107432 Redistribution and use in source and binary forms, with or without
107433 modification, are permitted provided that the following conditions are met:
107434
107435 1. Redistributions of source code must retain the above copyright notice, this
107436 list of conditions and the following disclaimer.
107437
107438 2. Redistributions in binary form must reproduce the above copyright notice,
107439 this list of conditions and the following disclaimer in the documentation
107440 and/or other materials provided with the distribution.
107441
107442 3. Neither the name of the copyright holder nor the names of its
107443 contributors may be used to endorse or promote products derived from
107444 this software without specific prior written permission.
107445
107446 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
107447 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
107448 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
107449 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
107450 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
107451 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
107452 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
107453 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
107454 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
107455 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
107456 <?php
107457
107458 declare (strict_types=1);
107459 /*
107460 * This file is part of sebastian/global-state.
107461 *
107462 * (c) Sebastian Bergmann <sebastian@phpunit.de>
107463 *
107464 * For the full copyright and license information, please view the LICENSE
107465 * file that was distributed with this source code.
107466 */
107467 namespace PHPUnitPHAR\SebastianBergmann\GlobalState;
107468
107469 use const PHP_EOL;
107470 use function is_array;
107471 use function is_scalar;
107472 use function serialize;
107473 use function sprintf;
107474 use function var_export;
107475 final class CodeExporter
107476 {
107477 public function constants(Snapshot $snapshot): string
107478 {
107479 $result = '';
107480 foreach ($snapshot->constants() as $name => $value) {
107481 $result .= sprintf('if (!defined(\'%s\')) define(\'%s\', %s);' . "\n", $name, $name, $this->exportVariable($value));
107482 }
107483 return $result;
107484 }
107485 public function globalVariables(Snapshot $snapshot): string
107486 {
107487 $result = <<<'EOT'
107488 call_user_func(
107489 function ()
107490 {
107491 foreach (array_keys($GLOBALS) as $key) {
107492 unset($GLOBALS[$key]);
107493 }
107494 }
107495 );
107496
107497
107498 EOT;
107499 foreach ($snapshot->globalVariables() as $name => $value) {
107500 $result .= sprintf('$GLOBALS[%s] = %s;' . PHP_EOL, $this->exportVariable($name), $this->exportVariable($value));
107501 }
107502 return $result;
107503 }
107504 public function iniSettings(Snapshot $snapshot): string
107505 {
107506 $result = '';
107507 foreach ($snapshot->iniSettings() as $key => $value) {
107508 $result .= sprintf('@ini_set(%s, %s);' . "\n", $this->exportVariable($key), $this->exportVariable($value));
107509 }
107510 return $result;
107511 }
107512 private function exportVariable(mixed $variable): string
107513 {
107514 if (is_scalar($variable) || null === $variable || is_array($variable) && $this->arrayOnlyContainsScalars($variable)) {
107515 return var_export($variable, \true);
107516 }
107517 return 'unserialize(' . var_export(serialize($variable), \true) . ')';
107518 }
107519 private function arrayOnlyContainsScalars(array $array): bool
107520 {
107521 $result = \true;
107522 foreach ($array as $element) {
107523 if (is_array($element)) {
107524 $result = $this->arrayOnlyContainsScalars($element);
107525 } elseif (!is_scalar($element) && null !== $element) {
107526 $result = \false;
107527 }
107528 if ($result === \false) {
107529 break;
107530 }
107531 }
107532 return $result;
107533 }
107534 }
107535 <?php
107536
107537 declare (strict_types=1);
107538 /*
107539 * This file is part of sebastian/global-state.
107540 *
107541 * (c) Sebastian Bergmann <sebastian@phpunit.de>
107542 *
107543 * For the full copyright and license information, please view the LICENSE
107544 * file that was distributed with this source code.
107545 */
107546 namespace PHPUnitPHAR\SebastianBergmann\GlobalState;
107547
107548 use function in_array;
107549 use function str_starts_with;
107550 use ReflectionClass;
107551 final class ExcludeList
107552 {
107553 private array $globalVariables = [];
107554 private array $classes = [];
107555 private array $classNamePrefixes = [];
107556 private array $parentClasses = [];
107557 private array $interfaces = [];
107558 private array $staticProperties = [];
107559 public function addGlobalVariable(string $variableName): void
107560 {
107561 $this->globalVariables[$variableName] = \true;
107562 }
107563 public function addClass(string $className): void
107564 {
107565 $this->classes[] = $className;
107566 }
107567 public function addSubclassesOf(string $className): void
107568 {
107569 $this->parentClasses[] = $className;
107570 }
107571 public function addImplementorsOf(string $interfaceName): void
107572 {
107573 $this->interfaces[] = $interfaceName;
107574 }
107575 public function addClassNamePrefix(string $classNamePrefix): void
107576 {
107577 $this->classNamePrefixes[] = $classNamePrefix;
107578 }
107579 public function addStaticProperty(string $className, string $propertyName): void
107580 {
107581 if (!isset($this->staticProperties[$className])) {
107582 $this->staticProperties[$className] = [];
107583 }
107584 $this->staticProperties[$className][$propertyName] = \true;
107585 }
107586 public function isGlobalVariableExcluded(string $variableName): bool
107587 {
107588 return isset($this->globalVariables[$variableName]);
107589 }
107590 /**
107591 * @psalm-param class-string $className
107592 */
107593 public function isStaticPropertyExcluded(string $className, string $propertyName): bool
107594 {
107595 if (in_array($className, $this->classes, \true)) {
107596 return \true;
107597 }
107598 foreach ($this->classNamePrefixes as $prefix) {
107599 if (str_starts_with($className, $prefix)) {
107600 return \true;
107601 }
107602 }
107603 $class = new ReflectionClass($className);
107604 foreach ($this->parentClasses as $type) {
107605 if ($class->isSubclassOf($type)) {
107606 return \true;
107607 }
107608 }
107609 foreach ($this->interfaces as $type) {
107610 if ($class->implementsInterface($type)) {
107611 return \true;
107612 }
107613 }
107614 return isset($this->staticProperties[$className][$propertyName]);
107615 }
107616 }
107617 BSD 3-Clause License
107618
107619 Copyright (c) 2001-2024, Sebastian Bergmann
107620 All rights reserved.
107621
107622 Redistribution and use in source and binary forms, with or without
107623 modification, are permitted provided that the following conditions are met:
107624
107625 1. Redistributions of source code must retain the above copyright notice, this
107626 list of conditions and the following disclaimer.
107627
107628 2. Redistributions in binary form must reproduce the above copyright notice,
107629 this list of conditions and the following disclaimer in the documentation
107630 and/or other materials provided with the distribution.
107631
107632 3. Neither the name of the copyright holder nor the names of its
107633 contributors may be used to endorse or promote products derived from
107634 this software without specific prior written permission.
107635
107636 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
107637 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
107638 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
107639 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
107640 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
107641 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
107642 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
107643 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
107644 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
107645 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
107646 <?php
107647
107648 declare (strict_types=1);
107649 /*
107650 * This file is part of sebastian/global-state.
107651 *
107652 * (c) Sebastian Bergmann <sebastian@phpunit.de>
107653 *
107654 * For the full copyright and license information, please view the LICENSE
107655 * file that was distributed with this source code.
107656 */
107657 namespace PHPUnitPHAR\SebastianBergmann\GlobalState;
107658
107659 use function array_diff;
107660 use function array_key_exists;
107661 use function array_keys;
107662 use function array_merge;
107663 use function in_array;
107664 use function is_array;
107665 use ReflectionClass;
107666 use ReflectionProperty;
107667 final class Restorer
107668 {
107669 public function restoreGlobalVariables(Snapshot $snapshot): void
107670 {
107671 $superGlobalArrays = $snapshot->superGlobalArrays();
107672 foreach ($superGlobalArrays as $superGlobalArray) {
107673 $this->restoreSuperGlobalArray($snapshot, $superGlobalArray);
107674 }
107675 $globalVariables = $snapshot->globalVariables();
107676 foreach (array_keys($GLOBALS) as $key) {
107677 if ($key !== 'GLOBALS' && !in_array($key, $superGlobalArrays, \true) && !$snapshot->excludeList()->isGlobalVariableExcluded($key)) {
107678 if (array_key_exists($key, $globalVariables)) {
107679 $GLOBALS[$key] = $globalVariables[$key];
107680 } else {
107681 unset($GLOBALS[$key]);
107682 }
107683 }
107684 }
107685 }
107686 public function restoreStaticProperties(Snapshot $snapshot): void
107687 {
107688 $current = new Snapshot($snapshot->excludeList(), \false, \false, \false, \false, \true, \false, \false, \false, \false);
107689 $newClasses = array_diff($current->classes(), $snapshot->classes());
107690 unset($current);
107691 foreach ($snapshot->staticProperties() as $className => $staticProperties) {
107692 foreach ($staticProperties as $name => $value) {
107693 $reflector = new ReflectionProperty($className, $name);
107694 $reflector->setValue(null, $value);
107695 }
107696 }
107697 foreach ($newClasses as $className) {
107698 $class = new ReflectionClass($className);
107699 $defaults = $class->getDefaultProperties();
107700 foreach ($class->getProperties() as $property) {
107701 if (!$property->isStatic()) {
107702 continue;
107703 }
107704 $name = $property->getName();
107705 if ($snapshot->excludeList()->isStaticPropertyExcluded($className, $name)) {
107706 continue;
107707 }
107708 if (!isset($defaults[$name])) {
107709 continue;
107710 }
107711 $property->setValue(null, $defaults[$name]);
107712 }
107713 }
107714 }
107715 private function restoreSuperGlobalArray(Snapshot $snapshot, string $superGlobalArray): void
107716 {
107717 $superGlobalVariables = $snapshot->superGlobalVariables();
107718 if (isset($GLOBALS[$superGlobalArray], $superGlobalVariables[$superGlobalArray]) && is_array($GLOBALS[$superGlobalArray])) {
107719 $keys = array_keys(array_merge($GLOBALS[$superGlobalArray], $superGlobalVariables[$superGlobalArray]));
107720 foreach ($keys as $key) {
107721 if (isset($superGlobalVariables[$superGlobalArray][$key])) {
107722 $GLOBALS[$superGlobalArray][$key] = $superGlobalVariables[$superGlobalArray][$key];
107723 } else {
107724 unset($GLOBALS[$superGlobalArray][$key]);
107725 }
107726 }
107727 }
107728 }
107729 }
107730 <?php
107731
107732 declare (strict_types=1);
107733 /*
107734 * This file is part of sebastian/global-state.
107735 *
107736 * (c) Sebastian Bergmann <sebastian@phpunit.de>
107737 *
107738 * For the full copyright and license information, please view the LICENSE
107739 * file that was distributed with this source code.
107740 */
107741 namespace PHPUnitPHAR\SebastianBergmann\GlobalState;
107742
107743 use function array_keys;
107744 use function array_merge;
107745 use function array_reverse;
107746 use function assert;
107747 use function func_get_args;
107748 use function get_declared_classes;
107749 use function get_declared_interfaces;
107750 use function get_declared_traits;
107751 use function get_defined_constants;
107752 use function get_defined_functions;
107753 use function get_included_files;
107754 use function in_array;
107755 use function ini_get_all;
107756 use function is_array;
107757 use function is_object;
107758 use function is_resource;
107759 use function is_scalar;
107760 use function serialize;
107761 use function unserialize;
107762 use ReflectionClass;
107763 use PHPUnitPHAR\SebastianBergmann\ObjectReflector\ObjectReflector;
107764 use PHPUnitPHAR\SebastianBergmann\RecursionContext\Context;
107765 use Throwable;
107766 /**
107767 * A snapshot of global state.
107768 */
107769 class Snapshot
107770 {
107771 private ExcludeList $excludeList;
107772 private array $globalVariables = [];
107773 private array $superGlobalArrays = [];
107774 private array $superGlobalVariables = [];
107775 private array $staticProperties = [];
107776 private array $iniSettings = [];
107777 private array $includedFiles = [];
107778 private array $constants = [];
107779 private array $functions = [];
107780 private array $interfaces = [];
107781 private array $classes = [];
107782 private array $traits = [];
107783 public function __construct(?ExcludeList $excludeList = null, bool $includeGlobalVariables = \true, bool $includeStaticProperties = \true, bool $includeConstants = \true, bool $includeFunctions = \true, bool $includeClasses = \true, bool $includeInterfaces = \true, bool $includeTraits = \true, bool $includeIniSettings = \true, bool $includeIncludedFiles = \true)
107784 {
107785 $this->excludeList = $excludeList ?: new ExcludeList();
107786 if ($includeConstants) {
107787 $this->snapshotConstants();
107788 }
107789 if ($includeFunctions) {
107790 $this->snapshotFunctions();
107791 }
107792 if ($includeClasses || $includeStaticProperties) {
107793 $this->snapshotClasses();
107794 }
107795 if ($includeInterfaces) {
107796 $this->snapshotInterfaces();
107797 }
107798 if ($includeGlobalVariables) {
107799 $this->setupSuperGlobalArrays();
107800 $this->snapshotGlobals();
107801 }
107802 if ($includeStaticProperties) {
107803 $this->snapshotStaticProperties();
107804 }
107805 if ($includeIniSettings) {
107806 $this->iniSettings = ini_get_all(null, \false);
107807 }
107808 if ($includeIncludedFiles) {
107809 $this->includedFiles = get_included_files();
107810 }
107811 if ($includeTraits) {
107812 $this->traits = get_declared_traits();
107813 }
107814 }
107815 public function excludeList(): ExcludeList
107816 {
107817 return $this->excludeList;
107818 }
107819 public function globalVariables(): array
107820 {
107821 return $this->globalVariables;
107822 }
107823 public function superGlobalVariables(): array
107824 {
107825 return $this->superGlobalVariables;
107826 }
107827 public function superGlobalArrays(): array
107828 {
107829 return $this->superGlobalArrays;
107830 }
107831 public function staticProperties(): array
107832 {
107833 return $this->staticProperties;
107834 }
107835 public function iniSettings(): array
107836 {
107837 return $this->iniSettings;
107838 }
107839 public function includedFiles(): array
107840 {
107841 return $this->includedFiles;
107842 }
107843 public function constants(): array
107844 {
107845 return $this->constants;
107846 }
107847 public function functions(): array
107848 {
107849 return $this->functions;
107850 }
107851 public function interfaces(): array
107852 {
107853 return $this->interfaces;
107854 }
107855 public function classes(): array
107856 {
107857 return $this->classes;
107858 }
107859 public function traits(): array
107860 {
107861 return $this->traits;
107862 }
107863 private function snapshotConstants(): void
107864 {
107865 $constants = get_defined_constants(\true);
107866 if (isset($constants['user'])) {
107867 $this->constants = $constants['user'];
107868 }
107869 }
107870 private function snapshotFunctions(): void
107871 {
107872 $functions = get_defined_functions();
107873 $this->functions = $functions['user'];
107874 }
107875 private function snapshotClasses(): void
107876 {
107877 foreach (array_reverse(get_declared_classes()) as $className) {
107878 $class = new ReflectionClass($className);
107879 if (!$class->isUserDefined()) {
107880 break;
107881 }
107882 $this->classes[] = $className;
107883 }
107884 $this->classes = array_reverse($this->classes);
107885 }
107886 private function snapshotInterfaces(): void
107887 {
107888 foreach (array_reverse(get_declared_interfaces()) as $interfaceName) {
107889 $class = new ReflectionClass($interfaceName);
107890 if (!$class->isUserDefined()) {
107891 break;
107892 }
107893 $this->interfaces[] = $interfaceName;
107894 }
107895 $this->interfaces = array_reverse($this->interfaces);
107896 }
107897 private function snapshotGlobals(): void
107898 {
107899 $superGlobalArrays = $this->superGlobalArrays();
107900 foreach ($superGlobalArrays as $superGlobalArray) {
107901 $this->snapshotSuperGlobalArray($superGlobalArray);
107902 }
107903 foreach (array_keys($GLOBALS) as $key) {
107904 if ($key !== 'GLOBALS' && !in_array($key, $superGlobalArrays, \true) && $this->canBeSerialized($GLOBALS[$key]) && !$this->excludeList->isGlobalVariableExcluded($key)) {
107905 /* @noinspection UnserializeExploitsInspection */
107906 $this->globalVariables[$key] = unserialize(serialize($GLOBALS[$key]));
107907 }
107908 }
107909 }
107910 private function snapshotSuperGlobalArray(string $superGlobalArray): void
107911 {
107912 $this->superGlobalVariables[$superGlobalArray] = [];
107913 if (isset($GLOBALS[$superGlobalArray]) && is_array($GLOBALS[$superGlobalArray])) {
107914 foreach ($GLOBALS[$superGlobalArray] as $key => $value) {
107915 /* @noinspection UnserializeExploitsInspection */
107916 $this->superGlobalVariables[$superGlobalArray][$key] = unserialize(serialize($value));
107917 }
107918 }
107919 }
107920 private function snapshotStaticProperties(): void
107921 {
107922 foreach ($this->classes as $className) {
107923 $class = new ReflectionClass($className);
107924 $snapshot = [];
107925 foreach ($class->getProperties() as $property) {
107926 if ($property->isStatic()) {
107927 $name = $property->getName();
107928 if ($this->excludeList->isStaticPropertyExcluded($className, $name)) {
107929 continue;
107930 }
107931 if (!$property->isInitialized()) {
107932 continue;
107933 }
107934 $value = $property->getValue();
107935 if ($this->canBeSerialized($value)) {
107936 /* @noinspection UnserializeExploitsInspection */
107937 $snapshot[$name] = unserialize(serialize($value));
107938 }
107939 }
107940 }
107941 if (!empty($snapshot)) {
107942 $this->staticProperties[$className] = $snapshot;
107943 }
107944 }
107945 }
107946 private function setupSuperGlobalArrays(): void
107947 {
107948 $this->superGlobalArrays = ['_ENV', '_POST', '_GET', '_COOKIE', '_SERVER', '_FILES', '_REQUEST'];
107949 }
107950 private function canBeSerialized(mixed $variable): bool
107951 {
107952 if (is_scalar($variable) || $variable === null) {
107953 return \true;
107954 }
107955 if (is_resource($variable)) {
107956 return \false;
107957 }
107958 foreach ($this->enumerateObjectsAndResources($variable) as $value) {
107959 if (is_resource($value)) {
107960 return \false;
107961 }
107962 if (is_object($value)) {
107963 $class = new ReflectionClass($value);
107964 if ($class->isAnonymous()) {
107965 return \false;
107966 }
107967 try {
107968 @serialize($value);
107969 } catch (Throwable $t) {
107970 return \false;
107971 }
107972 }
107973 }
107974 return \true;
107975 }
107976 private function enumerateObjectsAndResources(mixed $variable): array
107977 {
107978 if (isset(func_get_args()[1])) {
107979 $processed = func_get_args()[1];
107980 } else {
107981 $processed = new Context();
107982 }
107983 assert($processed instanceof Context);
107984 $result = [];
107985 if ($processed->contains($variable)) {
107986 return $result;
107987 }
107988 $array = $variable;
107989 /* @noinspection UnusedFunctionResultInspection */
107990 $processed->add($variable);
107991 if (is_array($variable)) {
107992 foreach ($array as $element) {
107993 if (!is_array($element) && !is_object($element) && !is_resource($element)) {
107994 continue;
107995 }
107996 if (!is_resource($element)) {
107997 /** @noinspection SlowArrayOperationsInLoopInspection */
107998 $result = array_merge($result, $this->enumerateObjectsAndResources($element, $processed));
107999 } else {
108000 $result[] = $element;
108001 }
108002 }
108003 } else {
108004 $result[] = $variable;
108005 foreach ((new ObjectReflector())->getProperties($variable) as $value) {
108006 if (!is_array($value) && !is_object($value) && !is_resource($value)) {
108007 continue;
108008 }
108009 if (!is_resource($value)) {
108010 /** @noinspection SlowArrayOperationsInLoopInspection */
108011 $result = array_merge($result, $this->enumerateObjectsAndResources($value, $processed));
108012 } else {
108013 $result[] = $value;
108014 }
108015 }
108016 }
108017 return $result;
108018 }
108019 }
108020 <?php
108021
108022 declare (strict_types=1);
108023 /*
108024 * This file is part of sebastian/global-state.
108025 *
108026 * (c) Sebastian Bergmann <sebastian@phpunit.de>
108027 *
108028 * For the full copyright and license information, please view the LICENSE
108029 * file that was distributed with this source code.
108030 */
108031 namespace PHPUnitPHAR\SebastianBergmann\GlobalState;
108032
108033 use Throwable;
108034 interface Exception extends Throwable
108035 {
108036 }
108037 <?php
108038
108039 declare (strict_types=1);
108040 /*
108041 * This file is part of sebastian/global-state.
108042 *
108043 * (c) Sebastian Bergmann <sebastian@phpunit.de>
108044 *
108045 * For the full copyright and license information, please view the LICENSE
108046 * file that was distributed with this source code.
108047 */
108048 namespace PHPUnitPHAR\SebastianBergmann\GlobalState;
108049
108050 final class RuntimeException extends \RuntimeException implements Exception
108051 {
108052 }
108053 <?php
108054
108055 declare (strict_types=1);
108056 /*
108057 * This file is part of sebastian/lines-of-code.
108058 *
108059 * (c) Sebastian Bergmann <sebastian@phpunit.de>
108060 *
108061 * For the full copyright and license information, please view the LICENSE
108062 * file that was distributed with this source code.
108063 */
108064 namespace PHPUnitPHAR\SebastianBergmann\LinesOfCode;
108065
108066 use function assert;
108067 use function file_get_contents;
108068 use function substr_count;
108069 use PHPUnitPHAR\PhpParser\Error;
108070 use PHPUnitPHAR\PhpParser\Node;
108071 use PHPUnitPHAR\PhpParser\NodeTraverser;
108072 use PHPUnitPHAR\PhpParser\ParserFactory;
108073 final class Counter
108074 {
108075 /**
108076 * @throws RuntimeException
108077 */
108078 public function countInSourceFile(string $sourceFile): LinesOfCode
108079 {
108080 return $this->countInSourceString(file_get_contents($sourceFile));
108081 }
108082 /**
108083 * @throws RuntimeException
108084 */
108085 public function countInSourceString(string $source): LinesOfCode
108086 {
108087 $linesOfCode = substr_count($source, "\n");
108088 if ($linesOfCode === 0 && !empty($source)) {
108089 $linesOfCode = 1;
108090 }
108091 assert($linesOfCode >= 0);
108092 try {
108093 $nodes = (new ParserFactory())->createForHostVersion()->parse($source);
108094 assert($nodes !== null);
108095 return $this->countInAbstractSyntaxTree($linesOfCode, $nodes);
108096 // @codeCoverageIgnoreStart
108097 } catch (Error $error) {
108098 throw new RuntimeException($error->getMessage(), $error->getCode(), $error);
108099 }
108100 // @codeCoverageIgnoreEnd
108101 }
108102 /**
108103 * @psalm-param non-negative-int $linesOfCode
108104 *
108105 * @param Node[] $nodes
108106 *
108107 * @throws RuntimeException
108108 */
108109 public function countInAbstractSyntaxTree(int $linesOfCode, array $nodes): LinesOfCode
108110 {
108111 $traverser = new NodeTraverser();
108112 $visitor = new LineCountingVisitor($linesOfCode);
108113 $traverser->addVisitor($visitor);
108114 try {
108115 /* @noinspection UnusedFunctionResultInspection */
108116 $traverser->traverse($nodes);
108117 // @codeCoverageIgnoreStart
108118 } catch (Error $error) {
108119 throw new RuntimeException($error->getMessage(), $error->getCode(), $error);
108120 }
108121 // @codeCoverageIgnoreEnd
108122 return $visitor->result();
108123 }
108124 }
108125 <?php
108126
108127 declare (strict_types=1);
108128 /*
108129 * This file is part of sebastian/lines-of-code.
108130 *
108131 * (c) Sebastian Bergmann <sebastian@phpunit.de>
108132 *
108133 * For the full copyright and license information, please view the LICENSE
108134 * file that was distributed with this source code.
108135 */
108136 namespace PHPUnitPHAR\SebastianBergmann\LinesOfCode;
108137
108138 use Throwable;
108139 interface Exception extends Throwable
108140 {
108141 }
108142 <?php
108143
108144 declare (strict_types=1);
108145 /*
108146 * This file is part of sebastian/lines-of-code.
108147 *
108148 * (c) Sebastian Bergmann <sebastian@phpunit.de>
108149 *
108150 * For the full copyright and license information, please view the LICENSE
108151 * file that was distributed with this source code.
108152 */
108153 namespace PHPUnitPHAR\SebastianBergmann\LinesOfCode;
108154
108155 use LogicException;
108156 final class IllogicalValuesException extends LogicException implements Exception
108157 {
108158 }
108159 <?php
108160
108161 declare (strict_types=1);
108162 /*
108163 * This file is part of sebastian/lines-of-code.
108164 *
108165 * (c) Sebastian Bergmann <sebastian@phpunit.de>
108166 *
108167 * For the full copyright and license information, please view the LICENSE
108168 * file that was distributed with this source code.
108169 */
108170 namespace PHPUnitPHAR\SebastianBergmann\LinesOfCode;
108171
108172 use InvalidArgumentException;
108173 final class NegativeValueException extends InvalidArgumentException implements Exception
108174 {
108175 }
108176 <?php
108177
108178 declare (strict_types=1);
108179 /*
108180 * This file is part of sebastian/lines-of-code.
108181 *
108182 * (c) Sebastian Bergmann <sebastian@phpunit.de>
108183 *
108184 * For the full copyright and license information, please view the LICENSE
108185 * file that was distributed with this source code.
108186 */
108187 namespace PHPUnitPHAR\SebastianBergmann\LinesOfCode;
108188
108189 final class RuntimeException extends \RuntimeException implements Exception
108190 {
108191 }
108192 BSD 3-Clause License
108193
108194 Copyright (c) 2020-2023, Sebastian Bergmann
108195 All rights reserved.
108196
108197 Redistribution and use in source and binary forms, with or without
108198 modification, are permitted provided that the following conditions are met:
108199
108200 1. Redistributions of source code must retain the above copyright notice, this
108201 list of conditions and the following disclaimer.
108202
108203 2. Redistributions in binary form must reproduce the above copyright notice,
108204 this list of conditions and the following disclaimer in the documentation
108205 and/or other materials provided with the distribution.
108206
108207 3. Neither the name of the copyright holder nor the names of its
108208 contributors may be used to endorse or promote products derived from
108209 this software without specific prior written permission.
108210
108211 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
108212 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
108213 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
108214 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
108215 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
108216 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
108217 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
108218 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
108219 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
108220 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
108221 <?php
108222
108223 declare (strict_types=1);
108224 /*
108225 * This file is part of sebastian/lines-of-code.
108226 *
108227 * (c) Sebastian Bergmann <sebastian@phpunit.de>
108228 *
108229 * For the full copyright and license information, please view the LICENSE
108230 * file that was distributed with this source code.
108231 */
108232 namespace PHPUnitPHAR\SebastianBergmann\LinesOfCode;
108233
108234 use function array_merge;
108235 use function array_unique;
108236 use function assert;
108237 use function count;
108238 use PHPUnitPHAR\PhpParser\Comment;
108239 use PHPUnitPHAR\PhpParser\Node;
108240 use PHPUnitPHAR\PhpParser\Node\Expr;
108241 use PHPUnitPHAR\PhpParser\NodeVisitorAbstract;
108242 final class LineCountingVisitor extends NodeVisitorAbstract
108243 {
108244 /**
108245 * @psalm-var non-negative-int
108246 */
108247 private readonly int $linesOfCode;
108248 /**
108249 * @var Comment[]
108250 */
108251 private array $comments = [];
108252 /**
108253 * @var int[]
108254 */
108255 private array $linesWithStatements = [];
108256 /**
108257 * @psalm-param non-negative-int $linesOfCode
108258 */
108259 public function __construct(int $linesOfCode)
108260 {
108261 $this->linesOfCode = $linesOfCode;
108262 }
108263 public function enterNode(Node $node): void
108264 {
108265 $this->comments = array_merge($this->comments, $node->getComments());
108266 if (!$node instanceof Expr) {
108267 return;
108268 }
108269 $this->linesWithStatements[] = $node->getStartLine();
108270 }
108271 public function result(): LinesOfCode
108272 {
108273 $commentLinesOfCode = 0;
108274 foreach ($this->comments() as $comment) {
108275 $commentLinesOfCode += $comment->getEndLine() - $comment->getStartLine() + 1;
108276 }
108277 $nonCommentLinesOfCode = $this->linesOfCode - $commentLinesOfCode;
108278 $logicalLinesOfCode = count(array_unique($this->linesWithStatements));
108279 assert($commentLinesOfCode >= 0);
108280 assert($nonCommentLinesOfCode >= 0);
108281 assert($logicalLinesOfCode >= 0);
108282 return new LinesOfCode($this->linesOfCode, $commentLinesOfCode, $nonCommentLinesOfCode, $logicalLinesOfCode);
108283 }
108284 /**
108285 * @return Comment[]
108286 */
108287 private function comments(): array
108288 {
108289 $comments = [];
108290 foreach ($this->comments as $comment) {
108291 $comments[$comment->getStartLine() . '_' . $comment->getStartTokenPos() . '_' . $comment->getEndLine() . '_' . $comment->getEndTokenPos()] = $comment;
108292 }
108293 return $comments;
108294 }
108295 }
108296 <?php
108297
108298 declare (strict_types=1);
108299 /*
108300 * This file is part of sebastian/lines-of-code.
108301 *
108302 * (c) Sebastian Bergmann <sebastian@phpunit.de>
108303 *
108304 * For the full copyright and license information, please view the LICENSE
108305 * file that was distributed with this source code.
108306 */
108307 namespace PHPUnitPHAR\SebastianBergmann\LinesOfCode;
108308
108309 /**
108310 * @psalm-immutable
108311 */
108312 final class LinesOfCode
108313 {
108314 /**
108315 * @psalm-var non-negative-int
108316 */
108317 private readonly int $linesOfCode;
108318 /**
108319 * @psalm-var non-negative-int
108320 */
108321 private readonly int $commentLinesOfCode;
108322 /**
108323 * @psalm-var non-negative-int
108324 */
108325 private readonly int $nonCommentLinesOfCode;
108326 /**
108327 * @psalm-var non-negative-int
108328 */
108329 private readonly int $logicalLinesOfCode;
108330 /**
108331 * @psalm-param non-negative-int $linesOfCode
108332 * @psalm-param non-negative-int $commentLinesOfCode
108333 * @psalm-param non-negative-int $nonCommentLinesOfCode
108334 * @psalm-param non-negative-int $logicalLinesOfCode
108335 *
108336 * @throws IllogicalValuesException
108337 * @throws NegativeValueException
108338 */
108339 public function __construct(int $linesOfCode, int $commentLinesOfCode, int $nonCommentLinesOfCode, int $logicalLinesOfCode)
108340 {
108341 /** @psalm-suppress DocblockTypeContradiction */
108342 if ($linesOfCode < 0) {
108343 throw new NegativeValueException('$linesOfCode must not be negative');
108344 }
108345 /** @psalm-suppress DocblockTypeContradiction */
108346 if ($commentLinesOfCode < 0) {
108347 throw new NegativeValueException('$commentLinesOfCode must not be negative');
108348 }
108349 /** @psalm-suppress DocblockTypeContradiction */
108350 if ($nonCommentLinesOfCode < 0) {
108351 throw new NegativeValueException('$nonCommentLinesOfCode must not be negative');
108352 }
108353 /** @psalm-suppress DocblockTypeContradiction */
108354 if ($logicalLinesOfCode < 0) {
108355 throw new NegativeValueException('$logicalLinesOfCode must not be negative');
108356 }
108357 if ($linesOfCode - $commentLinesOfCode !== $nonCommentLinesOfCode) {
108358 throw new IllogicalValuesException('$linesOfCode !== $commentLinesOfCode + $nonCommentLinesOfCode');
108359 }
108360 $this->linesOfCode = $linesOfCode;
108361 $this->commentLinesOfCode = $commentLinesOfCode;
108362 $this->nonCommentLinesOfCode = $nonCommentLinesOfCode;
108363 $this->logicalLinesOfCode = $logicalLinesOfCode;
108364 }
108365 /**
108366 * @psalm-return non-negative-int
108367 */
108368 public function linesOfCode(): int
108369 {
108370 return $this->linesOfCode;
108371 }
108372 /**
108373 * @psalm-return non-negative-int
108374 */
108375 public function commentLinesOfCode(): int
108376 {
108377 return $this->commentLinesOfCode;
108378 }
108379 /**
108380 * @psalm-return non-negative-int
108381 */
108382 public function nonCommentLinesOfCode(): int
108383 {
108384 return $this->nonCommentLinesOfCode;
108385 }
108386 /**
108387 * @psalm-return non-negative-int
108388 */
108389 public function logicalLinesOfCode(): int
108390 {
108391 return $this->logicalLinesOfCode;
108392 }
108393 public function plus(self $other): self
108394 {
108395 return new self($this->linesOfCode() + $other->linesOfCode(), $this->commentLinesOfCode() + $other->commentLinesOfCode(), $this->nonCommentLinesOfCode() + $other->nonCommentLinesOfCode(), $this->logicalLinesOfCode() + $other->logicalLinesOfCode());
108396 }
108397 }
108398 <?php
108399
108400 declare (strict_types=1);
108401 /*
108402 * This file is part of sebastian/object-enumerator.
108403 *
108404 * (c) Sebastian Bergmann <sebastian@phpunit.de>
108405 *
108406 * For the full copyright and license information, please view the LICENSE
108407 * file that was distributed with this source code.
108408 */
108409 namespace PHPUnitPHAR\SebastianBergmann\ObjectEnumerator;
108410
108411 use function array_merge;
108412 use function is_array;
108413 use function is_object;
108414 use PHPUnitPHAR\SebastianBergmann\ObjectReflector\ObjectReflector;
108415 use PHPUnitPHAR\SebastianBergmann\RecursionContext\Context;
108416 final class Enumerator
108417 {
108418 /**
108419 * @psalm-return list<object>
108420 */
108421 public function enumerate(array|object $variable, Context $processed = new Context()): array
108422 {
108423 $objects = [];
108424 if ($processed->contains($variable)) {
108425 return $objects;
108426 }
108427 $array = $variable;
108428 /* @noinspection UnusedFunctionResultInspection */
108429 $processed->add($variable);
108430 if (is_array($variable)) {
108431 foreach ($array as $element) {
108432 if (!is_array($element) && !is_object($element)) {
108433 continue;
108434 }
108435 /** @noinspection SlowArrayOperationsInLoopInspection */
108436 $objects = array_merge($objects, $this->enumerate($element, $processed));
108437 }
108438 return $objects;
108439 }
108440 $objects[] = $variable;
108441 foreach ((new ObjectReflector())->getProperties($variable) as $value) {
108442 if (!is_array($value) && !is_object($value)) {
108443 continue;
108444 }
108445 /** @noinspection SlowArrayOperationsInLoopInspection */
108446 $objects = array_merge($objects, $this->enumerate($value, $processed));
108447 }
108448 return $objects;
108449 }
108450 }
108451 <?php
108452
108453 declare (strict_types=1);
108454 /*
108455 * This file is part of sebastian/object-reflector.
108456 *
108457 * (c) Sebastian Bergmann <sebastian@phpunit.de>
108458 *
108459 * For the full copyright and license information, please view the LICENSE
108460 * file that was distributed with this source code.
108461 */
108462 namespace PHPUnitPHAR\SebastianBergmann\ObjectReflector;
108463
108464 use function count;
108465 use function explode;
108466 final class ObjectReflector
108467 {
108468 /**
108469 * @psalm-return array<string,mixed>
108470 */
108471 public function getProperties(object $object): array
108472 {
108473 $properties = [];
108474 $className = $object::class;
108475 foreach ((array) $object as $name => $value) {
108476 $name = explode("\x00", (string) $name);
108477 if (count($name) === 1) {
108478 $name = $name[0];
108479 } elseif ($name[1] !== $className) {
108480 $name = $name[1] . '::' . $name[2];
108481 } else {
108482 $name = $name[2];
108483 }
108484 $properties[$name] = $value;
108485 }
108486 return $properties;
108487 }
108488 }
108489 <?php
108490
108491 declare (strict_types=1);
108492 /*
108493 * This file is part of sebastian/recursion-context.
108494 *
108495 * (c) Sebastian Bergmann <sebastian@phpunit.de>
108496 *
108497 * For the full copyright and license information, please view the LICENSE
108498 * file that was distributed with this source code.
108499 */
108500 namespace PHPUnitPHAR\SebastianBergmann\RecursionContext;
108501
108502 use const PHP_INT_MAX;
108503 use const PHP_INT_MIN;
108504 use function array_key_exists;
108505 use function array_pop;
108506 use function array_slice;
108507 use function count;
108508 use function is_array;
108509 use function random_int;
108510 use function spl_object_hash;
108511 use SplObjectStorage;
108512 final class Context
108513 {
108514 private array $arrays = [];
108515 private SplObjectStorage $objects;
108516 public function __construct()
108517 {
108518 $this->objects = new SplObjectStorage();
108519 }
108520 /**
108521 * @codeCoverageIgnore
108522 */
108523 public function __destruct()
108524 {
108525 foreach ($this->arrays as &$array) {
108526 if (is_array($array)) {
108527 array_pop($array);
108528 array_pop($array);
108529 }
108530 }
108531 }
108532 /**
108533 * @psalm-template T of object|array
108534 *
108535 * @psalm-param T $value
108536 *
108537 * @param-out T $value
108538 */
108539 public function add(array|object &$value): false|int|string
108540 {
108541 if (is_array($value)) {
108542 return $this->addArray($value);
108543 }
108544 return $this->addObject($value);
108545 }
108546 /**
108547 * @psalm-template T of object|array
108548 *
108549 * @psalm-param T $value
108550 *
108551 * @param-out T $value
108552 */
108553 public function contains(array|object &$value): false|int|string
108554 {
108555 if (is_array($value)) {
108556 return $this->containsArray($value);
108557 }
108558 return $this->containsObject($value);
108559 }
108560 private function addArray(array &$array): int
108561 {
108562 $key = $this->containsArray($array);
108563 if ($key !== \false) {
108564 return $key;
108565 }
108566 $key = count($this->arrays);
108567 $this->arrays[] =& $array;
108568 if (!array_key_exists(PHP_INT_MAX, $array) && !array_key_exists(PHP_INT_MAX - 1, $array)) {
108569 $array[] = $key;
108570 $array[] = $this->objects;
108571 } else {
108572 /* Cover the improbable case, too.
108573 *
108574 * Note that array_slice() (used in containsArray()) will return the
108575 * last two values added, *not necessarily* the highest integer keys
108576 * in the array. Therefore, the order of these writes to $array is
108577 * important, but the actual keys used is not. */
108578 do {
108579 /** @noinspection PhpUnhandledExceptionInspection */
108580 $key = random_int(PHP_INT_MIN, PHP_INT_MAX);
108581 } while (array_key_exists($key, $array));
108582 $array[$key] = $key;
108583 do {
108584 /** @noinspection PhpUnhandledExceptionInspection */
108585 $key = random_int(PHP_INT_MIN, PHP_INT_MAX);
108586 } while (array_key_exists($key, $array));
108587 $array[$key] = $this->objects;
108588 }
108589 return $key;
108590 }
108591 private function addObject(object $object): string
108592 {
108593 if (!$this->objects->offsetExists($object)) {
108594 $this->objects->offsetSet($object);
108595 }
108596 return spl_object_hash($object);
108597 }
108598 private function containsArray(array $array): false|int
108599 {
108600 $end = array_slice($array, -2);
108601 return isset($end[1]) && $end[1] === $this->objects ? $end[0] : \false;
108602 }
108603 private function containsObject(object $value): false|string
108604 {
108605 if ($this->objects->offsetExists($value)) {
108606 return spl_object_hash($value);
108607 }
108608 return \false;
108609 }
108610 }
108611 BSD 3-Clause License
108612
108613 Copyright (c) 2002-2025, Sebastian Bergmann
108614 All rights reserved.
108615
108616 Redistribution and use in source and binary forms, with or without
108617 modification, are permitted provided that the following conditions are met:
108618
108619 1. Redistributions of source code must retain the above copyright notice, this
108620 list of conditions and the following disclaimer.
108621
108622 2. Redistributions in binary form must reproduce the above copyright notice,
108623 this list of conditions and the following disclaimer in the documentation
108624 and/or other materials provided with the distribution.
108625
108626 3. Neither the name of the copyright holder nor the names of its
108627 contributors may be used to endorse or promote products derived from
108628 this software without specific prior written permission.
108629
108630 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
108631 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
108632 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
108633 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
108634 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
108635 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
108636 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
108637 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
108638 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
108639 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
108640 BSD 3-Clause License
108641
108642 Copyright (c) 2019-2023, Sebastian Bergmann
108643 All rights reserved.
108644
108645 Redistribution and use in source and binary forms, with or without
108646 modification, are permitted provided that the following conditions are met:
108647
108648 1. Redistributions of source code must retain the above copyright notice, this
108649 list of conditions and the following disclaimer.
108650
108651 2. Redistributions in binary form must reproduce the above copyright notice,
108652 this list of conditions and the following disclaimer in the documentation
108653 and/or other materials provided with the distribution.
108654
108655 3. Neither the name of the copyright holder nor the names of its
108656 contributors may be used to endorse or promote products derived from
108657 this software without specific prior written permission.
108658
108659 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
108660 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
108661 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
108662 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
108663 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
108664 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
108665 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
108666 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
108667 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
108668 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
108669 <?php
108670
108671 declare (strict_types=1);
108672 /*
108673 * This file is part of sebastian/type.
108674 *
108675 * (c) Sebastian Bergmann <sebastian@phpunit.de>
108676 *
108677 * For the full copyright and license information, please view the LICENSE
108678 * file that was distributed with this source code.
108679 */
108680 namespace PHPUnitPHAR\SebastianBergmann\Type;
108681
108682 final class Parameter
108683 {
108684 /**
108685 * @psalm-var non-empty-string
108686 */
108687 private string $name;
108688 private Type $type;
108689 /**
108690 * @psalm-param non-empty-string $name
108691 */
108692 public function __construct(string $name, Type $type)
108693 {
108694 $this->name = $name;
108695 $this->type = $type;
108696 }
108697 public function name(): string
108698 {
108699 return $this->name;
108700 }
108701 public function type(): Type
108702 {
108703 return $this->type;
108704 }
108705 }
108706 <?php
108707
108708 declare (strict_types=1);
108709 /*
108710 * This file is part of sebastian/type.
108711 *
108712 * (c) Sebastian Bergmann <sebastian@phpunit.de>
108713 *
108714 * For the full copyright and license information, please view the LICENSE
108715 * file that was distributed with this source code.
108716 */
108717 namespace PHPUnitPHAR\SebastianBergmann\Type;
108718
108719 use function assert;
108720 use ReflectionFunction;
108721 use ReflectionIntersectionType;
108722 use ReflectionMethod;
108723 use ReflectionNamedType;
108724 use ReflectionType;
108725 use ReflectionUnionType;
108726 final class ReflectionMapper
108727 {
108728 /**
108729 * @psalm-return list<Parameter>
108730 */
108731 public function fromParameterTypes(ReflectionFunction|ReflectionMethod $functionOrMethod): array
108732 {
108733 $parameters = [];
108734 foreach ($functionOrMethod->getParameters() as $parameter) {
108735 $name = $parameter->getName();
108736 assert($name !== '');
108737 if (!$parameter->hasType()) {
108738 $parameters[] = new Parameter($name, new UnknownType());
108739 continue;
108740 }
108741 $type = $parameter->getType();
108742 if ($type instanceof ReflectionNamedType) {
108743 $parameters[] = new Parameter($name, $this->mapNamedType($type, $functionOrMethod));
108744 continue;
108745 }
108746 if ($type instanceof ReflectionUnionType) {
108747 $parameters[] = new Parameter($name, $this->mapUnionType($type, $functionOrMethod));
108748 continue;
108749 }
108750 if ($type instanceof ReflectionIntersectionType) {
108751 $parameters[] = new Parameter($name, $this->mapIntersectionType($type, $functionOrMethod));
108752 }
108753 }
108754 return $parameters;
108755 }
108756 public function fromReturnType(ReflectionFunction|ReflectionMethod $functionOrMethod): Type
108757 {
108758 if (!$this->hasReturnType($functionOrMethod)) {
108759 return new UnknownType();
108760 }
108761 $returnType = $this->returnType($functionOrMethod);
108762 assert($returnType instanceof ReflectionNamedType || $returnType instanceof ReflectionUnionType || $returnType instanceof ReflectionIntersectionType);
108763 if ($returnType instanceof ReflectionNamedType) {
108764 return $this->mapNamedType($returnType, $functionOrMethod);
108765 }
108766 if ($returnType instanceof ReflectionUnionType) {
108767 return $this->mapUnionType($returnType, $functionOrMethod);
108768 }
108769 if ($returnType instanceof ReflectionIntersectionType) {
108770 return $this->mapIntersectionType($returnType, $functionOrMethod);
108771 }
108772 }
108773 private function mapNamedType(ReflectionNamedType $type, ReflectionFunction|ReflectionMethod $functionOrMethod): Type
108774 {
108775 if ($functionOrMethod instanceof ReflectionMethod && $type->getName() === 'self') {
108776 return ObjectType::fromName($functionOrMethod->getDeclaringClass()->getName(), $type->allowsNull());
108777 }
108778 if ($functionOrMethod instanceof ReflectionMethod && $type->getName() === 'static') {
108779 return new StaticType(TypeName::fromReflection($functionOrMethod->getDeclaringClass()), $type->allowsNull());
108780 }
108781 if ($type->getName() === 'mixed') {
108782 return new MixedType();
108783 }
108784 if ($functionOrMethod instanceof ReflectionMethod && $type->getName() === 'parent') {
108785 return ObjectType::fromName($functionOrMethod->getDeclaringClass()->getParentClass()->getName(), $type->allowsNull());
108786 }
108787 return Type::fromName($type->getName(), $type->allowsNull());
108788 }
108789 private function mapUnionType(ReflectionUnionType $type, ReflectionFunction|ReflectionMethod $functionOrMethod): Type
108790 {
108791 $types = [];
108792 foreach ($type->getTypes() as $_type) {
108793 assert($_type instanceof ReflectionNamedType || $_type instanceof ReflectionIntersectionType);
108794 if ($_type instanceof ReflectionNamedType) {
108795 $types[] = $this->mapNamedType($_type, $functionOrMethod);
108796 continue;
108797 }
108798 $types[] = $this->mapIntersectionType($_type, $functionOrMethod);
108799 }
108800 return new UnionType(...$types);
108801 }
108802 private function mapIntersectionType(ReflectionIntersectionType $type, ReflectionFunction|ReflectionMethod $functionOrMethod): Type
108803 {
108804 $types = [];
108805 foreach ($type->getTypes() as $_type) {
108806 assert($_type instanceof ReflectionNamedType);
108807 $types[] = $this->mapNamedType($_type, $functionOrMethod);
108808 }
108809 return new IntersectionType(...$types);
108810 }
108811 private function hasReturnType(ReflectionFunction|ReflectionMethod $functionOrMethod): bool
108812 {
108813 if ($functionOrMethod->hasReturnType()) {
108814 return \true;
108815 }
108816 return $functionOrMethod->hasTentativeReturnType();
108817 }
108818 private function returnType(ReflectionFunction|ReflectionMethod $functionOrMethod): ?ReflectionType
108819 {
108820 if ($functionOrMethod->hasReturnType()) {
108821 return $functionOrMethod->getReturnType();
108822 }
108823 return $functionOrMethod->getTentativeReturnType();
108824 }
108825 }
108826 <?php
108827
108828 declare (strict_types=1);
108829 /*
108830 * This file is part of sebastian/type.
108831 *
108832 * (c) Sebastian Bergmann <sebastian@phpunit.de>
108833 *
108834 * For the full copyright and license information, please view the LICENSE
108835 * file that was distributed with this source code.
108836 */
108837 namespace PHPUnitPHAR\SebastianBergmann\Type;
108838
108839 use function array_pop;
108840 use function explode;
108841 use function implode;
108842 use function substr;
108843 use ReflectionClass;
108844 final class TypeName
108845 {
108846 private ?string $namespaceName;
108847 private string $simpleName;
108848 public static function fromQualifiedName(string $fullClassName): self
108849 {
108850 if ($fullClassName[0] === '\\') {
108851 $fullClassName = substr($fullClassName, 1);
108852 }
108853 $classNameParts = explode('\\', $fullClassName);
108854 $simpleName = array_pop($classNameParts);
108855 $namespaceName = implode('\\', $classNameParts);
108856 return new self($namespaceName, $simpleName);
108857 }
108858 public static function fromReflection(ReflectionClass $type): self
108859 {
108860 return new self($type->getNamespaceName(), $type->getShortName());
108861 }
108862 public function __construct(?string $namespaceName, string $simpleName)
108863 {
108864 if ($namespaceName === '') {
108865 $namespaceName = null;
108866 }
108867 $this->namespaceName = $namespaceName;
108868 $this->simpleName = $simpleName;
108869 }
108870 public function namespaceName(): ?string
108871 {
108872 return $this->namespaceName;
108873 }
108874 public function simpleName(): string
108875 {
108876 return $this->simpleName;
108877 }
108878 public function qualifiedName(): string
108879 {
108880 return $this->namespaceName === null ? $this->simpleName : $this->namespaceName . '\\' . $this->simpleName;
108881 }
108882 public function isNamespaced(): bool
108883 {
108884 return $this->namespaceName !== null;
108885 }
108886 }
108887 <?php
108888
108889 declare (strict_types=1);
108890 /*
108891 * This file is part of sebastian/type.
108892 *
108893 * (c) Sebastian Bergmann <sebastian@phpunit.de>
108894 *
108895 * For the full copyright and license information, please view the LICENSE
108896 * file that was distributed with this source code.
108897 */
108898 namespace PHPUnitPHAR\SebastianBergmann\Type;
108899
108900 use Throwable;
108901 interface Exception extends Throwable
108902 {
108903 }
108904 <?php
108905
108906 declare (strict_types=1);
108907 /*
108908 * This file is part of sebastian/type.
108909 *
108910 * (c) Sebastian Bergmann <sebastian@phpunit.de>
108911 *
108912 * For the full copyright and license information, please view the LICENSE
108913 * file that was distributed with this source code.
108914 */
108915 namespace PHPUnitPHAR\SebastianBergmann\Type;
108916
108917 final class RuntimeException extends \RuntimeException implements Exception
108918 {
108919 }
108920 <?php
108921
108922 declare (strict_types=1);
108923 /*
108924 * This file is part of sebastian/type.
108925 *
108926 * (c) Sebastian Bergmann <sebastian@phpunit.de>
108927 *
108928 * For the full copyright and license information, please view the LICENSE
108929 * file that was distributed with this source code.
108930 */
108931 namespace PHPUnitPHAR\SebastianBergmann\Type;
108932
108933 use function assert;
108934 use function class_exists;
108935 use function count;
108936 use function explode;
108937 use function function_exists;
108938 use function is_array;
108939 use function is_object;
108940 use function is_string;
108941 use function str_contains;
108942 use Closure;
108943 use ReflectionClass;
108944 use ReflectionObject;
108945 final class CallableType extends Type
108946 {
108947 private bool $allowsNull;
108948 public function __construct(bool $nullable)
108949 {
108950 $this->allowsNull = $nullable;
108951 }
108952 public function isAssignable(Type $other): bool
108953 {
108954 if ($this->allowsNull && $other instanceof NullType) {
108955 return \true;
108956 }
108957 if ($other instanceof self) {
108958 return \true;
108959 }
108960 if ($other instanceof ObjectType) {
108961 if ($this->isClosure($other)) {
108962 return \true;
108963 }
108964 if ($this->hasInvokeMethod($other)) {
108965 return \true;
108966 }
108967 }
108968 if ($other instanceof SimpleType) {
108969 if ($this->isFunction($other)) {
108970 return \true;
108971 }
108972 if ($this->isClassCallback($other)) {
108973 return \true;
108974 }
108975 if ($this->isObjectCallback($other)) {
108976 return \true;
108977 }
108978 }
108979 return \false;
108980 }
108981 public function name(): string
108982 {
108983 return 'callable';
108984 }
108985 public function allowsNull(): bool
108986 {
108987 return $this->allowsNull;
108988 }
108989 /**
108990 * @psalm-assert-if-true CallableType $this
108991 */
108992 public function isCallable(): bool
108993 {
108994 return \true;
108995 }
108996 private function isClosure(ObjectType $type): bool
108997 {
108998 return $type->className()->qualifiedName() === Closure::class;
108999 }
109000 private function hasInvokeMethod(ObjectType $type): bool
109001 {
109002 $className = $type->className()->qualifiedName();
109003 assert(class_exists($className));
109004 return (new ReflectionClass($className))->hasMethod('__invoke');
109005 }
109006 private function isFunction(SimpleType $type): bool
109007 {
109008 if (!is_string($type->value())) {
109009 return \false;
109010 }
109011 return function_exists($type->value());
109012 }
109013 private function isObjectCallback(SimpleType $type): bool
109014 {
109015 if (!is_array($type->value())) {
109016 return \false;
109017 }
109018 if (count($type->value()) !== 2) {
109019 return \false;
109020 }
109021 if (!isset($type->value()[0], $type->value()[1])) {
109022 return \false;
109023 }
109024 if (!is_object($type->value()[0]) || !is_string($type->value()[1])) {
109025 return \false;
109026 }
109027 [$object, $methodName] = $type->value();
109028 return (new ReflectionObject($object))->hasMethod($methodName);
109029 }
109030 private function isClassCallback(SimpleType $type): bool
109031 {
109032 if (!is_string($type->value()) && !is_array($type->value())) {
109033 return \false;
109034 }
109035 if (is_string($type->value())) {
109036 if (!str_contains($type->value(), '::')) {
109037 return \false;
109038 }
109039 [$className, $methodName] = explode('::', $type->value());
109040 }
109041 if (is_array($type->value())) {
109042 if (count($type->value()) !== 2) {
109043 return \false;
109044 }
109045 if (!isset($type->value()[0], $type->value()[1])) {
109046 return \false;
109047 }
109048 if (!is_string($type->value()[0]) || !is_string($type->value()[1])) {
109049 return \false;
109050 }
109051 [$className, $methodName] = $type->value();
109052 }
109053 assert(isset($className) && is_string($className));
109054 assert(isset($methodName) && is_string($methodName));
109055 if (!class_exists($className)) {
109056 return \false;
109057 }
109058 $class = new ReflectionClass($className);
109059 if (!$class->hasMethod($methodName)) {
109060 return \false;
109061 }
109062 $method = $class->getMethod($methodName);
109063 return $method->isPublic() && $method->isStatic();
109064 }
109065 }
109066 <?php
109067
109068 declare (strict_types=1);
109069 /*
109070 * This file is part of sebastian/type.
109071 *
109072 * (c) Sebastian Bergmann <sebastian@phpunit.de>
109073 *
109074 * For the full copyright and license information, please view the LICENSE
109075 * file that was distributed with this source code.
109076 */
109077 namespace PHPUnitPHAR\SebastianBergmann\Type;
109078
109079 final class FalseType extends Type
109080 {
109081 public function isAssignable(Type $other): bool
109082 {
109083 if ($other instanceof self) {
109084 return \true;
109085 }
109086 return $other instanceof SimpleType && $other->name() === 'bool' && $other->value() === \false;
109087 }
109088 public function name(): string
109089 {
109090 return 'false';
109091 }
109092 public function allowsNull(): bool
109093 {
109094 return \false;
109095 }
109096 /**
109097 * @psalm-assert-if-true FalseType $this
109098 */
109099 public function isFalse(): bool
109100 {
109101 return \true;
109102 }
109103 }
109104 <?php
109105
109106 declare (strict_types=1);
109107 /*
109108 * This file is part of sebastian/type.
109109 *
109110 * (c) Sebastian Bergmann <sebastian@phpunit.de>
109111 *
109112 * For the full copyright and license information, please view the LICENSE
109113 * file that was distributed with this source code.
109114 */
109115 namespace PHPUnitPHAR\SebastianBergmann\Type;
109116
109117 final class GenericObjectType extends Type
109118 {
109119 private bool $allowsNull;
109120 public function __construct(bool $nullable)
109121 {
109122 $this->allowsNull = $nullable;
109123 }
109124 public function isAssignable(Type $other): bool
109125 {
109126 if ($this->allowsNull && $other instanceof NullType) {
109127 return \true;
109128 }
109129 if (!$other instanceof ObjectType) {
109130 return \false;
109131 }
109132 return \true;
109133 }
109134 public function name(): string
109135 {
109136 return 'object';
109137 }
109138 public function allowsNull(): bool
109139 {
109140 return $this->allowsNull;
109141 }
109142 /**
109143 * @psalm-assert-if-true GenericObjectType $this
109144 */
109145 public function isGenericObject(): bool
109146 {
109147 return \true;
109148 }
109149 }
109150 <?php
109151
109152 declare (strict_types=1);
109153 /*
109154 * This file is part of sebastian/type.
109155 *
109156 * (c) Sebastian Bergmann <sebastian@phpunit.de>
109157 *
109158 * For the full copyright and license information, please view the LICENSE
109159 * file that was distributed with this source code.
109160 */
109161 namespace PHPUnitPHAR\SebastianBergmann\Type;
109162
109163 use function assert;
109164 use function count;
109165 use function implode;
109166 use function in_array;
109167 use function sort;
109168 final class IntersectionType extends Type
109169 {
109170 /**
109171 * @psalm-var non-empty-list<Type>
109172 */
109173 private array $types;
109174 /**
109175 * @throws RuntimeException
109176 */
109177 public function __construct(Type ...$types)
109178 {
109179 $this->ensureMinimumOfTwoTypes(...$types);
109180 $this->ensureOnlyValidTypes(...$types);
109181 $this->ensureNoDuplicateTypes(...$types);
109182 $this->types = $types;
109183 }
109184 public function isAssignable(Type $other): bool
109185 {
109186 return $other->isObject();
109187 }
109188 public function asString(): string
109189 {
109190 return $this->name();
109191 }
109192 public function name(): string
109193 {
109194 $types = [];
109195 foreach ($this->types as $type) {
109196 $types[] = $type->name();
109197 }
109198 sort($types);
109199 return implode('&', $types);
109200 }
109201 public function allowsNull(): bool
109202 {
109203 return \false;
109204 }
109205 /**
109206 * @psalm-assert-if-true IntersectionType $this
109207 */
109208 public function isIntersection(): bool
109209 {
109210 return \true;
109211 }
109212 /**
109213 * @psalm-return non-empty-list<Type>
109214 */
109215 public function types(): array
109216 {
109217 return $this->types;
109218 }
109219 /**
109220 * @throws RuntimeException
109221 */
109222 private function ensureMinimumOfTwoTypes(Type ...$types): void
109223 {
109224 if (count($types) < 2) {
109225 throw new RuntimeException('An intersection type must be composed of at least two types');
109226 }
109227 }
109228 /**
109229 * @throws RuntimeException
109230 */
109231 private function ensureOnlyValidTypes(Type ...$types): void
109232 {
109233 foreach ($types as $type) {
109234 if (!$type->isObject()) {
109235 throw new RuntimeException('An intersection type can only be composed of interfaces and classes');
109236 }
109237 }
109238 }
109239 /**
109240 * @throws RuntimeException
109241 */
109242 private function ensureNoDuplicateTypes(Type ...$types): void
109243 {
109244 $names = [];
109245 foreach ($types as $type) {
109246 assert($type instanceof ObjectType);
109247 $classQualifiedName = $type->className()->qualifiedName();
109248 if (in_array($classQualifiedName, $names, \true)) {
109249 throw new RuntimeException('An intersection type must not contain duplicate types');
109250 }
109251 $names[] = $classQualifiedName;
109252 }
109253 }
109254 }
109255 <?php
109256
109257 declare (strict_types=1);
109258 /*
109259 * This file is part of sebastian/type.
109260 *
109261 * (c) Sebastian Bergmann <sebastian@phpunit.de>
109262 *
109263 * For the full copyright and license information, please view the LICENSE
109264 * file that was distributed with this source code.
109265 */
109266 namespace PHPUnitPHAR\SebastianBergmann\Type;
109267
109268 use function assert;
109269 use function class_exists;
109270 use function is_iterable;
109271 use ReflectionClass;
109272 final class IterableType extends Type
109273 {
109274 private bool $allowsNull;
109275 public function __construct(bool $nullable)
109276 {
109277 $this->allowsNull = $nullable;
109278 }
109279 /**
109280 * @throws RuntimeException
109281 */
109282 public function isAssignable(Type $other): bool
109283 {
109284 if ($this->allowsNull && $other instanceof NullType) {
109285 return \true;
109286 }
109287 if ($other instanceof self) {
109288 return \true;
109289 }
109290 if ($other instanceof SimpleType) {
109291 return is_iterable($other->value());
109292 }
109293 if ($other instanceof ObjectType) {
109294 $className = $other->className()->qualifiedName();
109295 assert(class_exists($className));
109296 return (new ReflectionClass($className))->isIterable();
109297 }
109298 return \false;
109299 }
109300 public function name(): string
109301 {
109302 return 'iterable';
109303 }
109304 public function allowsNull(): bool
109305 {
109306 return $this->allowsNull;
109307 }
109308 /**
109309 * @psalm-assert-if-true IterableType $this
109310 */
109311 public function isIterable(): bool
109312 {
109313 return \true;
109314 }
109315 }
109316 <?php
109317
109318 declare (strict_types=1);
109319 /*
109320 * This file is part of sebastian/type.
109321 *
109322 * (c) Sebastian Bergmann <sebastian@phpunit.de>
109323 *
109324 * For the full copyright and license information, please view the LICENSE
109325 * file that was distributed with this source code.
109326 */
109327 namespace PHPUnitPHAR\SebastianBergmann\Type;
109328
109329 final class MixedType extends Type
109330 {
109331 public function isAssignable(Type $other): bool
109332 {
109333 return !$other instanceof VoidType;
109334 }
109335 public function asString(): string
109336 {
109337 return 'mixed';
109338 }
109339 public function name(): string
109340 {
109341 return 'mixed';
109342 }
109343 public function allowsNull(): bool
109344 {
109345 return \true;
109346 }
109347 /**
109348 * @psalm-assert-if-true MixedType $this
109349 */
109350 public function isMixed(): bool
109351 {
109352 return \true;
109353 }
109354 }
109355 <?php
109356
109357 declare (strict_types=1);
109358 /*
109359 * This file is part of sebastian/type.
109360 *
109361 * (c) Sebastian Bergmann <sebastian@phpunit.de>
109362 *
109363 * For the full copyright and license information, please view the LICENSE
109364 * file that was distributed with this source code.
109365 */
109366 namespace PHPUnitPHAR\SebastianBergmann\Type;
109367
109368 final class NeverType extends Type
109369 {
109370 public function isAssignable(Type $other): bool
109371 {
109372 return $other instanceof self;
109373 }
109374 public function name(): string
109375 {
109376 return 'never';
109377 }
109378 public function allowsNull(): bool
109379 {
109380 return \false;
109381 }
109382 /**
109383 * @psalm-assert-if-true NeverType $this
109384 */
109385 public function isNever(): bool
109386 {
109387 return \true;
109388 }
109389 }
109390 <?php
109391
109392 declare (strict_types=1);
109393 /*
109394 * This file is part of sebastian/type.
109395 *
109396 * (c) Sebastian Bergmann <sebastian@phpunit.de>
109397 *
109398 * For the full copyright and license information, please view the LICENSE
109399 * file that was distributed with this source code.
109400 */
109401 namespace PHPUnitPHAR\SebastianBergmann\Type;
109402
109403 final class NullType extends Type
109404 {
109405 public function isAssignable(Type $other): bool
109406 {
109407 return !$other instanceof VoidType;
109408 }
109409 public function name(): string
109410 {
109411 return 'null';
109412 }
109413 public function asString(): string
109414 {
109415 return 'null';
109416 }
109417 public function allowsNull(): bool
109418 {
109419 return \true;
109420 }
109421 /**
109422 * @psalm-assert-if-true NullType $this
109423 */
109424 public function isNull(): bool
109425 {
109426 return \true;
109427 }
109428 }
109429 <?php
109430
109431 declare (strict_types=1);
109432 /*
109433 * This file is part of sebastian/type.
109434 *
109435 * (c) Sebastian Bergmann <sebastian@phpunit.de>
109436 *
109437 * For the full copyright and license information, please view the LICENSE
109438 * file that was distributed with this source code.
109439 */
109440 namespace PHPUnitPHAR\SebastianBergmann\Type;
109441
109442 use function is_subclass_of;
109443 use function strcasecmp;
109444 final class ObjectType extends Type
109445 {
109446 private TypeName $className;
109447 private bool $allowsNull;
109448 public function __construct(TypeName $className, bool $allowsNull)
109449 {
109450 $this->className = $className;
109451 $this->allowsNull = $allowsNull;
109452 }
109453 public function isAssignable(Type $other): bool
109454 {
109455 if ($this->allowsNull && $other instanceof NullType) {
109456 return \true;
109457 }
109458 if ($other instanceof self) {
109459 if (0 === strcasecmp($this->className->qualifiedName(), $other->className->qualifiedName())) {
109460 return \true;
109461 }
109462 if (is_subclass_of($other->className->qualifiedName(), $this->className->qualifiedName(), \true)) {
109463 return \true;
109464 }
109465 }
109466 return \false;
109467 }
109468 public function name(): string
109469 {
109470 return $this->className->qualifiedName();
109471 }
109472 public function allowsNull(): bool
109473 {
109474 return $this->allowsNull;
109475 }
109476 public function className(): TypeName
109477 {
109478 return $this->className;
109479 }
109480 /**
109481 * @psalm-assert-if-true ObjectType $this
109482 */
109483 public function isObject(): bool
109484 {
109485 return \true;
109486 }
109487 }
109488 <?php
109489
109490 declare (strict_types=1);
109491 /*
109492 * This file is part of sebastian/type.
109493 *
109494 * (c) Sebastian Bergmann <sebastian@phpunit.de>
109495 *
109496 * For the full copyright and license information, please view the LICENSE
109497 * file that was distributed with this source code.
109498 */
109499 namespace PHPUnitPHAR\SebastianBergmann\Type;
109500
109501 use function strtolower;
109502 final class SimpleType extends Type
109503 {
109504 private string $name;
109505 private bool $allowsNull;
109506 private mixed $value;
109507 public function __construct(string $name, bool $nullable, mixed $value = null)
109508 {
109509 $this->name = $this->normalize($name);
109510 $this->allowsNull = $nullable;
109511 $this->value = $value;
109512 }
109513 public function isAssignable(Type $other): bool
109514 {
109515 if ($this->allowsNull && $other instanceof NullType) {
109516 return \true;
109517 }
109518 if ($this->name === 'bool' && $other->name() === 'true') {
109519 return \true;
109520 }
109521 if ($this->name === 'bool' && $other->name() === 'false') {
109522 return \true;
109523 }
109524 if ($other instanceof self) {
109525 return $this->name === $other->name;
109526 }
109527 return \false;
109528 }
109529 public function name(): string
109530 {
109531 return $this->name;
109532 }
109533 public function allowsNull(): bool
109534 {
109535 return $this->allowsNull;
109536 }
109537 public function value(): mixed
109538 {
109539 return $this->value;
109540 }
109541 /**
109542 * @psalm-assert-if-true SimpleType $this
109543 */
109544 public function isSimple(): bool
109545 {
109546 return \true;
109547 }
109548 private function normalize(string $name): string
109549 {
109550 $name = strtolower($name);
109551 return match ($name) {
109552 'boolean' => 'bool',
109553 'real', 'double' => 'float',
109554 'integer' => 'int',
109555 '[]' => 'array',
109556 default => $name,
109557 };
109558 }
109559 }
109560 <?php
109561
109562 declare (strict_types=1);
109563 /*
109564 * This file is part of sebastian/type.
109565 *
109566 * (c) Sebastian Bergmann <sebastian@phpunit.de>
109567 *
109568 * For the full copyright and license information, please view the LICENSE
109569 * file that was distributed with this source code.
109570 */
109571 namespace PHPUnitPHAR\SebastianBergmann\Type;
109572
109573 use function is_subclass_of;
109574 use function strcasecmp;
109575 final class StaticType extends Type
109576 {
109577 private TypeName $className;
109578 private bool $allowsNull;
109579 public function __construct(TypeName $className, bool $allowsNull)
109580 {
109581 $this->className = $className;
109582 $this->allowsNull = $allowsNull;
109583 }
109584 public function isAssignable(Type $other): bool
109585 {
109586 if ($this->allowsNull && $other instanceof NullType) {
109587 return \true;
109588 }
109589 if (!$other instanceof ObjectType) {
109590 return \false;
109591 }
109592 if (0 === strcasecmp($this->className->qualifiedName(), $other->className()->qualifiedName())) {
109593 return \true;
109594 }
109595 if (is_subclass_of($other->className()->qualifiedName(), $this->className->qualifiedName(), \true)) {
109596 return \true;
109597 }
109598 return \false;
109599 }
109600 public function name(): string
109601 {
109602 return 'static';
109603 }
109604 public function allowsNull(): bool
109605 {
109606 return $this->allowsNull;
109607 }
109608 /**
109609 * @psalm-assert-if-true StaticType $this
109610 */
109611 public function isStatic(): bool
109612 {
109613 return \true;
109614 }
109615 }
109616 <?php
109617
109618 declare (strict_types=1);
109619 /*
109620 * This file is part of sebastian/type.
109621 *
109622 * (c) Sebastian Bergmann <sebastian@phpunit.de>
109623 *
109624 * For the full copyright and license information, please view the LICENSE
109625 * file that was distributed with this source code.
109626 */
109627 namespace PHPUnitPHAR\SebastianBergmann\Type;
109628
109629 final class TrueType extends Type
109630 {
109631 public function isAssignable(Type $other): bool
109632 {
109633 if ($other instanceof self) {
109634 return \true;
109635 }
109636 return $other instanceof SimpleType && $other->name() === 'bool' && $other->value() === \true;
109637 }
109638 public function name(): string
109639 {
109640 return 'true';
109641 }
109642 public function allowsNull(): bool
109643 {
109644 return \false;
109645 }
109646 /**
109647 * @psalm-assert-if-true TrueType $this
109648 */
109649 public function isTrue(): bool
109650 {
109651 return \true;
109652 }
109653 }
109654 <?php
109655
109656 declare (strict_types=1);
109657 /*
109658 * This file is part of sebastian/type.
109659 *
109660 * (c) Sebastian Bergmann <sebastian@phpunit.de>
109661 *
109662 * For the full copyright and license information, please view the LICENSE
109663 * file that was distributed with this source code.
109664 */
109665 namespace PHPUnitPHAR\SebastianBergmann\Type;
109666
109667 use function gettype;
109668 use function strtolower;
109669 abstract class Type
109670 {
109671 public static function fromValue(mixed $value, bool $allowsNull): self
109672 {
109673 if ($allowsNull === \false) {
109674 if ($value === \true) {
109675 return new TrueType();
109676 }
109677 if ($value === \false) {
109678 return new FalseType();
109679 }
109680 }
109681 $typeName = gettype($value);
109682 if ($typeName === 'object') {
109683 return new ObjectType(TypeName::fromQualifiedName($value::class), $allowsNull);
109684 }
109685 $type = self::fromName($typeName, $allowsNull);
109686 if ($type instanceof SimpleType) {
109687 $type = new SimpleType($typeName, $allowsNull, $value);
109688 }
109689 return $type;
109690 }
109691 public static function fromName(string $typeName, bool $allowsNull): self
109692 {
109693 return match (strtolower($typeName)) {
109694 'callable' => new CallableType($allowsNull),
109695 'true' => new TrueType(),
109696 'false' => new FalseType(),
109697 'iterable' => new IterableType($allowsNull),
109698 'never' => new NeverType(),
109699 'null' => new NullType(),
109700 'object' => new GenericObjectType($allowsNull),
109701 'unknown type' => new UnknownType(),
109702 'void' => new VoidType(),
109703 'array', 'bool', 'boolean', 'double', 'float', 'int', 'integer', 'real', 'resource', 'resource (closed)', 'string' => new SimpleType($typeName, $allowsNull),
109704 'mixed' => new MixedType(),
109705 default => new ObjectType(TypeName::fromQualifiedName($typeName), $allowsNull),
109706 };
109707 }
109708 public function asString(): string
109709 {
109710 return ($this->allowsNull() ? '?' : '') . $this->name();
109711 }
109712 /**
109713 * @psalm-assert-if-true CallableType $this
109714 */
109715 public function isCallable(): bool
109716 {
109717 return \false;
109718 }
109719 /**
109720 * @psalm-assert-if-true TrueType $this
109721 */
109722 public function isTrue(): bool
109723 {
109724 return \false;
109725 }
109726 /**
109727 * @psalm-assert-if-true FalseType $this
109728 */
109729 public function isFalse(): bool
109730 {
109731 return \false;
109732 }
109733 /**
109734 * @psalm-assert-if-true GenericObjectType $this
109735 */
109736 public function isGenericObject(): bool
109737 {
109738 return \false;
109739 }
109740 /**
109741 * @psalm-assert-if-true IntersectionType $this
109742 */
109743 public function isIntersection(): bool
109744 {
109745 return \false;
109746 }
109747 /**
109748 * @psalm-assert-if-true IterableType $this
109749 */
109750 public function isIterable(): bool
109751 {
109752 return \false;
109753 }
109754 /**
109755 * @psalm-assert-if-true MixedType $this
109756 */
109757 public function isMixed(): bool
109758 {
109759 return \false;
109760 }
109761 /**
109762 * @psalm-assert-if-true NeverType $this
109763 */
109764 public function isNever(): bool
109765 {
109766 return \false;
109767 }
109768 /**
109769 * @psalm-assert-if-true NullType $this
109770 */
109771 public function isNull(): bool
109772 {
109773 return \false;
109774 }
109775 /**
109776 * @psalm-assert-if-true ObjectType $this
109777 */
109778 public function isObject(): bool
109779 {
109780 return \false;
109781 }
109782 /**
109783 * @psalm-assert-if-true SimpleType $this
109784 */
109785 public function isSimple(): bool
109786 {
109787 return \false;
109788 }
109789 /**
109790 * @psalm-assert-if-true StaticType $this
109791 */
109792 public function isStatic(): bool
109793 {
109794 return \false;
109795 }
109796 /**
109797 * @psalm-assert-if-true UnionType $this
109798 */
109799 public function isUnion(): bool
109800 {
109801 return \false;
109802 }
109803 /**
109804 * @psalm-assert-if-true UnknownType $this
109805 */
109806 public function isUnknown(): bool
109807 {
109808 return \false;
109809 }
109810 /**
109811 * @psalm-assert-if-true VoidType $this
109812 */
109813 public function isVoid(): bool
109814 {
109815 return \false;
109816 }
109817 abstract public function isAssignable(self $other): bool;
109818 abstract public function name(): string;
109819 abstract public function allowsNull(): bool;
109820 }
109821 <?php
109822
109823 declare (strict_types=1);
109824 /*
109825 * This file is part of sebastian/type.
109826 *
109827 * (c) Sebastian Bergmann <sebastian@phpunit.de>
109828 *
109829 * For the full copyright and license information, please view the LICENSE
109830 * file that was distributed with this source code.
109831 */
109832 namespace PHPUnitPHAR\SebastianBergmann\Type;
109833
109834 use function count;
109835 use function implode;
109836 use function sort;
109837 final class UnionType extends Type
109838 {
109839 /**
109840 * @psalm-var non-empty-list<Type>
109841 */
109842 private array $types;
109843 /**
109844 * @throws RuntimeException
109845 */
109846 public function __construct(Type ...$types)
109847 {
109848 $this->ensureMinimumOfTwoTypes(...$types);
109849 $this->ensureOnlyValidTypes(...$types);
109850 $this->types = $types;
109851 }
109852 public function isAssignable(Type $other): bool
109853 {
109854 foreach ($this->types as $type) {
109855 if ($type->isAssignable($other)) {
109856 return \true;
109857 }
109858 }
109859 return \false;
109860 }
109861 public function asString(): string
109862 {
109863 return $this->name();
109864 }
109865 public function name(): string
109866 {
109867 $types = [];
109868 foreach ($this->types as $type) {
109869 if ($type->isIntersection()) {
109870 $types[] = '(' . $type->name() . ')';
109871 continue;
109872 }
109873 $types[] = $type->name();
109874 }
109875 sort($types);
109876 return implode('|', $types);
109877 }
109878 public function allowsNull(): bool
109879 {
109880 foreach ($this->types as $type) {
109881 if ($type instanceof NullType) {
109882 return \true;
109883 }
109884 }
109885 return \false;
109886 }
109887 /**
109888 * @psalm-assert-if-true UnionType $this
109889 */
109890 public function isUnion(): bool
109891 {
109892 return \true;
109893 }
109894 public function containsIntersectionTypes(): bool
109895 {
109896 foreach ($this->types as $type) {
109897 if ($type->isIntersection()) {
109898 return \true;
109899 }
109900 }
109901 return \false;
109902 }
109903 /**
109904 * @psalm-return non-empty-list<Type>
109905 */
109906 public function types(): array
109907 {
109908 return $this->types;
109909 }
109910 /**
109911 * @throws RuntimeException
109912 */
109913 private function ensureMinimumOfTwoTypes(Type ...$types): void
109914 {
109915 if (count($types) < 2) {
109916 throw new RuntimeException('A union type must be composed of at least two types');
109917 }
109918 }
109919 /**
109920 * @throws RuntimeException
109921 */
109922 private function ensureOnlyValidTypes(Type ...$types): void
109923 {
109924 foreach ($types as $type) {
109925 if ($type instanceof UnknownType) {
109926 throw new RuntimeException('A union type must not be composed of an unknown type');
109927 }
109928 if ($type instanceof VoidType) {
109929 throw new RuntimeException('A union type must not be composed of a void type');
109930 }
109931 }
109932 }
109933 }
109934 <?php
109935
109936 declare (strict_types=1);
109937 /*
109938 * This file is part of sebastian/type.
109939 *
109940 * (c) Sebastian Bergmann <sebastian@phpunit.de>
109941 *
109942 * For the full copyright and license information, please view the LICENSE
109943 * file that was distributed with this source code.
109944 */
109945 namespace PHPUnitPHAR\SebastianBergmann\Type;
109946
109947 final class UnknownType extends Type
109948 {
109949 public function isAssignable(Type $other): bool
109950 {
109951 return \true;
109952 }
109953 public function name(): string
109954 {
109955 return 'unknown type';
109956 }
109957 public function asString(): string
109958 {
109959 return '';
109960 }
109961 public function allowsNull(): bool
109962 {
109963 return \true;
109964 }
109965 /**
109966 * @psalm-assert-if-true UnknownType $this
109967 */
109968 public function isUnknown(): bool
109969 {
109970 return \true;
109971 }
109972 }
109973 <?php
109974
109975 declare (strict_types=1);
109976 /*
109977 * This file is part of sebastian/type.
109978 *
109979 * (c) Sebastian Bergmann <sebastian@phpunit.de>
109980 *
109981 * For the full copyright and license information, please view the LICENSE
109982 * file that was distributed with this source code.
109983 */
109984 namespace PHPUnitPHAR\SebastianBergmann\Type;
109985
109986 final class VoidType extends Type
109987 {
109988 public function isAssignable(Type $other): bool
109989 {
109990 return $other instanceof self;
109991 }
109992 public function name(): string
109993 {
109994 return 'void';
109995 }
109996 public function allowsNull(): bool
109997 {
109998 return \false;
109999 }
110000 /**
110001 * @psalm-assert-if-true VoidType $this
110002 */
110003 public function isVoid(): bool
110004 {
110005 return \true;
110006 }
110007 }
110008 BSD 3-Clause License
110009
110010 Copyright (c) 2013-2023, Sebastian Bergmann
110011 All rights reserved.
110012
110013 Redistribution and use in source and binary forms, with or without
110014 modification, are permitted provided that the following conditions are met:
110015
110016 1. Redistributions of source code must retain the above copyright notice, this
110017 list of conditions and the following disclaimer.
110018
110019 2. Redistributions in binary form must reproduce the above copyright notice,
110020 this list of conditions and the following disclaimer in the documentation
110021 and/or other materials provided with the distribution.
110022
110023 3. Neither the name of the copyright holder nor the names of its
110024 contributors may be used to endorse or promote products derived from
110025 this software without specific prior written permission.
110026
110027 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
110028 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
110029 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
110030 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
110031 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
110032 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
110033 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
110034 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
110035 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
110036 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
110037 <?php
110038
110039 declare (strict_types=1);
110040 /*
110041 * This file is part of sebastian/version.
110042 *
110043 * (c) Sebastian Bergmann <sebastian@phpunit.de>
110044 *
110045 * For the full copyright and license information, please view the LICENSE
110046 * file that was distributed with this source code.
110047 */
110048 namespace PHPUnitPHAR\SebastianBergmann;
110049
110050 use function end;
110051 use function explode;
110052 use function fclose;
110053 use function is_dir;
110054 use function is_resource;
110055 use function proc_close;
110056 use function proc_open;
110057 use function stream_get_contents;
110058 use function substr_count;
110059 use function trim;
110060 final class Version
110061 {
110062 private readonly string $version;
110063 public function __construct(string $release, string $path)
110064 {
110065 $this->version = $this->generate($release, $path);
110066 }
110067 public function asString(): string
110068 {
110069 return $this->version;
110070 }
110071 private function generate(string $release, string $path): string
110072 {
110073 if (substr_count($release, '.') + 1 === 3) {
110074 $version = $release;
110075 } else {
110076 $version = $release . '-dev';
110077 }
110078 $git = $this->getGitInformation($path);
110079 if (!$git) {
110080 return $version;
110081 }
110082 if (substr_count($release, '.') + 1 === 3) {
110083 return $git;
110084 }
110085 $git = explode('-', $git);
110086 return $release . '-' . end($git);
110087 }
110088 private function getGitInformation(string $path): bool|string
110089 {
110090 if (!is_dir($path . \DIRECTORY_SEPARATOR . '.git')) {
110091 return \false;
110092 }
110093 $process = proc_open('git describe --tags', [1 => ['pipe', 'w'], 2 => ['pipe', 'w']], $pipes, $path);
110094 if (!is_resource($process)) {
110095 return \false;
110096 }
110097 $result = trim(stream_get_contents($pipes[1]));
110098 fclose($pipes[1]);
110099 fclose($pipes[2]);
110100 $returnCode = proc_close($process);
110101 if ($returnCode !== 0) {
110102 return \false;
110103 }
110104 return $result;
110105 }
110106 }
110107 <?php
110108
110109 declare (strict_types=1);
110110 namespace PHPUnitPHAR\TheSeer\Tokenizer;
110111
110112 class Exception extends \Exception
110113 {
110114 }
110115 Tokenizer
110116
110117 Copyright (c) 2017 Arne Blankerts <arne@blankerts.de> and contributors
110118 All rights reserved.
110119
110120 Redistribution and use in source and binary forms, with or without modification,
110121 are permitted provided that the following conditions are met:
110122
110123 * Redistributions of source code must retain the above copyright notice,
110124 this list of conditions and the following disclaimer.
110125
110126 * Redistributions in binary form must reproduce the above copyright notice,
110127 this list of conditions and the following disclaimer in the documentation
110128 and/or other materials provided with the distribution.
110129
110130 * Neither the name of Arne Blankerts nor the names of contributors
110131 may be used to endorse or promote products derived from this software
110132 without specific prior written permission.
110133
110134 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
110135 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT * NOT LIMITED TO,
110136 THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
110137 PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
110138 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
110139 OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
110140 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
110141 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
110142 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
110143 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
110144 POSSIBILITY OF SUCH DAMAGE.
110145 <?php
110146
110147 declare (strict_types=1);
110148 namespace PHPUnitPHAR\TheSeer\Tokenizer;
110149
110150 class NamespaceUri
110151 {
110152 /** @var string */
110153 private $value;
110154 public function __construct(string $value)
110155 {
110156 $this->ensureValidUri($value);
110157 $this->value = $value;
110158 }
110159 public function asString(): string
110160 {
110161 return $this->value;
110162 }
110163 private function ensureValidUri($value): void
110164 {
110165 if (\strpos($value, ':') === \false) {
110166 throw new NamespaceUriException(\sprintf("Namespace URI '%s' must contain at least one colon", $value));
110167 }
110168 }
110169 }
110170 <?php
110171
110172 declare (strict_types=1);
110173 namespace PHPUnitPHAR\TheSeer\Tokenizer;
110174
110175 class NamespaceUriException extends Exception
110176 {
110177 }
110178 <?php
110179
110180 declare (strict_types=1);
110181 namespace PHPUnitPHAR\TheSeer\Tokenizer;
110182
110183 class Token
110184 {
110185 /** @var int */
110186 private $line;
110187 /** @var string */
110188 private $name;
110189 /** @var string */
110190 private $value;
110191 /**
110192 * Token constructor.
110193 */
110194 public function __construct(int $line, string $name, string $value)
110195 {
110196 $this->line = $line;
110197 $this->name = $name;
110198 $this->value = $value;
110199 }
110200 public function getLine(): int
110201 {
110202 return $this->line;
110203 }
110204 public function getName(): string
110205 {
110206 return $this->name;
110207 }
110208 public function getValue(): string
110209 {
110210 return $this->value;
110211 }
110212 }
110213 <?php
110214
110215 declare (strict_types=1);
110216 namespace PHPUnitPHAR\TheSeer\Tokenizer;
110217
110218 use ArrayAccess;
110219 use ArrayIterator;
110220 use Countable;
110221 use Iterator;
110222 use IteratorAggregate;
110223 /**
110224 * @implements IteratorAggregate<int, Token>
110225 */
110226 class TokenCollection implements IteratorAggregate, ArrayAccess, Countable
110227 {
110228 /** @var Token[] */
110229 private $tokens = [];
110230 public function addToken(Token $token): void
110231 {
110232 $this->tokens[] = $token;
110233 }
110234 public function getIterator(): Iterator
110235 {
110236 return new ArrayIterator($this->tokens);
110237 }
110238 public function count(): int
110239 {
110240 return \count($this->tokens);
110241 }
110242 public function offsetExists($offset): bool
110243 {
110244 return isset($this->tokens[$offset]);
110245 }
110246 /**
110247 * @throws TokenCollectionException
110248 */
110249 public function offsetGet($offset): Token
110250 {
110251 if (!$this->offsetExists($offset)) {
110252 throw new TokenCollectionException(\sprintf('No Token at offest %s', $offset));
110253 }
110254 return $this->tokens[$offset];
110255 }
110256 /**
110257 * @param Token $value
110258 *
110259 * @throws TokenCollectionException
110260 */
110261 public function offsetSet($offset, $value): void
110262 {
110263 if (!\is_int($offset)) {
110264 $type = \gettype($offset);
110265 throw new TokenCollectionException(\sprintf('Offset must be of type integer, %s given', $type === 'object' ? \get_class($value) : $type));
110266 }
110267 if (!$value instanceof Token) {
110268 $type = \gettype($value);
110269 throw new TokenCollectionException(\sprintf('Value must be of type %s, %s given', Token::class, $type === 'object' ? \get_class($value) : $type));
110270 }
110271 $this->tokens[$offset] = $value;
110272 }
110273 public function offsetUnset($offset): void
110274 {
110275 unset($this->tokens[$offset]);
110276 }
110277 }
110278 <?php
110279
110280 declare (strict_types=1);
110281 namespace PHPUnitPHAR\TheSeer\Tokenizer;
110282
110283 class TokenCollectionException extends Exception
110284 {
110285 }
110286 <?php
110287
110288 declare (strict_types=1);
110289 namespace PHPUnitPHAR\TheSeer\Tokenizer;
110290
110291 class Tokenizer
110292 {
110293 /**
110294 * Token Map for "non-tokens"
110295 *
110296 * @var array
110297 */
110298 private const MAP = ['(' => 'T_OPEN_BRACKET', ')' => 'T_CLOSE_BRACKET', '[' => 'T_OPEN_SQUARE', ']' => 'T_CLOSE_SQUARE', '{' => 'T_OPEN_CURLY', '}' => 'T_CLOSE_CURLY', ';' => 'T_SEMICOLON', '.' => 'T_DOT', ',' => 'T_COMMA', '=' => 'T_EQUAL', '<' => 'T_LT', '>' => 'T_GT', '+' => 'T_PLUS', '-' => 'T_MINUS', '*' => 'T_MULT', '/' => 'T_DIV', '?' => 'T_QUESTION_MARK', '!' => 'T_EXCLAMATION_MARK', ':' => 'T_COLON', '"' => 'T_DOUBLE_QUOTES', '@' => 'T_AT', '&' => 'T_AMPERSAND', '%' => 'T_PERCENT', '|' => 'T_PIPE', '$' => 'T_DOLLAR', '^' => 'T_CARET', '~' => 'T_TILDE', '`' => 'T_BACKTICK'];
110299 public function parse(string $source): TokenCollection
110300 {
110301 $result = new TokenCollection();
110302 if ($source === '') {
110303 return $result;
110304 }
110305 $tokens = \token_get_all($source);
110306 $lastToken = new Token($tokens[0][2], 'Placeholder', '');
110307 foreach ($tokens as $pos => $tok) {
110308 if (\is_string($tok)) {
110309 $token = new Token($lastToken->getLine(), self::MAP[$tok], $tok);
110310 $result->addToken($token);
110311 $lastToken = $token;
110312 continue;
110313 }
110314 $line = $tok[2];
110315 $values = \preg_split('/\R+/Uu', $tok[1]);
110316 if (!$values) {
110317 $result->addToken(new Token($line, \token_name($tok[0]), '{binary data}'));
110318 continue;
110319 }
110320 foreach ($values as $v) {
110321 $token = new Token($line, \token_name($tok[0]), $v);
110322 $lastToken = $token;
110323 $line++;
110324 if ($v === '') {
110325 continue;
110326 }
110327 $result->addToken($token);
110328 }
110329 }
110330 return $this->fillBlanks($result, $lastToken->getLine());
110331 }
110332 private function fillBlanks(TokenCollection $tokens, int $maxLine): TokenCollection
110333 {
110334 $prev = new Token(0, 'Placeholder', '');
110335 $final = new TokenCollection();
110336 $prevLine = $prev->getLine();
110337 foreach ($tokens as $token) {
110338 $line = $token->getLine();
110339 $gap = $line - $prevLine;
110340 while ($gap > 1) {
110341 $linebreak = new Token($prevLine + 1, 'T_WHITESPACE', '');
110342 $final->addToken($linebreak);
110343 $prevLine = $linebreak->getLine();
110344 $gap--;
110345 }
110346 $final->addToken($token);
110347 $prevLine = $line;
110348 }
110349 $gap = $maxLine - $prevLine;
110350 while ($gap > 0) {
110351 $linebreak = new Token($prevLine + 1, 'T_WHITESPACE', '');
110352 $final->addToken($linebreak);
110353 $prevLine = $linebreak->getLine();
110354 $gap--;
110355 }
110356 return $final;
110357 }
110358 }
110359 <?php
110360
110361 declare (strict_types=1);
110362 namespace PHPUnitPHAR\TheSeer\Tokenizer;
110363
110364 use DOMDocument;
110365 class XMLSerializer
110366 {
110367 /** @var NamespaceUri */
110368 private $xmlns;
110369 /**
110370 * XMLSerializer constructor.
110371 *
110372 * @param NamespaceUri $xmlns
110373 */
110374 public function __construct(?NamespaceUri $xmlns = null)
110375 {
110376 if ($xmlns === null) {
110377 $xmlns = new NamespaceUri('https://github.com/theseer/tokenizer');
110378 }
110379 $this->xmlns = $xmlns;
110380 }
110381 public function toDom(TokenCollection $tokens): DOMDocument
110382 {
110383 $dom = new DOMDocument();
110384 $dom->preserveWhiteSpace = \false;
110385 $dom->loadXML($this->toXML($tokens));
110386 return $dom;
110387 }
110388 public function toXML(TokenCollection $tokens): string
110389 {
110390 $writer = new \XMLWriter();
110391 $writer->openMemory();
110392 $writer->setIndent(\true);
110393 $writer->startDocument();
110394 $writer->startElement('source');
110395 $writer->writeAttribute('xmlns', $this->xmlns->asString());
110396 if (\count($tokens) > 0) {
110397 $writer->startElement('line');
110398 $writer->writeAttribute('no', '1');
110399 $iterator = $tokens->getIterator();
110400 $previousToken = $iterator->current();
110401 $previousLine = $previousToken->getLine();
110402 foreach ($iterator as $token) {
110403 $line = $token->getLine();
110404 if ($previousLine < $line) {
110405 $writer->endElement();
110406 $writer->startElement('line');
110407 $writer->writeAttribute('no', (string) $line);
110408 $previousLine = $line;
110409 }
110410 $value = $token->getValue();
110411 if ($value !== '') {
110412 $writer->startElement('token');
110413 $writer->writeAttribute('name', $token->getName());
110414 $writer->writeRaw(\htmlspecialchars($value, \ENT_NOQUOTES | \ENT_DISALLOWED | \ENT_XML1));
110415 $writer->endElement();
110416 }
110417 }
110418 $writer->endElement();
110419 }
110420 $writer->endElement();
110421 $writer->endDocument();
110422 return $writer->outputMemory();
110423 }
110424 }
110425 �ZK�%���b�2]��V���fV9��q6=����U������|X��!���Dm��L�eʀGBMB