diff --git a/composer.json b/composer.json
index b2e0e43d..26ee9ea8 100644
--- a/composer.json
+++ b/composer.json
@@ -5,7 +5,7 @@
"description": "Rector upgrades rules for Laravel Framework",
"require": {
"php": ">=8.1",
- "rector/rector": "^0.18.0"
+ "rector/rector": "^0.18.5"
},
"require-dev": {
"phpunit/phpunit": "^10.0",
@@ -18,8 +18,7 @@
"phpstan/extension-installer": "^1.1",
"phpstan/phpstan-webmozart-assert": "^1.1",
"phpstan/phpstan-strict-rules": "^1.2",
- "symplify/vendor-patches": "^11.0",
- "rector/rector-debugging": "dev-main"
+ "symplify/vendor-patches": "^11.0"
},
"autoload": {
"psr-4": {
diff --git a/docs/rector_rules_overview.md b/docs/rector_rules_overview.md
index dfaa9509..6acaf11a 100644
--- a/docs/rector_rules_overview.md
+++ b/docs/rector_rules_overview.md
@@ -1,4 +1,4 @@
-# 45 Rules Overview
+# 46 Rules Overview
## AddArgumentDefaultValueRector
@@ -1050,6 +1050,25 @@ Use `Str::startsWith()` or `Str::endsWith()` instead of `substr()` === `$str`
+## ThrowIfRector
+
+Change if throw to throw_if
+
+- class: [`RectorLaravel\Rector\If_\ThrowIfRector`](../src/Rector/If_/ThrowIfRector.php)
+
+```diff
+-if ($condition) {
+- throw new Exception();
+-}
+-if (!$condition) {
+- throw new Exception();
+-}
++throw_if($condition, new Exception());
++throw_unless($condition, new Exception());
+```
+
+
+
## UnifyModelDatesWithCastsRector
Unify Model `$dates` property with `$casts`
diff --git a/src/Rector/ClassMethod/AddGenericReturnTypeToRelationsRector.php b/src/Rector/ClassMethod/AddGenericReturnTypeToRelationsRector.php
index 97466340..f2b31a8c 100644
--- a/src/Rector/ClassMethod/AddGenericReturnTypeToRelationsRector.php
+++ b/src/Rector/ClassMethod/AddGenericReturnTypeToRelationsRector.php
@@ -23,6 +23,7 @@
use Rector\Core\PhpParser\Node\BetterNodeFinder;
use Rector\Core\Rector\AbstractScopeAwareRector;
use Rector\NodeTypeResolver\TypeComparator\TypeComparator;
+use Rector\StaticTypeMapper\StaticTypeMapper;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
@@ -45,6 +46,7 @@ public function __construct(
private readonly DocBlockUpdater $docBlockUpdater,
private readonly PhpDocInfoFactory $phpDocInfoFactory,
private readonly BetterNodeFinder $betterNodeFinder,
+ private readonly StaticTypeMapper $staticTypeMapper,
) {
}
diff --git a/src/Rector/If_/ThrowIfRector.php b/src/Rector/If_/ThrowIfRector.php
new file mode 100644
index 00000000..c4c7fcbb
--- /dev/null
+++ b/src/Rector/If_/ThrowIfRector.php
@@ -0,0 +1,76 @@
+stmts;
+
+ // Check if there's a single throw statement inside the if
+ if (count($ifStmts) === 1 && $ifStmts[0] instanceof Throw_) {
+ $condition = $node->cond;
+ $throwExpr = $ifStmts[0]->expr;
+
+ // Check if the condition is a negation
+ if ($condition instanceof BooleanNot) {
+ // Create a new throw_unless function call
+ return new Node\Stmt\Expression(new FuncCall(new Node\Name('throw_unless'), [
+ new Node\Arg($condition->expr),
+ new Node\Arg($throwExpr),
+ ]));
+ } else {
+ // Create a new throw_if function call
+ return new Node\Stmt\Expression(new FuncCall(new Node\Name('throw_if'), [
+ new Node\Arg($condition),
+ new Node\Arg($throwExpr),
+ ]));
+ }
+ }
+
+ return null;
+ }
+}
diff --git a/tests/Rector/If_/ThrowIfRector/Fixture/fixture.php.inc b/tests/Rector/If_/ThrowIfRector/Fixture/fixture.php.inc
new file mode 100644
index 00000000..8fd15d44
--- /dev/null
+++ b/tests/Rector/If_/ThrowIfRector/Fixture/fixture.php.inc
@@ -0,0 +1,33 @@
+
+-----
+
diff --git a/tests/Rector/If_/ThrowIfRector/Fixture/skip_if_more_statements.php.inc b/tests/Rector/If_/ThrowIfRector/Fixture/skip_if_more_statements.php.inc
new file mode 100644
index 00000000..66e3a399
--- /dev/null
+++ b/tests/Rector/If_/ThrowIfRector/Fixture/skip_if_more_statements.php.inc
@@ -0,0 +1,22 @@
+
diff --git a/tests/Rector/If_/ThrowIfRector/ThrowIfRectorTest.php b/tests/Rector/If_/ThrowIfRector/ThrowIfRectorTest.php
new file mode 100644
index 00000000..55c51e66
--- /dev/null
+++ b/tests/Rector/If_/ThrowIfRector/ThrowIfRectorTest.php
@@ -0,0 +1,28 @@
+doTestFile($filePath);
+ }
+
+ public static function provideData(): Iterator
+ {
+ return self::yieldFilesFromDirectory(__DIR__ . '/Fixture');
+ }
+
+ public function provideConfigFilePath(): string
+ {
+ return __DIR__ . '/config/configured_rule.php';
+ }
+}
diff --git a/tests/Rector/If_/ThrowIfRector/config/configured_rule.php b/tests/Rector/If_/ThrowIfRector/config/configured_rule.php
new file mode 100644
index 00000000..0a4d20d0
--- /dev/null
+++ b/tests/Rector/If_/ThrowIfRector/config/configured_rule.php
@@ -0,0 +1,11 @@
+import(__DIR__ . '/../../../../../config/config.php');
+
+ $rectorConfig->rule(\RectorLaravel\Rector\If_\ThrowIfRector::class);
+};