diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index bc728d92f..95324c69b 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -18,7 +18,7 @@ jobs:
steps:
- name: Checkout
- uses: actions/checkout@v5
+ uses: actions/checkout@v6
with:
fetch-depth: 1
ref: ${{ github.event.pull_request.head.sha || github.sha }}
@@ -49,7 +49,7 @@ jobs:
steps:
- name: Checkout
- uses: actions/checkout@v5
+ uses: actions/checkout@v6
with:
fetch-depth: 1
ref: ${{ github.event.pull_request.head.sha || github.sha }}
@@ -77,7 +77,7 @@ jobs:
echo "dir=$(composer config cache-files-dir)" >> "$GITHUB_OUTPUT"
- name: Cache Composer cache directory
- uses: actions/cache@v4
+ uses: actions/cache@v5
with:
path: ${{ steps.composer-cache.outputs.dir }}
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
@@ -121,7 +121,7 @@ jobs:
run: git config --global core.autocrlf false
- name: Checkout
- uses: actions/checkout@v5
+ uses: actions/checkout@v6
with:
fetch-depth: 1
ref: ${{ github.event.pull_request.head.sha || github.sha }}
@@ -150,7 +150,7 @@ jobs:
echo "dir=$(composer config cache-files-dir)" >> "$GITHUB_OUTPUT"
- name: Cache Composer cache directory
- uses: actions/cache@v4
+ uses: actions/cache@v5
with:
path: ${{ steps.composer-cache.outputs.dir }}
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
@@ -164,15 +164,18 @@ jobs:
- name: Upload test results to Codecov.io
if: ${{ !cancelled() }}
- uses: codecov/test-results-action@v1
+ uses: codecov/codecov-action@v5
with:
token: ${{ secrets.CODECOV_TOKEN }}
+ report_type: test_results
disable_search: true
files: ./test-results.xml
- name: Upload code coverage data to Codecov.io
- uses: codecov/codecov-action@v4
+ if: ${{ !cancelled() }}
+ uses: codecov/codecov-action@v5
with:
token: ${{ secrets.CODECOV_TOKEN }}
+ report_type: coverage
disable_search: true
files: ./code-coverage.xml
diff --git a/.phive/phars.xml b/.phive/phars.xml
index 07724ca0b..8adaef1d8 100644
--- a/.phive/phars.xml
+++ b/.phive/phars.xml
@@ -1,5 +1,5 @@
-
-
+
+
diff --git a/ChangeLog-12.5.md b/ChangeLog-12.5.md
index fcf4d69aa..4c377d9ed 100644
--- a/ChangeLog-12.5.md
+++ b/ChangeLog-12.5.md
@@ -2,7 +2,19 @@
All notable changes are documented in this file using the [Keep a CHANGELOG](http://keepachangelog.com/) principles.
-## [12.5.0] - 2025-MM-DD
+## [12.5.2] - 2025-MM-DD
+
+### Fixed
+
+* [#1131](https://github.com/sebastianbergmann/php-code-coverage/issues/1131): Invalid XML generated when both PCOV and Xdebug are loaded
+
+## [12.5.1] - 2025-12-08
+
+### Changed
+
+* [#1125](https://github.com/sebastianbergmann/php-code-coverage/pull/1125): Improve performance of XML report by using XMLWriter instead of DOM
+
+## [12.5.0] - 2025-11-29
### Added
@@ -14,6 +26,9 @@ All notable changes are documented in this file using the [Keep a CHANGELOG](htt
* [#1107](https://github.com/sebastianbergmann/php-code-coverage/pull/1107): Do not sort code coverage data over and over
* [#1108](https://github.com/sebastianbergmann/php-code-coverage/pull/1108): Do not sort covered files data over and over
* [#1109](https://github.com/sebastianbergmann/php-code-coverage/pull/1109): Represent line coverage data using objects
+* [#1126](https://github.com/sebastianbergmann/php-code-coverage/issues/1126): Add test execution time to `` elements under `projects/tests` in the XML reports index file
* [#1127](https://github.com/sebastianbergmann/php-code-coverage/issues/1127): Add SHA-1 hash of content of SUT source file to XML report
-[12.5.0]: https://github.com/sebastianbergmann/php-code-coverage/compare/12.4.0...main
+[12.5.2]: https://github.com/sebastianbergmann/php-code-coverage/compare/12.5.1...main
+[12.5.1]: https://github.com/sebastianbergmann/php-code-coverage/compare/12.5.0...12.5.1
+[12.5.0]: https://github.com/sebastianbergmann/php-code-coverage/compare/12.4.0...12.5.0
diff --git a/composer.json b/composer.json
index 65f2e5c32..550171f84 100644
--- a/composer.json
+++ b/composer.json
@@ -33,17 +33,17 @@
"ext-dom": "*",
"ext-libxml": "*",
"ext-xmlwriter": "*",
- "nikic/php-parser": "^5.6.1",
+ "nikic/php-parser": "^5.7.0",
"phpunit/php-file-iterator": "^6.0",
"phpunit/php-text-template": "^5.0",
"sebastian/complexity": "^5.0",
"sebastian/environment": "^8.0.3",
"sebastian/lines-of-code": "^4.0",
"sebastian/version": "^6.0",
- "theseer/tokenizer": "^1.2.3"
+ "theseer/tokenizer": "^2.0.1"
},
"require-dev": {
- "phpunit/phpunit": "^12.3.7"
+ "phpunit/phpunit": "^12.5.1"
},
"suggest": {
"ext-pcov": "PHP extension that provides line coverage",
diff --git a/src/CodeCoverage.php b/src/CodeCoverage.php
index ab9936ce7..32ff86d0b 100644
--- a/src/CodeCoverage.php
+++ b/src/CodeCoverage.php
@@ -39,7 +39,7 @@
/**
* Provides collection functionality for PHP code coverage information.
*
- * @phpstan-type TestType array{size: string, status: string}
+ * @phpstan-type TestType array{size: string, status: string, time: float}
* @phpstan-type TargetedLines array>
*/
final class CodeCoverage
@@ -189,11 +189,11 @@ public function start(string $id, ?TestSize $size = null, bool $clear = false):
$this->cachedReport = null;
}
- public function stop(bool $append = true, ?TestStatus $status = null, null|false|TargetCollection $covers = null, ?TargetCollection $uses = null): RawCodeCoverageData
+ public function stop(bool $append = true, ?TestStatus $status = null, null|false|TargetCollection $covers = null, ?TargetCollection $uses = null, float $time = 0.0): RawCodeCoverageData
{
$data = $this->driver->stop();
- $this->append($data, null, $append, $status, $covers, $uses);
+ $this->append($data, null, $append, $status, $covers, $uses, $time);
$this->currentId = null;
$this->currentSize = null;
@@ -207,7 +207,7 @@ public function stop(bool $append = true, ?TestStatus $status = null, null|false
* @throws TestIdMissingException
* @throws UnintentionallyCoveredCodeException
*/
- public function append(RawCodeCoverageData $rawData, ?string $id = null, bool $append = true, ?TestStatus $status = null, null|false|TargetCollection $covers = null, ?TargetCollection $uses = null): void
+ public function append(RawCodeCoverageData $rawData, ?string $id = null, bool $append = true, ?TestStatus $status = null, null|false|TargetCollection $covers = null, ?TargetCollection $uses = null, float $time = 0.0): void
{
if ($id === null) {
$id = $this->currentId;
@@ -280,6 +280,7 @@ public function append(RawCodeCoverageData $rawData, ?string $id = null, bool $a
$this->tests[$id] = [
'size' => $size->asString(),
'status' => $status->asString(),
+ 'time' => $time,
];
$this->data->markCodeAsExecutedByTestCase($id, $rawData);
@@ -405,6 +406,22 @@ public function validate(TargetCollection $targets): ValidationResult
return (new TargetCollectionValidator)->validate($this->targetMapper(), $targets);
}
+ /**
+ * @internal
+ */
+ public function driverIsPcov(): bool
+ {
+ return $this->driver->isPcov();
+ }
+
+ /**
+ * @internal
+ */
+ public function driverIsXdebug(): bool
+ {
+ return $this->driver->isXdebug();
+ }
+
/**
* @param false|TargetedLines $linesToBeCovered
* @param TargetedLines $linesToBeUsed
diff --git a/src/Driver/Driver.php b/src/Driver/Driver.php
index b839cca53..1174eaafb 100644
--- a/src/Driver/Driver.php
+++ b/src/Driver/Driver.php
@@ -76,6 +76,16 @@ public function disableBranchAndPathCoverage(): void
$this->collectBranchAndPathCoverage = false;
}
+ public function isPcov(): bool
+ {
+ return false;
+ }
+
+ public function isXdebug(): bool
+ {
+ return false;
+ }
+
abstract public function nameAndVersion(): string;
abstract public function start(): void;
diff --git a/src/Driver/PcovDriver.php b/src/Driver/PcovDriver.php
index d7975efe3..fbe42fe59 100644
--- a/src/Driver/PcovDriver.php
+++ b/src/Driver/PcovDriver.php
@@ -73,6 +73,11 @@ public function nameAndVersion(): string
return 'PCOV ' . phpversion('pcov');
}
+ public function isPcov(): true
+ {
+ return true;
+ }
+
/**
* @throws PcovNotAvailableException
*/
diff --git a/src/Driver/XdebugDriver.php b/src/Driver/XdebugDriver.php
index 039df00d0..5562af296 100644
--- a/src/Driver/XdebugDriver.php
+++ b/src/Driver/XdebugDriver.php
@@ -113,6 +113,11 @@ public function nameAndVersion(): string
return 'Xdebug ' . phpversion('xdebug');
}
+ public function isXdebug(): true
+ {
+ return true;
+ }
+
/**
* @throws XdebugNotAvailableException
* @throws XdebugNotEnabledException
diff --git a/src/Exception/UnintentionallyCoveredCodeException.php b/src/Exception/UnintentionallyCoveredCodeException.php
index bb7d88c97..1bbdac361 100644
--- a/src/Exception/UnintentionallyCoveredCodeException.php
+++ b/src/Exception/UnintentionallyCoveredCodeException.php
@@ -9,6 +9,7 @@
*/
namespace SebastianBergmann\CodeCoverage;
+use function rtrim;
use RuntimeException;
final class UnintentionallyCoveredCodeException extends RuntimeException implements Exception
@@ -44,6 +45,6 @@ private function toString(): string
$message .= '- ' . $unit . "\n";
}
- return $message;
+ return rtrim($message);
}
}
diff --git a/src/Report/Xml/BuildInformation.php b/src/Report/Xml/BuildInformation.php
index 654eecb31..b11fc6ede 100644
--- a/src/Report/Xml/BuildInformation.php
+++ b/src/Report/Xml/BuildInformation.php
@@ -9,63 +9,40 @@
*/
namespace SebastianBergmann\CodeCoverage\Report\Xml;
-use function assert;
-use function phpversion;
use DateTimeImmutable;
-use DOMElement;
use SebastianBergmann\Environment\Runtime;
+use XMLWriter;
/**
* @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
*/
final readonly class BuildInformation
{
- private DOMElement $contextNode;
-
public function __construct(
- DOMElement $contextNode,
+ XMLWriter $xmlWriter,
Runtime $runtime,
DateTimeImmutable $buildDate,
string $phpUnitVersion,
- string $coverageVersion
+ string $coverageVersion,
+ string $driverExtensionName,
+ string $driverExtensionVersion,
) {
- $this->contextNode = $contextNode;
-
- $runtimeNode = $this->nodeByName('runtime');
-
- $runtimeNode->setAttribute('name', $runtime->getName());
- $runtimeNode->setAttribute('version', $runtime->getVersion());
- $runtimeNode->setAttribute('url', $runtime->getVendorUrl());
-
- $driverNode = $this->nodeByName('driver');
-
- if ($runtime->hasXdebug()) {
- $driverNode->setAttribute('name', 'xdebug');
- $driverNode->setAttribute('version', phpversion('xdebug'));
- }
-
- if ($runtime->hasPCOV()) {
- $driverNode->setAttribute('name', 'pcov');
- $driverNode->setAttribute('version', phpversion('pcov'));
- }
-
- $this->contextNode->setAttribute('time', $buildDate->format('D M j G:i:s T Y'));
-
- $this->contextNode->setAttribute('phpunit', $phpUnitVersion);
- $this->contextNode->setAttribute('coverage', $coverageVersion);
- }
-
- private function nodeByName(string $name): DOMElement
- {
- $node = $this->contextNode->appendChild(
- $this->contextNode->ownerDocument->createElementNS(
- Facade::XML_NAMESPACE,
- $name,
- ),
- );
-
- assert($node instanceof DOMElement);
-
- return $node;
+ $xmlWriter->startElement('build');
+ $xmlWriter->writeAttribute('time', $buildDate->format('D M j G:i:s T Y'));
+ $xmlWriter->writeAttribute('phpunit', $phpUnitVersion);
+ $xmlWriter->writeAttribute('coverage', $coverageVersion);
+
+ $xmlWriter->startElement('runtime');
+ $xmlWriter->writeAttribute('name', $runtime->getName());
+ $xmlWriter->writeAttribute('version', $runtime->getVersion());
+ $xmlWriter->writeAttribute('url', $runtime->getVendorUrl());
+ $xmlWriter->endElement();
+
+ $xmlWriter->startElement('driver');
+ $xmlWriter->writeAttribute('name', $driverExtensionName);
+ $xmlWriter->writeAttribute('version', $driverExtensionVersion);
+ $xmlWriter->endElement();
+
+ $xmlWriter->endElement();
}
}
diff --git a/src/Report/Xml/Coverage.php b/src/Report/Xml/Coverage.php
index 9462780be..3038eb143 100644
--- a/src/Report/Xml/Coverage.php
+++ b/src/Report/Xml/Coverage.php
@@ -9,7 +9,6 @@
*/
namespace SebastianBergmann\CodeCoverage\Report\Xml;
-use DOMElement;
use XMLWriter;
/**
@@ -17,20 +16,21 @@
*/
final class Coverage
{
- private readonly DOMElement $contextNode;
+ private readonly XMLWriter $xmlWriter;
private readonly string $line;
- public function __construct(DOMElement $context, string $line)
- {
- $this->contextNode = $context;
- $this->line = $line;
+ public function __construct(
+ XMLWriter $xmlWriter,
+ string $line
+ ) {
+ $this->xmlWriter = $xmlWriter;
+ $this->line = $line;
}
public function finalize(array $tests): void
{
- $writer = new XMLWriter;
- $writer->openMemory();
- $writer->startElementNs(null, $this->contextNode->nodeName, Facade::XML_NAMESPACE);
+ $writer = $this->xmlWriter;
+ $writer->startElement('line');
$writer->writeAttribute('nr', $this->line);
foreach ($tests as $test) {
@@ -39,13 +39,5 @@ public function finalize(array $tests): void
$writer->endElement();
}
$writer->endElement();
-
- $fragment = $this->contextNode->ownerDocument->createDocumentFragment();
- $fragment->appendXML($writer->outputMemory());
-
- $this->contextNode->parentNode->replaceChild(
- $fragment,
- $this->contextNode,
- );
}
}
diff --git a/src/Report/Xml/Facade.php b/src/Report/Xml/Facade.php
index f31a1520d..05ab96a60 100644
--- a/src/Report/Xml/Facade.php
+++ b/src/Report/Xml/Facade.php
@@ -17,11 +17,11 @@
use function is_dir;
use function is_file;
use function is_writable;
+use function phpversion;
use function sprintf;
use function strlen;
use function substr;
use DateTimeImmutable;
-use DOMDocument;
use SebastianBergmann\CodeCoverage\CodeCoverage;
use SebastianBergmann\CodeCoverage\Data\ProcessedClassType;
use SebastianBergmann\CodeCoverage\Data\ProcessedFunctionType;
@@ -31,11 +31,11 @@
use SebastianBergmann\CodeCoverage\Node\File as FileNode;
use SebastianBergmann\CodeCoverage\PathExistsButIsNotDirectoryException;
use SebastianBergmann\CodeCoverage\Util\Filesystem;
-use SebastianBergmann\CodeCoverage\Util\Xml;
use SebastianBergmann\CodeCoverage\Version;
use SebastianBergmann\CodeCoverage\WriteOperationFailedException;
use SebastianBergmann\CodeCoverage\XmlException;
use SebastianBergmann\Environment\Runtime;
+use XMLWriter;
/**
* @phpstan-import-type TestType from CodeCoverage
@@ -68,24 +68,45 @@ public function process(CodeCoverage $coverage, string $target): void
$report = $coverage->getReport();
+ $writer = new XMLWriter;
+ $writer->openUri($this->targetFilePath('index'));
+ $writer->setIndent(true);
+ $writer->setIndentString(' ');
$this->project = new Project(
+ $writer,
$coverage->getReport()->name(),
);
- $this->setBuildInformation();
+ $this->setBuildInformation($coverage);
+
+ $this->project->startProject();
$this->processTests($coverage->getTests());
$this->processDirectory($report, $this->project);
-
- $this->saveDocument($this->project->asDom(), 'index');
+ $this->project->finalize();
}
- private function setBuildInformation(): void
+ private function setBuildInformation(CodeCoverage $coverage): void
{
+ if ($coverage->driverIsPcov()) {
+ $driverExtensionName = 'pcov';
+ $driverExtensionVersion = phpversion('pcov');
+ } elseif ($coverage->driverIsXdebug()) {
+ $driverExtensionName = 'xdebug';
+ $driverExtensionVersion = phpversion('xdebug');
+ } else {
+ // @codeCoverageIgnoreStart
+ $driverExtensionName = 'unknown';
+ $driverExtensionVersion = 'unknown';
+ // @codeCoverageIgnoreEnd
+ }
+
$this->project->buildInformation(
new Runtime,
new DateTimeImmutable,
$this->phpUnitVersion,
Version::id(),
+ $driverExtensionName,
+ $driverExtensionVersion,
);
}
@@ -121,7 +142,10 @@ private function processDirectory(DirectoryNode $directory, Node $context): void
$directoryName = '/';
}
- $directoryObject = $context->addDirectory($directoryName);
+ $writer = $this->project->getWriter();
+ $writer->startElement('directory');
+ $writer->writeAttribute('name', $directoryName);
+ $directoryObject = $context->addDirectory();
$this->setTotals($directory, $directoryObject->totals());
@@ -132,6 +156,7 @@ private function processDirectory(DirectoryNode $directory, Node $context): void
foreach ($directory->files() as $node) {
$this->processFile($node, $directoryObject);
}
+ $writer->endElement();
}
/**
@@ -139,20 +164,27 @@ private function processDirectory(DirectoryNode $directory, Node $context): void
*/
private function processFile(FileNode $file, Directory $context): void
{
- $fileObject = $context->addFile(
- $file->name(),
- $file->id() . '.xml',
- $file->sha1(),
- );
+ $context->getWriter()->startElement('file');
+ $context->getWriter()->writeAttribute('name', $file->name());
+ $context->getWriter()->writeAttribute('href', $file->id() . '.xml');
+ $context->getWriter()->writeAttribute('hash', $file->sha1());
+
+ $fileObject = $context->addFile();
$this->setTotals($file, $fileObject->totals());
+ $context->getWriter()->endElement();
+
$path = substr(
$file->pathAsString(),
strlen($this->project->projectSourceDirectory()),
);
- $fileReport = new Report($path, $file->sha1());
+ $writer = new XMLWriter;
+ $writer->openUri($this->targetFilePath($file->id()));
+ $writer->setIndent(true);
+ $writer->setIndentString(' ');
+ $fileReport = new Report($writer, $path, $file->sha1());
$this->setTotals($file, $fileReport->totals());
@@ -164,6 +196,8 @@ private function processFile(FileNode $file, Directory $context): void
$this->processFunction($function, $fileReport);
}
+ $fileReport->getWriter()->startElement('coverage');
+
foreach ($file->lineCoverageData() as $line => $tests) {
if (!is_array($tests) || count($tests) === 0) {
continue;
@@ -172,6 +206,7 @@ private function processFile(FileNode $file, Directory $context): void
$coverage = $fileReport->lineCoverage((string) $line);
$coverage->finalize($tests);
}
+ $fileReport->getWriter()->endElement();
if ($this->includeSource) {
$fileReport->source()->setSourceCode(
@@ -179,12 +214,14 @@ private function processFile(FileNode $file, Directory $context): void
);
}
- $this->saveDocument($fileReport->asDom(), $file->id());
+ $fileReport->finalize();
}
private function processUnit(ProcessedClassType|ProcessedTraitType $unit, Report $report): void
{
if ($unit instanceof ProcessedClassType) {
+ $report->getWriter()->startElement('class');
+
$unitObject = $report->classObject(
$unit->className,
$unit->namespace,
@@ -194,6 +231,8 @@ private function processUnit(ProcessedClassType|ProcessedTraitType $unit, Report
(float) $unit->crap,
);
} else {
+ $report->getWriter()->startElement('trait');
+
$unitObject = $report->traitObject(
$unit->traitName,
$unit->namespace,
@@ -205,6 +244,8 @@ private function processUnit(ProcessedClassType|ProcessedTraitType $unit, Report
}
foreach ($unit->methods as $method) {
+ $report->getWriter()->startElement('method');
+
$unitObject->addMethod(
$method->methodName,
$method->signature,
@@ -215,11 +256,17 @@ private function processUnit(ProcessedClassType|ProcessedTraitType $unit, Report
(string) $method->coverage,
$method->crap,
);
+
+ $report->getWriter()->endElement();
}
+
+ $report->getWriter()->endElement();
}
private function processFunction(ProcessedFunctionType $function, Report $report): void
{
+ $report->getWriter()->startElement('function');
+
$report->functionObject(
$function->functionName,
$function->signature,
@@ -230,6 +277,8 @@ private function processFunction(ProcessedFunctionType $function, Report $report
(string) $function->coverage,
$function->crap,
);
+
+ $report->getWriter()->endElement();
}
/**
@@ -237,15 +286,21 @@ private function processFunction(ProcessedFunctionType $function, Report $report
*/
private function processTests(array $tests): void
{
+ $this->project->getWriter()->startElement('tests');
+
$testsObject = $this->project->tests();
foreach ($tests as $test => $result) {
$testsObject->addTest($test, $result);
}
+
+ $this->project->getWriter()->endElement();
}
private function setTotals(AbstractNode $node, Totals $totals): void
{
+ $totals->getWriter()->startElement('totals');
+
$loc = $node->linesOfCode();
$totals->setNumLines(
@@ -256,6 +311,16 @@ private function setTotals(AbstractNode $node, Totals $totals): void
$node->numberOfExecutedLines(),
);
+ $totals->setNumMethods(
+ $node->numberOfMethods(),
+ $node->numberOfTestedMethods(),
+ );
+
+ $totals->setNumFunctions(
+ $node->numberOfFunctions(),
+ $node->numberOfTestedFunctions(),
+ );
+
$totals->setNumClasses(
$node->numberOfClasses(),
$node->numberOfTestedClasses(),
@@ -266,15 +331,7 @@ private function setTotals(AbstractNode $node, Totals $totals): void
$node->numberOfTestedTraits(),
);
- $totals->setNumMethods(
- $node->numberOfMethods(),
- $node->numberOfTestedMethods(),
- );
-
- $totals->setNumFunctions(
- $node->numberOfFunctions(),
- $node->numberOfTestedFunctions(),
- );
+ $totals->getWriter()->endElement();
}
private function targetDirectory(): string
@@ -290,12 +347,4 @@ private function targetFilePath(string $name): string
return $filename;
}
-
- /**
- * @throws XmlException
- */
- private function saveDocument(DOMDocument $document, string $name): void
- {
- Filesystem::write($this->targetFilePath($name), Xml::asString($document));
- }
}
diff --git a/src/Report/Xml/File.php b/src/Report/Xml/File.php
index e6dd5c4ba..2d35582a8 100644
--- a/src/Report/Xml/File.php
+++ b/src/Report/Xml/File.php
@@ -9,66 +9,32 @@
*/
namespace SebastianBergmann\CodeCoverage\Report\Xml;
-use function assert;
-use DOMDocument;
-use DOMElement;
-use DOMNode;
+use XMLWriter;
/**
* @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
*/
class File
{
- protected readonly DOMDocument $dom;
- private readonly DOMElement $contextNode;
- private ?DOMNode $lineCoverage = null;
+ protected XMLWriter $xmlWriter;
- public function __construct(DOMElement $context)
+ public function __construct(XMLWriter $xmlWriter)
{
- $this->dom = $context->ownerDocument;
- $this->contextNode = $context;
+ $this->xmlWriter = $xmlWriter;
}
- public function totals(): Totals
+ public function getWriter(): XMLWriter
{
- $totalsContainer = $this->contextNode->appendChild(
- $this->dom->createElementNS(
- Facade::XML_NAMESPACE,
- 'totals',
- ),
- );
-
- assert($totalsContainer instanceof DOMElement);
-
- return new Totals($totalsContainer);
+ return $this->xmlWriter;
}
- public function lineCoverage(string $line): Coverage
+ public function totals(): Totals
{
- if ($this->lineCoverage === null) {
- $this->lineCoverage = $this->contextNode->appendChild(
- $this->dom->createElementNS(
- Facade::XML_NAMESPACE,
- 'coverage',
- ),
- );
- }
- assert($this->lineCoverage instanceof DOMElement);
-
- $lineNode = $this->lineCoverage->appendChild(
- $this->dom->createElementNS(
- Facade::XML_NAMESPACE,
- 'line',
- ),
- );
-
- assert($lineNode instanceof DOMElement);
-
- return new Coverage($lineNode, $line);
+ return new Totals($this->xmlWriter);
}
- protected function contextNode(): DOMElement
+ public function lineCoverage(string $line): Coverage
{
- return $this->contextNode;
+ return new Coverage($this->xmlWriter, $line);
}
}
diff --git a/src/Report/Xml/Method.php b/src/Report/Xml/Method.php
index 1b5bdb28f..965ad5259 100644
--- a/src/Report/Xml/Method.php
+++ b/src/Report/Xml/Method.php
@@ -9,17 +9,17 @@
*/
namespace SebastianBergmann\CodeCoverage\Report\Xml;
-use DOMElement;
+use XMLWriter;
/**
* @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
*/
final readonly class Method
{
- private DOMElement $contextNode;
+ private XMLWriter $xmlWriter;
public function __construct(
- DOMElement $context,
+ XMLWriter $xmlWriter,
string $name,
string $signature,
string $start,
@@ -29,21 +29,21 @@ public function __construct(
string $coverage,
string $crap
) {
- $this->contextNode = $context;
+ $this->xmlWriter = $xmlWriter;
- $this->contextNode->setAttribute('name', $name);
- $this->contextNode->setAttribute('signature', $signature);
+ $this->xmlWriter->writeAttribute('name', $name);
+ $this->xmlWriter->writeAttribute('signature', $signature);
- $this->contextNode->setAttribute('start', $start);
+ $this->xmlWriter->writeAttribute('start', $start);
if ($end !== null) {
- $this->contextNode->setAttribute('end', $end);
+ $this->xmlWriter->writeAttribute('end', $end);
}
- $this->contextNode->setAttribute('crap', $crap);
+ $this->xmlWriter->writeAttribute('crap', $crap);
- $this->contextNode->setAttribute('executable', $executable);
- $this->contextNode->setAttribute('executed', $executed);
- $this->contextNode->setAttribute('coverage', $coverage);
+ $this->xmlWriter->writeAttribute('executable', $executable);
+ $this->xmlWriter->writeAttribute('executed', $executed);
+ $this->xmlWriter->writeAttribute('coverage', $coverage);
}
}
diff --git a/src/Report/Xml/Node.php b/src/Report/Xml/Node.php
index 37023b448..36b75bcfe 100644
--- a/src/Report/Xml/Node.php
+++ b/src/Report/Xml/Node.php
@@ -9,72 +9,37 @@
*/
namespace SebastianBergmann\CodeCoverage\Report\Xml;
-use function assert;
-use DOMDocument;
-use DOMElement;
+use XMLWriter;
/**
* @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
*/
abstract class Node
{
- protected readonly DOMDocument $dom;
- private readonly DOMElement $contextNode;
+ protected readonly XMLWriter $xmlWriter;
- public function __construct(DOMElement $context)
+ public function __construct(XMLWriter $xmlWriter)
{
- $this->dom = $context->ownerDocument;
- $this->contextNode = $context;
+ $this->xmlWriter = $xmlWriter;
}
public function totals(): Totals
{
- $totalsContainer = $this->contextNode()->firstChild;
-
- if ($totalsContainer === null) {
- $totalsContainer = $this->contextNode()->appendChild(
- $this->dom->createElementNS(
- Facade::XML_NAMESPACE,
- 'totals',
- ),
- );
- }
-
- assert($totalsContainer instanceof DOMElement);
-
- return new Totals($totalsContainer);
+ return new Totals($this->xmlWriter);
}
- public function addDirectory(string $name): Directory
+ public function addDirectory(): Directory
{
- $dirNode = $this->dom->createElementNS(
- Facade::XML_NAMESPACE,
- 'directory',
- );
-
- $dirNode->setAttribute('name', $name);
- $this->contextNode()->appendChild($dirNode);
-
- return new Directory($dirNode);
+ return new Directory($this->xmlWriter);
}
- public function addFile(string $name, string $href, string $hash): File
+ public function addFile(): File
{
- $fileNode = $this->dom->createElementNS(
- Facade::XML_NAMESPACE,
- 'file',
- );
-
- $fileNode->setAttribute('name', $name);
- $fileNode->setAttribute('href', $href);
- $fileNode->setAttribute('hash', $hash);
- $this->contextNode()->appendChild($fileNode);
-
- return new File($fileNode);
+ return new File($this->xmlWriter);
}
- protected function contextNode(): DOMElement
+ public function getWriter(): XMLWriter
{
- return $this->contextNode;
+ return $this->xmlWriter;
}
}
diff --git a/src/Report/Xml/Project.php b/src/Report/Xml/Project.php
index c81a6a933..e21addb56 100644
--- a/src/Report/Xml/Project.php
+++ b/src/Report/Xml/Project.php
@@ -9,11 +9,9 @@
*/
namespace SebastianBergmann\CodeCoverage\Report\Xml;
-use function assert;
use DateTimeImmutable;
-use DOMDocument;
-use DOMElement;
use SebastianBergmann\Environment\Runtime;
+use XMLWriter;
/**
* @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
@@ -22,19 +20,16 @@ final class Project extends Node
{
private readonly string $directory;
- public function __construct(string $directory)
+ public function __construct(XMLWriter $xmlWriter, string $directory)
{
- $dom = new DOMDocument;
- $dom->loadXML(' ');
+ $this->directory = $directory;
- parent::__construct(
- $dom->getElementsByTagNameNS(
- Facade::XML_NAMESPACE,
- 'project',
- )->item(0),
- );
+ parent::__construct($xmlWriter);
- $this->directory = $directory;
+ $this->xmlWriter->startDocument();
+
+ $this->xmlWriter->startElement('phpunit');
+ $this->xmlWriter->writeAttribute('xmlns', Facade::XML_NAMESPACE);
}
public function projectSourceDirectory(): string
@@ -46,42 +41,41 @@ public function buildInformation(
Runtime $runtime,
DateTimeImmutable $buildDate,
string $phpUnitVersion,
- string $coverageVersion
+ string $coverageVersion,
+ string $driverExtensionName,
+ string $driverExtensionVersion,
): void {
- $buildNode = $this->dom->getElementsByTagNameNS(
- Facade::XML_NAMESPACE,
- 'build',
- )->item(0);
-
- assert($buildNode instanceof DOMElement);
-
new BuildInformation(
- $buildNode,
+ $this->xmlWriter,
$runtime,
$buildDate,
$phpUnitVersion,
$coverageVersion,
+ $driverExtensionName,
+ $driverExtensionVersion,
);
}
public function tests(): Tests
{
- $testsNode = $this->contextNode()->appendChild(
- $this->dom->createElementNS(
- Facade::XML_NAMESPACE,
- 'tests',
- ),
- );
-
- assert($testsNode instanceof DOMElement);
+ return new Tests($this->xmlWriter);
+ }
- return new Tests($testsNode);
+ public function getWriter(): XMLWriter
+ {
+ return $this->xmlWriter;
}
- public function asDom(): DOMDocument
+ public function startProject(): void
{
- $this->contextNode()->setAttribute('source', $this->directory);
+ $this->xmlWriter->startElement('project');
+ $this->xmlWriter->writeAttribute('source', $this->directory);
+ }
- return $this->dom;
+ public function finalize(): void
+ {
+ $this->xmlWriter->endElement();
+ $this->xmlWriter->endDocument();
+ $this->xmlWriter->flush();
}
}
diff --git a/src/Report/Xml/Report.php b/src/Report/Xml/Report.php
index b57189d64..46d4dc0ed 100644
--- a/src/Report/Xml/Report.php
+++ b/src/Report/Xml/Report.php
@@ -9,11 +9,10 @@
*/
namespace SebastianBergmann\CodeCoverage\Report\Xml;
-use function assert;
use function basename;
use function dirname;
use DOMDocument;
-use DOMElement;
+use XMLWriter;
/**
* @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
@@ -23,8 +22,9 @@ final class Report extends File
private readonly string $name;
private readonly string $sha1;
- public function __construct(string $name, string $sha1)
+ public function __construct(XMLWriter $xmlWriter, string $name, string $sha1)
{
+ /*
$dom = new DOMDocument;
$dom->loadXML(' ');
@@ -32,20 +32,28 @@ public function __construct(string $name, string $sha1)
Facade::XML_NAMESPACE,
'file',
)->item(0);
-
- parent::__construct($contextNode);
+*/
+ parent::__construct($xmlWriter);
$this->name = $name;
$this->sha1 = $sha1;
+
+ $xmlWriter->startDocument();
+ $xmlWriter->startElement('phpunit');
+ $xmlWriter->writeAttribute('xmlns', Facade::XML_NAMESPACE);
+ $xmlWriter->startElement('file');
+ $xmlWriter->writeAttribute('name', basename($this->name));
+ $xmlWriter->writeAttribute('path', dirname($this->name));
+ $xmlWriter->writeAttribute('hash', $this->sha1);
}
- public function asDom(): DOMDocument
+ public function finalize(): void
{
- $this->contextNode()->setAttribute('name', basename($this->name));
- $this->contextNode()->setAttribute('path', dirname($this->name));
- $this->contextNode()->setAttribute('hash', $this->sha1);
+ $this->xmlWriter->endElement();
+ $this->xmlWriter->endElement();
- return $this->dom;
+ $this->xmlWriter->endDocument();
+ $this->xmlWriter->flush();
}
public function functionObject(
@@ -58,17 +66,8 @@ public function functionObject(
string $coverage,
string $crap
): void {
- $node = $this->contextNode()->appendChild(
- $this->dom->createElementNS(
- Facade::XML_NAMESPACE,
- 'function',
- ),
- );
-
- assert($node instanceof DOMElement);
-
new Method(
- $node,
+ $this->xmlWriter,
$name,
$signature,
$start,
@@ -88,16 +87,7 @@ public function classObject(
int $executed,
float $crap
): Unit {
- $node = $this->contextNode()->appendChild(
- $this->dom->createElementNS(
- Facade::XML_NAMESPACE,
- 'class',
- ),
- );
-
- assert($node instanceof DOMElement);
-
- return new Unit($node, $name, $namespace, $start, $executable, $executed, $crap);
+ return new Unit($this->xmlWriter, $name, $namespace, $start, $executable, $executed, $crap);
}
public function traitObject(
@@ -108,29 +98,11 @@ public function traitObject(
int $executed,
float $crap
): Unit {
- $node = $this->contextNode()->appendChild(
- $this->dom->createElementNS(
- Facade::XML_NAMESPACE,
- 'trait',
- ),
- );
-
- assert($node instanceof DOMElement);
-
- return new Unit($node, $name, $namespace, $start, $executable, $executed, $crap);
+ return new Unit($this->xmlWriter, $name, $namespace, $start, $executable, $executed, $crap);
}
public function source(): Source
{
- $source = $this->contextNode()->appendChild(
- $this->dom->createElementNS(
- Facade::XML_NAMESPACE,
- 'source',
- ),
- );
-
- assert($source instanceof DOMElement);
-
- return new Source($source);
+ return new Source($this->xmlWriter);
}
}
diff --git a/src/Report/Xml/Source.php b/src/Report/Xml/Source.php
index 698a71b6d..e82b2c382 100644
--- a/src/Report/Xml/Source.php
+++ b/src/Report/Xml/Source.php
@@ -9,33 +9,26 @@
*/
namespace SebastianBergmann\CodeCoverage\Report\Xml;
-use DOMElement;
use TheSeer\Tokenizer\NamespaceUri;
use TheSeer\Tokenizer\Tokenizer;
use TheSeer\Tokenizer\XMLSerializer;
+use XMLWriter;
/**
* @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
*/
final readonly class Source
{
- private DOMElement $context;
+ private XMLWriter $xmlWriter;
- public function __construct(DOMElement $context)
+ public function __construct(XMLWriter $xmlWriter)
{
- $this->context = $context;
+ $this->xmlWriter = $xmlWriter;
}
public function setSourceCode(string $source): void
{
- $context = $this->context;
-
$tokens = (new Tokenizer)->parse($source);
- $srcDom = (new XMLSerializer(new NamespaceUri(Facade::XML_NAMESPACE)))->toDom($tokens);
-
- $context->parentNode->replaceChild(
- $context->ownerDocument->importNode($srcDom->documentElement, true),
- $context,
- );
+ (new XMLSerializer(new NamespaceUri(Facade::XML_NAMESPACE)))->appendToWriter($this->xmlWriter, $tokens);
}
}
diff --git a/src/Report/Xml/Tests.php b/src/Report/Xml/Tests.php
index 1760fdfa5..fcb6bb7cc 100644
--- a/src/Report/Xml/Tests.php
+++ b/src/Report/Xml/Tests.php
@@ -9,9 +9,9 @@
*/
namespace SebastianBergmann\CodeCoverage\Report\Xml;
-use function assert;
-use DOMElement;
+use function sprintf;
use SebastianBergmann\CodeCoverage\CodeCoverage;
+use XMLWriter;
/**
* @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
@@ -20,11 +20,11 @@
*/
final readonly class Tests
{
- private DOMElement $contextNode;
+ private readonly XMLWriter $xmlWriter;
- public function __construct(DOMElement $context)
+ public function __construct(XMLWriter $xmlWriter)
{
- $this->contextNode = $context;
+ $this->xmlWriter = $xmlWriter;
}
/**
@@ -32,17 +32,13 @@ public function __construct(DOMElement $context)
*/
public function addTest(string $test, array $result): void
{
- $node = $this->contextNode->appendChild(
- $this->contextNode->ownerDocument->createElementNS(
- Facade::XML_NAMESPACE,
- 'test',
- ),
- );
+ $this->xmlWriter->startElement('test');
- assert($node instanceof DOMElement);
+ $this->xmlWriter->writeAttribute('name', $test);
+ $this->xmlWriter->writeAttribute('size', $result['size']);
+ $this->xmlWriter->writeAttribute('status', $result['status']);
+ $this->xmlWriter->writeAttribute('time', sprintf('%F', $result['time']));
- $node->setAttribute('name', $test);
- $node->setAttribute('size', $result['size']);
- $node->setAttribute('status', $result['status']);
+ $this->xmlWriter->endElement();
}
}
diff --git a/src/Report/Xml/Totals.php b/src/Report/Xml/Totals.php
index 28612f7aa..b0c57ec30 100644
--- a/src/Report/Xml/Totals.php
+++ b/src/Report/Xml/Totals.php
@@ -10,106 +10,86 @@
namespace SebastianBergmann\CodeCoverage\Report\Xml;
use function sprintf;
-use DOMElement;
use SebastianBergmann\CodeCoverage\Util\Percentage;
+use XMLWriter;
/**
* @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
*/
final readonly class Totals
{
- private DOMElement $linesNode;
- private DOMElement $methodsNode;
- private DOMElement $functionsNode;
- private DOMElement $classesNode;
- private DOMElement $traitsNode;
+ private XMLWriter $xmlWriter;
- public function __construct(DOMElement $container)
+ public function __construct(XMLWriter $xmlWriter)
{
- $dom = $container->ownerDocument;
-
- $this->linesNode = $dom->createElementNS(
- Facade::XML_NAMESPACE,
- 'lines',
- );
-
- $this->methodsNode = $dom->createElementNS(
- Facade::XML_NAMESPACE,
- 'methods',
- );
-
- $this->functionsNode = $dom->createElementNS(
- Facade::XML_NAMESPACE,
- 'functions',
- );
-
- $this->classesNode = $dom->createElementNS(
- Facade::XML_NAMESPACE,
- 'classes',
- );
-
- $this->traitsNode = $dom->createElementNS(
- Facade::XML_NAMESPACE,
- 'traits',
- );
-
- $container->appendChild($this->linesNode);
- $container->appendChild($this->methodsNode);
- $container->appendChild($this->functionsNode);
- $container->appendChild($this->classesNode);
- $container->appendChild($this->traitsNode);
+ $this->xmlWriter = $xmlWriter;
}
public function setNumLines(int $loc, int $cloc, int $ncloc, int $executable, int $executed): void
{
- $this->linesNode->setAttribute('total', (string) $loc);
- $this->linesNode->setAttribute('comments', (string) $cloc);
- $this->linesNode->setAttribute('code', (string) $ncloc);
- $this->linesNode->setAttribute('executable', (string) $executable);
- $this->linesNode->setAttribute('executed', (string) $executed);
- $this->linesNode->setAttribute(
+ $this->xmlWriter->startElement('lines');
+ $this->xmlWriter->writeAttribute('total', (string) $loc);
+ $this->xmlWriter->writeAttribute('comments', (string) $cloc);
+ $this->xmlWriter->writeAttribute('code', (string) $ncloc);
+ $this->xmlWriter->writeAttribute('executable', (string) $executable);
+ $this->xmlWriter->writeAttribute('executed', (string) $executed);
+ $this->xmlWriter->writeAttribute(
'percent',
$executable === 0 ? '0' : sprintf('%01.2F', Percentage::fromFractionAndTotal($executed, $executable)->asFloat()),
);
+ $this->xmlWriter->endElement();
}
public function setNumClasses(int $count, int $tested): void
{
- $this->classesNode->setAttribute('count', (string) $count);
- $this->classesNode->setAttribute('tested', (string) $tested);
- $this->classesNode->setAttribute(
+ $this->xmlWriter->startElement('classes');
+ $this->xmlWriter->writeAttribute('count', (string) $count);
+ $this->xmlWriter->writeAttribute('tested', (string) $tested);
+ $this->xmlWriter->writeAttribute(
'percent',
$count === 0 ? '0' : sprintf('%01.2F', Percentage::fromFractionAndTotal($tested, $count)->asFloat()),
);
+ $this->xmlWriter->endElement();
}
public function setNumTraits(int $count, int $tested): void
{
- $this->traitsNode->setAttribute('count', (string) $count);
- $this->traitsNode->setAttribute('tested', (string) $tested);
- $this->traitsNode->setAttribute(
+ $this->xmlWriter->startElement('traits');
+ $this->xmlWriter->writeAttribute('count', (string) $count);
+ $this->xmlWriter->writeAttribute('tested', (string) $tested);
+ $this->xmlWriter->writeAttribute(
'percent',
$count === 0 ? '0' : sprintf('%01.2F', Percentage::fromFractionAndTotal($tested, $count)->asFloat()),
);
+ $this->xmlWriter->endElement();
}
public function setNumMethods(int $count, int $tested): void
{
- $this->methodsNode->setAttribute('count', (string) $count);
- $this->methodsNode->setAttribute('tested', (string) $tested);
- $this->methodsNode->setAttribute(
+ $this->xmlWriter->startElement('methods');
+ $this->xmlWriter->writeAttribute('count', (string) $count);
+ $this->xmlWriter->writeAttribute('tested', (string) $tested);
+ $this->xmlWriter->writeAttribute(
'percent',
$count === 0 ? '0' : sprintf('%01.2F', Percentage::fromFractionAndTotal($tested, $count)->asFloat()),
);
+ $this->xmlWriter->endElement();
}
public function setNumFunctions(int $count, int $tested): void
{
- $this->functionsNode->setAttribute('count', (string) $count);
- $this->functionsNode->setAttribute('tested', (string) $tested);
- $this->functionsNode->setAttribute(
+ $this->xmlWriter->startElement('functions');
+ $this->xmlWriter->writeAttribute('count', (string) $count);
+ $this->xmlWriter->writeAttribute('tested', (string) $tested);
+ $this->xmlWriter->writeAttribute(
'percent',
$count === 0 ? '0' : sprintf('%01.2F', Percentage::fromFractionAndTotal($tested, $count)->asFloat()),
);
+ $this->xmlWriter->endElement();
+ }
+
+ public function getWriter(): XMLWriter
+ {
+ return $this->xmlWriter;
}
}
diff --git a/src/Report/Xml/Unit.php b/src/Report/Xml/Unit.php
index fa97909c2..bfc5029c4 100644
--- a/src/Report/Xml/Unit.php
+++ b/src/Report/Xml/Unit.php
@@ -9,18 +9,17 @@
*/
namespace SebastianBergmann\CodeCoverage\Report\Xml;
-use function assert;
-use DOMElement;
+use XMLWriter;
/**
* @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage
*/
final readonly class Unit
{
- private DOMElement $contextNode;
+ private XMLWriter $xmlWriter;
public function __construct(
- DOMElement $context,
+ XMLWriter $xmlWriter,
string $name,
string $namespace,
int $start,
@@ -28,23 +27,17 @@ public function __construct(
int $executed,
float $crap
) {
- $this->contextNode = $context;
+ $this->xmlWriter = $xmlWriter;
- $this->contextNode->setAttribute('name', $name);
- $this->contextNode->setAttribute('start', (string) $start);
- $this->contextNode->setAttribute('executable', (string) $executable);
- $this->contextNode->setAttribute('executed', (string) $executed);
- $this->contextNode->setAttribute('crap', (string) $crap);
+ $this->xmlWriter->writeAttribute('name', $name);
+ $this->xmlWriter->writeAttribute('start', (string) $start);
+ $this->xmlWriter->writeAttribute('executable', (string) $executable);
+ $this->xmlWriter->writeAttribute('executed', (string) $executed);
+ $this->xmlWriter->writeAttribute('crap', (string) $crap);
- $node = $this->contextNode->appendChild(
- $this->contextNode->ownerDocument->createElementNS(
- Facade::XML_NAMESPACE,
- 'namespace',
- ),
- );
- assert($node instanceof DOMElement);
-
- $node->setAttribute('name', $namespace);
+ $this->xmlWriter->startElement('namespace');
+ $this->xmlWriter->writeAttribute('name', $namespace);
+ $this->xmlWriter->endElement();
}
public function addMethod(
@@ -57,17 +50,8 @@ public function addMethod(
string $coverage,
string $crap
): void {
- $node = $this->contextNode->appendChild(
- $this->contextNode->ownerDocument->createElementNS(
- Facade::XML_NAMESPACE,
- 'method',
- ),
- );
-
- assert($node instanceof DOMElement);
-
new Method(
- $node,
+ $this->xmlWriter,
$name,
$signature,
$start,
diff --git a/src/Version.php b/src/Version.php
index a52b872a3..e8dd97314 100644
--- a/src/Version.php
+++ b/src/Version.php
@@ -19,7 +19,7 @@ final class Version
public static function id(): string
{
if (self::$version === '') {
- self::$version = (new VersionId('12.4.0', dirname(__DIR__)))->asString();
+ self::$version = (new VersionId('12.5.1', dirname(__DIR__)))->asString();
}
return self::$version;
diff --git a/tests/_files/Report/XML/CoverageForBankAccount/BankAccount.php.xml b/tests/_files/Report/XML/CoverageForBankAccount/BankAccount.php.xml
index b3589c8dd..a5b9ede6e 100644
--- a/tests/_files/Report/XML/CoverageForBankAccount/BankAccount.php.xml
+++ b/tests/_files/Report/XML/CoverageForBankAccount/BankAccount.php.xml
@@ -35,7 +35,7 @@
-
+
<?php
diff --git a/tests/_files/Report/XML/CoverageForBankAccount/index.xml b/tests/_files/Report/XML/CoverageForBankAccount/index.xml
index 48dd17e32..6c70139ff 100644
--- a/tests/_files/Report/XML/CoverageForBankAccount/index.xml
+++ b/tests/_files/Report/XML/CoverageForBankAccount/index.xml
@@ -6,10 +6,10 @@
-
-
-
-
+
+
+
+
diff --git a/tests/_files/Report/XML/CoverageForBankAccountWithoutSource/index.xml b/tests/_files/Report/XML/CoverageForBankAccountWithoutSource/index.xml
index 48dd17e32..6c70139ff 100644
--- a/tests/_files/Report/XML/CoverageForBankAccountWithoutSource/index.xml
+++ b/tests/_files/Report/XML/CoverageForBankAccountWithoutSource/index.xml
@@ -6,10 +6,10 @@
-
-
-
-
+
+
+
+
diff --git a/tests/_files/Report/XML/CoverageForClassWithAnonymousFunction/index.xml b/tests/_files/Report/XML/CoverageForClassWithAnonymousFunction/index.xml
index 97083250c..cd6610ead 100644
--- a/tests/_files/Report/XML/CoverageForClassWithAnonymousFunction/index.xml
+++ b/tests/_files/Report/XML/CoverageForClassWithAnonymousFunction/index.xml
@@ -6,7 +6,7 @@
-
+
diff --git a/tests/_files/Report/XML/CoverageForClassWithAnonymousFunction/source_with_class_and_anonymous_function.php.xml b/tests/_files/Report/XML/CoverageForClassWithAnonymousFunction/source_with_class_and_anonymous_function.php.xml
index 2423be0ae..88523d37c 100644
--- a/tests/_files/Report/XML/CoverageForClassWithAnonymousFunction/source_with_class_and_anonymous_function.php.xml
+++ b/tests/_files/Report/XML/CoverageForClassWithAnonymousFunction/source_with_class_and_anonymous_function.php.xml
@@ -38,7 +38,7 @@
-
+
<?php
diff --git a/tests/_files/Report/XML/CoverageForFileWithIgnoredLines/index.xml b/tests/_files/Report/XML/CoverageForFileWithIgnoredLines/index.xml
index a6b8b62eb..ff32be810 100644
--- a/tests/_files/Report/XML/CoverageForFileWithIgnoredLines/index.xml
+++ b/tests/_files/Report/XML/CoverageForFileWithIgnoredLines/index.xml
@@ -6,7 +6,7 @@
-
+
diff --git a/tests/_files/Report/XML/CoverageForFileWithIgnoredLines/source_with_ignore.php.xml b/tests/_files/Report/XML/CoverageForFileWithIgnoredLines/source_with_ignore.php.xml
index 69941c405..f5559b09e 100644
--- a/tests/_files/Report/XML/CoverageForFileWithIgnoredLines/source_with_ignore.php.xml
+++ b/tests/_files/Report/XML/CoverageForFileWithIgnoredLines/source_with_ignore.php.xml
@@ -22,7 +22,7 @@
-
+
<?php
diff --git a/tests/src/TestCase.php b/tests/src/TestCase.php
index f8273d17c..c086f62af 100644
--- a/tests/src/TestCase.php
+++ b/tests/src/TestCase.php
@@ -1009,7 +1009,8 @@ protected function getLineCoverageForBankAccount(): CodeCoverage
$stub = $this->createStub(Driver::class);
- $stub->method('stop')
+ $stub
+ ->method('stop')
->willReturn(...$data);
$filter = new Filter;
@@ -1031,6 +1032,7 @@ protected function getLineCoverageForBankAccount(): CodeCoverage
Target::forMethod(BankAccount::class, 'getBalance'),
],
),
+ time: 0.1,
);
$coverage->start(
@@ -1045,6 +1047,7 @@ protected function getLineCoverageForBankAccount(): CodeCoverage
Target::forMethod(BankAccount::class, 'withdrawMoney'),
],
),
+ time: 0.2,
);
$coverage->start(
@@ -1059,6 +1062,7 @@ protected function getLineCoverageForBankAccount(): CodeCoverage
Target::forMethod(BankAccount::class, 'depositMoney'),
],
),
+ time: 0.3,
);
$coverage->start(
@@ -1075,6 +1079,7 @@ protected function getLineCoverageForBankAccount(): CodeCoverage
Target::forMethod(BankAccount::class, 'withdrawMoney'),
],
),
+ time: 0.4,
);
return $coverage;
@@ -1086,7 +1091,8 @@ protected function getPathCoverageForBankAccount(): CodeCoverage
$stub = $this->createStub(Driver::class);
- $stub->method('stop')
+ $stub
+ ->method('stop')
->willReturn(...$data);
$filter = new Filter;
@@ -1110,6 +1116,7 @@ protected function getPathCoverageForBankAccount(): CodeCoverage
Target::forMethod(BankAccount::class, 'getBalance'),
],
),
+ time: 0.5,
);
$coverage->start(
@@ -1124,6 +1131,7 @@ protected function getPathCoverageForBankAccount(): CodeCoverage
Target::forMethod(BankAccount::class, 'withdrawMoney'),
],
),
+ time: 0.6,
);
$coverage->start(
@@ -1138,6 +1146,7 @@ protected function getPathCoverageForBankAccount(): CodeCoverage
Target::forMethod(BankAccount::class, 'depositMoney'),
],
),
+ time: 0.7,
);
$coverage->start(
@@ -1154,6 +1163,7 @@ protected function getPathCoverageForBankAccount(): CodeCoverage
Target::forMethod(BankAccount::class, 'withdrawMoney'),
],
),
+ time: 0.8,
);
return $coverage;
@@ -1165,7 +1175,8 @@ protected function getPathCoverageForSourceWithoutNamespace(): CodeCoverage
$stub = $this->createStub(Driver::class);
- $stub->method('stop')
+ $stub
+ ->method('stop')
->willReturn(...$data);
$filter = new Filter;
@@ -1244,7 +1255,8 @@ protected function getLineCoverageForNamespacedBankAccount(): CodeCoverage
$stub = $this->createStub(Driver::class);
- $stub->method('stop')
+ $stub
+ ->method('stop')
->willReturn(...$data);
$filter = new Filter;
@@ -1276,6 +1288,7 @@ protected function getLineCoverageForNamespacedBankAccount(): CodeCoverage
TargetCollection::fromArray([
Target::forMethod(BankAccountTrait::class, 'withdrawMoney'),
]),
+ time: 0.9,
);
$coverage->start(
@@ -1288,6 +1301,7 @@ protected function getLineCoverageForNamespacedBankAccount(): CodeCoverage
TargetCollection::fromArray([
Target::forMethod(BankAccountTrait::class, 'depositMoney'),
]),
+ time: 1.0,
);
$coverage->start(
@@ -1302,6 +1316,7 @@ protected function getLineCoverageForNamespacedBankAccount(): CodeCoverage
Target::forMethod(BankAccountTrait::class, 'depositMoney'),
Target::forMethod(BankAccountTrait::class, 'withdrawMoney'),
]),
+ time: 1.1,
);
return $coverage;
@@ -1313,7 +1328,8 @@ protected function getLineCoverageForBankAccountForFirstTwoTests(): CodeCoverage
$stub = $this->createStub(Driver::class);
- $stub->method('stop')
+ $stub
+ ->method('stop')
->willReturn(...$data);
$filter = new Filter;
@@ -1335,6 +1351,7 @@ protected function getLineCoverageForBankAccountForFirstTwoTests(): CodeCoverage
Target::forMethod(BankAccount::class, 'getBalance'),
],
),
+ time: 1.2,
);
$coverage->start(
@@ -1349,6 +1366,7 @@ protected function getLineCoverageForBankAccountForFirstTwoTests(): CodeCoverage
Target::forMethod(BankAccount::class, 'withdrawMoney'),
],
),
+ time: 1.3,
);
return $coverage;
@@ -1360,7 +1378,8 @@ protected function getLineCoverageForBankAccountForLastTwoTests(): CodeCoverage
$stub = $this->createStub(Driver::class);
- $stub->method('stop')
+ $stub
+ ->method('stop')
->willReturn($data[2], $data[3]);
$filter = new Filter;
@@ -1380,6 +1399,7 @@ protected function getLineCoverageForBankAccountForLastTwoTests(): CodeCoverage
Target::forMethod(BankAccount::class, 'depositMoney'),
],
),
+ time: 1.4,
);
$coverage->start(
@@ -1396,6 +1416,7 @@ protected function getLineCoverageForBankAccountForLastTwoTests(): CodeCoverage
Target::forMethod(BankAccount::class, 'withdrawMoney'),
],
),
+ time: 1.5,
);
return $coverage;
@@ -1467,7 +1488,8 @@ protected function getPathCoverageForBankAccountForFirstTwoTests(): CodeCoverage
$stub = $this->createStub(Driver::class);
- $stub->method('stop')
+ $stub
+ ->method('stop')
->willReturn(...$data);
$filter = new Filter;
@@ -1491,6 +1513,7 @@ protected function getPathCoverageForBankAccountForFirstTwoTests(): CodeCoverage
Target::forMethod(BankAccount::class, 'getBalance'),
],
),
+ time: 1.6,
);
$coverage->start(
@@ -1505,6 +1528,7 @@ protected function getPathCoverageForBankAccountForFirstTwoTests(): CodeCoverage
Target::forMethod(BankAccount::class, 'withdrawMoney'),
],
),
+ time: 1.7,
);
return $coverage;
@@ -1516,7 +1540,8 @@ protected function getPathCoverageForBankAccountForLastTwoTests(): CodeCoverage
$stub = $this->createStub(Driver::class);
- $stub->method('stop')
+ $stub
+ ->method('stop')
->willReturn($data[2], $data[3]);
$filter = new Filter;
@@ -1538,6 +1563,7 @@ protected function getPathCoverageForBankAccountForLastTwoTests(): CodeCoverage
Target::forMethod(BankAccount::class, 'depositMoney'),
],
),
+ time: 1.8,
);
$coverage->start(
@@ -1554,6 +1580,7 @@ protected function getPathCoverageForBankAccountForLastTwoTests(): CodeCoverage
Target::forMethod(BankAccount::class, 'withdrawMoney'),
],
),
+ time: 1.9,
);
return $coverage;
@@ -1780,7 +1807,8 @@ protected function setUpXdebugStubForFileWithIgnoredLines(): Driver
{
$stub = $this->createStub(Driver::class);
- $stub->method('stop')
+ $stub
+ ->method('stop')
->willReturn(RawCodeCoverageData::fromXdebugWithoutPathCoverage(
[
TEST_FILES_PATH . 'source_with_ignore.php' => [
@@ -1814,7 +1842,8 @@ protected function setUpXdebugStubForFileWithEval(): Driver
{
$stub = $this->createStub(Driver::class);
- $stub->method('stop')
+ $stub
+ ->method('stop')
->willReturn(RawCodeCoverageData::fromXdebugWithoutPathCoverage(
[
TEST_FILES_PATH . 'source_with_eval.php' => [
@@ -1850,7 +1879,8 @@ protected function setUpXdebugStubForClassWithAnonymousFunction(): Driver
{
$stub = $this->createStub(Driver::class);
- $stub->method('stop')
+ $stub
+ ->method('stop')
->willReturn(RawCodeCoverageData::fromXdebugWithoutPathCoverage(
[
TEST_FILES_PATH . 'source_with_class_and_anonymous_function.php' => [
@@ -1890,7 +1920,8 @@ protected function setUpXdebugStubForClassWithOutsideFunction(): Driver
{
$stub = $this->createStub(Driver::class);
- $stub->method('stop')
+ $stub
+ ->method('stop')
->willReturn(RawCodeCoverageData::fromXdebugWithoutPathCoverage(
[
TEST_FILES_PATH . 'source_with_class_and_outside_function.php' => [
@@ -1925,7 +1956,8 @@ protected function getCoverageForFilesWithUncoveredIncluded(): CodeCoverage
$stub = $this->createStub(Driver::class);
- $stub->method('stop')
+ $stub
+ ->method('stop')
->willReturn(...$data);
$filter = new Filter;
@@ -1947,6 +1979,7 @@ protected function getCoverageForFilesWithUncoveredIncluded(): CodeCoverage
TargetCollection::fromArray([
Target::forMethod(BankAccount::class, 'getBalance'),
]),
+ time: 2.0,
);
$coverage->start(
@@ -1959,6 +1992,7 @@ protected function getCoverageForFilesWithUncoveredIncluded(): CodeCoverage
TargetCollection::fromArray([
Target::forMethod(BankAccount::class, 'withdrawMoney'),
]),
+ time: 2.1,
);
$coverage->start(
@@ -1971,6 +2005,7 @@ protected function getCoverageForFilesWithUncoveredIncluded(): CodeCoverage
TargetCollection::fromArray([
Target::forMethod(BankAccount::class, 'depositMoney'),
]),
+ time: 2.2,
);
$coverage->start(
@@ -1985,6 +2020,7 @@ protected function getCoverageForFilesWithUncoveredIncluded(): CodeCoverage
Target::forMethod(BankAccount::class, 'depositMoney'),
Target::forMethod(BankAccount::class, 'withdrawMoney'),
]),
+ time: 2.3,
);
return $coverage;
@@ -1996,7 +2032,8 @@ protected function getCoverageForFilesWithUncoveredExcluded(): CodeCoverage
$stub = $this->createStub(Driver::class);
- $stub->method('stop')
+ $stub
+ ->method('stop')
->willReturn(...$data);
$filter = new Filter;
@@ -2018,6 +2055,7 @@ protected function getCoverageForFilesWithUncoveredExcluded(): CodeCoverage
TargetCollection::fromArray([
Target::forMethod(BankAccount::class, 'getBalance'),
]),
+ time: 2.4,
);
$coverage->start(
@@ -2030,6 +2068,7 @@ protected function getCoverageForFilesWithUncoveredExcluded(): CodeCoverage
TargetCollection::fromArray([
Target::forMethod(BankAccount::class, 'withdrawMoney'),
]),
+ time: 2.5,
);
$coverage->start(
@@ -2042,6 +2081,7 @@ protected function getCoverageForFilesWithUncoveredExcluded(): CodeCoverage
TargetCollection::fromArray([
Target::forMethod(BankAccount::class, 'depositMoney'),
]),
+ time: 2.6,
);
$coverage->start(
@@ -2056,6 +2096,7 @@ protected function getCoverageForFilesWithUncoveredExcluded(): CodeCoverage
Target::forMethod(BankAccount::class, 'depositMoney'),
Target::forMethod(BankAccount::class, 'withdrawMoney'),
]),
+ time: 2.7,
);
return $coverage;
diff --git a/tests/tests/CodeCoverageTest.php b/tests/tests/CodeCoverageTest.php
index 32f2f1de0..895be4588 100644
--- a/tests/tests/CodeCoverageTest.php
+++ b/tests/tests/CodeCoverageTest.php
@@ -48,10 +48,10 @@ public function testCollect(): void
$this->assertEquals(
[
- 'BankAccountTest::testBalanceIsInitiallyZero' => ['size' => 'unknown', 'status' => 'unknown'],
- 'BankAccountTest::testBalanceCannotBecomeNegative' => ['size' => 'unknown', 'status' => 'unknown'],
- 'BankAccountTest::testBalanceCannotBecomeNegative2' => ['size' => 'unknown', 'status' => 'unknown'],
- 'BankAccountTest::testDepositWithdrawMoney' => ['size' => 'unknown', 'status' => 'unknown'],
+ 'BankAccountTest::testBalanceIsInitiallyZero' => ['size' => 'unknown', 'status' => 'unknown', 'time' => 0.1],
+ 'BankAccountTest::testBalanceCannotBecomeNegative' => ['size' => 'unknown', 'status' => 'unknown', 'time' => 0.2],
+ 'BankAccountTest::testBalanceCannotBecomeNegative2' => ['size' => 'unknown', 'status' => 'unknown', 'time' => 0.3],
+ 'BankAccountTest::testDepositWithdrawMoney' => ['size' => 'unknown', 'status' => 'unknown', 'time' => 0.4],
],
$coverage->getTests(),
);
diff --git a/tests/tests/Exception/UnintentionallyCoveredCodeExceptionTest.php b/tests/tests/Exception/UnintentionallyCoveredCodeExceptionTest.php
index 5cafd013a..2853ac4ff 100644
--- a/tests/tests/Exception/UnintentionallyCoveredCodeExceptionTest.php
+++ b/tests/tests/Exception/UnintentionallyCoveredCodeExceptionTest.php
@@ -43,7 +43,6 @@ public function testCanConstructWithNonEmptyArray(): void
- foo
- bar
- baz
-
TXT;
$this->assertSame($expected, $exception->getMessage());
diff --git a/tools/.phpstan/composer.json b/tools/.phpstan/composer.json
index 9851b7c08..8e13d1359 100644
--- a/tools/.phpstan/composer.json
+++ b/tools/.phpstan/composer.json
@@ -1,9 +1,9 @@
{
"require-dev": {
- "phpstan/phpstan": "^2.1.32",
+ "phpstan/phpstan": "^2.1.33",
"phpstan/extension-installer": "^1.4.3",
"phpstan/phpstan-strict-rules": "^2.0.7",
- "tomasvotruba/type-coverage": "^2.0.2",
+ "tomasvotruba/type-coverage": "^2.1.0",
"ergebnis/phpstan-rules": "^2.12.0"
},
"config": {
diff --git a/tools/.phpstan/composer.lock b/tools/.phpstan/composer.lock
index e823a15ad..c99f4b27d 100644
--- a/tools/.phpstan/composer.lock
+++ b/tools/.phpstan/composer.lock
@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
- "content-hash": "2c8ea294a7a4e09e4793951d07859bf8",
+ "content-hash": "4409cdc49212f7e878b14b7ae9285bb2",
"packages": [],
"packages-dev": [
{
@@ -82,20 +82,20 @@
},
{
"name": "nette/utils",
- "version": "v4.0.8",
+ "version": "v4.1.0",
"source": {
"type": "git",
"url": "https://github.com/nette/utils.git",
- "reference": "c930ca4e3cf4f17dcfb03037703679d2396d2ede"
+ "reference": "fa1f0b8261ed150447979eb22e373b7b7ad5a8e0"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/nette/utils/zipball/c930ca4e3cf4f17dcfb03037703679d2396d2ede",
- "reference": "c930ca4e3cf4f17dcfb03037703679d2396d2ede",
+ "url": "https://api.github.com/repos/nette/utils/zipball/fa1f0b8261ed150447979eb22e373b7b7ad5a8e0",
+ "reference": "fa1f0b8261ed150447979eb22e373b7b7ad5a8e0",
"shasum": ""
},
"require": {
- "php": "8.0 - 8.5"
+ "php": "8.2 - 8.5"
},
"conflict": {
"nette/finder": "<3",
@@ -118,7 +118,7 @@
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "4.0-dev"
+ "dev-master": "4.1-dev"
}
},
"autoload": {
@@ -165,9 +165,9 @@
],
"support": {
"issues": "https://github.com/nette/utils/issues",
- "source": "https://github.com/nette/utils/tree/v4.0.8"
+ "source": "https://github.com/nette/utils/tree/v4.1.0"
},
- "time": "2025-08-06T21:43:34+00:00"
+ "time": "2025-12-01T17:49:23+00:00"
},
{
"name": "phpstan/extension-installer",
@@ -219,11 +219,11 @@
},
{
"name": "phpstan/phpstan",
- "version": "2.1.32",
+ "version": "2.1.33",
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/phpstan/phpstan/zipball/e126cad1e30a99b137b8ed75a85a676450ebb227",
- "reference": "e126cad1e30a99b137b8ed75a85a676450ebb227",
+ "url": "https://api.github.com/repos/phpstan/phpstan/zipball/9e800e6bee7d5bd02784d4c6069b48032d16224f",
+ "reference": "9e800e6bee7d5bd02784d4c6069b48032d16224f",
"shasum": ""
},
"require": {
@@ -268,7 +268,7 @@
"type": "github"
}
],
- "time": "2025-11-11T15:18:17+00:00"
+ "time": "2025-12-05T10:24:31+00:00"
},
{
"name": "phpstan/phpstan-strict-rules",
@@ -320,16 +320,16 @@
},
{
"name": "tomasvotruba/type-coverage",
- "version": "2.0.2",
+ "version": "2.1.0",
"source": {
"type": "git",
"url": "https://github.com/TomasVotruba/type-coverage.git",
- "reference": "d033429580f2c18bda538fa44f2939236a990e0c"
+ "reference": "468354b3964120806a69890cbeb3fcf005876391"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/TomasVotruba/type-coverage/zipball/d033429580f2c18bda538fa44f2939236a990e0c",
- "reference": "d033429580f2c18bda538fa44f2939236a990e0c",
+ "url": "https://api.github.com/repos/TomasVotruba/type-coverage/zipball/468354b3964120806a69890cbeb3fcf005876391",
+ "reference": "468354b3964120806a69890cbeb3fcf005876391",
"shasum": ""
},
"require": {
@@ -361,7 +361,7 @@
],
"support": {
"issues": "https://github.com/TomasVotruba/type-coverage/issues",
- "source": "https://github.com/TomasVotruba/type-coverage/tree/2.0.2"
+ "source": "https://github.com/TomasVotruba/type-coverage/tree/2.1.0"
},
"funding": [
{
@@ -373,7 +373,7 @@
"type": "github"
}
],
- "time": "2025-01-07T00:10:26+00:00"
+ "time": "2025-12-05T16:38:02+00:00"
}
],
"aliases": [],
diff --git a/tools/.phpstan/vendor/composer/installed.json b/tools/.phpstan/vendor/composer/installed.json
index 76385ec26..bb0437ecf 100644
--- a/tools/.phpstan/vendor/composer/installed.json
+++ b/tools/.phpstan/vendor/composer/installed.json
@@ -78,21 +78,21 @@
},
{
"name": "nette/utils",
- "version": "v4.0.8",
- "version_normalized": "4.0.8.0",
+ "version": "v4.1.0",
+ "version_normalized": "4.1.0.0",
"source": {
"type": "git",
"url": "https://github.com/nette/utils.git",
- "reference": "c930ca4e3cf4f17dcfb03037703679d2396d2ede"
+ "reference": "fa1f0b8261ed150447979eb22e373b7b7ad5a8e0"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/nette/utils/zipball/c930ca4e3cf4f17dcfb03037703679d2396d2ede",
- "reference": "c930ca4e3cf4f17dcfb03037703679d2396d2ede",
+ "url": "https://api.github.com/repos/nette/utils/zipball/fa1f0b8261ed150447979eb22e373b7b7ad5a8e0",
+ "reference": "fa1f0b8261ed150447979eb22e373b7b7ad5a8e0",
"shasum": ""
},
"require": {
- "php": "8.0 - 8.5"
+ "php": "8.2 - 8.5"
},
"conflict": {
"nette/finder": "<3",
@@ -112,11 +112,11 @@
"ext-mbstring": "to use Strings::lower() etc...",
"ext-tokenizer": "to use Nette\\Utils\\Reflection::getUseStatements()"
},
- "time": "2025-08-06T21:43:34+00:00",
+ "time": "2025-12-01T17:49:23+00:00",
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "4.0-dev"
+ "dev-master": "4.1-dev"
}
},
"installation-source": "dist",
@@ -164,7 +164,7 @@
],
"support": {
"issues": "https://github.com/nette/utils/issues",
- "source": "https://github.com/nette/utils/tree/v4.0.8"
+ "source": "https://github.com/nette/utils/tree/v4.1.0"
},
"install-path": "../nette/utils"
},
@@ -221,12 +221,12 @@
},
{
"name": "phpstan/phpstan",
- "version": "2.1.32",
- "version_normalized": "2.1.32.0",
+ "version": "2.1.33",
+ "version_normalized": "2.1.33.0",
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/phpstan/phpstan/zipball/e126cad1e30a99b137b8ed75a85a676450ebb227",
- "reference": "e126cad1e30a99b137b8ed75a85a676450ebb227",
+ "url": "https://api.github.com/repos/phpstan/phpstan/zipball/9e800e6bee7d5bd02784d4c6069b48032d16224f",
+ "reference": "9e800e6bee7d5bd02784d4c6069b48032d16224f",
"shasum": ""
},
"require": {
@@ -235,7 +235,7 @@
"conflict": {
"phpstan/phpstan-shim": "*"
},
- "time": "2025-11-11T15:18:17+00:00",
+ "time": "2025-12-05T10:24:31+00:00",
"bin": [
"phpstan",
"phpstan.phar"
@@ -328,17 +328,17 @@
},
{
"name": "tomasvotruba/type-coverage",
- "version": "2.0.2",
- "version_normalized": "2.0.2.0",
+ "version": "2.1.0",
+ "version_normalized": "2.1.0.0",
"source": {
"type": "git",
"url": "https://github.com/TomasVotruba/type-coverage.git",
- "reference": "d033429580f2c18bda538fa44f2939236a990e0c"
+ "reference": "468354b3964120806a69890cbeb3fcf005876391"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/TomasVotruba/type-coverage/zipball/d033429580f2c18bda538fa44f2939236a990e0c",
- "reference": "d033429580f2c18bda538fa44f2939236a990e0c",
+ "url": "https://api.github.com/repos/TomasVotruba/type-coverage/zipball/468354b3964120806a69890cbeb3fcf005876391",
+ "reference": "468354b3964120806a69890cbeb3fcf005876391",
"shasum": ""
},
"require": {
@@ -346,7 +346,7 @@
"php": "^7.4 || ^8.0",
"phpstan/phpstan": "^2.0"
},
- "time": "2025-01-07T00:10:26+00:00",
+ "time": "2025-12-05T16:38:02+00:00",
"type": "phpstan-extension",
"extra": {
"phpstan": {
@@ -372,7 +372,7 @@
],
"support": {
"issues": "https://github.com/TomasVotruba/type-coverage/issues",
- "source": "https://github.com/TomasVotruba/type-coverage/tree/2.0.2"
+ "source": "https://github.com/TomasVotruba/type-coverage/tree/2.1.0"
},
"funding": [
{
diff --git a/tools/.phpstan/vendor/composer/installed.php b/tools/.phpstan/vendor/composer/installed.php
index 58d90cfef..759f7f1b7 100644
--- a/tools/.phpstan/vendor/composer/installed.php
+++ b/tools/.phpstan/vendor/composer/installed.php
@@ -3,7 +3,7 @@
'name' => '__root__',
'pretty_version' => 'dev-main',
'version' => 'dev-main',
- 'reference' => '37047b5f0e98b31dccb9b7e7241e4f66ebfcd358',
+ 'reference' => '5b74f6242eb0baf4414dd15033afd51abc0bb45d',
'type' => 'library',
'install_path' => __DIR__ . '/../../',
'aliases' => array(),
@@ -13,7 +13,7 @@
'__root__' => array(
'pretty_version' => 'dev-main',
'version' => 'dev-main',
- 'reference' => '37047b5f0e98b31dccb9b7e7241e4f66ebfcd358',
+ 'reference' => '5b74f6242eb0baf4414dd15033afd51abc0bb45d',
'type' => 'library',
'install_path' => __DIR__ . '/../../',
'aliases' => array(),
@@ -29,9 +29,9 @@
'dev_requirement' => true,
),
'nette/utils' => array(
- 'pretty_version' => 'v4.0.8',
- 'version' => '4.0.8.0',
- 'reference' => 'c930ca4e3cf4f17dcfb03037703679d2396d2ede',
+ 'pretty_version' => 'v4.1.0',
+ 'version' => '4.1.0.0',
+ 'reference' => 'fa1f0b8261ed150447979eb22e373b7b7ad5a8e0',
'type' => 'library',
'install_path' => __DIR__ . '/../nette/utils',
'aliases' => array(),
@@ -47,9 +47,9 @@
'dev_requirement' => true,
),
'phpstan/phpstan' => array(
- 'pretty_version' => '2.1.32',
- 'version' => '2.1.32.0',
- 'reference' => 'e126cad1e30a99b137b8ed75a85a676450ebb227',
+ 'pretty_version' => '2.1.33',
+ 'version' => '2.1.33.0',
+ 'reference' => '9e800e6bee7d5bd02784d4c6069b48032d16224f',
'type' => 'library',
'install_path' => __DIR__ . '/../phpstan/phpstan',
'aliases' => array(),
@@ -65,9 +65,9 @@
'dev_requirement' => true,
),
'tomasvotruba/type-coverage' => array(
- 'pretty_version' => '2.0.2',
- 'version' => '2.0.2.0',
- 'reference' => 'd033429580f2c18bda538fa44f2939236a990e0c',
+ 'pretty_version' => '2.1.0',
+ 'version' => '2.1.0.0',
+ 'reference' => '468354b3964120806a69890cbeb3fcf005876391',
'type' => 'phpstan-extension',
'install_path' => __DIR__ . '/../tomasvotruba/type-coverage',
'aliases' => array(),
diff --git a/tools/.phpstan/vendor/nette/utils/composer.json b/tools/.phpstan/vendor/nette/utils/composer.json
index b17ea832b..6f6db4a45 100644
--- a/tools/.phpstan/vendor/nette/utils/composer.json
+++ b/tools/.phpstan/vendor/nette/utils/composer.json
@@ -15,7 +15,7 @@
}
],
"require": {
- "php": "8.0 - 8.5"
+ "php": "8.2 - 8.5"
},
"require-dev": {
"nette/tester": "^2.5",
@@ -48,7 +48,7 @@
},
"extra": {
"branch-alias": {
- "dev-master": "4.0-dev"
+ "dev-master": "4.1-dev"
}
}
}
diff --git a/tools/.phpstan/vendor/nette/utils/readme.md b/tools/.phpstan/vendor/nette/utils/readme.md
index 46e255170..8c717be42 100644
--- a/tools/.phpstan/vendor/nette/utils/readme.md
+++ b/tools/.phpstan/vendor/nette/utils/readme.md
@@ -41,7 +41,7 @@ The recommended way to install is via Composer:
composer require nette/utils
```
-Nette Utils 4.0 is compatible with PHP 8.0 to 8.5.
+Nette Utils 4.1 is compatible with PHP 8.2 to 8.5.
diff --git a/tools/.phpstan/vendor/nette/utils/src/Iterators/CachingIterator.php b/tools/.phpstan/vendor/nette/utils/src/Iterators/CachingIterator.php
index 02bd74070..bf6ef85ce 100644
--- a/tools/.phpstan/vendor/nette/utils/src/Iterators/CachingIterator.php
+++ b/tools/.phpstan/vendor/nette/utils/src/Iterators/CachingIterator.php
@@ -34,7 +34,7 @@ class CachingIterator extends \CachingIterator implements \Countable
public function __construct(iterable|\stdClass $iterable)
{
$iterable = $iterable instanceof \stdClass
- ? new \ArrayIterator($iterable)
+ ? new \ArrayIterator((array) $iterable)
: Nette\Utils\Iterables::toIterator($iterable);
parent::__construct($iterable, 0);
}
diff --git a/tools/.phpstan/vendor/nette/utils/src/StaticClass.php b/tools/.phpstan/vendor/nette/utils/src/StaticClass.php
index b1d84862e..46b278669 100644
--- a/tools/.phpstan/vendor/nette/utils/src/StaticClass.php
+++ b/tools/.phpstan/vendor/nette/utils/src/StaticClass.php
@@ -21,14 +21,4 @@ trait StaticClass
private function __construct()
{
}
-
-
- /**
- * Call to undefined static method.
- * @throws MemberAccessException
- */
- public static function __callStatic(string $name, array $args): mixed
- {
- Utils\ObjectHelpers::strictStaticCall(static::class, $name);
- }
}
diff --git a/tools/.phpstan/vendor/nette/utils/src/Utils/ArrayList.php b/tools/.phpstan/vendor/nette/utils/src/Utils/ArrayList.php
index c9fe5386f..98a508219 100644
--- a/tools/.phpstan/vendor/nette/utils/src/Utils/ArrayList.php
+++ b/tools/.phpstan/vendor/nette/utils/src/Utils/ArrayList.php
@@ -21,8 +21,6 @@
*/
class ArrayList implements \ArrayAccess, \Countable, \IteratorAggregate
{
- use Nette\SmartObject;
-
private array $list = [];
diff --git a/tools/.phpstan/vendor/nette/utils/src/Utils/Arrays.php b/tools/.phpstan/vendor/nette/utils/src/Utils/Arrays.php
index 8985a7078..986118c89 100644
--- a/tools/.phpstan/vendor/nette/utils/src/Utils/Arrays.php
+++ b/tools/.phpstan/vendor/nette/utils/src/Utils/Arrays.php
@@ -11,8 +11,8 @@
use JetBrains\PhpStorm\Language;
use Nette;
-use function array_combine, array_intersect_key, array_is_list, array_key_exists, array_key_first, array_key_last, array_keys, array_reverse, array_search, array_slice, array_walk_recursive, count, func_num_args, in_array, is_array, is_int, is_object, key, preg_split, range;
-use const PHP_VERSION_ID, PREG_GREP_INVERT, PREG_SPLIT_DELIM_CAPTURE, PREG_SPLIT_NO_EMPTY;
+use function array_combine, array_intersect_key, array_is_list, array_key_exists, array_key_first, array_key_last, array_keys, array_reverse, array_search, array_slice, array_walk_recursive, count, func_num_args, in_array, is_array, is_int, is_object, key, preg_split;
+use const PREG_GREP_INVERT, PREG_SPLIT_DELIM_CAPTURE, PREG_SPLIT_NO_EMPTY;
/**
@@ -278,11 +278,7 @@ public static function flatten(array $array, bool $preserveKeys = false): array
*/
public static function isList(mixed $value): bool
{
- return is_array($value) && (
- PHP_VERSION_ID < 80100
- ? !$value || array_keys($value) === range(0, count($value) - 1)
- : array_is_list($value)
- );
+ return is_array($value) && array_is_list($value);
}
@@ -533,7 +529,7 @@ public static function toObject(iterable $array, object $object): object
*/
public static function toKey(mixed $value): int|string
{
- return key([$value => null]);
+ return key(@[$value => null]);
}
diff --git a/tools/.phpstan/vendor/nette/utils/src/Utils/DateTime.php b/tools/.phpstan/vendor/nette/utils/src/Utils/DateTime.php
index cb59682fd..6191223f5 100644
--- a/tools/.phpstan/vendor/nette/utils/src/Utils/DateTime.php
+++ b/tools/.phpstan/vendor/nette/utils/src/Utils/DateTime.php
@@ -9,7 +9,6 @@
namespace Nette\Utils;
-use Nette;
use function array_merge, checkdate, implode, is_numeric, is_string, preg_replace_callback, sprintf, time, trim;
@@ -18,8 +17,6 @@
*/
class DateTime extends \DateTime implements \JsonSerializable
{
- use Nette\SmartObject;
-
/** minute in seconds */
public const MINUTE = 60;
@@ -63,7 +60,7 @@ public static function from(string|int|\DateTimeInterface|null $time): static
/**
* Creates DateTime object.
- * @throws Nette\InvalidArgumentException if the date and time are not valid.
+ * @throws \Exception if the date and time are not valid.
*/
public static function fromParts(
int $year,
@@ -74,17 +71,10 @@ public static function fromParts(
float $second = 0.0,
): static
{
- $s = sprintf('%04d-%02d-%02d %02d:%02d:%02.5F', $year, $month, $day, $hour, $minute, $second);
- if (
- !checkdate($month, $day, $year)
- || $hour < 0 || $hour > 23
- || $minute < 0 || $minute > 59
- || $second < 0 || $second >= 60
- ) {
- throw new Nette\InvalidArgumentException("Invalid date '$s'");
- }
-
- return new static($s);
+ $sec = (int) floor($second);
+ return (new static(''))
+ ->setDate($year, $month, $day)
+ ->setTime($hour, $minute, $sec, (int) round(($second - $sec) * 1e6));
}
@@ -122,7 +112,7 @@ public function modify(string $modifier): static
public function setDate(int $year, int $month, int $day): static
{
if (!checkdate($month, $day, $year)) {
- trigger_error(sprintf(self::class . ': The date %04d-%02d-%02d is not valid.', $year, $month, $day), E_USER_WARNING);
+ throw new \Exception(sprintf('The date %04d-%02d-%02d is not valid.', $year, $month, $day));
}
return parent::setDate($year, $month, $day);
}
@@ -136,7 +126,7 @@ public function setTime(int $hour, int $minute, int $second = 0, int $microsecon
|| $second < 0 || $second >= 60
|| $microsecond < 0 || $microsecond >= 1_000_000
) {
- trigger_error(sprintf(self::class . ': The time %02d:%02d:%08.5F is not valid.', $hour, $minute, $second + $microsecond / 1_000_000), E_USER_WARNING);
+ throw new \Exception(sprintf('The time %02d:%02d:%08.5F is not valid.', $hour, $minute, $second + $microsecond / 1_000_000));
}
return parent::setTime($hour, $minute, $second, $microsecond);
}
@@ -213,7 +203,7 @@ private function handleErrors(string $value): void
$errors = self::getLastErrors();
$errors = array_merge($errors['errors'] ?? [], $errors['warnings'] ?? []);
if ($errors) {
- trigger_error(self::class . ': ' . implode(', ', $errors) . " '$value'", E_USER_WARNING);
+ throw new \Exception(implode(', ', $errors) . " '$value'");
}
}
}
diff --git a/tools/.phpstan/vendor/nette/utils/src/Utils/FileInfo.php b/tools/.phpstan/vendor/nette/utils/src/Utils/FileInfo.php
index a102dad10..59dd72271 100644
--- a/tools/.phpstan/vendor/nette/utils/src/Utils/FileInfo.php
+++ b/tools/.phpstan/vendor/nette/utils/src/Utils/FileInfo.php
@@ -19,7 +19,7 @@
*/
final class FileInfo extends \SplFileInfo
{
- private string $relativePath;
+ private readonly string $relativePath;
public function __construct(string $file, string $relativePath = '')
diff --git a/tools/.phpstan/vendor/nette/utils/src/Utils/FileSystem.php b/tools/.phpstan/vendor/nette/utils/src/Utils/FileSystem.php
index a95a7f741..8adb21e66 100644
--- a/tools/.phpstan/vendor/nette/utils/src/Utils/FileSystem.php
+++ b/tools/.phpstan/vendor/nette/utils/src/Utils/FileSystem.php
@@ -23,7 +23,7 @@ final class FileSystem
* Creates a directory if it does not exist, including parent directories.
* @throws Nette\IOException on error occurred
*/
- public static function createDir(string $dir, int $mode = 0777): void
+ public static function createDir(string $dir, int $mode = 0o777): void
{
if (!is_dir($dir) && !@mkdir($dir, $mode, recursive: true) && !is_dir($dir)) { // @ - dir may already exist
throw new Nette\IOException(sprintf(
@@ -211,7 +211,7 @@ public static function readLines(string $file, bool $stripNewLines = true): \Gen
* Writes the string to a file.
* @throws Nette\IOException on error occurred
*/
- public static function write(string $file, string $content, ?int $mode = 0666): void
+ public static function write(string $file, string $content, ?int $mode = 0o666): void
{
static::createDir(dirname($file));
if (@file_put_contents($file, $content) === false) { // @ is escalated to exception
@@ -238,7 +238,7 @@ public static function write(string $file, string $content, ?int $mode = 0666):
* Recursively traverses and sets permissions on the entire contents of the directory as well.
* @throws Nette\IOException on error occurred
*/
- public static function makeWritable(string $path, int $dirMode = 0777, int $fileMode = 0666): void
+ public static function makeWritable(string $path, int $dirMode = 0o777, int $fileMode = 0o666): void
{
if (is_file($path)) {
if (!@chmod($path, $fileMode)) { // @ is escalated to exception
diff --git a/tools/.phpstan/vendor/nette/utils/src/Utils/Finder.php b/tools/.phpstan/vendor/nette/utils/src/Utils/Finder.php
index 0027e7743..2f5f7d16b 100644
--- a/tools/.phpstan/vendor/nette/utils/src/Utils/Finder.php
+++ b/tools/.phpstan/vendor/nette/utils/src/Utils/Finder.php
@@ -26,8 +26,6 @@
*/
class Finder implements \IteratorAggregate
{
- use Nette\SmartObject;
-
/** @var array */
private array $find = [];
@@ -387,7 +385,7 @@ private function traverseDir(string $dir, array $searches, array $subdirs = []):
$relativePathname = FileSystem::unixSlashes($file->getRelativePathname());
foreach ($searches as $search) {
if (
- $file->{'is' . $search->mode}()
+ "is_$search->mode"(Helpers::IsWindows && $file->isLink() ? $file->getLinkTarget() : $file->getPathname())
&& preg_match($search->pattern, $relativePathname)
&& $this->proveFilters($this->filters, $file, $cache)
) {
diff --git a/tools/.phpstan/vendor/nette/utils/src/Utils/Helpers.php b/tools/.phpstan/vendor/nette/utils/src/Utils/Helpers.php
index 31c9439a3..c7d78943d 100644
--- a/tools/.phpstan/vendor/nette/utils/src/Utils/Helpers.php
+++ b/tools/.phpstan/vendor/nette/utils/src/Utils/Helpers.php
@@ -106,4 +106,16 @@ public static function compare(mixed $left, string $operator, mixed $right): boo
default => throw new Nette\InvalidArgumentException("Unknown operator '$operator'"),
};
}
+
+
+ /**
+ * Splits a class name into namespace and short class name.
+ * @return array{string, string}
+ */
+ public static function splitClassName(string $name): array
+ {
+ return ($pos = strrpos($name, '\\')) === false
+ ? ['', $name]
+ : [substr($name, 0, $pos), substr($name, $pos + 1)];
+ }
}
diff --git a/tools/.phpstan/vendor/nette/utils/src/Utils/Html.php b/tools/.phpstan/vendor/nette/utils/src/Utils/Html.php
index cad0baddb..3a57de5ed 100644
--- a/tools/.phpstan/vendor/nette/utils/src/Utils/Html.php
+++ b/tools/.phpstan/vendor/nette/utils/src/Utils/Html.php
@@ -9,7 +9,6 @@
namespace Nette\Utils;
-use Nette;
use Nette\HtmlStringable;
use function array_merge, array_splice, count, explode, func_num_args, html_entity_decode, htmlspecialchars, http_build_query, implode, is_array, is_bool, is_float, is_object, is_string, json_encode, max, number_format, rtrim, str_contains, str_repeat, str_replace, strip_tags, strncmp, strpbrk, substr;
use const ENT_HTML5, ENT_NOQUOTES, ENT_QUOTES;
@@ -234,20 +233,18 @@
*/
class Html implements \ArrayAccess, \Countable, \IteratorAggregate, HtmlStringable
{
- use Nette\SmartObject;
-
/** @var array element's attributes */
- public $attrs = [];
+ public array $attrs = [];
/** void elements */
- public static $emptyElements = [
+ public static array $emptyElements = [
'img' => 1, 'hr' => 1, 'br' => 1, 'input' => 1, 'meta' => 1, 'area' => 1, 'embed' => 1, 'keygen' => 1,
'source' => 1, 'base' => 1, 'col' => 1, 'link' => 1, 'param' => 1, 'basefont' => 1, 'frame' => 1,
'isindex' => 1, 'wbr' => 1, 'command' => 1, 'track' => 1,
];
/** @var array nodes */
- protected $children = [];
+ protected array $children = [];
/** element's name */
private string $name = '';
@@ -576,7 +573,7 @@ final public function getText(): string
/**
* Adds new element's child.
*/
- final public function addHtml(mixed $child): static
+ final public function addHtml(HtmlStringable|string $child): static
{
return $this->insert(null, $child);
}
@@ -585,7 +582,7 @@ final public function addHtml(mixed $child): static
/**
* Appends plain-text string to element content.
*/
- public function addText(mixed $text): static
+ public function addText(\Stringable|string $text): static
{
if (!$text instanceof HtmlStringable) {
$text = htmlspecialchars((string) $text, ENT_NOQUOTES, 'UTF-8');
diff --git a/tools/.phpstan/vendor/nette/utils/src/Utils/Image.php b/tools/.phpstan/vendor/nette/utils/src/Utils/Image.php
index a557a1881..a6bb4782a 100644
--- a/tools/.phpstan/vendor/nette/utils/src/Utils/Image.php
+++ b/tools/.phpstan/vendor/nette/utils/src/Utils/Image.php
@@ -239,8 +239,8 @@ public static function fromBlank(int $width, int $height, ImageColor|array|null
*/
public static function detectTypeFromFile(string $file, &$width = null, &$height = null): ?int
{
- [$width, $height, $type] = @getimagesize($file); // @ - files smaller than 12 bytes causes read error
- return isset(self::Formats[$type]) ? $type : null;
+ [$width, $height, $type] = Helpers::falseToNull(@getimagesize($file)); // @ - files smaller than 12 bytes causes read error
+ return $type && isset(self::Formats[$type]) ? $type : null;
}
@@ -250,8 +250,8 @@ public static function detectTypeFromFile(string $file, &$width = null, &$height
*/
public static function detectTypeFromString(string $s, &$width = null, &$height = null): ?int
{
- [$width, $height, $type] = @getimagesizefromstring($s); // @ - strings smaller than 12 bytes causes read error
- return isset(self::Formats[$type]) ? $type : null;
+ [$width, $height, $type] = Helpers::falseToNull(@getimagesizefromstring($s)); // @ - strings smaller than 12 bytes causes read error
+ return $type && isset(self::Formats[$type]) ? $type : null;
}
diff --git a/tools/.phpstan/vendor/nette/utils/src/Utils/Iterables.php b/tools/.phpstan/vendor/nette/utils/src/Utils/Iterables.php
index 8eb6a9117..28c9269cf 100644
--- a/tools/.phpstan/vendor/nette/utils/src/Utils/Iterables.php
+++ b/tools/.phpstan/vendor/nette/utils/src/Utils/Iterables.php
@@ -178,6 +178,31 @@ public static function mapWithKeys(iterable $iterable, callable $transformer): \
}
+ /**
+ * Creates a repeatable iterator from a factory function.
+ * The factory is called every time the iterator is iterated.
+ * @template K
+ * @template V
+ * @param callable(): iterable $factory
+ * @return \IteratorAggregate
+ */
+ public static function repeatable(callable $factory): \IteratorAggregate
+ {
+ return new class ($factory) implements \IteratorAggregate {
+ public function __construct(
+ private $factory,
+ ) {
+ }
+
+
+ public function getIterator(): \Iterator
+ {
+ return Iterables::toIterator(($this->factory)());
+ }
+ };
+ }
+
+
/**
* Wraps around iterator and caches its keys and values during iteration.
* This allows the data to be re-iterated multiple times.
@@ -186,7 +211,7 @@ public static function mapWithKeys(iterable $iterable, callable $transformer): \
* @param iterable $iterable
* @return \IteratorAggregate
*/
- public static function memoize(iterable $iterable): iterable
+ public static function memoize(iterable $iterable): \IteratorAggregate
{
return new class (self::toIterator($iterable)) implements \IteratorAggregate {
public function __construct(
diff --git a/tools/.phpstan/vendor/nette/utils/src/Utils/Reflection.php b/tools/.phpstan/vendor/nette/utils/src/Utils/Reflection.php
index e68476228..022098422 100644
--- a/tools/.phpstan/vendor/nette/utils/src/Utils/Reflection.php
+++ b/tools/.phpstan/vendor/nette/utils/src/Utils/Reflection.php
@@ -11,7 +11,7 @@
use Nette;
use function constant, current, defined, end, explode, file_get_contents, implode, ltrim, next, ord, strrchr, strtolower, substr;
-use const PHP_VERSION_ID, T_AS, T_CLASS, T_COMMENT, T_CURLY_OPEN, T_DOC_COMMENT, T_DOLLAR_OPEN_CURLY_BRACES, T_ENUM, T_INTERFACE, T_NAME_FULLY_QUALIFIED, T_NAME_QUALIFIED, T_NAMESPACE, T_NS_SEPARATOR, T_STRING, T_TRAIT, T_USE, T_WHITESPACE, TOKEN_PARSE;
+use const T_AS, T_CLASS, T_COMMENT, T_CURLY_OPEN, T_DOC_COMMENT, T_DOLLAR_OPEN_CURLY_BRACES, T_ENUM, T_INTERFACE, T_NAME_FULLY_QUALIFIED, T_NAME_QUALIFIED, T_NAMESPACE, T_NS_SEPARATOR, T_STRING, T_TRAIT, T_USE, T_WHITESPACE, TOKEN_PARSE;
/**
@@ -28,7 +28,7 @@ public static function isBuiltinType(string $type): bool
}
- /** @deprecated use Nette\Utils\Validators::isClassKeyword() */
+ #[\Deprecated('use Nette\Utils\Validators::isClassKeyword()')]
public static function isClassKeyword(string $name): bool
{
return Validators::isClassKeyword($name);
@@ -137,9 +137,7 @@ public static function toString(\Reflector $ref): string
} elseif ($ref instanceof \ReflectionMethod) {
return $ref->getDeclaringClass()->name . '::' . $ref->name . '()';
} elseif ($ref instanceof \ReflectionFunction) {
- return PHP_VERSION_ID >= 80200 && $ref->isAnonymous()
- ? '{closure}()'
- : $ref->name . '()';
+ return $ref->isAnonymous() ? '{closure}()' : $ref->name . '()';
} elseif ($ref instanceof \ReflectionProperty) {
return self::getPropertyDeclaringClass($ref)->name . '::$' . $ref->name;
} elseif ($ref instanceof \ReflectionParameter) {
@@ -241,7 +239,7 @@ private static function parseUseStatements(string $code, ?string $forClass = nul
case T_CLASS:
case T_INTERFACE:
case T_TRAIT:
- case PHP_VERSION_ID < 80100 ? T_CLASS : T_ENUM:
+ case T_ENUM:
if ($name = self::fetch($tokens, T_STRING)) {
$class = $namespace . $name;
$classLevel = $level + 1;
diff --git a/tools/.phpstan/vendor/nette/utils/src/Utils/Strings.php b/tools/.phpstan/vendor/nette/utils/src/Utils/Strings.php
index 19d20f805..eb44b481d 100644
--- a/tools/.phpstan/vendor/nette/utils/src/Utils/Strings.php
+++ b/tools/.phpstan/vendor/nette/utils/src/Utils/Strings.php
@@ -24,7 +24,7 @@ class Strings
public const TrimCharacters = " \t\n\r\0\x0B\u{A0}\u{2000}\u{2001}\u{2002}\u{2003}\u{2004}\u{2005}\u{2006}\u{2007}\u{2008}\u{2009}\u{200A}\u{200B}\u{2028}\u{3000}";
- /** @deprecated use Strings::TrimCharacters */
+ #[\Deprecated('use Strings::TrimCharacters')]
public const TRIM_CHARACTERS = self::TrimCharacters;
@@ -186,17 +186,12 @@ public static function platformNewLines(string $s): string
*/
public static function toAscii(string $s): string
{
- $iconv = defined('ICONV_IMPL') ? trim(ICONV_IMPL, '"\'') : null;
- static $transliterator = null;
- if ($transliterator === null) {
- if (class_exists('Transliterator', false)) {
- $transliterator = \Transliterator::create('Any-Latin; Latin-ASCII');
- } else {
- trigger_error(__METHOD__ . "(): it is recommended to enable PHP extensions 'intl'.", E_USER_NOTICE);
- $transliterator = false;
- }
+ if (!extension_loaded('intl')) {
+ throw new Nette\NotSupportedException(__METHOD__ . '() requires INTL extension that is not loaded.');
}
+ $iconv = defined('ICONV_IMPL') ? trim(ICONV_IMPL, '"\'') : null;
+
// remove control characters and check UTF-8 validity
$s = self::pcre('preg_replace', ['#[^\x09\x0A\x0D\x20-\x7E\xA0-\x{2FF}\x{370}-\x{10FFFF}]#u', '', $s]);
@@ -206,39 +201,15 @@ public static function toAscii(string $s): string
$s = strtr($s, ["\u{AE}" => '(R)', "\u{A9}" => '(c)', "\u{2026}" => '...', "\u{AB}" => '<<', "\u{BB}" => '>>', "\u{A3}" => 'lb', "\u{A5}" => 'yen', "\u{B2}" => '^2', "\u{B3}" => '^3', "\u{B5}" => 'u', "\u{B9}" => '^1', "\u{BA}" => 'o', "\u{BF}" => '?', "\u{2CA}" => "'", "\u{2CD}" => '_', "\u{2DD}" => '"', "\u{1FEF}" => '', "\u{20AC}" => 'EUR', "\u{2122}" => 'TM', "\u{212E}" => 'e', "\u{2190}" => '<-', "\u{2191}" => '^', "\u{2192}" => '->', "\u{2193}" => 'V', "\u{2194}" => '<->']); // ® © … « » £ ¥ ² ³ µ ¹ º ¿ ˊ ˍ ˝ ` € ™ ℮ ← ↑ → ↓ ↔
}
- if ($transliterator) {
- $s = $transliterator->transliterate($s);
- // use iconv because The transliterator leaves some characters out of ASCII, eg → ʾ
- if ($iconv === 'glibc') {
- $s = strtr($s, '?', "\x01"); // temporarily hide ? to distinguish them from the garbage that iconv creates
- $s = iconv('UTF-8', 'ASCII//TRANSLIT//IGNORE', $s);
- $s = str_replace(['?', "\x01"], ['', '?'], $s); // remove garbage and restore ? characters
- } elseif ($iconv === 'libiconv') {
- $s = iconv('UTF-8', 'ASCII//TRANSLIT//IGNORE', $s);
- } else { // null or 'unknown' (#216)
- $s = self::pcre('preg_replace', ['#[^\x00-\x7F]++#', '', $s]); // remove non-ascii chars
- }
- } elseif ($iconv === 'glibc' || $iconv === 'libiconv') {
- // temporarily hide these characters to distinguish them from the garbage that iconv creates
- $s = strtr($s, '`\'"^~?', "\x01\x02\x03\x04\x05\x06");
- if ($iconv === 'glibc') {
- // glibc implementation is very limited. transliterate into Windows-1250 and then into ASCII, so most Eastern European characters are preserved
- $s = iconv('UTF-8', 'WINDOWS-1250//TRANSLIT//IGNORE', $s);
- $s = strtr(
- $s,
- "\xa5\xa3\xbc\x8c\xa7\x8a\xaa\x8d\x8f\x8e\xaf\xb9\xb3\xbe\x9c\x9a\xba\x9d\x9f\x9e\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf8\xf9\xfa\xfb\xfc\xfd\xfe\x96\xa0\x8b\x97\x9b\xa6\xad\xb7",
- 'ALLSSSSTZZZallssstzzzRAAAALCCCEEEEIIDDNNOOOOxRUUUUYTsraaaalccceeeeiiddnnooooruuuuyt- <->|-.',
- );
- $s = self::pcre('preg_replace', ['#[^\x00-\x7F]++#', '', $s]);
- } else {
- $s = iconv('UTF-8', 'ASCII//TRANSLIT//IGNORE', $s);
- }
-
- // remove garbage that iconv creates during transliteration (eg Ý -> Y')
- $s = str_replace(['`', "'", '"', '^', '~', '?'], '', $s);
- // restore temporarily hidden characters
- $s = strtr($s, "\x01\x02\x03\x04\x05\x06", '`\'"^~?');
- } else {
+ $s = \Transliterator::create('Any-Latin; Latin-ASCII')->transliterate($s);
+ // use iconv because The transliterator leaves some characters out of ASCII, eg → ʾ
+ if ($iconv === 'glibc') {
+ $s = strtr($s, '?', "\x01"); // temporarily hide ? to distinguish them from the garbage that iconv creates
+ $s = iconv('UTF-8', 'ASCII//TRANSLIT//IGNORE', $s);
+ $s = str_replace(['?', "\x01"], ['', '?'], $s); // remove garbage and restore ? characters
+ } elseif ($iconv === 'libiconv') {
+ $s = iconv('UTF-8', 'ASCII//TRANSLIT//IGNORE', $s);
+ } else { // null or 'unknown' (#216)
$s = self::pcre('preg_replace', ['#[^\x00-\x7F]++#', '', $s]); // remove non-ascii chars
}
diff --git a/tools/.phpstan/vendor/nette/utils/src/Utils/Type.php b/tools/.phpstan/vendor/nette/utils/src/Utils/Type.php
index f1a8fa1c9..92aac80de 100644
--- a/tools/.phpstan/vendor/nette/utils/src/Utils/Type.php
+++ b/tools/.phpstan/vendor/nette/utils/src/Utils/Type.php
@@ -10,14 +10,13 @@
namespace Nette\Utils;
use Nette;
-use function array_map, array_search, array_splice, count, explode, implode, is_a, is_string, strcasecmp, strtolower, substr, trim;
-use const PHP_VERSION_ID;
+use function array_map, array_search, array_splice, count, explode, implode, is_a, is_resource, is_string, strcasecmp, strtolower, substr, trim;
/**
* PHP type reflection.
*/
-final class Type
+final readonly class Type
{
/** @var array */
private array $types;
@@ -34,7 +33,7 @@ public static function fromReflection(
): ?self
{
$type = $reflection instanceof \ReflectionFunctionAbstract
- ? $reflection->getReturnType() ?? (PHP_VERSION_ID >= 80100 && $reflection instanceof \ReflectionMethod ? $reflection->getTentativeReturnType() : null)
+ ? $reflection->getReturnType() ?? ($reflection instanceof \ReflectionMethod ? $reflection->getTentativeReturnType() : null)
: $reflection->getType();
return $type ? self::fromReflectionType($type, $reflection, asObject: true) : null;
@@ -86,6 +85,23 @@ public static function fromString(string $type): self
}
+ /**
+ * Creates a Type object based on the actual type of value.
+ */
+ public static function fromValue(mixed $value): self
+ {
+ $type = get_debug_type($value);
+ if (is_resource($value)) {
+ $type = 'mixed';
+ } elseif (str_ends_with($type, '@anonymous')) {
+ $parent = substr($type, 0, -10);
+ $type = $parent === 'class' ? 'object' : $parent;
+ }
+
+ return new self([$type]);
+ }
+
+
/**
* Resolves 'self', 'static' and 'parent' to the actual class name.
*/
@@ -138,6 +154,23 @@ public function __toString(): string
}
+ /**
+ * Returns a type that accepts both the current type and the given type.
+ */
+ public function with(string|self $type): self
+ {
+ $type = is_string($type) ? self::fromString($type) : $type;
+ return match (true) {
+ $this->allows($type) => $this,
+ $type->allows($this) => $type,
+ default => new self(array_unique(
+ array_merge($this->isIntersection() ? [$this] : $this->types, $type->isIntersection() ? [$type] : $type->types),
+ SORT_REGULAR,
+ ), '|'),
+ };
+ }
+
+
/**
* Returns the array of subtypes that make up the compound type as strings.
* @return array
@@ -196,7 +229,7 @@ public function isSimple(): bool
}
- /** @deprecated use isSimple() */
+ #[\Deprecated('use isSimple()')]
public function isSingle(): bool
{
return $this->simple;
@@ -233,36 +266,36 @@ public function isClassKeyword(): bool
/**
* Verifies type compatibility. For example, it checks if a value of a certain type could be passed as a parameter.
*/
- public function allows(string $subtype): bool
+ public function allows(string|self $type): bool
{
if ($this->types === ['mixed']) {
return true;
}
- $subtype = self::fromString($subtype);
- return $subtype->isUnion()
- ? Arrays::every($subtype->types, fn($t) => $this->allows2($t instanceof self ? $t->types : [$t]))
- : $this->allows2($subtype->types);
+ $type = is_string($type) ? self::fromString($type) : $type;
+ return $type->isUnion()
+ ? Arrays::every($type->types, fn($t) => $this->allowsAny($t instanceof self ? $t->types : [$t]))
+ : $this->allowsAny($type->types);
}
- private function allows2(array $subtypes): bool
+ private function allowsAny(array $givenTypes): bool
{
return $this->isUnion()
- ? Arrays::some($this->types, fn($t) => $this->allows3($t instanceof self ? $t->types : [$t], $subtypes))
- : $this->allows3($this->types, $subtypes);
+ ? Arrays::some($this->types, fn($t) => $this->allowsAll($t instanceof self ? $t->types : [$t], $givenTypes))
+ : $this->allowsAll($this->types, $givenTypes);
}
- private function allows3(array $types, array $subtypes): bool
+ private function allowsAll(array $ourTypes, array $givenTypes): bool
{
return Arrays::every(
- $types,
- fn($type) => Arrays::some(
- $subtypes,
- fn($subtype) => Validators::isBuiltinType($type)
- ? strcasecmp($type, $subtype) === 0
- : is_a($subtype, $type, allow_string: true),
+ $ourTypes,
+ fn($ourType) => Arrays::some(
+ $givenTypes,
+ fn($givenType) => Validators::isBuiltinType($ourType)
+ ? strcasecmp($ourType, $givenType) === 0
+ : is_a($givenType, $ourType, allow_string: true),
),
);
}
diff --git a/tools/.phpstan/vendor/phpstan/extension-installer/src/GeneratedConfig.php b/tools/.phpstan/vendor/phpstan/extension-installer/src/GeneratedConfig.php
index c708b87ff..1d81e9e0e 100644
--- a/tools/.phpstan/vendor/phpstan/extension-installer/src/GeneratedConfig.php
+++ b/tools/.phpstan/vendor/phpstan/extension-installer/src/GeneratedConfig.php
@@ -12,7 +12,7 @@ final class GeneratedConfig
public const EXTENSIONS = array (
'ergebnis/phpstan-rules' =>
array (
- 'install_path' => '/Users/sb/Work/OpenSource/php-code-coverage/tools/.phpstan/vendor/ergebnis/phpstan-rules',
+ 'install_path' => '/usr/local/src/php-code-coverage/tools/.phpstan/vendor/ergebnis/phpstan-rules',
'relative_install_path' => '../../../ergebnis/phpstan-rules',
'extra' =>
array (
@@ -26,7 +26,7 @@ final class GeneratedConfig
),
'phpstan/phpstan-strict-rules' =>
array (
- 'install_path' => '/Users/sb/Work/OpenSource/php-code-coverage/tools/.phpstan/vendor/phpstan/phpstan-strict-rules',
+ 'install_path' => '/usr/local/src/php-code-coverage/tools/.phpstan/vendor/phpstan/phpstan-strict-rules',
'relative_install_path' => '../../phpstan-strict-rules',
'extra' =>
array (
@@ -40,7 +40,7 @@ final class GeneratedConfig
),
'tomasvotruba/type-coverage' =>
array (
- 'install_path' => '/Users/sb/Work/OpenSource/php-code-coverage/tools/.phpstan/vendor/tomasvotruba/type-coverage',
+ 'install_path' => '/usr/local/src/php-code-coverage/tools/.phpstan/vendor/tomasvotruba/type-coverage',
'relative_install_path' => '../../../tomasvotruba/type-coverage',
'extra' =>
array (
@@ -49,7 +49,7 @@ final class GeneratedConfig
0 => 'config/extension.neon',
),
),
- 'version' => '2.0.2',
+ 'version' => '2.1.0',
'phpstanVersionConstraint' => '>=2.0.0.0-dev, <3.0.0.0-dev',
),
);
diff --git a/tools/.phpstan/vendor/phpstan/phpstan/README.md b/tools/.phpstan/vendor/phpstan/phpstan/README.md
index 49bed4fd7..689f9841c 100644
--- a/tools/.phpstan/vendor/phpstan/phpstan/README.md
+++ b/tools/.phpstan/vendor/phpstan/phpstan/README.md
@@ -29,7 +29,10 @@ Want your logo here? [Learn more »](https://phpstan.org/sponsor)
### Gold Sponsors
+
+
+
diff --git a/tools/.phpstan/vendor/phpstan/phpstan/phpstan.phar b/tools/.phpstan/vendor/phpstan/phpstan/phpstan.phar
index 8c83a085d..bc32b8047 100755
Binary files a/tools/.phpstan/vendor/phpstan/phpstan/phpstan.phar and b/tools/.phpstan/vendor/phpstan/phpstan/phpstan.phar differ
diff --git a/tools/.phpstan/vendor/phpstan/phpstan/phpstan.phar.asc b/tools/.phpstan/vendor/phpstan/phpstan/phpstan.phar.asc
index 62f935e89..fec010bf3 100644
--- a/tools/.phpstan/vendor/phpstan/phpstan/phpstan.phar.asc
+++ b/tools/.phpstan/vendor/phpstan/phpstan/phpstan.phar.asc
@@ -1,16 +1,16 @@
-----BEGIN PGP SIGNATURE-----
-iQIzBAABCgAdFiEEynwsejDI6OEnSoR2UcZzBf/C5cAFAmkTU5cACgkQUcZzBf/C
-5cC1bg/+MAMAfCH1CDfI78Inqo/Mqa5q40QOn4RmVNex+xb8lKZ1AApc76nwNfn/
-BLI+War1G/5C2WWNgiqI9X7j/jo46oi+oO/1qywssqEn+7S9Ob7C56N2ERoikS3c
-MsrseR5XEVMFRG/enk1Gsmde9PesuIiN10FnsFyhZiMDNUXhoiLHPrERzTlUocAv
-K7/zm4gF152HM8tUir38i+h9BxadfNvah0zWCfzn7v+5OxSAHjz/DriWWdZkIsmB
-VuyZUg1QX05JzRkVBAdEy3h1N9c57ktWVf92PDrNha3hhQ1lw0OvH9+1+B5+Me5w
-BTUrLz+S6PGpFKkLY8M5ucQAvqHB41zgYp1QIN/Da1ZxvsQyAFq6yvD+d+yYG/zn
-k1NVNDrQMAE6GV7YjCK1bDSKExaFyYXmTb93fRN90cxYi3pfZpIMaaiKNGLYFPsk
-YHe1N4/et3741Y8VNSb2S1iu3KVTOzSnEsQL/olD5Trt6faKtscCSY7deeINoMkq
-IGLQmZjbj4TUO0js2Lw8zTp/d8X3bd67ktdVmijjaKurNYXJsecYuAZXz3WOTek9
-aXuT8kC1aZz/h7CxvjaN2G3KAi5yZ2aN57CSUYhDpmeN2VhvDGaGgHBPFSHcE5fx
-dr4BzRNTOU1ACBONChMGSvuDKCqC7kzt+qvWY29TlZxgwO+iIq8=
-=0Qu+
+iQIzBAABCgAdFiEEynwsejDI6OEnSoR2UcZzBf/C5cAFAmkysr4ACgkQUcZzBf/C
+5cDE+RAAlbDueQxsbyo+wqm1sURcXT4fPbwdFAv1RXSYfZl7XraoagxYHssIHt9n
+TcKuBSOPOmlKgZ4FmVW05TRr0yoLZtckpRDCWuJoPzI9ilW2tiVi6AbEVhV0EqwL
+xVToGIzZXmti+X5Mm2OwQMCdpAbqpAy0mwmv/TudFiKdgZBzl5zHWDUSNCwP8s2m
+pLGBupQis6sA45+u28vLpyR7vn3mIq3F3hJgb5nrZlWt33jVJ7MDFnpGpeJ6+jBn
+/1BmefK0sXwN4EqaJbrRkHdRePISt2+jQXa/V/L3oJ0a3hVFufcGze41ARecSQ/0
+203aB0XcBtIFlshE5OIpXW+ibmgBabd+ggZEkRoS3OXtV5cJizLh49B+16A97QOr
+H0NWgLfY/W1u2t0Iu+WDT37Na5LPsuucW9vv9PwS6WY9eCr4Jbbmq1PtF0T17aqx
+STyPWNjs5A8NNjVUQ+Ufj/AAdH3hmNj4B5H6psxHD5UsFHoOLVFtwih4GdHrKXIZ
+N2lznVo8HDCcvKo6C4F8ejG1t4f5qBHNpYeEC9aVQVvXrBockQQz4lUclibW7MIe
+g33fXgO/GIm0dn2u0NCzjYof+TAVOfvtbK4GY0Z9BOlJcQnzu7V1LxqFamG5ef+u
+A2ABQa0HVEeKTomB3jzNQQVKw9QzWyfI21xSskfpFs4FXW3A5xc=
+=edJd
-----END PGP SIGNATURE-----
diff --git a/tools/.phpstan/vendor/tomasvotruba/type-coverage/.editorconfig b/tools/.phpstan/vendor/tomasvotruba/type-coverage/.editorconfig
deleted file mode 100644
index bec95c449..000000000
--- a/tools/.phpstan/vendor/tomasvotruba/type-coverage/.editorconfig
+++ /dev/null
@@ -1,9 +0,0 @@
-root = true
-
-[*]
-charset = utf-8
-end_of_line = lf
-insert_final_newline = true
-trim_trailing_whitespace = true
-indent_style = space
-indent_size = 4
diff --git a/tools/.phpstan/vendor/tomasvotruba/type-coverage/.gitignore b/tools/.phpstan/vendor/tomasvotruba/type-coverage/.gitignore
deleted file mode 100644
index a6edf7a9b..000000000
--- a/tools/.phpstan/vendor/tomasvotruba/type-coverage/.gitignore
+++ /dev/null
@@ -1,5 +0,0 @@
-/vendor
-composer.lock
-
-.idea
-/.phpunit.cache
diff --git a/tools/.phpstan/vendor/tomasvotruba/type-coverage/README.md b/tools/.phpstan/vendor/tomasvotruba/type-coverage/README.md
index 5d673fdf0..cb7e71f7c 100644
--- a/tools/.phpstan/vendor/tomasvotruba/type-coverage/README.md
+++ b/tools/.phpstan/vendor/tomasvotruba/type-coverage/README.md
@@ -2,25 +2,34 @@
-
-
-
+A PHPStan extension, to check and require minimal type coverage of PHP code.
+The type coverage rate = total count of **defined** type declarations / total count of **possible** type declarations.
+
+E.g. we have 10 methods, but only 7 have defined return type = 70 % return type coverage.
+
+---
+
PHPStan uses type declarations to determine the type of variables, properties and other expression. Sometimes it's hard to see what PHPStan errors are the important ones among thousands of others.
Instead of fixing all PHPStan errors at once, we can start with minimal require type coverage.
-What is the type coverage you ask? We have 4 type possible declarations in total here:
+
+## How to increase type coverage?
+
+Here we have 3 possible type declarations:
+
+* property,
+* param
+* and return type
```php
final class ConferenceFactory
{
- const SPEAKER_TAG = 'speaker';
-
private $talkFactory;
public function createConference(array $data)
@@ -32,20 +41,17 @@ final class ConferenceFactory
}
```
-*Note: Class constant types require PHP 8.3 to run.*
+The param type is defined as `array`.
-The param type is defined. But the property, return and constant types are missing.
+1 defined / 3 possible = **33.3 % type coverage**
-* 1 out of 4 = 25 % coverage
+
-Our code quality is only at one-quarter of its potential. Let's get to 100 %!
+Our code quality is only at one-third of its potential. Let's get to 100 %!
```diff
final class ConferenceFactory
{
-- public const SPEAKER_TAG = 'speaker';
-+ public const string SPEAKER_TAG = 'speaker';
-
- private $talkFactory;
+ private TalkFactory $talkFactory;
@@ -69,7 +75,7 @@ This technique is very simple to start even on legacy project. Also, you're now
composer require tomasvotruba/type-coverage --dev
```
-The package is available on PHP 7.2+ version in tagged releases.
+The package is available on PHP 7.2+.
@@ -86,6 +92,8 @@ parameters:
return: 50
param: 35.5
property: 70
+
+ # since PHP 8.3
constant: 85
```
diff --git a/tools/.phpstan/vendor/tomasvotruba/type-coverage/docs/required_type_level.jpg b/tools/.phpstan/vendor/tomasvotruba/type-coverage/docs/required_type_level.jpg
deleted file mode 100644
index cd219abe8..000000000
Binary files a/tools/.phpstan/vendor/tomasvotruba/type-coverage/docs/required_type_level.jpg and /dev/null differ
diff --git a/tools/.phpstan/vendor/tomasvotruba/type-coverage/rector.php b/tools/.phpstan/vendor/tomasvotruba/type-coverage/rector.php
deleted file mode 100644
index 224fbf73e..000000000
--- a/tools/.phpstan/vendor/tomasvotruba/type-coverage/rector.php
+++ /dev/null
@@ -1,18 +0,0 @@
-withPaths([
- __DIR__ . '/src',
- __DIR__ . '/tests',
- ])
- ->withPhpSets()
- ->withPreparedSets(deadCode: true, codeQuality: true, codingStyle: true, typeDeclarations: true, privatization: true, naming: true)
- ->withImportNames(removeUnusedImports: true)
- ->withSkip([
- '*/Fixture/*',
- '*/Source/*',
- ]);
diff --git a/tools/.phpstan/vendor/tomasvotruba/type-coverage/src/Collectors/ConstantTypeDeclarationCollector.php b/tools/.phpstan/vendor/tomasvotruba/type-coverage/src/Collectors/ConstantTypeDeclarationCollector.php
index 4296b6135..b0babdd80 100644
--- a/tools/.phpstan/vendor/tomasvotruba/type-coverage/src/Collectors/ConstantTypeDeclarationCollector.php
+++ b/tools/.phpstan/vendor/tomasvotruba/type-coverage/src/Collectors/ConstantTypeDeclarationCollector.php
@@ -26,7 +26,7 @@ public function getNodeType(): string
/**
* @param ClassConstantsNode $node
- * @return mixed[]
+ * @return array)>>
*/
public function processNode(Node $node, Scope $scope): array
{
diff --git a/tools/.phpstan/vendor/tomasvotruba/type-coverage/src/Collectors/PropertyTypeDeclarationCollector.php b/tools/.phpstan/vendor/tomasvotruba/type-coverage/src/Collectors/PropertyTypeDeclarationCollector.php
index 893a60ba4..86c09ccde 100644
--- a/tools/.phpstan/vendor/tomasvotruba/type-coverage/src/Collectors/PropertyTypeDeclarationCollector.php
+++ b/tools/.phpstan/vendor/tomasvotruba/type-coverage/src/Collectors/PropertyTypeDeclarationCollector.php
@@ -27,7 +27,7 @@ public function getNodeType(): string
/**
* @param InClassNode $node
- * @return mixed[]
+ * @return array)>>
*/
public function processNode(Node $node, Scope $scope): array
{
diff --git a/tools/.phpstan/vendor/tomasvotruba/type-coverage/src/Configuration.php b/tools/.phpstan/vendor/tomasvotruba/type-coverage/src/Configuration.php
index f2fd6f2b9..311d103fa 100644
--- a/tools/.phpstan/vendor/tomasvotruba/type-coverage/src/Configuration.php
+++ b/tools/.phpstan/vendor/tomasvotruba/type-coverage/src/Configuration.php
@@ -30,6 +30,7 @@ public function getRequiredPropertyTypeLevel()
public function isConstantTypeCoverageEnabled(): bool
{
+ // constant types are available only on PHP 8.3+
if (PHP_VERSION_ID < 80300) {
return false;
}
diff --git a/tools/.phpstan/vendor/tomasvotruba/type-coverage/src/Configuration/ScopeConfigurationResolver.php b/tools/.phpstan/vendor/tomasvotruba/type-coverage/src/Configuration/ScopeConfigurationResolver.php
index 7b4cec24f..4929c86fe 100644
--- a/tools/.phpstan/vendor/tomasvotruba/type-coverage/src/Configuration/ScopeConfigurationResolver.php
+++ b/tools/.phpstan/vendor/tomasvotruba/type-coverage/src/Configuration/ScopeConfigurationResolver.php
@@ -51,7 +51,9 @@ public static function areFullPathsAnalysed(Scope $scope): bool
private static function getPrivateProperty(object $object, string $propertyName): object
{
$reflectionProperty = new ReflectionProperty($object, $propertyName);
- $reflectionProperty->setAccessible(true);
+ if (PHP_VERSION_ID < 80100) {
+ $reflectionProperty->setAccessible(true);
+ }
return $reflectionProperty->getValue($object);
}
diff --git a/tools/.phpstan/vendor/tomasvotruba/type-coverage/src/Rules/ConstantTypeCoverageRule.php b/tools/.phpstan/vendor/tomasvotruba/type-coverage/src/Rules/ConstantTypeCoverageRule.php
index b53da098c..7fe74a9e0 100644
--- a/tools/.phpstan/vendor/tomasvotruba/type-coverage/src/Rules/ConstantTypeCoverageRule.php
+++ b/tools/.phpstan/vendor/tomasvotruba/type-coverage/src/Rules/ConstantTypeCoverageRule.php
@@ -48,8 +48,11 @@ final class ConstantTypeCoverageRule implements Rule
*/
private CollectorDataNormalizer $collectorDataNormalizer;
- public function __construct(TypeCoverageFormatter $typeCoverageFormatter, Configuration $configuration, CollectorDataNormalizer $collectorDataNormalizer)
- {
+ public function __construct(
+ TypeCoverageFormatter $typeCoverageFormatter,
+ Configuration $configuration,
+ CollectorDataNormalizer $collectorDataNormalizer
+ ) {
$this->typeCoverageFormatter = $typeCoverageFormatter;
$this->configuration = $configuration;
$this->collectorDataNormalizer = $collectorDataNormalizer;
@@ -69,6 +72,11 @@ public function getNodeType(): string
*/
public function processNode(Node $node, Scope $scope): array
{
+ // enable only on PHP 8.3+
+ if (PHP_VERSION_ID < 80300) {
+ return [];
+ }
+
// if only subpaths are analysed, skip as data will be false positive
if (! ScopeConfigurationResolver::areFullPathsAnalysed($scope)) {
return [];
diff --git a/tools/.phpstan/vendor/tomasvotruba/type-coverage/src/Rules/ParamTypeCoverageRule.php b/tools/.phpstan/vendor/tomasvotruba/type-coverage/src/Rules/ParamTypeCoverageRule.php
index ed300eea6..81df4581f 100644
--- a/tools/.phpstan/vendor/tomasvotruba/type-coverage/src/Rules/ParamTypeCoverageRule.php
+++ b/tools/.phpstan/vendor/tomasvotruba/type-coverage/src/Rules/ParamTypeCoverageRule.php
@@ -48,8 +48,11 @@ final class ParamTypeCoverageRule implements Rule
*/
private CollectorDataNormalizer $collectorDataNormalizer;
- public function __construct(TypeCoverageFormatter $typeCoverageFormatter, Configuration $configuration, CollectorDataNormalizer $collectorDataNormalizer)
- {
+ public function __construct(
+ TypeCoverageFormatter $typeCoverageFormatter,
+ Configuration $configuration,
+ CollectorDataNormalizer $collectorDataNormalizer
+ ) {
$this->typeCoverageFormatter = $typeCoverageFormatter;
$this->configuration = $configuration;
$this->collectorDataNormalizer = $collectorDataNormalizer;
diff --git a/tools/.phpstan/vendor/tomasvotruba/type-coverage/src/Rules/PropertyTypeCoverageRule.php b/tools/.phpstan/vendor/tomasvotruba/type-coverage/src/Rules/PropertyTypeCoverageRule.php
index 27dcec2cf..74edaa063 100644
--- a/tools/.phpstan/vendor/tomasvotruba/type-coverage/src/Rules/PropertyTypeCoverageRule.php
+++ b/tools/.phpstan/vendor/tomasvotruba/type-coverage/src/Rules/PropertyTypeCoverageRule.php
@@ -48,8 +48,11 @@ final class PropertyTypeCoverageRule implements Rule
*/
private CollectorDataNormalizer $collectorDataNormalizer;
- public function __construct(TypeCoverageFormatter $typeCoverageFormatter, Configuration $configuration, CollectorDataNormalizer $collectorDataNormalizer)
- {
+ public function __construct(
+ TypeCoverageFormatter $typeCoverageFormatter,
+ Configuration $configuration,
+ CollectorDataNormalizer $collectorDataNormalizer
+ ) {
$this->typeCoverageFormatter = $typeCoverageFormatter;
$this->configuration = $configuration;
$this->collectorDataNormalizer = $collectorDataNormalizer;
diff --git a/tools/.phpstan/vendor/tomasvotruba/type-coverage/src/Rules/ReturnTypeCoverageRule.php b/tools/.phpstan/vendor/tomasvotruba/type-coverage/src/Rules/ReturnTypeCoverageRule.php
index c7e7fbaa6..cee1d65a3 100644
--- a/tools/.phpstan/vendor/tomasvotruba/type-coverage/src/Rules/ReturnTypeCoverageRule.php
+++ b/tools/.phpstan/vendor/tomasvotruba/type-coverage/src/Rules/ReturnTypeCoverageRule.php
@@ -48,8 +48,11 @@ final class ReturnTypeCoverageRule implements Rule
*/
private CollectorDataNormalizer $collectorDataNormalizer;
- public function __construct(TypeCoverageFormatter $typeCoverageFormatter, Configuration $configuration, CollectorDataNormalizer $collectorDataNormalizer)
- {
+ public function __construct(
+ TypeCoverageFormatter $typeCoverageFormatter,
+ Configuration $configuration,
+ CollectorDataNormalizer $collectorDataNormalizer
+ ) {
$this->typeCoverageFormatter = $typeCoverageFormatter;
$this->configuration = $configuration;
$this->collectorDataNormalizer = $collectorDataNormalizer;
diff --git a/tools/composer b/tools/composer
index 572223953..02740c582 100755
Binary files a/tools/composer and b/tools/composer differ
diff --git a/tools/php-cs-fixer b/tools/php-cs-fixer
index 997a14782..04a544723 100755
Binary files a/tools/php-cs-fixer and b/tools/php-cs-fixer differ