Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

unique(), with(), zip(), zip_all() #209

Open
wants to merge 2 commits into
base: psalm
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ vendor/
composer.lock
phpcs.xml
phpunit.xml
/lsp/
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,4 @@ install:
script:
- composer tests
- composer coding-style
- composer types
4 changes: 3 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@
}
],
"require": {
"php": "~7"
"php": "~7",
"vimeo/psalm": "^3.7"
},
"require-dev": {
"phpunit/phpunit": "~7",
Expand Down Expand Up @@ -123,6 +124,7 @@
},
"scripts": {
"tests": "vendor/bin/phpunit",
"types": "vendor/bin/psalm",
"coding-style": "vendor/bin/phpcs && vendor/bin/php-cs-fixer fix --dry-run --diff --config=.php_cs.dist",
"clear": "rm -rf vendor/"
}
Expand Down
55 changes: 55 additions & 0 deletions psalm.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<?xml version="1.0"?>
<psalm
totallyTyped="false"
resolveFromConfigFile="true"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="https://getpsalm.org/schema/config"
xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd"
>
<projectFiles>
<directory name="src" />
<ignoreFiles>
<directory name="vendor" />
</ignoreFiles>
</projectFiles>

<issueHandlers>
<LessSpecificReturnType errorLevel="info" />

<!-- level 3 issues - slightly lazy code writing, but provably low false-negatives -->

<DeprecatedMethod errorLevel="info" />
<DeprecatedProperty errorLevel="info" />
<DeprecatedClass errorLevel="info" />
<DeprecatedConstant errorLevel="info" />
<DeprecatedFunction errorLevel="info" />
<DeprecatedInterface errorLevel="info" />
<DeprecatedTrait errorLevel="info" />

<InternalMethod errorLevel="info" />
<InternalProperty errorLevel="info" />
<InternalClass errorLevel="info" />

<MissingClosureReturnType errorLevel="info" />
<MissingReturnType errorLevel="info" />
<MissingPropertyType errorLevel="info" />
<InvalidDocblock errorLevel="info" />
<MisplacedRequiredParam errorLevel="info" />

<PropertyNotSetInConstructor errorLevel="info" />
<MissingConstructor errorLevel="info" />
<MissingClosureParamType errorLevel="info" />
<MissingParamType errorLevel="info" />

<RedundantCondition errorLevel="info" />

<DocblockTypeContradiction errorLevel="info" />
<RedundantConditionGivenDocblockType errorLevel="info" />

<UnresolvableInclude errorLevel="info" />

<RawObjectIteration errorLevel="info" />

<InvalidStringClass errorLevel="info" />
</issueHandlers>
</psalm>
4 changes: 2 additions & 2 deletions src/Functional/Average.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
* Returns the average of all numeric values in the array or null if no numeric value was found
*
* @param Traversable|array $collection
* @return null|float|int
* @return numeric|null
*/
function average($collection)
{
Expand All @@ -28,7 +28,7 @@ function average($collection)

foreach ($collection as $element) {
if (\is_numeric($element)) {
$sum += $element;
$sum = ($sum === null) ? $element : $sum + $element;
++$divisor;
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/Functional/Concat.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
/**
* Concatenates zero or more strings
*
* @param string[] ...$strings
* @param array<array-key, string> $strings
* @return string
*/
function concat(string ...$strings)
Expand Down
3 changes: 3 additions & 0 deletions src/Functional/Curry.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,10 @@
*/
function curry(callable $function, $required = true)
{
/** @psalm-suppress ArgumentTypeCoercion */
if (\method_exists('Closure', 'fromCallable')) {
// Closure::fromCallable was introduced in PHP 7.1
/** @psalm-suppress InvalidArgument */
$reflection = new ReflectionFunction(Closure::fromCallable($function));
} else {
if (\is_string($function) && \strpos($function, '::', 1) !== false) {
Expand All @@ -35,6 +37,7 @@ function curry(callable $function, $required = true)
} elseif (\is_object($function) && \method_exists($function, '__invoke')) {
$reflection = new ReflectionMethod($function, '__invoke');
} else {
/** @psalm-suppress InvalidArgument */
$reflection = new ReflectionFunction($function);
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/Functional/Difference.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@
* Takes a collection and returns the difference of all elements
*
* @param Traversable|array $collection
* @param integer|float $initial
* @return integer|float
* @param numeric $initial
* @return numeric
*/
function difference($collection, $initial = 0)
{
Expand Down
67 changes: 52 additions & 15 deletions src/Functional/Exceptions/InvalidArgumentException.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
class InvalidArgumentException extends \InvalidArgumentException
{
/**
* @psalm-pure
*
* @param mixed $callback
* @param string $callee
* @param integer $parameterPosition
Expand All @@ -22,7 +24,7 @@ public static function assertCallback($callback, $callee, $parameterPosition)
{
if (!\is_callable($callback)) {
if (!\is_array($callback) && !\is_string($callback)) {
throw new static(
throw new self(
\sprintf(
'%s() expected parameter %d to be a valid callback, no array, string, closure or functor given',
$callee,
Expand All @@ -43,15 +45,15 @@ public static function assertCallback($callback, $callee, $parameterPosition)
$sep = '->';
}

$callback = \implode($callback, $sep);
$callback = \implode($sep, $callback);
break;

default:
$type = 'function';
break;
}

throw new static(
throw new self(
\sprintf(
"%s() expects parameter %d to be a valid callback, %s '%s' not found or invalid %s name",
$callee,
Expand All @@ -64,20 +66,29 @@ public static function assertCallback($callback, $callee, $parameterPosition)
}
}

/**
* @psalm-pure
*/
public static function assertCollection($collection, $callee, $parameterPosition)
{
self::assertCollectionAlike($collection, 'Traversable', $callee, $parameterPosition);
}

/**
* @psalm-pure
*/
public static function assertArrayAccess($collection, $callee, $parameterPosition)
{
self::assertCollectionAlike($collection, 'ArrayAccess', $callee, $parameterPosition);
}

/**
* @psalm-pure
*/
public static function assertMethodName($methodName, $callee, $parameterPosition)
{
if (!\is_string($methodName)) {
throw new static(
throw new self(
\sprintf(
'%s() expects parameter %d to be string, %s given',
$callee,
Expand All @@ -89,6 +100,8 @@ public static function assertMethodName($methodName, $callee, $parameterPosition
}

/**
* @psalm-pure
*
* @param mixed $propertyName
* @param string $callee
* @param integer $parameterPosition
Expand All @@ -102,7 +115,7 @@ public static function assertPropertyName($propertyName, $callee, $parameterPosi
!\is_float($propertyName) &&
!\is_null($propertyName)
) {
throw new static(
throw new self(
\sprintf(
'%s() expects parameter %d to be a valid property name or array index, %s given',
$callee,
Expand All @@ -113,13 +126,16 @@ public static function assertPropertyName($propertyName, $callee, $parameterPosi
}
}

/**
* @psalm-pure
*/
public static function assertPositiveInteger($value, $callee, $parameterPosition)
{
if ((string)(int)$value !== (string)$value || $value < 0) {
$type = self::getType($value);
$type = $type === 'integer' ? 'negative integer' : $type;

throw new static(
throw new self(
\sprintf(
'%s() expects parameter %d to be positive integer, %s given',
$callee,
Expand All @@ -131,9 +147,11 @@ public static function assertPositiveInteger($value, $callee, $parameterPosition
}

/**
* @psalm-pure
*
* @param mixed $key
* @param string $callee
* @throws static
* @throws InvalidArgumentException
*/
public static function assertValidArrayKey($key, $callee)
{
Expand All @@ -142,7 +160,7 @@ public static function assertValidArrayKey($key, $callee)
$keyType = \gettype($key);

if (!\in_array($keyType, $keyTypes, true)) {
throw new static(
throw new self(
\sprintf(
'%s(): callback returned invalid array key of type "%s". Expected %4$s or %3$s',
$callee,
Expand All @@ -154,10 +172,13 @@ public static function assertValidArrayKey($key, $callee)
}
}

/**
* @psalm-pure
*/
public static function assertArrayKeyExists($collection, $key, $callee)
{
if (!isset($collection[$key])) {
throw new static(
throw new self(
\sprintf(
'%s(): unknown key "%s"',
$callee,
Expand All @@ -168,6 +189,8 @@ public static function assertArrayKeyExists($collection, $key, $callee)
}

/**
* @psalm-pure
*
* @param boolean $value
* @param string $callee
* @param integer $parameterPosition
Expand All @@ -176,7 +199,7 @@ public static function assertArrayKeyExists($collection, $key, $callee)
public static function assertBoolean($value, $callee, $parameterPosition)
{
if (!\is_bool($value)) {
throw new static(
throw new self(
\sprintf(
'%s() expects parameter %d to be boolean, %s given',
$callee,
Expand All @@ -188,6 +211,8 @@ public static function assertBoolean($value, $callee, $parameterPosition)
}

/**
* @psalm-pure
*
* @param mixed $value
* @param string $callee
* @param integer $parameterPosition
Expand All @@ -196,7 +221,7 @@ public static function assertBoolean($value, $callee, $parameterPosition)
public static function assertInteger($value, $callee, $parameterPosition)
{
if (!\is_int($value)) {
throw new static(
throw new self(
\sprintf(
'%s() expects parameter %d to be integer, %s given',
$callee,
Expand All @@ -208,6 +233,8 @@ public static function assertInteger($value, $callee, $parameterPosition)
}

/**
* @psalm-pure
*
* @param integer $value
* @param integer $limit
* @param string $callee
Expand All @@ -217,7 +244,7 @@ public static function assertInteger($value, $callee, $parameterPosition)
public static function assertIntegerGreaterThanOrEqual($value, $limit, $callee, $parameterPosition)
{
if (!\is_int($value) || $value < $limit) {
throw new static(
throw new self(
\sprintf(
'%s() expects parameter %d to be an integer greater than or equal to %d',
$callee,
Expand All @@ -229,6 +256,8 @@ public static function assertIntegerGreaterThanOrEqual($value, $limit, $callee,
}

/**
* @psalm-pure
*
* @param integer $value
* @param integer $limit
* @param string $callee
Expand All @@ -238,7 +267,7 @@ public static function assertIntegerGreaterThanOrEqual($value, $limit, $callee,
public static function assertIntegerLessThanOrEqual($value, $limit, $callee, $parameterPosition)
{
if (!\is_int($value) || $value > $limit) {
throw new static(
throw new self(
\sprintf(
'%s() expects parameter %d to be an integer less than or equal to %d',
$callee,
Expand All @@ -249,16 +278,21 @@ public static function assertIntegerLessThanOrEqual($value, $limit, $callee, $pa
}
}

/**
* @psalm-pure
*/
public static function assertResolvablePlaceholder(array $args, $position)
{
if (\count($args) === 0) {
throw new static(
throw new self(
\sprintf('Cannot resolve parameter placeholder at position %d. Parameter stack is empty.', $position)
);
}
}

/**
* @psalm-pure
*
* @param mixed $collection
* @param string $className
* @param string $callee
Expand All @@ -268,7 +302,7 @@ public static function assertResolvablePlaceholder(array $args, $position)
private static function assertCollectionAlike($collection, $className, $callee, $parameterPosition)
{
if (!\is_array($collection) && !$collection instanceof $className) {
throw new static(
throw new self(
\sprintf(
'%s() expects parameter %d to be array or instance of %s, %s given',
$callee,
Expand All @@ -280,6 +314,9 @@ private static function assertCollectionAlike($collection, $className, $callee,
}
}

/**
* @psalm-pure
*/
private static function getType($value)
{
return \is_object($value) ? \get_class($value) : \gettype($value);
Expand Down
Loading