Skip to content

Commit

Permalink
Fix static analysis
Browse files Browse the repository at this point in the history
  • Loading branch information
veewee committed Sep 16, 2024
1 parent 64fd853 commit d46ac5a
Show file tree
Hide file tree
Showing 24 changed files with 240 additions and 41 deletions.
1 change: 1 addition & 0 deletions .github/workflows/analyzers.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ jobs:
matrix:
operating-system: [ubuntu-latest]
php-versions: ['8.4']
composer-options: ['--ignore-platform-req=php+']
fail-fast: false
name: PHP ${{ matrix.php-versions }} @ ${{ matrix.operating-system }}
steps:
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/autoloader.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ jobs:
matrix:
operating-system: [ubuntu-latest]
php-versions: ['8.4']
composer-options: ['--ignore-platform-req=php+']
fail-fast: false
name: PHP ${{ matrix.php-versions }} @ ${{ matrix.operating-system }}
steps:
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/code-style.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ jobs:
matrix:
operating-system: [ubuntu-latest]
php-versions: ['8.4']
composer-options: ['--ignore-platform-req=php+']
fail-fast: false
name: PHP ${{ matrix.php-versions }} @ ${{ matrix.operating-system }}
steps:
Expand Down
3 changes: 2 additions & 1 deletion .github/workflows/stress.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ jobs:
matrix:
operating-system: [ubuntu-latest]
php-versions: ['8.4']
composer-options: ['--ignore-platform-req=php+']
fail-fast: false
name: PHP ${{ matrix.php-versions }} @ ${{ matrix.operating-system }}
steps:
Expand All @@ -21,6 +22,6 @@ jobs:
tools: 'composer:v2'
extensions: pcov, mbstring, posix, dom, libxml, xml, xsl, xmlreader, xmlwriter
- name: Install dependencies
run: composer update --prefer-dist --no-progress --no-suggest
run: composer update --prefer-dist --no-progress --no-suggest ${{ matrix.composer-options }}
- name: Run the stress tests
run: composer run stress
4 changes: 2 additions & 2 deletions .github/workflows/tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:
matrix:
operating-system: [ubuntu-latest]
php-versions: ['8.4']
experimental: [false]
composer-options: ['--ignore-platform-req=php+']
fail-fast: false
name: PHP ${{ matrix.php-versions }} @ ${{ matrix.operating-system }}
steps:
Expand All @@ -27,7 +27,7 @@ jobs:
ini-values: error_reporting=E_ALL
extensions: pcov, mbstring, posix, dom, libxml, xml, xsl, xmlreader, xmlwriter
- name: Install dependencies
run: composer update --prefer-dist --no-progress --no-suggest
run: composer update --prefer-dist --no-progress --no-suggest ${{ matrix.composer-options }}
- name: Run the tests
run: composer run tests
- name: Check tests quality
Expand Down
1 change: 1 addition & 0 deletions psalm.xml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
</issueHandlers>
<stubs>
<file name="stubs/DOM.phpstub" />
<file name="stubs/php_xsl.stub.phpstub" />
<file name="stubs/XMLReader.phpstub" />
<file name="stubs/XMLWriter.phpstub" />
</stubs>
Expand Down
6 changes: 3 additions & 3 deletions src/Xml/Dom/Collection/NodeList.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
use \DOM\Element;
use \DOM\Node;
use \DOM\NodeList as DOMNodeList;
use DOMXpath as DOMXpath;
use \DOM\XPath as DOMXPath;
use Generator;
use InvalidArgumentException;
use IteratorAggregate;
Expand Down Expand Up @@ -193,7 +193,7 @@ public function reduce(callable $reducer, mixed $initial): mixed
}

/**
* @param list<callable(DOMXpath): DOMXpath> $configurators
* @param list<callable(DOMXPath): DOMXPath> $configurators
* @throws RuntimeException
* @return NodeList<\DOM\Node>
*/
Expand All @@ -211,7 +211,7 @@ public function query(string $xpath, callable ... $configurators): self

/**
* @template X
* @param list<callable(DOMXpath): DOMXpath> $configurators
* @param list<callable(DOMXPath): DOMXPath> $configurators
* @param TypeInterface<X> $type
* @return list<X>
*/
Expand Down
6 changes: 2 additions & 4 deletions src/Xml/Dom/Locator/Node/detect_document.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,14 @@
namespace VeeWee\Xml\Dom\Locator\Node;

use \DOM\XMLDocument;
use \DOM\Node;
use InvalidArgumentException;
use Webmozart\Assert\Assert;
use function VeeWee\Xml\Dom\Assert\assert_document;
use function VeeWee\Xml\Dom\Predicate\is_document;

/**
* @throws InvalidArgumentException
* @psalm-suppress RedundantCondition - node->ownerDocument can also be null...
*/
function detect_document(\DOM\Node $node): \DOM\XMLDocument
{
return is_document($node) ? $node : $node->ownerDocument;
return is_document($node) ? $node : assert_document($node->ownerDocument);
}
7 changes: 4 additions & 3 deletions src/Xml/Dom/Locator/Xsd/locate_namespaced_xsd_schemas.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,22 +10,23 @@
use VeeWee\Xml\Xsd\Schema\Schema;
use VeeWee\Xml\Xsd\Schema\SchemaCollection;
use function Psl\Regex\split;
use function VeeWee\Xml\Dom\Locator\document_element;

/**
* @throws RuntimeException
*/
function locate_namespaced_xsd_schemas(\DOM\XMLDocument $document): SchemaCollection
{
$schemaNs = Xmlns::xsi()->value();
$attributes = $document->documentElement->attributes;
$documentElement = document_element()($document);
$attributes = $documentElement->attributes;
$collection = new SchemaCollection();

if (!$schemaLocation = $attributes->getNamedItemNS($schemaNs, 'schemaLocation')) {
return $collection;
}

/** @psalm-suppress MissingThrowsDocblock - Covered the runtime exception! */
$parts = split(trim($schemaLocation->textContent), '/\s+/');
$parts = split(trim($schemaLocation->textContent ?? ''), '/\s+/');
$partsCount = count($parts);
for ($k = 0; $k < $partsCount; $k += 2) {
$collection = $collection->add(Schema::withNamespace($parts[$k], $parts[$k + 1]));
Expand Down
7 changes: 4 additions & 3 deletions src/Xml/Dom/Locator/Xsd/locate_no_namespaced_xsd_schemas.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,21 @@
use VeeWee\Xml\Xsd\Schema\SchemaCollection;
use function Psl\Dict\map;
use function Psl\Regex\split;
use function VeeWee\Xml\Dom\Locator\document_element;

/**
* @throws RuntimeException
*/
function locate_no_namespaced_xsd_schemas(\DOM\XMLDocument $document): SchemaCollection
{
$schemaNs = Xmlns::xsi()->value();
$attributes = $document->documentElement->attributes;
$documentElement = document_element()($document);
$attributes = $documentElement->attributes;
if (!$schemaLocNoNamespace = $attributes->getNamedItemNS($schemaNs, 'noNamespaceSchemaLocation')) {
return new SchemaCollection();
}

/** @psalm-suppress MissingThrowsDocblock - Covered the runtime exception! */
$parts = split(trim($schemaLocNoNamespace->textContent), '/\s+/');
$parts = split(trim($schemaLocNoNamespace->textContent ?? ''), '/\s+/');

return new SchemaCollection(
...map(
Expand Down
3 changes: 2 additions & 1 deletion src/Xml/Dom/Locator/document_element.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,12 @@
use Closure;
use \DOM\XMLDocument;
use \DOM\Element;
use function VeeWee\Xml\Dom\Assert\assert_element;

/**
* @return Closure(\DOM\XMLDocument): \DOM\Element
*/
function document_element(): Closure
{
return static fn (\DOM\XMLDocument $document): \DOM\Element => $document->documentElement;
return static fn (\DOM\XMLDocument $document): \DOM\Element => assert_element($document->documentElement);
}
6 changes: 5 additions & 1 deletion src/Xml/Dom/Locator/elements_with_namespaced_tagname.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,9 @@ function elements_with_namespaced_tagname(string $namespace, string $localTagNam
* @return NodeList<\DOM\Element>
*/
static fn (\DOM\XMLDocument $document): NodeList
=> locate_by_namespaced_tag_name($document->documentElement, $namespace, $localTagName);
=> locate_by_namespaced_tag_name(
document_element()($document),
$namespace,
$localTagName
);
}
5 changes: 4 additions & 1 deletion src/Xml/Dom/Locator/elements_with_tagname.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,8 @@ function elements_with_tagname(string $tagName): Closure
* @return NodeList<\DOM\Element>
*/
static fn (\DOM\XMLDocument $document): NodeList
=> locate_by_tag_name($document->documentElement, $tagName);
=> locate_by_tag_name(
document_element()($document),
$tagName
);
}
2 changes: 1 addition & 1 deletion src/Xml/Dom/Locator/root_namespace.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,5 @@
*/
function root_namespace_uri(): Closure
{
return static fn (\DOM\XMLDocument $document): ?string => $document->documentElement->namespaceURI;
return static fn (\DOM\XMLDocument $document): ?string => document_element()($document)->namespaceURI;
}
5 changes: 4 additions & 1 deletion src/Xml/Dom/Manipulator/Attribute/rename.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ function rename(\DOM\Attr $target, string $newQName, ?string $newNamespaceURI =
{
return disallow_issues(static fn (): \DOM\Attr => match(true) {
is_xmlns_attribute($target) => rename_xmlns_attribute($target, $newQName),
default => tap(fn () => $target->rename($newNamespaceURI, $newQName))($target)
default => (function() use ($target, $newNamespaceURI, $newQName): \DOM\Attr {
$target->rename($newNamespaceURI, $newQName);
return $target;
})()
});
}
5 changes: 3 additions & 2 deletions src/Xml/Dom/Manipulator/Document/optimize_namespaces.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
use function Psl\Vec\sort;
use function Psl\Vec\values;
use function VeeWee\Xml\Dom\Builder\xmlns_attribute;
use function VeeWee\Xml\Dom\Locator\document_element;
use function VeeWee\Xml\Dom\Locator\Xmlns\recursive_linked_namespaces;
use function VeeWee\Xml\Dom\Manipulator\Xmlns\rename_element_namespace;

Expand All @@ -18,10 +19,10 @@
*/
function optimize_namespaces(\DOM\XMLDocument $document, string $prefix = 'ns'): void
{
$documentElement = $document->documentElement;
$documentElement = document_element()($document);
$namespaceURIs = values(unique(map(
recursive_linked_namespaces($documentElement),
static fn (\DOM\NamespaceInfo $info): string => $info->namespaceURI
static fn (\DOM\NamespaceInfo $info): string => $info->namespaceURI ?? ''
)));

foreach (sort($namespaceURIs) as $index => $namespaceURI) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
function copy_named_xmlns_attributes(\DOM\Element $target, \DOM\Element $source): void
{
xmlns_attributes_list($source)->forEach(static function (\DOM\Attr $xmlns) use ($target) {
if ($xmlns->prefix && !$target->hasAttribute($xmlns->nodeName)) {
if ($xmlns->prefix !== null && !$target->hasAttribute($xmlns->nodeName)) {
xmlns_attribute($xmlns->localName, $xmlns->value)($target);
}
});
Expand Down
4 changes: 2 additions & 2 deletions src/Xml/Dom/Manipulator/Element/rename.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,15 @@ function rename(\DOM\Element $target, string $newQName, ?string $newNamespaceURI
$newPrefix = $parts[0] ?? '';

/*
* To make sure the new namespace prefix is being used, we need to apply an additional xmlns declaration chech:
* To make sure the new namespace prefix is being used, we need to apply an additional xmlns declaration check:
* This is due to a particular rule in the XML serialization spec,
* that enforces that a namespaceURI on an element is only associated with exactly one prefix.
* See the note of bullet point 2 of https://www.w3.org/TR/DOM-Parsing/#dfn-concept-serialize-xml.
*
* If you rename a:xx to b:xx an xmlns:b="xx" attribute gets added at the end, but prefix a: will still be serialized.
* So in this case, we need to remove the xmlns declaration first.
*/
if ($newPrefix && $newPrefix !== $target->prefix && $target->hasAttribute('xmlns:'.$target->prefix)) {
if ($newPrefix && $target->prefix !== null && $newPrefix !== $target->prefix && $target->hasAttribute('xmlns:'.$target->prefix)) {
$target->removeAttribute('xmlns:'.$target->prefix);
}

Expand Down
3 changes: 2 additions & 1 deletion src/Xml/Dom/Traverser/Visitor/RemoveNamespaces.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ final class RemoveNamespaces extends AbstractVisitor
private $filter;

/**
* @param null | callable(\DOM\Attr): bool $filter
* @param null | callable(\DOM\Attr | \DOM\Element): bool $filter
*/
public function __construct(
?callable $filter = null
Expand Down Expand Up @@ -81,6 +81,7 @@ public function onNodeEnter(\DOM\Node $node): Action
return new Action\Noop();
}

/** @var \DOM\Element | \DOM\Attr $node */
return new Action\RenameNode($node->localName, null);
}

Expand Down
4 changes: 2 additions & 2 deletions src/Xml/Encoding/Internal/Decoder/Builder/element.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,15 @@ function element(\DOM\Element $element): array
$namespaces = namespaces($element);

if (!count($children) && !count($attributes) && !count($namespaces)) {
return [$name => $element->textContent];
return [$name => $element->textContent ?? ''];
}

return [
$name => filter(
merge(
$namespaces,
$attributes,
$children ?: ['@value' => $element->textContent]
$children ?: ['@value' => $element->textContent ?? '']
),
static fn (mixed $data): bool => $data !== []
)
Expand Down
2 changes: 1 addition & 1 deletion src/Xml/Encoding/Internal/Decoder/Builder/namespaces.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ function namespaces(\DOM\Element $element): array
static fn (array $namespaces, \DOM\Attr $node)
=> $node->value
? merge($namespaces, [
($node->prefix ? $node->localName : '') => $node->value
($node->prefix !== null ? $node->localName : '') => $node->value
])
: $namespaces,
[]
Expand Down
Loading

0 comments on commit d46ac5a

Please sign in to comment.