Browse Source

Add typehints to Collection classes.

Mark Story 7 years ago
parent
commit
a0c8826daf

+ 2 - 2
src/Collection/Collection.php

@@ -76,7 +76,7 @@ class Collection extends IteratorIterator implements CollectionInterface, Serial
      *
      * @return int
      */
-    public function count()
+    public function count(): int
     {
         $traversable = $this->optimizeUnwrap();
 
@@ -92,7 +92,7 @@ class Collection extends IteratorIterator implements CollectionInterface, Serial
      *
      * @return int
      */
-    public function countKeys()
+    public function countKeys(): int
     {
         return count($this->toArray());
     }

+ 96 - 38
src/Collection/CollectionInterface.php

@@ -16,6 +16,7 @@ namespace Cake\Collection;
 
 use Iterator;
 use JsonSerializable;
+use Traversable;
 
 /**
  * Describes the methods a Collection should implement. A collection is an immutable
@@ -42,7 +43,7 @@ interface CollectionInterface extends Iterator, JsonSerializable
      * in this collection
      * @return \Cake\Collection\CollectionInterface
      */
-    public function each(callable $c);
+    public function each(callable $c): CollectionInterface;
 
     /**
      * Looks through each value in the collection, and returns another collection with
@@ -69,7 +70,7 @@ interface CollectionInterface extends Iterator, JsonSerializable
      *   If left null, a callback that filters out falsey values will be used.
      * @return \Cake\Collection\CollectionInterface
      */
-    public function filter(callable $c = null);
+    public function filter(callable $c = null): CollectionInterface;
 
     /**
      * Looks through each value in the collection, and returns another collection with
@@ -94,7 +95,7 @@ interface CollectionInterface extends Iterator, JsonSerializable
      * returns true whether or not they should be out of the resulting collection.
      * @return \Cake\Collection\CollectionInterface
      */
-    public function reject(callable $c);
+    public function reject(callable $c): CollectionInterface;
 
     /**
      * Returns true if all values in this collection pass the truth test provided
@@ -118,7 +119,7 @@ interface CollectionInterface extends Iterator, JsonSerializable
      * @return bool true if for all elements in this collection the provided
      *   callback returns true, false otherwise.
      */
-    public function every(callable $c);
+    public function every(callable $c): bool;
 
     /**
      * Returns true if any of the values in this collection pass the truth test
@@ -140,7 +141,7 @@ interface CollectionInterface extends Iterator, JsonSerializable
      * @return bool true if the provided callback returns true for any element in this
      * collection, false otherwise
      */
-    public function some(callable $c);
+    public function some(callable $c): bool;
 
     /**
      * Returns true if $value is present in this collection. Comparisons are made
@@ -149,7 +150,7 @@ interface CollectionInterface extends Iterator, JsonSerializable
      * @param mixed $value The value to check for
      * @return bool true if $value is present in this collection
      */
-    public function contains($value);
+    public function contains($value): bool;
 
     /**
      * Returns another collection after modifying each of the values in this one using
@@ -173,7 +174,7 @@ interface CollectionInterface extends Iterator, JsonSerializable
      * returns the new value for the key that is being iterated
      * @return \Cake\Collection\CollectionInterface
      */
-    public function map(callable $c);
+    public function map(callable $c): CollectionInterface;
 
     /**
      * Folds the values in this collection to a single value, as the result of
@@ -231,7 +232,7 @@ interface CollectionInterface extends Iterator, JsonSerializable
      * inside the hierarchy of each value so that the column can be extracted.
      * @return \Cake\Collection\CollectionInterface
      */
-    public function extract($matcher);
+    public function extract($matcher): CollectionInterface;
 
     /**
      * Returns the top element in this collection after being sorted by a property.
@@ -378,7 +379,7 @@ interface CollectionInterface extends Iterator, JsonSerializable
      * SORT_NUMERIC or SORT_NATURAL
      * @return \Cake\Collection\CollectionInterface
      */
-    public function sortBy($callback, $dir = SORT_DESC, $type = \SORT_NUMERIC);
+    public function sortBy($callback, $dir = SORT_DESC, $type = \SORT_NUMERIC): CollectionInterface;
 
     /**
      * Splits a collection into sets, grouped by the result of running each value
@@ -421,7 +422,7 @@ interface CollectionInterface extends Iterator, JsonSerializable
      * or a function returning the grouping key out of the provided element
      * @return \Cake\Collection\CollectionInterface
      */
-    public function groupBy($callback);
+    public function groupBy($callback): CollectionInterface;
 
     /**
      * Given a list and a callback function that returns a key for each element
@@ -460,7 +461,7 @@ interface CollectionInterface extends Iterator, JsonSerializable
      * or a function returning the indexing key out of the provided element
      * @return \Cake\Collection\CollectionInterface
      */
-    public function indexBy($callback);
+    public function indexBy($callback): CollectionInterface;
 
     /**
      * Sorts a list into groups and returns a count for the number of elements
@@ -498,7 +499,7 @@ interface CollectionInterface extends Iterator, JsonSerializable
      * or a function returning the indexing key out of the provided element
      * @return \Cake\Collection\CollectionInterface
      */
-    public function countBy($callback);
+    public function countBy($callback): CollectionInterface;
 
     /**
      * Returns the total sum of all the values extracted with $matcher
@@ -533,7 +534,7 @@ interface CollectionInterface extends Iterator, JsonSerializable
      *
      * @return \Cake\Collection\CollectionInterface
      */
-    public function shuffle();
+    public function shuffle(): CollectionInterface;
 
     /**
      * Returns a new collection with maximum $size random elements
@@ -543,7 +544,7 @@ interface CollectionInterface extends Iterator, JsonSerializable
      * take from this collection
      * @return \Cake\Collection\CollectionInterface
      */
-    public function sample($size = 10);
+    public function sample($size = 10): CollectionInterface;
 
     /**
      * Returns a new collection with maximum $size elements in the internal
@@ -555,7 +556,7 @@ interface CollectionInterface extends Iterator, JsonSerializable
      * @param int $from A positional offset from where to take the elements
      * @return \Cake\Collection\CollectionInterface
      */
-    public function take($size = 1, $from = 0);
+    public function take($size = 1, $from = 0): CollectionInterface;
 
     /**
      * Returns a new collection that will skip the specified amount of elements
@@ -564,7 +565,7 @@ interface CollectionInterface extends Iterator, JsonSerializable
      * @param int $howMany The number of elements to skip.
      * @return \Cake\Collection\CollectionInterface
      */
-    public function skip($howMany);
+    public function skip($howMany): CollectionInterface;
 
     /**
      * Looks through each value in the list, returning a Collection of all the
@@ -591,7 +592,7 @@ interface CollectionInterface extends Iterator, JsonSerializable
      * and the value the condition against with each element will be matched
      * @return \Cake\Collection\CollectionInterface
      */
-    public function match(array $conditions);
+    public function match(array $conditions): CollectionInterface;
 
     /**
      * Returns the first result matching all of the key-value pairs listed in
@@ -626,7 +627,33 @@ interface CollectionInterface extends Iterator, JsonSerializable
      * @param array|\Traversable $items Items list.
      * @return \Cake\Collection\CollectionInterface
      */
-    public function append($items);
+    public function append($items): CollectionInterface;
+
+    /**
+     * Append a single item creating a new collection.
+     *
+     * @param mixed $item The item to append.
+     * @param mixed $key The key to append the item with. If null a key will be generated.
+     * @return \Cake\Collection\CollectionInterface
+     */
+    public function appendItem($item, $key = null): CollectionInterface;
+
+    /**
+     * Prepend a set of items to a collection creating a new collection
+     *
+     * @param mixed $items The items to prepend.
+     * @return \Cake\Collection\CollectionInterface
+     */
+    public function prepend($items): CollectionInterface;
+
+    /**
+     * Prepend a single item creating a new collection.
+     *
+     * @param mixed $item The item to prepend.
+     * @param mixed $key The key to prepend the item with. If null a key will be generated.
+     * @return \Cake\Collection\CollectionInterface
+     */
+    public function prependItem($item, $key = null): CollectionInterface;
 
     /**
      * Returns a new collection where the values extracted based on a value path
@@ -668,7 +695,7 @@ interface CollectionInterface extends Iterator, JsonSerializable
      * grouping key or a function returning the key out of the provided element
      * @return \Cake\Collection\CollectionInterface
      */
-    public function combine($keyPath, $valuePath, $groupPath = null);
+    public function combine($keyPath, $valuePath, $groupPath = null): CollectionInterface;
 
     /**
      * Returns a new collection where the values are nested in a tree-like structure
@@ -681,7 +708,7 @@ interface CollectionInterface extends Iterator, JsonSerializable
      * @param string $nestingKey The key name under which children are nested
      * @return \Cake\Collection\CollectionInterface
      */
-    public function nest($idPath, $parentPath, $nestingKey = 'children');
+    public function nest($idPath, $parentPath, $nestingKey = 'children'): CollectionInterface;
 
     /**
      * Returns a new collection containing each of the elements found in `$values` as
@@ -719,7 +746,7 @@ interface CollectionInterface extends Iterator, JsonSerializable
      * values are matched with the elements in this collection by its positional index.
      * @return \Cake\Collection\CollectionInterface
      */
-    public function insert($path, $values);
+    public function insert($path, $values): CollectionInterface;
 
     /**
      * Returns an array representation of the results
@@ -730,7 +757,7 @@ interface CollectionInterface extends Iterator, JsonSerializable
      * can help getting all items if keys are not important in the result.
      * @return array
      */
-    public function toArray($preserveKeys = true);
+    public function toArray($preserveKeys = true): array;
 
     /**
      * Returns an numerically-indexed array representation of the results.
@@ -738,7 +765,7 @@ interface CollectionInterface extends Iterator, JsonSerializable
      *
      * @return array
      */
-    public function toList();
+    public function toList(): array;
 
     /**
      * Convert a result set into JSON.
@@ -781,7 +808,7 @@ interface CollectionInterface extends Iterator, JsonSerializable
      * can help getting all items if keys are not important in the result.
      * @return \Cake\Collection\CollectionInterface
      */
-    public function compile($preserveKeys = true);
+    public function compile($preserveKeys = true): CollectionInterface;
 
     /**
      * Returns a new collection where the operations performed by this collection.
@@ -792,7 +819,7 @@ interface CollectionInterface extends Iterator, JsonSerializable
      *
      * @return \Cake\Collection\CollectionInterface
      */
-    public function buffered();
+    public function buffered(): CollectionInterface;
 
     /**
      * Returns a new collection with each of the elements of this collection
@@ -833,7 +860,7 @@ interface CollectionInterface extends Iterator, JsonSerializable
      * or a callable function that will return the children list
      * @return \Cake\Collection\CollectionInterface
      */
-    public function listNested($dir = 'desc', $nestingKey = 'children');
+    public function listNested($dir = 'desc', $nestingKey = 'children'): CollectionInterface;
 
     /**
      * Creates a new collection that when iterated will stop yielding results if
@@ -868,7 +895,7 @@ interface CollectionInterface extends Iterator, JsonSerializable
      * and the value the condition against with each element will be matched.
      * @return \Cake\Collection\CollectionInterface
      */
-    public function stopWhen($condition);
+    public function stopWhen($condition): CollectionInterface;
 
     /**
      * Creates a new collection where the items are the
@@ -903,7 +930,7 @@ interface CollectionInterface extends Iterator, JsonSerializable
      * the items in the collection and should return an array or Traversable object
      * @return \Cake\Collection\CollectionInterface
      */
-    public function unfold(callable $transformer = null);
+    public function unfold(callable $transformer = null): CollectionInterface;
 
     /**
      * Passes this collection through a callable as its first argument.
@@ -922,7 +949,7 @@ interface CollectionInterface extends Iterator, JsonSerializable
      * this collection as first argument.
      * @return \Cake\Collection\CollectionInterface
      */
-    public function through(callable $handler);
+    public function through(callable $handler): CollectionInterface;
 
     /**
      * Combines the elements of this collection with each of the elements of the
@@ -938,7 +965,7 @@ interface CollectionInterface extends Iterator, JsonSerializable
      * @param array|\Traversable ...$items The collections to zip.
      * @return \Cake\Collection\CollectionInterface
      */
-    public function zip($items);
+    public function zip($items): CollectionInterface;
 
     /**
      * Combines the elements of this collection with each of the elements of the
@@ -960,7 +987,7 @@ interface CollectionInterface extends Iterator, JsonSerializable
      * @param callable $callable The function to use for zipping the elements together.
      * @return \Cake\Collection\CollectionInterface
      */
-    public function zipWith($items, $callable);
+    public function zipWith($items, $callable): CollectionInterface;
 
     /**
      * Breaks the collection into smaller arrays of the given size.
@@ -976,7 +1003,7 @@ interface CollectionInterface extends Iterator, JsonSerializable
      * @param int $chunkSize The maximum size for each chunk
      * @return \Cake\Collection\CollectionInterface
      */
-    public function chunk($chunkSize);
+    public function chunk($chunkSize): CollectionInterface;
 
     /**
      * Breaks the collection into smaller arrays of the given size.
@@ -993,7 +1020,7 @@ interface CollectionInterface extends Iterator, JsonSerializable
      * @param bool $preserveKeys If the keys of the array should be preserved
      * @return \Cake\Collection\CollectionInterface
      */
-    public function chunkWithKeys($chunkSize, $preserveKeys = true);
+    public function chunkWithKeys($chunkSize, $preserveKeys = true): CollectionInterface;
 
     /**
      * Returns whether or not there are elements in this collection
@@ -1011,7 +1038,7 @@ interface CollectionInterface extends Iterator, JsonSerializable
      *
      * @return bool
      */
-    public function isEmpty();
+    public function isEmpty(): bool;
 
     /**
      * Returns the closest nested iterator that can be safely traversed without
@@ -1020,7 +1047,7 @@ interface CollectionInterface extends Iterator, JsonSerializable
      *
      * @return \Traversable
      */
-    public function unwrap();
+    public function unwrap(): Traversable;
 
     /**
      * Transpose rows and columns into columns and rows
@@ -1048,7 +1075,7 @@ interface CollectionInterface extends Iterator, JsonSerializable
      *
      * @return \Cake\Collection\CollectionInterface
      */
-    public function transpose();
+    public function transpose(): CollectionInterface;
 
     /**
      * Returns the amount of elements in the collection.
@@ -1085,7 +1112,7 @@ interface CollectionInterface extends Iterator, JsonSerializable
      *
      * @return int
      */
-    public function count();
+    public function count(): int;
 
     /**
      * Returns the number of unique keys in this iterator. This is, the number of
@@ -1097,5 +1124,36 @@ interface CollectionInterface extends Iterator, JsonSerializable
      * @see \Cake\Collection\CollectionInterface::count()
      * @return int
      */
-    public function countKeys();
+    public function countKeys(): int;
+
+    /**
+     * Create a new collection that is the cartesian product of the current collection
+     *
+     * In order to create a carteisan product a collection must contain a single dimension
+     * of data.
+     *
+     * ### Example
+     *
+     * ```
+     * $collection = new Collection([['A', 'B', 'C'], [1, 2, 3]]);
+     * $result = $collection->cartesianProduct()->toArray();
+     * $expected = [
+     *     ['A', 1],
+     *     ['A', 2],
+     *     ['A', 3],
+     *     ['B', 1],
+     *     ['B', 2],
+     *     ['B', 3],
+     *     ['C', 1],
+     *     ['C', 2],
+     *     ['C', 3],
+     * ];
+     * ```
+     *
+     * @param callable|null $operation A callable that allows you to customize the product result.
+     * @param callable|null $filter A filtering callback that must return true for a result to be part
+     *   of the final results.
+     * @return \Cake\Collection\CollectionInterface
+     */
+    public function cartesianProduct(callable $operation = null, callable $filter = null): CollectionInterface;
 }

+ 50 - 49
src/Collection/CollectionTrait.php

@@ -16,6 +16,7 @@ namespace Cake\Collection;
 
 use AppendIterator;
 use ArrayIterator;
+use Cake\Collection\CollectionInterface;
 use Cake\Collection\Iterator\BufferedIterator;
 use Cake\Collection\Iterator\ExtractIterator;
 use Cake\Collection\Iterator\FilterIterator;
@@ -45,7 +46,7 @@ trait CollectionTrait
     /**
      * {@inheritDoc}
      */
-    public function each(callable $c)
+    public function each(callable $c): CollectionInterface
     {
         foreach ($this->optimizeUnwrap() as $k => $v) {
             $c($v, $k);
@@ -57,9 +58,9 @@ trait CollectionTrait
     /**
      * {@inheritDoc}
      *
-     * @return \Cake\Collection\Iterator\FilterIterator
+     * @return \Cake\Collection\CollectionInterface
      */
-    public function filter(callable $c = null)
+    public function filter(callable $c = null): CollectionInterface
     {
         if ($c === null) {
             $c = function ($v) {
@@ -73,9 +74,9 @@ trait CollectionTrait
     /**
      * {@inheritDoc}
      *
-     * @return \Cake\Collection\Iterator\FilterIterator
+     * @return \Cake\Collection\CollectionInterface
      */
-    public function reject(callable $c)
+    public function reject(callable $c): CollectionInterface
     {
         return new FilterIterator($this->unwrap(), function ($key, $value, $items) use ($c) {
             return !$c($key, $value, $items);
@@ -85,7 +86,7 @@ trait CollectionTrait
     /**
      * {@inheritDoc}
      */
-    public function every(callable $c)
+    public function every(callable $c): bool
     {
         foreach ($this->optimizeUnwrap() as $key => $value) {
             if (!$c($value, $key)) {
@@ -99,7 +100,7 @@ trait CollectionTrait
     /**
      * {@inheritDoc}
      */
-    public function some(callable $c)
+    public function some(callable $c): bool
     {
         foreach ($this->optimizeUnwrap() as $key => $value) {
             if ($c($value, $key) === true) {
@@ -113,7 +114,7 @@ trait CollectionTrait
     /**
      * {@inheritDoc}
      */
-    public function contains($value)
+    public function contains($value): bool
     {
         foreach ($this->optimizeUnwrap() as $v) {
             if ($value === $v) {
@@ -127,9 +128,9 @@ trait CollectionTrait
     /**
      * {@inheritDoc}
      *
-     * @return \Cake\Collection\Iterator\ReplaceIterator
+     * @return \Cake\Collection\CollectionInterface
      */
-    public function map(callable $c)
+    public function map(callable $c): CollectionInterface
     {
         return new ReplaceIterator($this->unwrap(), $c);
     }
@@ -160,7 +161,7 @@ trait CollectionTrait
     /**
      * {@inheritDoc}
      */
-    public function extract($matcher)
+    public function extract($matcher): CollectionInterface
     {
         $extractor = new ExtractIterator($this->unwrap(), $matcher);
         if (is_string($matcher) && strpos($matcher, '{*}') !== false) {
@@ -242,7 +243,7 @@ trait CollectionTrait
     /**
      * {@inheritDoc}
      */
-    public function sortBy($callback, $dir = \SORT_DESC, $type = \SORT_NUMERIC)
+    public function sortBy($callback, $dir = \SORT_DESC, $type = \SORT_NUMERIC): CollectionInterface
     {
         return new SortIterator($this->unwrap(), $callback, $dir, $type);
     }
@@ -250,7 +251,7 @@ trait CollectionTrait
     /**
      * {@inheritDoc}
      */
-    public function groupBy($callback)
+    public function groupBy($callback): CollectionInterface
     {
         $callback = $this->_propertyExtractor($callback);
         $group = [];
@@ -264,7 +265,7 @@ trait CollectionTrait
     /**
      * {@inheritDoc}
      */
-    public function indexBy($callback)
+    public function indexBy($callback): CollectionInterface
     {
         $callback = $this->_propertyExtractor($callback);
         $group = [];
@@ -278,7 +279,7 @@ trait CollectionTrait
     /**
      * {@inheritDoc}
      */
-    public function countBy($callback)
+    public function countBy($callback): CollectionInterface
     {
         $callback = $this->_propertyExtractor($callback);
 
@@ -296,7 +297,7 @@ trait CollectionTrait
     /**
      * {@inheritDoc}
      */
-    public function sumOf($matcher = null)
+    public function sumOf($matcher = null): int
     {
         if ($matcher === null) {
             return array_sum($this->toList());
@@ -314,7 +315,7 @@ trait CollectionTrait
     /**
      * {@inheritDoc}
      */
-    public function shuffle()
+    public function shuffle(): CollectionInterface
     {
         $elements = $this->toArray();
         shuffle($elements);
@@ -325,7 +326,7 @@ trait CollectionTrait
     /**
      * {@inheritDoc}
      */
-    public function sample($size = 10)
+    public function sample($size = 10): CollectionInterface
     {
         return new Collection(new LimitIterator($this->shuffle(), 0, $size));
     }
@@ -333,7 +334,7 @@ trait CollectionTrait
     /**
      * {@inheritDoc}
      */
-    public function take($size = 1, $from = 0)
+    public function take($size = 1, $from = 0): CollectionInterface
     {
         return new Collection(new LimitIterator($this, $from, $size));
     }
@@ -341,7 +342,7 @@ trait CollectionTrait
     /**
      * {@inheritDoc}
      */
-    public function skip($howMany)
+    public function skip($howMany): CollectionInterface
     {
         return new Collection(new LimitIterator($this, $howMany));
     }
@@ -349,7 +350,7 @@ trait CollectionTrait
     /**
      * {@inheritDoc}
      */
-    public function match(array $conditions)
+    public function match(array $conditions): CollectionInterface
     {
         return $this->filter($this->_createMatcherFilter($conditions));
     }
@@ -402,7 +403,7 @@ trait CollectionTrait
     /**
      * {@inheritDoc}
      */
-    public function append($items)
+    public function append($items): CollectionInterface
     {
         $list = new AppendIterator();
         $list->append($this->unwrap());
@@ -414,7 +415,7 @@ trait CollectionTrait
     /**
      * {@inheritDoc}
      */
-    public function appendItem($item, $key = null)
+    public function appendItem($item, $key = null): CollectionInterface
     {
         if ($key !== null) {
             $data = [$key => $item];
@@ -428,7 +429,7 @@ trait CollectionTrait
     /**
      * {@inheritDoc}
      */
-    public function prepend($items)
+    public function prepend($items): CollectionInterface
     {
         return (new Collection($items))->append($this);
     }
@@ -436,7 +437,7 @@ trait CollectionTrait
     /**
      * {@inheritDoc}
      */
-    public function prependItem($item, $key = null)
+    public function prependItem($item, $key = null): CollectionInterface
     {
         if ($key !== null) {
             $data = [$key => $item];
@@ -450,7 +451,7 @@ trait CollectionTrait
     /**
      * {@inheritDoc}
      */
-    public function combine($keyPath, $valuePath, $groupPath = null)
+    public function combine($keyPath, $valuePath, $groupPath = null): CollectionInterface
     {
         $options = [
             'keyPath' => $this->_propertyExtractor($keyPath),
@@ -489,7 +490,7 @@ trait CollectionTrait
     /**
      * {@inheritDoc}
      */
-    public function nest($idPath, $parentPath, $nestingKey = 'children')
+    public function nest($idPath, $parentPath, $nestingKey = 'children'): CollectionInterface
     {
         $parents = [];
         $idPath = $this->_propertyExtractor($idPath);
@@ -535,9 +536,9 @@ trait CollectionTrait
     /**
      * {@inheritDoc}
      *
-     * @return \Cake\Collection\Iterator\InsertIterator
+     * @return \Cake\Collection\CollectionInterface
      */
-    public function insert($path, $values)
+    public function insert($path, $values): CollectionInterface
     {
         return new InsertIterator($this->unwrap(), $path, $values);
     }
@@ -545,7 +546,7 @@ trait CollectionTrait
     /**
      * {@inheritDoc}
      */
-    public function toArray($preserveKeys = true)
+    public function toArray($preserveKeys = true): array
     {
         $iterator = $this->unwrap();
         if ($iterator instanceof ArrayIterator) {
@@ -565,7 +566,7 @@ trait CollectionTrait
     /**
      * {@inheritDoc}
      */
-    public function toList()
+    public function toList(): array
     {
         return $this->toArray(false);
     }
@@ -581,7 +582,7 @@ trait CollectionTrait
     /**
      * {@inheritDoc}
      */
-    public function compile($preserveKeys = true)
+    public function compile($preserveKeys = true): CollectionInterface
     {
         return new Collection($this->toArray($preserveKeys));
     }
@@ -589,9 +590,9 @@ trait CollectionTrait
     /**
      * {@inheritDoc}
      *
-     * @return \Cake\Collection\Iterator\BufferedIterator
+     * @return \Cake\Collection\CollectionInterface
      */
-    public function buffered()
+    public function buffered(): CollectionInterface
     {
         return new BufferedIterator($this->unwrap());
     }
@@ -599,9 +600,9 @@ trait CollectionTrait
     /**
      * {@inheritDoc}
      *
-     * @return \Cake\Collection\Iterator\TreeIterator
+     * @return \Cake\Collection\CollectionInterface
      */
-    public function listNested($dir = 'desc', $nestingKey = 'children')
+    public function listNested($dir = 'desc', $nestingKey = 'children'): CollectionInterface
     {
         $dir = strtolower($dir);
         $modes = [
@@ -621,7 +622,7 @@ trait CollectionTrait
      *
      * @return \Cake\Collection\Iterator\StoppableIterator
      */
-    public function stopWhen($condition)
+    public function stopWhen($condition): CollectionInterface
     {
         if (!is_callable($condition)) {
             $condition = $this->_createMatcherFilter($condition);
@@ -633,7 +634,7 @@ trait CollectionTrait
     /**
      * {@inheritDoc}
      */
-    public function unfold(callable $transformer = null)
+    public function unfold(callable $transformer = null): CollectionInterface
     {
         if ($transformer === null) {
             $transformer = function ($item) {
@@ -652,7 +653,7 @@ trait CollectionTrait
     /**
      * {@inheritDoc}
      */
-    public function through(callable $handler)
+    public function through(callable $handler): CollectionInterface
     {
         $result = $handler($this);
 
@@ -662,7 +663,7 @@ trait CollectionTrait
     /**
      * {@inheritDoc}
      */
-    public function zip($items)
+    public function zip($items): CollectionInterface
     {
         return new ZipIterator(array_merge([$this->unwrap()], func_get_args()));
     }
@@ -670,7 +671,7 @@ trait CollectionTrait
     /**
      * {@inheritDoc}
      */
-    public function zipWith($items, $callable)
+    public function zipWith($items, $callable): CollectionInterface
     {
         if (func_num_args() > 2) {
             $items = func_get_args();
@@ -685,7 +686,7 @@ trait CollectionTrait
     /**
      * {@inheritDoc}
      */
-    public function chunk($chunkSize)
+    public function chunk($chunkSize): CollectionInterface
     {
         return $this->map(function ($v, $k, $iterator) use ($chunkSize) {
             $values = [$v];
@@ -704,7 +705,7 @@ trait CollectionTrait
     /**
      * {@inheritDoc}
      */
-    public function chunkWithKeys($chunkSize, $preserveKeys = true)
+    public function chunkWithKeys($chunkSize, $preserveKeys = true): CollectionInterface
     {
         return $this->map(function ($v, $k, $iterator) use ($chunkSize, $preserveKeys) {
             $key = 0;
@@ -731,7 +732,7 @@ trait CollectionTrait
     /**
      * {@inheritDoc}
      */
-    public function isEmpty()
+    public function isEmpty(): bool
     {
         foreach ($this as $el) {
             return false;
@@ -743,7 +744,7 @@ trait CollectionTrait
     /**
      * {@inheritDoc}
      */
-    public function unwrap()
+    public function unwrap(): Traversable
     {
         $iterator = $this;
         while (get_class($iterator) === 'Cake\Collection\Collection') {
@@ -762,7 +763,7 @@ trait CollectionTrait
      *
      * @return \Cake\Collection\CollectionInterface
      */
-    public function cartesianProduct(callable $operation = null, callable $filter = null)
+    public function cartesianProduct(callable $operation = null, callable $filter = null): CollectionInterface
     {
         if ($this->isEmpty()) {
             return new Collection([]);
@@ -815,7 +816,7 @@ trait CollectionTrait
      *
      * @return \Cake\Collection\CollectionInterface
      */
-    public function transpose()
+    public function transpose(): CollectionInterface
     {
         $arrayValue = $this->toList();
         $length = count(current($arrayValue));
@@ -838,7 +839,7 @@ trait CollectionTrait
      *
      * @return int
      */
-    public function count()
+    public function count(): int
     {
         $traversable = $this->optimizeUnwrap();
 
@@ -854,7 +855,7 @@ trait CollectionTrait
      *
      * @return int
      */
-    public function countKeys()
+    public function countKeys(): int
     {
         return count($this->toArray());
     }

+ 2 - 2
src/Collection/ExtractTrait.php

@@ -32,7 +32,7 @@ trait ExtractTrait
      * of doing that.
      * @return callable
      */
-    protected function _propertyExtractor($callback)
+    protected function _propertyExtractor($callback): callable
     {
         if (!is_string($callback)) {
             return $callback;
@@ -124,7 +124,7 @@ trait ExtractTrait
      * value to be compared the item with.
      * @return callable
      */
-    protected function _createMatcherFilter(array $conditions)
+    protected function _createMatcherFilter(array $conditions): callable
     {
         $matchers = [];
         foreach ($conditions as $property => $value) {

+ 1 - 1
src/Collection/Iterator/BufferedIterator.php

@@ -168,7 +168,7 @@ class BufferedIterator extends Collection implements Countable, Serializable
      *
      * @return int
      */
-    public function count()
+    public function count(): int
     {
         if (!$this->_started) {
             $this->rewind();

+ 3 - 2
src/Collection/Iterator/ExtractIterator.php

@@ -17,6 +17,7 @@ namespace Cake\Collection\Iterator;
 use ArrayIterator;
 use Cake\Collection\Collection;
 use Cake\Collection\CollectionInterface;
+use Traversable;
 
 /**
  * Creates an iterator from another iterator that extract the requested column
@@ -78,9 +79,9 @@ class ExtractIterator extends Collection
      * We perform here some strictness analysis so that the
      * iterator logic is bypassed entirely.
      *
-     * @return \Iterator
+     * @return \Traversable
      */
-    public function unwrap()
+    public function unwrap(): Traversable
     {
         $iterator = $this->getInnerIterator();
 

+ 3 - 3
src/Collection/Iterator/FilterIterator.php

@@ -19,6 +19,7 @@ use Cake\Collection\Collection;
 use Cake\Collection\CollectionInterface;
 use CallbackFilterIterator;
 use Iterator;
+use Traversable;
 
 /**
  * Creates a filtered iterator from another iterator. The filtering is done by
@@ -63,9 +64,9 @@ class FilterIterator extends Collection
      * We perform here some strictness analysis so that the
      * iterator logic is bypassed entirely.
      *
-     * @return \Iterator
+     * @return \Traversable
      */
-    public function unwrap()
+    public function unwrap(): Traversable
     {
         $filter = $this->getInnerIterator();
         $iterator = $filter->getInnerIterator();
@@ -80,7 +81,6 @@ class FilterIterator extends Collection
 
         // ArrayIterator can be traversed strictly.
         // Let's do that for performance gains
-
         $callback = $this->_callback;
         $res = [];
 

+ 3 - 2
src/Collection/Iterator/ReplaceIterator.php

@@ -17,6 +17,7 @@ namespace Cake\Collection\Iterator;
 use ArrayIterator;
 use Cake\Collection\Collection;
 use Cake\Collection\CollectionInterface;
+use Traversable;
 
 /**
  * Creates an iterator from another iterator that will modify each of the values
@@ -76,9 +77,9 @@ class ReplaceIterator extends Collection
      * We perform here some strictness analysis so that the
      * iterator logic is bypassed entirely.
      *
-     * @return \Iterator
+     * @return \Traversable
      */
-    public function unwrap()
+    public function unwrap(): Traversable
     {
         $iterator = $this->_innerIterator;
 

+ 3 - 2
src/Collection/Iterator/SortIterator.php

@@ -16,6 +16,7 @@ namespace Cake\Collection\Iterator;
 
 use Cake\Collection\Collection;
 use DateTimeInterface;
+use Traversable;
 
 /**
  * An iterator that will return the passed items in order. The order is given by
@@ -84,9 +85,9 @@ class SortIterator extends Collection
     /**
      * {@inheritDoc}
      *
-     * @return \Iterator
+     * @return \Traversable
      */
-    public function unwrap()
+    public function unwrap(): Traversable
     {
         return $this->getInnerIterator();
     }

+ 3 - 2
src/Collection/Iterator/StoppableIterator.php

@@ -17,6 +17,7 @@ namespace Cake\Collection\Iterator;
 use ArrayIterator;
 use Cake\Collection\Collection;
 use Cake\Collection\CollectionInterface;
+use Traversable;
 
 /**
  * Creates an iterator from another iterator that will verify a condition on each
@@ -87,9 +88,9 @@ class StoppableIterator extends Collection
      * We perform here some strictness analysis so that the
      * iterator logic is bypassed entirely.
      *
-     * @return \Iterator
+     * @return \Traversable
      */
-    public function unwrap()
+    public function unwrap(): Traversable
     {
         $iterator = $this->_innerIterator;
 

+ 2 - 1
src/Collection/Iterator/TreeIterator.php

@@ -14,6 +14,7 @@
  */
 namespace Cake\Collection\Iterator;
 
+use Cake\Collection\CollectionInterface;
 use Cake\Collection\CollectionTrait;
 use RecursiveIterator;
 use RecursiveIteratorIterator;
@@ -22,7 +23,7 @@ use RecursiveIteratorIterator;
  * A Recursive iterator used to flatten nested structures and also exposes
  * all Collection methods
  */
-class TreeIterator extends RecursiveIteratorIterator
+class TreeIterator extends RecursiveIteratorIterator implements CollectionInterface
 {
 
     use CollectionTrait;