Update composer dependencies
authorTim Düsterhus <duesterhus@woltlab.com>
Thu, 9 Jun 2022 07:22:16 +0000 (09:22 +0200)
committerTim Düsterhus <duesterhus@woltlab.com>
Thu, 9 Jun 2022 07:22:16 +0000 (09:22 +0200)
14 files changed:
wcfsetup/install/files/lib/system/api/composer.lock
wcfsetup/install/files/lib/system/api/composer/installed.json
wcfsetup/install/files/lib/system/api/composer/installed.php
wcfsetup/install/files/lib/system/api/guzzlehttp/psr7/CHANGELOG.md
wcfsetup/install/files/lib/system/api/guzzlehttp/psr7/README.md
wcfsetup/install/files/lib/system/api/guzzlehttp/psr7/composer.json
wcfsetup/install/files/lib/system/api/guzzlehttp/psr7/src/Message.php
wcfsetup/install/files/lib/system/api/guzzlehttp/psr7/src/MessageTrait.php
wcfsetup/install/files/lib/system/api/guzzlehttp/psr7/src/MultipartStream.php
wcfsetup/install/files/lib/system/api/guzzlehttp/psr7/src/Stream.php
wcfsetup/install/files/lib/system/api/laminas/laminas-stdlib/README.md
wcfsetup/install/files/lib/system/api/laminas/laminas-stdlib/psalm-baseline.xml
wcfsetup/install/files/lib/system/api/laminas/laminas-stdlib/src/PriorityQueue.php
wcfsetup/install/files/lib/system/api/laminas/laminas-stdlib/src/SplPriorityQueue.php

index 64c226b10823656cb31999751ff720a14b26f73a..dc43262a35d3cad5c10cf5bfa26dc7755b472557 100644 (file)
         },
         {
             "name": "guzzlehttp/psr7",
-            "version": "2.2.1",
+            "version": "2.2.2",
             "source": {
                 "type": "git",
                 "url": "https://github.com/guzzle/psr7.git",
-                "reference": "c94a94f120803a18554c1805ef2e539f8285f9a2"
+                "reference": "a119247127ff95789a2d95c347cd74721fbedaa4"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/guzzle/psr7/zipball/c94a94f120803a18554c1805ef2e539f8285f9a2",
-                "reference": "c94a94f120803a18554c1805ef2e539f8285f9a2",
+                "url": "https://api.github.com/repos/guzzle/psr7/zipball/a119247127ff95789a2d95c347cd74721fbedaa4",
+                "reference": "a119247127ff95789a2d95c347cd74721fbedaa4",
                 "shasum": ""
             },
             "require": {
             ],
             "support": {
                 "issues": "https://github.com/guzzle/psr7/issues",
-                "source": "https://github.com/guzzle/psr7/tree/2.2.1"
+                "source": "https://github.com/guzzle/psr7/tree/2.2.2"
             },
             "funding": [
                 {
                     "type": "tidelift"
                 }
             ],
-            "time": "2022-03-20T21:55:58+00:00"
+            "time": "2022-06-08T19:55:23+00:00"
         },
         {
             "name": "laminas/laminas-diactoros",
         },
         {
             "name": "laminas/laminas-stdlib",
-            "version": "3.7.1",
+            "version": "3.9.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/laminas/laminas-stdlib.git",
-                "reference": "bcd869e2fe88d567800057c1434f2380354fe325"
+                "reference": "1df1cc0b9c2b8c7d1e322da1669a576386b5da46"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/laminas/laminas-stdlib/zipball/bcd869e2fe88d567800057c1434f2380354fe325",
-                "reference": "bcd869e2fe88d567800057c1434f2380354fe325",
+                "url": "https://api.github.com/repos/laminas/laminas-stdlib/zipball/1df1cc0b9c2b8c7d1e322da1669a576386b5da46",
+                "reference": "1df1cc0b9c2b8c7d1e322da1669a576386b5da46",
                 "shasum": ""
             },
             "require": {
                     "type": "community_bridge"
                 }
             ],
-            "time": "2022-01-21T15:50:46+00:00"
+            "time": "2022-06-08T11:33:13+00:00"
         },
         {
             "name": "paragonie/constant_time_encoding",
index 076fbe69dc2c06522ca001b435d5549941b95389..5649ed2a1f89aa3794542ffb394b5d338a165291 100644 (file)
         },
         {
             "name": "guzzlehttp/psr7",
-            "version": "2.2.1",
-            "version_normalized": "2.2.1.0",
+            "version": "2.2.2",
+            "version_normalized": "2.2.2.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/guzzle/psr7.git",
-                "reference": "c94a94f120803a18554c1805ef2e539f8285f9a2"
+                "reference": "a119247127ff95789a2d95c347cd74721fbedaa4"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/guzzle/psr7/zipball/c94a94f120803a18554c1805ef2e539f8285f9a2",
-                "reference": "c94a94f120803a18554c1805ef2e539f8285f9a2",
+                "url": "https://api.github.com/repos/guzzle/psr7/zipball/a119247127ff95789a2d95c347cd74721fbedaa4",
+                "reference": "a119247127ff95789a2d95c347cd74721fbedaa4",
                 "shasum": ""
             },
             "require": {
             "suggest": {
                 "laminas/laminas-httphandlerrunner": "Emit PSR-7 responses"
             },
-            "time": "2022-03-20T21:55:58+00:00",
+            "time": "2022-06-08T19:55:23+00:00",
             "type": "library",
             "extra": {
                 "branch-alias": {
             ],
             "support": {
                 "issues": "https://github.com/guzzle/psr7/issues",
-                "source": "https://github.com/guzzle/psr7/tree/2.2.1"
+                "source": "https://github.com/guzzle/psr7/tree/2.2.2"
             },
             "funding": [
                 {
         },
         {
             "name": "laminas/laminas-stdlib",
-            "version": "3.7.1",
-            "version_normalized": "3.7.1.0",
+            "version": "3.9.1",
+            "version_normalized": "3.9.1.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/laminas/laminas-stdlib.git",
-                "reference": "bcd869e2fe88d567800057c1434f2380354fe325"
+                "reference": "1df1cc0b9c2b8c7d1e322da1669a576386b5da46"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/laminas/laminas-stdlib/zipball/bcd869e2fe88d567800057c1434f2380354fe325",
-                "reference": "bcd869e2fe88d567800057c1434f2380354fe325",
+                "url": "https://api.github.com/repos/laminas/laminas-stdlib/zipball/1df1cc0b9c2b8c7d1e322da1669a576386b5da46",
+                "reference": "1df1cc0b9c2b8c7d1e322da1669a576386b5da46",
                 "shasum": ""
             },
             "require": {
                 "psalm/plugin-phpunit": "^0.16.0",
                 "vimeo/psalm": "^4.7"
             },
-            "time": "2022-01-21T15:50:46+00:00",
+            "time": "2022-06-08T11:33:13+00:00",
             "type": "library",
             "installation-source": "dist",
             "autoload": {
             "install-path": "../symfony/polyfill-php82"
         }
     ],
-    "dev": true,
+    "dev": false,
     "dev-package-names": []
 }
index a059612c3729edeb9726eaa4f4990156513a7cc3..cd3ac5becc4c9687a6ede8c04b93b65bd7a6cfac 100644 (file)
@@ -7,7 +7,7 @@
         'aliases' => array(),
         'reference' => NULL,
         'name' => '__root__',
-        'dev' => true,
+        'dev' => false,
     ),
     'versions' => array(
         '__root__' => array(
             'dev_requirement' => false,
         ),
         'guzzlehttp/psr7' => array(
-            'pretty_version' => '2.2.1',
-            'version' => '2.2.1.0',
+            'pretty_version' => '2.2.2',
+            'version' => '2.2.2.0',
             'type' => 'library',
             'install_path' => __DIR__ . '/../guzzlehttp/psr7',
             'aliases' => array(),
-            'reference' => 'c94a94f120803a18554c1805ef2e539f8285f9a2',
+            'reference' => 'a119247127ff95789a2d95c347cd74721fbedaa4',
             'dev_requirement' => false,
         ),
         'laminas/laminas-diactoros' => array(
             'dev_requirement' => false,
         ),
         'laminas/laminas-stdlib' => array(
-            'pretty_version' => '3.7.1',
-            'version' => '3.7.1.0',
+            'pretty_version' => '3.9.1',
+            'version' => '3.9.1.0',
             'type' => 'library',
             'install_path' => __DIR__ . '/../laminas/laminas-stdlib',
             'aliases' => array(),
-            'reference' => 'bcd869e2fe88d567800057c1434f2380354fe325',
+            'reference' => '1df1cc0b9c2b8c7d1e322da1669a576386b5da46',
             'dev_requirement' => false,
         ),
         'paragonie/constant_time_encoding' => array(
index 14637cbb31382830acda55144318a5232623eb74..e595f0ae3e441f19e5cb596b10b2bd17083e7217 100644 (file)
@@ -7,6 +7,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 
 ## Unreleased
 
+## 2.2.2 - 2022-06-08
+
+### Fixed
+
+- Fix `Message::parseRequestUri()` for numeric headers
+- Re-wrap exceptions thrown in `fread` into runtime exceptions
+- Throw an exception when multipart options is misformatted
+
 ## 2.2.1 - 2022-03-20
 
 ### Fixed
index ed81c927e30abf30de78a9d044087adc71beb271..671fc351783c726a6ece3611bae6b7570adce417 100644 (file)
@@ -807,6 +807,12 @@ Whether two URIs can be considered equivalent. Both URIs are normalized automati
 This of course assumes they will be resolved against the same base URI. If this is not the case, determination of
 equivalence or difference of relative references does not mean anything.
 
+## Version Guidance
+
+| Version | Status         | PHP Version      |
+|---------|----------------|------------------|
+| 1.x     | Security fixes | >= 5.4, < 8.2    |
+| 2.x     | Latest         | ^7.2.5 \|\| ^8.0 |
 
 ## Security
 
index 1aed3ed68cd45b6572da02d8388e5bd4e759004d..115de111568d28b39cd21d05fb02da8fcb7ac9ff 100644 (file)
@@ -87,9 +87,6 @@
             "bamarni/composer-bin-plugin": true
         },
         "preferred-install": "dist",
-        "sort-packages": true,
-        "allow-plugins": {
-            "bamarni/composer-bin-plugin": true
-        }
+        "sort-packages": true
     }
 }
index 9b825b3007f59406ccca48b156a9bbb452559aec..335a6dd38541d591f781090265ca79100b12a6ef 100644 (file)
@@ -175,6 +175,9 @@ final class Message
     public static function parseRequestUri(string $path, array $headers): string
     {
         $hostKey = array_filter(array_keys($headers), function ($k) {
+            // Numeric array keys are converted to int by PHP.
+            $k = (string) $k;
+
             return strtolower($k) === 'host';
         });
 
index a8696b98cb5655438cfab967af718847c49691b8..d2dc28b602ada1466d46c523ef2cf74df8467762 100644 (file)
@@ -145,11 +145,9 @@ trait MessageTrait
     {
         $this->headerNames = $this->headers = [];
         foreach ($headers as $header => $value) {
-            if (is_int($header)) {
-                // Numeric array keys are converted to int by PHP but having a header name '123' is not forbidden by the spec
-                // and also allowed in withHeader(). So we need to cast it to string again for the following assertion to pass.
-                $header = (string) $header;
-            }
+            // Numeric array keys are converted to int by PHP.
+            $header = (string) $header;
+
             $this->assertHeader($header);
             $value = $this->normalizeHeaderValue($value);
             $normalized = strtolower($header);
index c25172282396a43b1c7d0c34cf777c6b179174f1..24667075ca5c1704714aef8c2ffde5fa3279dc26 100644 (file)
@@ -68,6 +68,9 @@ final class MultipartStream implements StreamInterface
         $stream = new AppendStream();
 
         foreach ($elements as $element) {
+            if (!is_array($element)) {
+                throw new \UnexpectedValueException("An array is expected");
+            }
             $this->addElement($stream, $element);
         }
 
index d389427c67a69d1c3e7a84122bc27fc8c91959e2..5baecfaecc2e95e00b87946083131e1b8f5fbb76 100644 (file)
@@ -229,7 +229,12 @@ class Stream implements StreamInterface
             return '';
         }
 
-        $string = fread($this->stream, $length);
+        try {
+            $string = fread($this->stream, $length);
+        } catch (\Exception $e) {
+            throw new \RuntimeException('Unable to read from stream', 0, $e);
+        }
+
         if (false === $string) {
             throw new \RuntimeException('Unable to read from stream');
         }
index 2dab9afd58b732d7d657c7cca5bdfdd0d7d987ae..764f96573132d6c99d9d52951287ab72b817010b 100644 (file)
@@ -3,6 +3,22 @@
 [![Build Status](https://github.com/laminas/laminas-stdlib/actions/workflows/continuous-integration.yml/badge.svg)](https://github.com/laminas/laminas-stdlib/actions/workflows/continuous-integration.yml)
 [![Coverage Status](https://coveralls.io/repos/github/laminas/laminas-stdlib/badge.svg?branch=master)](https://coveralls.io/github/laminas/laminas-stdlib?branch=master)
 
+> ## 🇷🇺 Русским гражданам
+>
+> Мы, участники Laminas, родились и живем в разных странах. У многих из нас есть друзья, родственники и коллеги как в России, так и в Украине. Некоторые из нас родились в России. Некоторые из нас живут в России. У некоторых бабушки и дедушки сражались с фашистами во Второй мировой войне. Здесь никто не поддерживает фашизм.
+>
+> У одного из нас есть украинская родственница, которая спаслась из дома вместе с сыном. Поезд задержался из-за бомбежки на дороге впереди. У нас есть друзья, которые прячутся в бомбоубежищах. Мы с тревогой ждем весточки от них после воздушных налетов, которые беспорядочно наносят удары и попадают по больницам, школам, детским садам и домам. Мы не берем это из каких-либо СМИ. Мы наблюдаем это напрямую.
+>
+> Вы доверяете нам достаточно, чтоб использовать наши программы, и мы просим вас довериться нам вновь. Мы нуждаемся в помощи. Выходите и протестуйте против этой бесполезной войны. Остановите кровопролитие. Скажите "Нет войне!"
+>
+> ## 🇺🇸 To Citizens of Russia
+>
+> We at Laminas come from all over the world. Many of us have friends, family and colleagues in both Russia and Ukraine. Some of us were born in Russia. Some of us currently live in Russia. Some have grandparents who fought Nazis in World War II. Nobody here supports fascism.
+>
+> One team member has a Ukrainian relative who fled her home with her son. The train was delayed due to bombing on the road ahead. We have friends who are hiding in bomb shelters. We anxiously follow up on them after the air raids, which indiscriminately fire at hospitals, schools, kindergartens and houses. We're not taking this from any media. These are our actual experiences.
+>
+> You trust us enough to use our software. We ask that you trust us to say the truth on this. We need your help. Go out and protest this unnecessary war. Stop the bloodshed. Say "stop the war!"
+
 `Laminas\Stdlib` is a set of components that implements general purpose utility
 class for different scopes like:
 
index 69bfc462ebdff7f011754d1fc7ae493b8d70228a..aaf4bc7c72c675e2f05d5db1e6acb6efedca7d18 100644 (file)
       <code>(int) $priority</code>
     </RedundantCastGivenDocblockType>
   </file>
-  <file src="src/PriorityQueue.php">
-    <DocblockTypeContradiction occurrences="1">
-      <code>null === $this-&gt;queue</code>
-    </DocblockTypeContradiction>
-    <InvalidStringClass occurrences="1">
-      <code>new $this-&gt;queueClass()</code>
-    </InvalidStringClass>
-    <LessSpecificReturnStatement occurrences="1">
-      <code>$this-&gt;queue</code>
-    </LessSpecificReturnStatement>
-    <MissingClosureReturnType occurrences="2">
-      <code>function ($item) {</code>
-      <code>function ($item) {</code>
-    </MissingClosureReturnType>
-    <MissingConstructor occurrences="1">
-      <code>$queue</code>
-    </MissingConstructor>
-    <MixedArgument occurrences="1">
-      <code>$item['priority']</code>
-    </MixedArgument>
-    <MixedArrayAccess occurrences="13">
-      <code>$item['data']</code>
-      <code>$item['data']</code>
-      <code>$item['data']</code>
-      <code>$item['data']</code>
-      <code>$item['data']</code>
-      <code>$item['data']</code>
-      <code>$item['priority']</code>
-      <code>$item['priority']</code>
-      <code>$item['priority']</code>
-      <code>$item['priority']</code>
-      <code>$item['priority']</code>
-      <code>$item['priority']</code>
-      <code>$item['priority']</code>
-    </MixedArrayAccess>
-    <MixedArrayOffset occurrences="1">
-      <code>$this-&gt;items[$key]</code>
-    </MixedArrayOffset>
-    <MixedAssignment occurrences="9">
-      <code>$highestPriority</code>
-      <code>$highestPriority</code>
-      <code>$item</code>
-      <code>$item</code>
-      <code>$item</code>
-      <code>$item</code>
-      <code>$item</code>
-      <code>$item</code>
-      <code>$value</code>
-    </MixedAssignment>
-    <MoreSpecificReturnType occurrences="1">
-      <code>SplPriorityQueue</code>
-    </MoreSpecificReturnType>
-    <PossiblyNullPropertyAssignmentValue occurrences="1">
-      <code>null</code>
-    </PossiblyNullPropertyAssignmentValue>
-    <PossiblyUndefinedVariable occurrences="1">
-      <code>$key</code>
-    </PossiblyUndefinedVariable>
-    <PropertyTypeCoercion occurrences="1">
-      <code>new $this-&gt;queueClass()</code>
-    </PropertyTypeCoercion>
-    <RedundantCastGivenDocblockType occurrences="2">
-      <code>(int) $priority</code>
-      <code>(string) $class</code>
-    </RedundantCastGivenDocblockType>
-    <RedundantConditionGivenDocblockType occurrences="1">
-      <code>null !== $this-&gt;queue</code>
-    </RedundantConditionGivenDocblockType>
-  </file>
   <file src="src/SplPriorityQueue.php">
     <ImplementedReturnTypeMismatch occurrences="1">
       <code>void</code>
     <MethodSignatureMismatch occurrences="1">
       <code>public function insert($datum, $priority)</code>
     </MethodSignatureMismatch>
-    <MixedAssignment occurrences="4">
-      <code>$array[]</code>
-      <code>$data[]</code>
-      <code>$item</code>
-      <code>$item</code>
-    </MixedAssignment>
   </file>
   <file src="src/StringUtils.php">
     <DocblockTypeContradiction occurrences="1">
index 431ab1508a106d5f4051eb1b293d5d6b208e7b9f..bdf01ab60b79ad014bc69d326539665aec7d3337 100644 (file)
@@ -29,6 +29,10 @@ use function unserialize;
  * This class aggregates items for the queue itself, but also composes an
  * "inner" iterator in the form of an SplPriorityQueue object for performing
  * the actual iteration.
+ *
+ * @template T
+ * @template TPriority of int
+ * @implements IteratorAggregate<array-key, T>
  */
 class PriorityQueue implements Countable, IteratorAggregate, Serializable
 {
@@ -39,7 +43,7 @@ class PriorityQueue implements Countable, IteratorAggregate, Serializable
     /**
      * Inner queue class to use for iteration
      *
-     * @var string
+     * @var class-string<\SplPriorityQueue>
      */
     protected $queueClass = SplPriorityQueue::class;
 
@@ -47,14 +51,14 @@ class PriorityQueue implements Countable, IteratorAggregate, Serializable
      * Actual items aggregated in the priority queue. Each item is an array
      * with keys "data" and "priority".
      *
-     * @var array
+     * @var list<array{data: T, priority: TPriority}>
      */
     protected $items = [];
 
     /**
      * Inner queue object
      *
-     * @var SplPriorityQueue
+     * @var \SplPriorityQueue<TPriority, T>|null
      */
     protected $queue;
 
@@ -63,12 +67,13 @@ class PriorityQueue implements Countable, IteratorAggregate, Serializable
      *
      * Priority defaults to 1 (low priority) if none provided.
      *
-     * @param  mixed $data
-     * @param  int $priority
-     * @return PriorityQueue
+     * @param  T         $data
+     * @param  TPriority $priority
+     * @return $this
      */
     public function insert($data, $priority = 1)
     {
+        /** @psalm-var TPriority $priority */
         $priority      = (int) $priority;
         $this->items[] = [
             'data'     => $data,
@@ -97,13 +102,14 @@ class PriorityQueue implements Countable, IteratorAggregate, Serializable
     public function remove($datum)
     {
         $found = false;
+        $key   = null;
         foreach ($this->items as $key => $item) {
             if ($item['data'] === $datum) {
                 $found = true;
                 break;
             }
         }
-        if ($found) {
+        if ($found && $key !== null) {
             unset($this->items[$key]);
             $this->queue = null;
 
@@ -142,17 +148,19 @@ class PriorityQueue implements Countable, IteratorAggregate, Serializable
     /**
      * Peek at the top node in the queue, based on priority.
      *
-     * @return mixed
+     * @return T
      */
     public function top()
     {
-        return $this->getIterator()->top();
+        $queue = clone $this->getQueue();
+
+        return $queue->top();
     }
 
     /**
      * Extract a node from the inner queue and sift up
      *
-     * @return mixed
+     * @return T
      */
     public function extract()
     {
@@ -196,7 +204,7 @@ class PriorityQueue implements Countable, IteratorAggregate, Serializable
      * retrieves the inner queue object, and clones it for purposes of
      * iteration.
      *
-     * @return SplPriorityQueue
+     * @return \SplPriorityQueue<TPriority, T>
      */
     #[ReturnTypeWillChange]
     public function getIterator()
@@ -218,7 +226,7 @@ class PriorityQueue implements Countable, IteratorAggregate, Serializable
     /**
      * Magic method used for serializing of an instance.
      *
-     * @return array
+     * @return list<array{data: T, priority: TPriority}>
      */
     public function __serialize()
     {
@@ -228,7 +236,7 @@ class PriorityQueue implements Countable, IteratorAggregate, Serializable
     /**
      * Unserialize a string into a PriorityQueue object
      *
-     * Serialization format is compatible with {@link Laminas\Stdlib\SplPriorityQueue}
+     * Serialization format is compatible with {@link SplPriorityQueue}
      *
      * @param  string $data
      * @return void
@@ -243,13 +251,15 @@ class PriorityQueue implements Countable, IteratorAggregate, Serializable
             ));
         }
 
+        /** @psalm-var list<array{data: T, priority: TPriority}> $toUnserialize */
+
         $this->__unserialize($toUnserialize);
     }
 
    /**
     * Magic method used to rebuild an instance.
     *
-    * @param array $data Data array.
+    * @param list<array{data: T, priority: TPriority}> $data Data array.
     * @return void
     */
     public function __unserialize($data)
@@ -261,13 +271,18 @@ class PriorityQueue implements Countable, IteratorAggregate, Serializable
 
     /**
      * Serialize to an array
-     *
      * By default, returns only the item data, and in the order registered (not
      * sorted). You may provide one of the EXTR_* flags as an argument, allowing
      * the ability to return priorities or both data and priority.
      *
      * @param  int $flag
-     * @return array
+     * @return array<array-key, mixed>
+     * @psalm-return ($flag is self::EXTR_BOTH
+     *                      ? list<array{data: T, priority: TPriority}>
+     *                      : $flag is self::EXTR_PRIORITY
+     *                          ? list<TPriority>
+     *                          : list<T>
+     *               )
      */
     public function toArray($flag = self::EXTR_DATA)
     {
@@ -292,11 +307,12 @@ class PriorityQueue implements Countable, IteratorAggregate, Serializable
      * Please see {@link getIterator()} for details on the necessity of an
      * internal queue class. The class provided should extend SplPriorityQueue.
      *
-     * @param  string $class
-     * @return PriorityQueue
+     * @param  class-string<\SplPriorityQueue> $class
+     * @return $this
      */
     public function setInternalQueueClass($class)
     {
+        /** @psalm-suppress RedundantCastGivenDocblockType */
         $this->queueClass = (string) $class;
         return $this;
     }
@@ -304,7 +320,7 @@ class PriorityQueue implements Countable, IteratorAggregate, Serializable
     /**
      * Does the queue contain the given datum?
      *
-     * @param  mixed $datum
+     * @param  T $datum
      * @return bool
      */
     public function contains($datum)
@@ -320,7 +336,7 @@ class PriorityQueue implements Countable, IteratorAggregate, Serializable
     /**
      * Does the queue have an item with the given priority?
      *
-     * @param  int $priority
+     * @param  TPriority $priority
      * @return bool
      */
     public function hasPriority($priority)
@@ -337,12 +353,17 @@ class PriorityQueue implements Countable, IteratorAggregate, Serializable
      * Get the inner priority queue instance
      *
      * @throws Exception\DomainException
-     * @return SplPriorityQueue
+     * @return \SplPriorityQueue<TPriority, T>
+     * @psalm-assert !null $this->queue
      */
     protected function getQueue()
     {
         if (null === $this->queue) {
-            $this->queue = new $this->queueClass();
+            /** @psalm-suppress UnsafeInstantiation */
+            $queue = new $this->queueClass();
+            /** @psalm-var \SplPriorityQueue<TPriority, T> $queue */
+            $this->queue = $queue;
+            /** @psalm-suppress DocblockTypeContradiction, MixedArgument */
             if (! $this->queue instanceof \SplPriorityQueue) {
                 throw new Exception\DomainException(sprintf(
                     'PriorityQueue expects an internal queue of type SplPriorityQueue; received "%s"',
@@ -350,6 +371,7 @@ class PriorityQueue implements Countable, IteratorAggregate, Serializable
                 ));
             }
         }
+
         return $this->queue;
     }
 
index 770d9b2b5b0b351776196f74645e2ac195874245..e55a0e9fd45ab2c857a4bf76ce08e844fc5bc546 100644 (file)
@@ -23,6 +23,11 @@ use const PHP_INT_MAX;
  *
  * Also, provides predictable heap order for datums added with the same priority
  * (i.e., they will be emitted in the same order they are enqueued).
+ *
+ * @psalm-type InternalPriority = array{0: mixed, 1: int}
+ * @template TValue
+ * @template TPriority of InternalPriority
+ * @extends \SplPriorityQueue<TPriority, TValue>
  */
 class SplPriorityQueue extends \SplPriorityQueue implements Serializable
 {
@@ -35,8 +40,8 @@ class SplPriorityQueue extends \SplPriorityQueue implements Serializable
      * Utilizes {@var $serial} to ensure that values of equal priority are
      * emitted in the same order in which they are inserted.
      *
-     * @param  mixed $datum
-     * @param  mixed $priority
+     * @param  TValue          $datum
+     * @param  TPriority|mixed $priority
      * @return void
      */
     public function insert($datum, $priority)
@@ -44,6 +49,9 @@ class SplPriorityQueue extends \SplPriorityQueue implements Serializable
         if (! is_array($priority)) {
             $priority = [$priority, $this->serial--];
         }
+
+        /** @psalm-var TPriority $priority */
+
         parent::insert($datum, $priority);
     }
 
@@ -52,7 +60,7 @@ class SplPriorityQueue extends \SplPriorityQueue implements Serializable
      *
      * Array will be priority => data pairs
      *
-     * @return array
+     * @return list<TValue>
      */
     public function toArray()
     {
@@ -140,6 +148,8 @@ class SplPriorityQueue extends \SplPriorityQueue implements Serializable
                 $priority = (int) $item['priority'];
             }
 
+            /** @psalm-var TValue $item['data'] */
+
             $this->insert($item['data'], $priority);
         }
     }