Skip to content

Commit

Permalink
Add throw_if and throw_unless extensions
Browse files Browse the repository at this point in the history
  • Loading branch information
Daanra committed Apr 21, 2020
1 parent 8262a7f commit 3eec8cc
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 4 deletions.
18 changes: 18 additions & 0 deletions extension.neon
Original file line number Diff line number Diff line change
Expand Up @@ -184,13 +184,31 @@ services:
tags:
- phpstan.typeSpecifier.functionTypeSpecifyingExtension
arguments:
methodName: 'abort'
negate: false

-
class: NunoMaduro\Larastan\Types\AbortIfFunctionTypeSpecifyingExtension
tags:
- phpstan.typeSpecifier.functionTypeSpecifyingExtension
arguments:
methodName: 'abort'
negate: true

-
class: NunoMaduro\Larastan\Types\AbortIfFunctionTypeSpecifyingExtension
tags:
- phpstan.typeSpecifier.functionTypeSpecifyingExtension
arguments:
methodName: throw
negate: false

-
class: NunoMaduro\Larastan\Types\AbortIfFunctionTypeSpecifyingExtension
tags:
- phpstan.typeSpecifier.functionTypeSpecifyingExtension
arguments:
methodName: throw
negate: true

-
Expand Down
10 changes: 6 additions & 4 deletions src/Types/AbortIfFunctionTypeSpecifyingExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,19 +30,21 @@ final class AbortIfFunctionTypeSpecifyingExtension implements FunctionTypeSpecif
/** @var bool */
protected $negate;

public function __construct(bool $negate)
/** @var string */
protected $methodName;

public function __construct(bool $negate, string $methodName)
{
$this->negate = $negate;
$this->methodName = $methodName.'_'.($negate === false ? 'if' : 'unless');
}

public function isFunctionSupported(
FunctionReflection $functionReflection,
FuncCall $node,
TypeSpecifierContext $context
): bool {
$methodName = $this->negate === false ? 'abort_if' : 'abort_unless';

return $functionReflection->getName() === $methodName && $context->null();
return $functionReflection->getName() === $this->methodName && $context->null();
}

public function specifyTypes(
Expand Down
33 changes: 33 additions & 0 deletions tests/Features/Types/ThrowIf.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

declare(strict_types=1);

namespace Tests\Features\Types;

use Illuminate\Validation\ValidationException;

class ThrowIf
{
public function testThrowIfTryCatch(?int $foo): ?int
{
try {
throw_if(! $foo, ValidationException::withMessages(['$foo is null']));
} catch (\Exception $e) {

}

// Should still be nullable because we don't know if the exception was caught.
return $foo;
}

/**
* @param int|string $foo
* @return int
*/
public function testThrowIfWithTypeCheck($foo = 5): int
{
throw_if(is_string($foo), new \Exception('$foo is a string'));

return $foo;
}
}
28 changes: 28 additions & 0 deletions tests/Features/Types/ThrowUnless.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

declare(strict_types=1);

namespace Tests\Features\Types;

use Illuminate\Validation\ValidationException;

class ThrowUnless
{
public function testThrowUnless(?int $foo): int
{
throw_unless(! is_null($foo), ValidationException::withMessages(['$foo is null']));

return $foo;
}

/**
* @param int|string $foo
* @return int
*/
public function testThrowUnlessWithTypeCheck($foo = 5): int
{
throw_unless(! is_string($foo), new \Exception('$foo is a string'));

return $foo;
}
}

0 comments on commit 3eec8cc

Please sign in to comment.