Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: cdn77/PhpFunctions
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 0.2.0
Choose a base ref
...
head repository: cdn77/PhpFunctions
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 0.2.x
Choose a head ref
  • 10 commits
  • 21 files changed
  • 3 contributors

Commits on May 22, 2024

  1. feat: introduce assert_return() (#48)

    simPod authored May 22, 2024

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature.
    Copy the full SHA
    00809e5 View commit details
  2. fix: add AssertReturnDynamicFunctionReturnTypeExtension (#49)

    simPod authored May 22, 2024
    Copy the full SHA
    49f6ba7 View commit details
  3. fix(phpstan): use original expression string in assert_return() dyn…

    …amic return type extension (#50)
    simPod authored May 22, 2024
    Copy the full SHA
    921721e View commit details

Commits on May 28, 2024

  1. chore(deps): update dependency infection/infection to ^0.29.0 (#51)

    Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
    renovate[bot] authored May 28, 2024
    Copy the full SHA
    2a4a9fe View commit details

Commits on Sep 4, 2024

  1. chore(phpunit): remove beStrictAboutTodoAnnotatedTests (#55)

    simPod authored Sep 4, 2024
    Copy the full SHA
    31fc1b1 View commit details
  2. chore(deps): allow azjezz/psl ^3.0 (#53)

    trearcul authored Sep 4, 2024
    Copy the full SHA
    661b21b View commit details

Commits on Sep 12, 2024

  1. feat(iterable): deprecate find() (#56)

    simPod authored Sep 12, 2024
    Copy the full SHA
    ec9c5cd View commit details

Commits on Sep 27, 2024

  1. chore(deps): update dependency ubuntu to v24 (#57)

    Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
    renovate[bot] authored Sep 27, 2024
    Copy the full SHA
    7fcd334 View commit details

Commits on Nov 11, 2024

  1. chore(deps): update phpstan packages to v2 (major) (#58)

    Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
    renovate[bot] authored Nov 11, 2024
    Copy the full SHA
    4817610 View commit details

Commits on Nov 14, 2024

  1. chore(deps): update codecov/codecov-action action to v5 (#59)

    Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
    renovate[bot] authored Nov 14, 2024
    Copy the full SHA
    433bf0a View commit details
6 changes: 3 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -10,7 +10,7 @@ on:
jobs:
phpunit:
name: "PHPUnit"
runs-on: "ubuntu-22.04"
runs-on: "ubuntu-24.04"

strategy:
matrix:
@@ -53,7 +53,7 @@ jobs:

upload_coverage:
name: "Upload coverage to Codecov"
runs-on: "ubuntu-22.04"
runs-on: "ubuntu-24.04"
needs:
- "phpunit"

@@ -69,7 +69,7 @@ jobs:
path: "reports"

- name: "Upload to Codecov"
uses: "codecov/codecov-action@v4"
uses: "codecov/codecov-action@v5"
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
with:
4 changes: 2 additions & 2 deletions .github/workflows/coding-standards.yml
Original file line number Diff line number Diff line change
@@ -10,7 +10,7 @@ on:
jobs:
coding-standards:
name: "Coding Standards"
runs-on: "ubuntu-22.04"
runs-on: "ubuntu-24.04"

steps:
- name: "Checkout"
@@ -32,7 +32,7 @@ jobs:

composer-normalize:
name: "Composer Normalize"
runs-on: "ubuntu-22.04"
runs-on: "ubuntu-24.04"

steps:
- name: "Checkout"
2 changes: 1 addition & 1 deletion .github/workflows/infection.yml
Original file line number Diff line number Diff line change
@@ -9,7 +9,7 @@ on:

jobs:
Infection:
runs-on: ubuntu-22.04
runs-on: ubuntu-24.04

steps:
- name: "Checkout"
4 changes: 2 additions & 2 deletions .github/workflows/static-analysis.yml
Original file line number Diff line number Diff line change
@@ -10,7 +10,7 @@ on:
jobs:
static-analysis-phpstan:
name: "Static Analysis with PHPStan"
runs-on: "ubuntu-22.04"
runs-on: "ubuntu-24.04"

steps:
- name: "Checkout code"
@@ -32,7 +32,7 @@ jobs:

static-analysis-composer-unused:
name: "Static Analysis with Composer Unused"
runs-on: "ubuntu-22.04"
runs-on: "ubuntu-24.04"

steps:
- name: "Checkout code"
17 changes: 17 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -12,6 +12,23 @@
Function that should have never been called.
Useful for `default` case in exhaustive matching.

### assert_return()

Asserts the value via the expression and returns it.

It's useful when you want to assert inline so for example you can keep the arrow function in place.

It uses native `assert()` internally.

```php
use function Cdn77\Functions\assert_return;

array_map(
fn (mixed $value) => new RequiresInt(assert_return($value, is_int(...))),
[1, 2, 3]
);
```

### noop()

Does nothing. Useful e.g. for `match` expression that currently supports single-line expressions in blocks.
15 changes: 15 additions & 0 deletions composer-dependency-analyser.php
Original file line number Diff line number Diff line change
@@ -3,8 +3,23 @@
declare(strict_types=1);

use ShipMonk\ComposerDependencyAnalyser\Config\Configuration;
use ShipMonk\ComposerDependencyAnalyser\Config\ErrorType;

$config = new Configuration();

return $config
->ignoreErrorsOnPath(
'tests/AssertTest.php',
[ErrorType::UNKNOWN_FUNCTION],
)
->ignoreErrorsOnPackageAndPaths(
'phpstan/phpstan',
['phpstan'],
[ErrorType::DEV_DEPENDENCY_IN_PROD],
)
->ignoreErrorsOnPackageAndPaths(
'nikic/php-parser',
['phpstan'],
[ErrorType::SHADOW_DEPENDENCY],
)
->addPathToScan(__DIR__ . '/src', isDev: false);
18 changes: 14 additions & 4 deletions composer.json
Original file line number Diff line number Diff line change
@@ -21,20 +21,23 @@
"require": {
"php": "^8.2",
"ext-ds": "*",
"azjezz/psl": "^2.9"
"azjezz/psl": "^2.9 || ^3.0"
},
"require-dev": {
"cdn77/coding-standard": "^7.0",
"ergebnis/composer-normalize": "^2.23",
"infection/infection": "^0.28.0",
"infection/infection": "^0.29.0",
"php-ds/php-ds": "^1.4",
"phpstan/extension-installer": "^1.1",
"phpstan/phpstan": "^1.3",
"phpstan/phpstan-phpunit": "^1.0.0",
"phpstan/phpstan": "^2.0",
"phpstan/phpstan-phpunit": "^2.0.0",
"phpunit/phpunit": "^11.0",
"shipmonk/composer-dependency-analyser": "^1.5"
},
"autoload": {
"psr-4": {
"Cdn77\\Functions\\PHPStan\\": "phpstan"
},
"files": [
"src/functions_include.php"
]
@@ -53,5 +56,12 @@
"phpstan/extension-installer": true
},
"sort-packages": true
},
"extra": {
"phpstan": {
"includes": [
"phpstan-extension.neon"
]
}
}
}
2 changes: 2 additions & 0 deletions phpcs.xml.dist
Original file line number Diff line number Diff line change
@@ -7,6 +7,8 @@

<rule ref="Cdn77" />

<file>composer-dependency-analyser.php</file>
<file>phpstan/</file>
<file>src/</file>
<file>tests/</file>
</ruleset>
10 changes: 10 additions & 0 deletions phpstan-extension.neon
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
services:
-
class: Cdn77\Functions\PHPStan\AssertReturnFunctionTypeSpecifyingExtension
tags:
- phpstan.typeSpecifier.functionTypeSpecifyingExtension

-
class: Cdn77\Functions\PHPStan\AssertReturnDynamicFunctionReturnTypeExtension
tags:
- phpstan.broker.dynamicFunctionReturnTypeExtension
4 changes: 4 additions & 0 deletions phpstan.neon.dist
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
includes:
- phpstan-extension.neon

parameters:
level: max
paths:
- %currentWorkingDirectory%/src
- %currentWorkingDirectory%/phpstan
- %currentWorkingDirectory%/tests
59 changes: 59 additions & 0 deletions phpstan/AssertReturnDynamicFunctionReturnTypeExtension.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<?php

declare(strict_types=1);

namespace Cdn77\Functions\PHPStan;

use PhpParser\Node\Expr\FuncCall;
use PHPStan\Analyser\Scope;
use PHPStan\Analyser\TypeSpecifier;
use PHPStan\Analyser\TypeSpecifierAwareExtension;
use PHPStan\Analyser\TypeSpecifierContext;
use PHPStan\Node\Printer\ExprPrinter;
use PHPStan\Reflection\FunctionReflection;
use PHPStan\Type\DynamicFunctionReturnTypeExtension;
use PHPStan\Type\Type;

use function assert;

final class AssertReturnDynamicFunctionReturnTypeExtension implements
DynamicFunctionReturnTypeExtension,
TypeSpecifierAwareExtension
{
private TypeSpecifier $typeSpecifier;

public function __construct(private ExprPrinter $exprPrinter)
{
}

public function isFunctionSupported(FunctionReflection $functionReflection): bool
{
return $functionReflection->getName() === 'Cdn77\Functions\assert_return';
}

public function getTypeFromFunctionCall(
FunctionReflection $functionReflection,
FuncCall $functionCall,
Scope $scope,
): Type|null {
$arg1 = $functionCall->getArgs()[1]->value;
assert($arg1 instanceof FuncCall, 'Second argument of assert_return must be a function call');

$call = new FuncCall($arg1->name, [$functionCall->getArgs()[0]], $arg1->getAttributes());

$specifiedTypes = $this->typeSpecifier->specifyTypesInCondition(
$scope,
$call,
TypeSpecifierContext::createTruthy(),
);

$originalExprString = $this->exprPrinter->printExpr($functionCall->getArgs()[0]->value);

return $specifiedTypes->getSureTypes()[$originalExprString][1] ?? null;
}

public function setTypeSpecifier(TypeSpecifier $typeSpecifier): void
{
$this->typeSpecifier = $typeSpecifier;
}
}
50 changes: 50 additions & 0 deletions phpstan/AssertReturnFunctionTypeSpecifyingExtension.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<?php

declare(strict_types=1);

namespace Cdn77\Functions\PHPStan;

use PhpParser\Node\Expr\FuncCall;
use PHPStan\Analyser\Scope;
use PHPStan\Analyser\SpecifiedTypes;
use PHPStan\Analyser\TypeSpecifier;
use PHPStan\Analyser\TypeSpecifierAwareExtension;
use PHPStan\Analyser\TypeSpecifierContext;
use PHPStan\Reflection\FunctionReflection;
use PHPStan\Type\FunctionTypeSpecifyingExtension;

use function assert;

final class AssertReturnFunctionTypeSpecifyingExtension implements
FunctionTypeSpecifyingExtension,
TypeSpecifierAwareExtension
{
private TypeSpecifier $typeSpecifier;

public function isFunctionSupported(
FunctionReflection $functionReflection,
FuncCall $node,
TypeSpecifierContext $context,
): bool {
return $functionReflection->getName() === 'Cdn77\Functions\assert_return';
}

public function specifyTypes(
FunctionReflection $functionReflection,
FuncCall $node,
Scope $scope,
TypeSpecifierContext $context,
): SpecifiedTypes {
$arg1 = $node->getArgs()[1]->value;
assert($arg1 instanceof FuncCall, 'Second argument of assert_return must be a function call');

$call = new FuncCall($arg1->name, [$node->getArgs()[0]], $arg1->getAttributes());

return $this->typeSpecifier->specifyTypesInCondition($scope, $call, TypeSpecifierContext::createTruthy());
}

public function setTypeSpecifier(TypeSpecifier $typeSpecifier): void
{
$this->typeSpecifier = $typeSpecifier;
}
}
1 change: 0 additions & 1 deletion phpunit.xml.dist
Original file line number Diff line number Diff line change
@@ -4,7 +4,6 @@
xsi:noNamespaceSchemaLocation="vendor/phpunit/phpunit/phpunit.xsd"
beStrictAboutChangesToGlobalState="true"
beStrictAboutOutputDuringTests="true"
beStrictAboutTodoAnnotatedTests="true"
executionOrder="random"
colors="true"
bootstrap="tests/bootstrap.php"
22 changes: 22 additions & 0 deletions src/assert.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php

declare(strict_types=1);

namespace Cdn77\Functions;

use Throwable;

use function assert;

/**
* @param TValue $assertionFn
* @param callable(TValue):(bool|string) $assertionFn
*
* @template TValue
*/
function assert_return(mixed $value, callable $assertionFn, Throwable|string|null $description = null): mixed
{
assert($assertionFn($value), $description);

return $value;
}
1 change: 1 addition & 0 deletions src/functions_include.php
Original file line number Diff line number Diff line change
@@ -3,6 +3,7 @@
declare(strict_types=1);

require_once __DIR__ . '/absurd.php';
require_once __DIR__ . '/assert.php';
require_once __DIR__ . '/ds.php';
require_once __DIR__ . '/generator.php';
require_once __DIR__ . '/iterable.php';
2 changes: 2 additions & 0 deletions src/iterable.php
Original file line number Diff line number Diff line change
@@ -7,6 +7,8 @@
use Psl\Option\Option;

/**
* @deprecated Use {@see \Psl\Iter\search_opt} instead
*
* @param iterable<K, T> $iterable
* @param callable(K, T): bool $filterFn
*
1 change: 1 addition & 0 deletions src/noop.php
Original file line number Diff line number Diff line change
@@ -4,6 +4,7 @@

namespace Cdn77\Functions;

/** @phpstan-ignore void.pure */
function noop(): void
{
return;
34 changes: 34 additions & 0 deletions tests/AssertTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php

declare(strict_types=1);

namespace Cdn77\Functions\Tests;

use PHPUnit\Framework\Attributes\CoversFunction;
use PHPUnit\Framework\TestCase;

use function Cdn77\Functions\assert_return;
use function is_int;
use function PHPStan\Testing\assertType;

#[CoversFunction('Cdn77\Functions\assert_return')]
final class AssertTest extends TestCase
{
public function testAssertReturn(): void
{
$value = 1;
self::assertSame(
$value,
/** @phpstan-ignore function.alreadyNarrowedType */
assert_return($value, is_int(...)),
);
}

public function phpstanType(mixed $value): void
{
$return = assert_return($value, is_int(...));

assertType('int', $value);
assertType('int', $return);
}
}
Loading