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
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public function createVariablesWithTypesFromArgs(array $args): array
$variablesWithTypes = [];

foreach ($args as $arg) {
$variableName = $this->variableNaming->resolveParamNameFromArg($arg);
$variableName = $this->variableNaming->resolveFromNode($arg);
$staticType = $this->nodeTypeResolver->getStaticType($arg->value);
$phpParserTypeNode = $this->staticTypeMapper->mapPHPStanTypeToPhpParserNode($staticType);

Expand Down
65 changes: 46 additions & 19 deletions rules/nette-kdyby/src/Naming/VariableNaming.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,17 @@

namespace Rector\NetteKdyby\Naming;

use PhpParser\Node;
use PhpParser\Node\Arg;
use PhpParser\Node\Expr\ArrayDimFetch;
use PhpParser\Node\Expr\Cast;
use PhpParser\Node\Expr\MethodCall;
use PhpParser\Node\Expr\PropertyFetch;
use PhpParser\Node\Expr\Ternary;
use PhpParser\Node\Scalar;
use PhpParser\Node\Scalar\String_;
use Rector\Core\Exception\NotImplementedException;
use Rector\Core\PhpParser\Node\Value\ValueResolver;
use Rector\NodeNameResolver\NodeNameResolver;

final class VariableNaming
Expand All @@ -21,52 +24,60 @@ final class VariableNaming
*/
private $nodeNameResolver;

public function __construct(NodeNameResolver $nodeNameResolver)
/**
* @var ValueResolver
*/
private $valueResolver;

public function __construct(NodeNameResolver $nodeNameResolver, ValueResolver $valueResolver)
{
$this->nodeNameResolver = $nodeNameResolver;
$this->valueResolver = $valueResolver;
}

public function resolveParamNameFromArg(Arg $arg): string
public function resolveFromNode(Node $node): string
{
$value = $arg->value;
if ($node instanceof Arg) {
$node = $node->value;
}

if ($value instanceof Cast) {
$value = $value->expr;
if ($node instanceof Cast) {
$node = $node->expr;
}

if ($value instanceof Ternary) {
$value = $value->if;
if ($node instanceof Ternary) {
$node = $node->if;
}

while ($value instanceof ArrayDimFetch) {
$value = $value->var;
if ($node instanceof ArrayDimFetch) {
return $this->resolveParamNameFromArrayDimFetch($node);
}

if ($value instanceof PropertyFetch) {
return $this->resolveParamNameFromPropertyFetch($value);
if ($node instanceof PropertyFetch) {
return $this->resolveFromPropertyFetch($node);
}

if ($value instanceof MethodCall) {
return $this->resolveParamNameFromMethodCall($value);
if ($node instanceof MethodCall) {
return $this->resolveFromMethodCall($node);
}

if ($value === null) {
if ($node === null) {
throw new NotImplementedException();
}

$paramName = $this->nodeNameResolver->getName($value);
$paramName = $this->nodeNameResolver->getName($node);
if ($paramName !== null) {
return $paramName;
}

if ($value instanceof String_) {
return $value->value;
if ($node instanceof String_) {
return $node->value;
}

throw new NotImplementedException();
}

private function resolveParamNameFromPropertyFetch(PropertyFetch $propertyFetch): string
private function resolveFromPropertyFetch(PropertyFetch $propertyFetch): string
{
$varName = $this->nodeNameResolver->getName($propertyFetch->var);
if (! is_string($varName)) {
Expand All @@ -81,7 +92,7 @@ private function resolveParamNameFromPropertyFetch(PropertyFetch $propertyFetch)
return $varName . ucfirst($propertyName);
}

private function resolveParamNameFromMethodCall(MethodCall $methodCall): string
private function resolveFromMethodCall(MethodCall $methodCall): string
{
$varName = $this->nodeNameResolver->getName($methodCall->var);
if (! is_string($varName)) {
Expand All @@ -95,4 +106,20 @@ private function resolveParamNameFromMethodCall(MethodCall $methodCall): string

return $varName . ucfirst($methodName);
}

private function resolveParamNameFromArrayDimFetch(ArrayDimFetch $arrayDimFetch): string
{
while ($arrayDimFetch instanceof ArrayDimFetch) {
if ($arrayDimFetch->dim instanceof Scalar) {
$valueName = $this->nodeNameResolver->getName($arrayDimFetch->var);
$dimName = $this->valueResolver->getValue($arrayDimFetch->dim);

return $valueName . ucfirst($dimName);
}

$arrayDimFetch = $arrayDimFetch->var;
}

return $this->resolveFromNode($arrayDimFetch);
}
}
34 changes: 29 additions & 5 deletions rules/nette-kdyby/src/NodeFactory/CustomEventFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,14 @@
use PhpParser\Builder\Method;
use PhpParser\Builder\Namespace_ as NamespaceBuilder;
use PhpParser\Node\Arg;
use PhpParser\Node\Expr\Assign;
use PhpParser\Node\Expr\PropertyFetch;
use PhpParser\Node\Expr\Variable;
use PhpParser\Node\Name\FullyQualified;
use PhpParser\Node\Param;
use PhpParser\Node\Stmt\Class_;
use PhpParser\Node\Stmt\ClassMethod;
use PhpParser\Node\Stmt\Namespace_;
use Rector\CodingStyle\Naming\ClassNaming;
use Rector\Core\Exception\ShouldNotHappenException;
use Rector\Core\PhpParser\Node\NodeFactory;
use Rector\NetteKdyby\BlueprintFactory\VariableWithTypesFactory;
use Rector\NetteKdyby\ValueObject\VariableWithType;
Expand Down Expand Up @@ -83,9 +82,7 @@ private function createConstructClassMethod(array $variableWithTypes): ClassMeth

$methodBuilder->addParam($param);

$assign = new Assign(new PropertyFetch(new Variable('this'), $variableWithType->getName()), new Variable(
$variableWithType->getName()
));
$assign = $this->nodeFactory->createPropertyAssignment($variableWithType->getName());
$methodBuilder->addStmt($assign);
}

Expand Down Expand Up @@ -123,6 +120,8 @@ private function decorateWithConstructorIfHasArgs(ClassBuilder $classBuilder, ar

$variablesWithTypes = $this->variableWithTypesFactory->createVariablesWithTypesFromArgs($args);

$this->ensureVariablesAreUnique($variablesWithTypes, $classBuilder);

$methodBuilder = $this->createConstructClassMethod($variablesWithTypes);
$classBuilder->addStmt($methodBuilder);

Expand All @@ -142,7 +141,32 @@ private function decorateWithConstructorIfHasArgs(ClassBuilder $classBuilder, ar
$variableWithType->getName(),
$variableWithType->getPhpParserTypeNode()
);

$classBuilder->addStmt($getterClassMethod);
}
}

/**
* @param VariableWithType[] $variablesWithTypes
*/
private function ensureVariablesAreUnique(array $variablesWithTypes, ClassBuilder $classBuilder): void
{
$usedVariableNames = [];

$className = $classBuilder->getNode()->name;

foreach ($variablesWithTypes as $variablesWithType) {
if (in_array($variablesWithType->getName(), $usedVariableNames, true)) {
$message = sprintf(
'Variable "$%s" is duplicated in to be created "%s" class',
$variablesWithType->getName(),
$className
);

throw new ShouldNotHappenException($message);
}

$usedVariableNames[] = $variablesWithType->getName();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<?php

namespace Rector\NetteKdyby\Tests\Rector\MethodCall\ReplaceMagicPropertyEventWithEventClassRector\Fixture;

use Rector\NetteKdyby\Tests\Rector\MethodCall\ReplaceMagicPropertyEventWithEventClassRector\Source\SomeUser;

final class DuplicatedEventParams
{
public $onUpload;

public function run(SomeUser $user)
{
$this->onUpload($user['id'], $user['name']);
}
}

?>
-----
<?php

namespace Rector\NetteKdyby\Tests\Rector\MethodCall\ReplaceMagicPropertyEventWithEventClassRector\Fixture;

use Rector\NetteKdyby\Tests\Rector\MethodCall\ReplaceMagicPropertyEventWithEventClassRector\Source\SomeUser;

final class DuplicatedEventParams
{
/**
* @var \Symfony\Contracts\EventDispatcher\EventDispatcherInterface
*/
private $eventDispatcher;
public function __construct(\Symfony\Contracts\EventDispatcher\EventDispatcherInterface $eventDispatcher)
{
$this->eventDispatcher = $eventDispatcher;
}
public function run(SomeUser $user)
{
$duplicatedEventParamsUploadEvent = new \Rector\NetteKdyby\Tests\Rector\MethodCall\ReplaceMagicPropertyEventWithEventClassRector\Fixture\Event\DuplicatedEventParamsUploadEvent($user['id'], $user['name']);
$this->eventDispatcher->dispatch($duplicatedEventParamsUploadEvent);
}
}

?>
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,18 @@ public function test(): void
$this->assertFileEquals(__DIR__ . '/Source/ExpectedFileManagerUploadEvent.php', $expectedEventFilePath);
}

public function testDuplicatedEventParams(): void
{
$this->doTestFile(__DIR__ . '/Fixture/duplicated_event_params.php.inc');

$expectedEventFilePath = dirname($this->originalTempFile) . '/Event/DuplicatedEventParamsUploadEvent.php';
$this->assertFileExists($expectedEventFilePath);
$this->assertFileEquals(
__DIR__ . '/Source/ExpectedDuplicatedEventParamsUploadEvent.php',
$expectedEventFilePath
);
}

protected function getRectorClass(): string
{
return ReplaceMagicPropertyEventWithEventClassRector::class;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

namespace Rector\NetteKdyby\Tests\Rector\MethodCall\ReplaceMagicPropertyEventWithEventClassRector\Fixture\Event;

final class DuplicatedEventParamsUploadEvent extends \Symfony\Contracts\EventDispatcher\Event
{
/**
* @var mixed
*/
private $userId;
/**
* @var mixed
*/
private $userName;
public function __construct($userId, $userName)
{
$this->userId = $userId;
$this->userName = $userName;
}
public function getUserId()
{
return $this->userId;
}
public function getUserName()
{
return $this->userName;
}
}