Skip to content
Merged
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
2 changes: 1 addition & 1 deletion .github/workflows/tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,4 @@ jobs:

- uses: ramsey/composer-install@v3

- run: vendor/bin/phpunit tests
- run: vendor/bin/phpunit
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,10 @@ use Rector\Config\RectorConfig;
use RectorLaravel\Rector\FuncCall\RemoveDumpDataDeadCodeRector;

return RectorConfig::configure()
// include default config
->withSets([
__DIR__ . '/vendor/driftingly/rector-laravel/config/config.php'
])
->withConfiguredRule(RemoveDumpDataDeadCodeRector::class, [
'dd', 'dump', 'var_dump'
]);
Expand All @@ -127,6 +131,10 @@ use Rector\Config\RectorConfig;
use RectorLaravel\Rector\MethodCall\ResponseHelperCallToJsonResponseRector;

return RectorConfig::configure()
// include default config
->withSets([
__DIR__ . '/vendor/driftingly/rector-laravel/config/config.php'
])
->withRules([
ResponseHelperCallToJsonResponseRector::class,
]);
Expand Down
14 changes: 13 additions & 1 deletion config/config.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,17 @@
declare(strict_types=1);

use Rector\Config\RectorConfig;
use Rector\Contract\PhpParser\DecoratingNodeVisitorInterface;
use RectorLaravel\NodeVisitor\ArrayDimFetchContextNodeVisitor;
use RectorLaravel\NodeVisitor\RandomEnumContextNodeVisitor;

return static function (RectorConfig $rectorConfig): void {};
/**
* to be imported, don't use RectorConfigBuilder for safe usage
*/
return static function (RectorConfig $rectorConfig): void {
$rectorConfig->singleton(ArrayDimFetchContextNodeVisitor::class);
$rectorConfig->tag(ArrayDimFetchContextNodeVisitor::class, DecoratingNodeVisitorInterface::class);

$rectorConfig->singleton(RandomEnumContextNodeVisitor::class);
$rectorConfig->tag(RandomEnumContextNodeVisitor::class, DecoratingNodeVisitorInterface::class);
};
17 changes: 15 additions & 2 deletions phpunit.xml
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,21 @@
displayDetailsOnTestsThatTriggerWarnings="true"
>
<testsuites>
<testsuite name="main">
<directory>tests</directory>
<testsuite name="commands">
<directory>tests/Commands</directory>
</testsuite>
<testsuite name="sets">
<directory>tests/Sets</directory>
</testsuite>
<testsuite name="rector">
<directory>tests/Rector</directory>
</testsuite>
<!--
This on the last as tests extends AbstractLazyTestCase
that clear configuration
-->
<testsuite name="node-analizer">
<directory>tests/NodeAnalyzer</directory>
</testsuite>
</testsuites>
</phpunit>
78 changes: 78 additions & 0 deletions src/NodeVisitor/ArrayDimFetchContextNodeVisitor.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
<?php

declare(strict_types=1);

namespace RectorLaravel\NodeVisitor;

use PhpParser\Node;
use PhpParser\Node\Expr;
use PhpParser\Node\Expr\ArrayDimFetch;
use PhpParser\Node\Expr\Assign;
use PhpParser\Node\Expr\Isset_;
use PhpParser\Node\Expr\Variable;
use PhpParser\Node\Scalar;
use PhpParser\Node\Scalar\InterpolatedString;
use PhpParser\Node\Stmt\Unset_;
use PhpParser\NodeVisitorAbstract;
use Rector\Contract\PhpParser\DecoratingNodeVisitorInterface;
use Rector\NodeNameResolver\NodeNameResolver;
use Rector\PhpDocParser\NodeTraverser\SimpleCallableNodeTraverser;

final class ArrayDimFetchContextNodeVisitor extends NodeVisitorAbstract implements DecoratingNodeVisitorInterface
{
public const string IS_INSIDE_ARRAY_DIM_FETCH_WITH_DIM_NOT_SCALAR = 'is_inside_array_dim_fetch_with_dim_not_scalar';
public const string IS_IN_SERVER_VARIABLE = 'is_in_server_variable';
public const string IS_INSIDE_ARRAY_DIM_FETCH_WITH_DIM_NOT_EXPR = 'is_inside_array_dim_fetch_with_dim_not_expr';

public function __construct(
private readonly NodeNameResolver $nodeNameResolver
) {}

public function enterNode(Node $node)
{
if (! $node instanceof ArrayDimFetch) {
if (in_array($node::class, [Assign::class, Isset_::class, Unset_::class, InterpolatedString::class], true)
&& (! $node instanceof Assign || $node->var instanceof ArrayDimFetch && $this->nodeNameResolver->isName($node->var->var, '_SERVER'))) {
SimpleCallableNodeTraverser::traverseNodesWithCallable($node, function (Node $subNode) {
if (! $subNode instanceof ArrayDimFetch) {
return null;
}

$subNode->setAttribute(self::IS_IN_SERVER_VARIABLE, true);

return $subNode;
});
}

return null;
}

if (! $node->dim instanceof Expr) {
SimpleCallableNodeTraverser::traverseNodesWithCallable($node, function (Node $subNode) {
if (! $subNode instanceof Variable) {
return null;
}

$subNode->setAttribute(self::IS_INSIDE_ARRAY_DIM_FETCH_WITH_DIM_NOT_EXPR, true);

return $subNode;
});
}

if ($node->dim instanceof Scalar) {
return null;
}

SimpleCallableNodeTraverser::traverseNodesWithCallable($node, function (Node $subSubNode) {
if ($subSubNode instanceof Variable) {
$subSubNode->setAttribute(self::IS_INSIDE_ARRAY_DIM_FETCH_WITH_DIM_NOT_SCALAR, true);

return $subSubNode;
}

return null;
});

return null;
}
}
47 changes: 47 additions & 0 deletions src/NodeVisitor/RandomEnumContextNodeVisitor.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?php

declare(strict_types=1);

namespace RectorLaravel\NodeVisitor;

use PhpParser\Node;
use PhpParser\Node\Expr\MethodCall;
use PhpParser\Node\Expr\PropertyFetch;
use PhpParser\Node\Scalar\InterpolatedString;
use PhpParser\NodeVisitorAbstract;
use Rector\Contract\PhpParser\DecoratingNodeVisitorInterface;
use Rector\NodeNameResolver\NodeNameResolver;
use Rector\PhpDocParser\NodeTraverser\SimpleCallableNodeTraverser;

final class RandomEnumContextNodeVisitor extends NodeVisitorAbstract implements DecoratingNodeVisitorInterface
{
public const string IS_IN_RANDOM_ENUM = 'is_in_random_enum';

public function __construct(
private readonly NodeNameResolver $nodeNameResolver
) {}

public function enterNode(Node $node)
{
if (! $node instanceof MethodCall) {
return null;
}

// The randomEnum() method is a special case where the faker instance is used
// see https://github.com/spatie/laravel-enum#faker-provider
if ($this->nodeNameResolver->isName($node->name, 'randomEnum')) {
$node->setAttribute(self::IS_IN_RANDOM_ENUM, true);
SimpleCallableNodeTraverser::traverseNodesWithCallable($node, function (Node $subNode) {
if (! $subNode instanceof PropertyFetch && ! $subNode instanceof InterpolatedString) {
return null;
}

$subNode->setAttribute(self::IS_IN_RANDOM_ENUM, true);

return $subNode;
});
}

return null;
}
}
38 changes: 6 additions & 32 deletions src/Rector/ArrayDimFetch/RequestVariablesToRequestFacadeRector.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,8 @@
use PhpParser\Node\Expr\Variable;
use PhpParser\Node\Scalar;
use PhpParser\Node\Scalar\String_;
use PHPStan\Analyser\Scope;
use Rector\NodeTypeResolver\Node\AttributeKey;
use RectorLaravel\AbstractRector;
use RectorLaravel\NodeVisitor\ArrayDimFetchContextNodeVisitor;
use RectorLaravel\ValueObject\ReplaceRequestKeyAndMethodValue;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
Expand All @@ -24,8 +23,6 @@
*/
class RequestVariablesToRequestFacadeRector extends AbstractRector
{
private const string IS_INSIDE_ARRAY_DIM_FETCH_WITH_DIM_NOT_SCALAR = 'is_inside_array_dim_fetch_with_dim_not_scalar';

public function getRuleDefinition(): RuleDefinition
{
return new RuleDefinition(
Expand Down Expand Up @@ -61,39 +58,16 @@ public function getRuleDefinition(): RuleDefinition

public function getNodeTypes(): array
{
return [Node::class, ArrayDimFetch::class, Variable::class, Isset_::class];
return [ArrayDimFetch::class, Variable::class, Isset_::class];
}

/**
* @param ArrayDimFetch|Variable|Isset_ $node
*/
public function refactor(Node $node): StaticCall|NotIdentical|null
{
if (! $node instanceof ArrayDimFetch && ! $node instanceof Variable && ! $node instanceof Isset_) {
$scope = $node->getAttribute(AttributeKey::SCOPE);
if ($scope instanceof Scope && $scope->isInFirstLevelStatement()) {
$this->traverseNodesWithCallable($node, function (Node $subNode) {
if ($subNode instanceof ArrayDimFetch) {

if ($subNode->dim instanceof Scalar) {
return null;
}

$this->traverseNodesWithCallable($subNode, function (Node $subSubNode) {
if ($subSubNode instanceof Variable) {
$subSubNode->setAttribute(self::IS_INSIDE_ARRAY_DIM_FETCH_WITH_DIM_NOT_SCALAR, true);

return $subSubNode;
}

return null;
});
}
});
}

return null;
}

if ($node instanceof Variable) {
if ($node->getAttribute(self::IS_INSIDE_ARRAY_DIM_FETCH_WITH_DIM_NOT_SCALAR) === true) {
if ($node->getAttribute(ArrayDimFetchContextNodeVisitor::IS_INSIDE_ARRAY_DIM_FETCH_WITH_DIM_NOT_SCALAR) === true) {
return null;
}

Expand Down
42 changes: 6 additions & 36 deletions src/Rector/ArrayDimFetch/ServerVariableToRequestFacadeRector.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,9 @@
use PhpParser\Node\Arg;
use PhpParser\Node\Expr;
use PhpParser\Node\Expr\ArrayDimFetch;
use PhpParser\Node\Expr\Assign;
use PhpParser\Node\Expr\Isset_;
use PhpParser\Node\Expr\StaticCall;
use PhpParser\Node\Scalar\InterpolatedString;
use PhpParser\Node\Stmt\Unset_;
use PHPStan\Analyser\Scope;
use Rector\NodeTypeResolver\Node\AttributeKey;
use RectorLaravel\AbstractRector;
use RectorLaravel\NodeVisitor\ArrayDimFetchContextNodeVisitor;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;

Expand All @@ -22,8 +17,6 @@
*/
class ServerVariableToRequestFacadeRector extends AbstractRector
{
private const string IS_IN_SERVER_VARIABLE = 'is_in_server_variable';

public function getRuleDefinition(): RuleDefinition
{
return new RuleDefinition(
Expand All @@ -41,37 +34,14 @@ public function getRuleDefinition(): RuleDefinition

public function getNodeTypes(): array
{
return [Node::class, ArrayDimFetch::class];
return [ArrayDimFetch::class];
}

/**
* @param ArrayDimFetch $node
*/
public function refactor(Node $node): ?StaticCall
{
if (! $node instanceof ArrayDimFetch) {
$scope = $node->getAttribute(AttributeKey::SCOPE);
if ($scope instanceof Scope && $scope->isInFirstLevelStatement()) {
$this->traverseNodesWithCallable($node, function (Node $subNode) {
if (in_array($subNode::class, [Assign::class, Isset_::class, Unset_::class, InterpolatedString::class], true)
&& (! $subNode instanceof Assign || $subNode->var instanceof ArrayDimFetch && $this->isName($subNode->var->var, '_SERVER'))) {
$this->traverseNodesWithCallable($subNode, function (Node $subSubNode) {
if (! $subSubNode instanceof ArrayDimFetch) {
return null;
}

$subSubNode->setAttribute(self::IS_IN_SERVER_VARIABLE, true);

return $subSubNode;
});

return $subNode;
}

return null;
});
}

return null;
}

if (! $this->isName($node->var, '_SERVER')) {
return null;
}
Expand All @@ -80,7 +50,7 @@ public function refactor(Node $node): ?StaticCall
return null;
}

if ($node->getAttribute(self::IS_IN_SERVER_VARIABLE) === true) {
if ($node->getAttribute(ArrayDimFetchContextNodeVisitor::IS_IN_SERVER_VARIABLE) === true) {
return null;
}

Expand Down
33 changes: 0 additions & 33 deletions src/Rector/ArrayDimFetch/SessionVariableToSessionFacadeRector.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@
use PhpParser\Node\Expr\Variable;
use PhpParser\Node\Stmt\Expression;
use PhpParser\Node\Stmt\Unset_;
use PHPStan\Analyser\Scope;
use Rector\NodeTypeResolver\Node\AttributeKey;
use RectorLaravel\AbstractRector;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
Expand Down Expand Up @@ -60,7 +58,6 @@ public function getRuleDefinition(): RuleDefinition
public function getNodeTypes(): array
{
return [
Node::class,
Isset_::class,
Unset_::class,
ArrayDimFetch::class,
Expand All @@ -75,36 +72,6 @@ public function getNodeTypes(): array
*/
public function refactor(Node $node): StaticCall|Expression|null
{
$scope = $node->getAttribute(AttributeKey::SCOPE);
if ($scope instanceof Scope && $scope->isInFirstLevelStatement()) {
$this->traverseNodesWithCallable($node, function (Node $subNode) {
if (! $subNode instanceof ArrayDimFetch) {
return null;
}

if (! $subNode->dim instanceof Expr) {
$subNode->setAttribute(self::IS_INSIDE_ARRAY_DIM_FETCH_WITH_DIM_NOT_EXPR, true);
$this->traverseNodesWithCallable($subNode, function (Node $subSubNode) {
if (! $subSubNode instanceof Variable) {
return null;
}

$subSubNode->setAttribute(self::IS_INSIDE_ARRAY_DIM_FETCH_WITH_DIM_NOT_EXPR, true);

return $subSubNode;
});

return $subNode;
}

return null;
});
}

if (! $node instanceof Isset_ && ! $node instanceof Unset_ && ! $node instanceof ArrayDimFetch && ! $node instanceof Assign && ! $node instanceof FuncCall && ! $node instanceof Variable) {
return null;
}

if ($node instanceof ArrayDimFetch) {
return $this->processDimFetch($node);
}
Expand Down
Loading