Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FEATURE: Add warnings for removed signals #98

Merged
merged 1 commit into from
Nov 28, 2024
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
61 changes: 60 additions & 1 deletion config/set/contentrepository-90.php
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
use Neos\Rector\Generic\Rules\InjectServiceIfNeededRector;
use Neos\Rector\Generic\Rules\MethodCallToWarningCommentRector;
use Neos\Rector\Generic\Rules\RemoveInjectionsRector;
use Neos\Rector\Generic\Rules\SignalSlotToWarningCommentRector;
use Neos\Rector\Generic\Rules\ToStringToMethodCallOrPropertyFetchRector;
use Neos\Rector\Generic\ValueObject\AddInjection;
use Neos\Rector\Generic\ValueObject\FusionFlowQueryNodePropertyToWarningComment;
Expand All @@ -74,6 +75,7 @@
use Neos\Rector\Generic\ValueObject\MethodCallToWarningComment;
use Neos\Rector\Generic\ValueObject\RemoveInjection;
use Neos\Rector\Generic\ValueObject\RemoveParentClass;
use Neos\Rector\Generic\ValueObject\SignalSlotToWarningComment;
use Rector\Config\RectorConfig;
use Rector\Renaming\Rector\MethodCall\RenameMethodRector;
use Rector\Renaming\Rector\Name\RenameClassRector;
Expand Down Expand Up @@ -407,6 +409,63 @@
*/
$rectorConfig->rule(WorkspaceGetNameRector::class);

/**
* Signals and Slots
* https://docs.neos.io/api/upgrade-instructions/9/signals-and-slots
*/
$signalsAndSlotsToComment = [];
// Neos\ContentRepository\Domain\Service\PublishingService
// - nodePublished
$signalsAndSlotsToComment[] = new SignalSlotToWarningComment(\Neos\ContentRepository\Domain\Service\PublishingService::class, 'nodePublished', 'The signal "nodePublished" on "PublishingService" has been removed. Please check https://docs.neos.io/api/upgrade-instructions/9/signals-and-slots for further information, how to replace a signal.');
// - nodeDiscarded
$signalsAndSlotsToComment[] = new SignalSlotToWarningComment(\Neos\ContentRepository\Domain\Service\PublishingService::class, 'nodeDiscarded', 'The signal "nodeDiscarded" on "PublishingService" has been removed. Please check https://docs.neos.io/api/upgrade-instructions/9/signals-and-slots for further information, how to replace a signal.');
// Neos\ContentRepository\Domain\Service\Context
// - beforeAdoptNode
$signalsAndSlotsToComment[] = new SignalSlotToWarningComment(\Neos\ContentRepository\Domain\Service\Context::class, 'beforeAdoptNode', 'The signal "beforeAdoptNode" on "Context" has been removed. Please check https://docs.neos.io/api/upgrade-instructions/9/signals-and-slots for further information, how to replace a signal.');
// - afterAdoptNode
$signalsAndSlotsToComment[] = new SignalSlotToWarningComment(\Neos\ContentRepository\Domain\Service\Context::class, 'afterAdoptNode', 'The signal "afterAdoptNode" on "Context" has been removed. Please check https://docs.neos.io/api/upgrade-instructions/9/signals-and-slots for further information, how to replace a signal.');
// Neos\ContentRepository\Domain\Repository\NodeDataRepository
// - repositoryObjectsPersisted
$signalsAndSlotsToComment[] = new SignalSlotToWarningComment(\Neos\ContentRepository\Domain\Repository\NodeDataRepository::class, 'repositoryObjectsPersisted', 'The signal "repositoryObjectsPersisted" on "NodeDataRepository" has been removed. Please check https://docs.neos.io/api/upgrade-instructions/9/signals-and-slots for further information, how to replace a signal.');
// Neos\ContentRepository\Domain\Model\Workspace
// - baseWorkspaceChanged
$signalsAndSlotsToComment[] = new SignalSlotToWarningComment(\Neos\ContentRepository\Domain\Model\Workspace::class, 'baseWorkspaceChanged', 'The signal "baseWorkspaceChanged" on "Workspace" has been removed. Please check https://docs.neos.io/api/upgrade-instructions/9/signals-and-slots for further information, how to replace a signal.');
// - beforeNodePublishing
$signalsAndSlotsToComment[] = new SignalSlotToWarningComment(\Neos\ContentRepository\Domain\Model\Workspace::class, 'beforeNodePublishing', 'The signal "beforeNodePublishing" on "Workspace" has been removed. Please check https://docs.neos.io/api/upgrade-instructions/9/signals-and-slots for further information, how to replace a signal.');
// - afterNodePublishing
$signalsAndSlotsToComment[] = new SignalSlotToWarningComment(\Neos\ContentRepository\Domain\Model\Workspace::class, 'afterNodePublishing', 'The signal "afterNodePublishing" on "Workspace" has been removed. Please check https://docs.neos.io/api/upgrade-instructions/9/signals-and-slots for further information, how to replace a signal.');
// Neos\ContentRepository\Domain\Model\NodeData
// - nodePathChanged
$signalsAndSlotsToComment[] = new SignalSlotToWarningComment(\Neos\ContentRepository\Domain\Model\NodeData::class, 'nodePathChanged', 'The signal "nodePathChanged" on "NodeData" has been removed. Please check https://docs.neos.io/api/upgrade-instructions/9/signals-and-slots for further information, how to replace a signal.');
// Neos\ContentRepository\Domain\Model\Node
// - beforeNodeMove
$signalsAndSlotsToComment[] = new SignalSlotToWarningComment(\Neos\ContentRepository\Domain\Model\Node::class, 'beforeNodeMove', 'The signal "beforeNodeMove" on "Node" has been removed. Please check https://docs.neos.io/api/upgrade-instructions/9/signals-and-slots for further information, how to replace a signal.');
// - afterNodeMove
$signalsAndSlotsToComment[] = new SignalSlotToWarningComment(\Neos\ContentRepository\Domain\Model\Node::class, 'afterNodeMove', 'The signal "afterNodeMove" on "Node" has been removed. Please check https://docs.neos.io/api/upgrade-instructions/9/signals-and-slots for further information, how to replace a signal.');
// - beforeNodeCopy
$signalsAndSlotsToComment[] = new SignalSlotToWarningComment(\Neos\ContentRepository\Domain\Model\Node::class, 'beforeNodeCopy', 'The signal "beforeNodeCopy" on "Node" has been removed. Please check https://docs.neos.io/api/upgrade-instructions/9/signals-and-slots for further information, how to replace a signal.');
// - afterNodeCopy
$signalsAndSlotsToComment[] = new SignalSlotToWarningComment(\Neos\ContentRepository\Domain\Model\Node::class, 'afterNodeCopy', 'The signal "afterNodeCopy" on "Node" has been removed. Please check https://docs.neos.io/api/upgrade-instructions/9/signals-and-slots for further information, how to replace a signal.');
// - nodePathChanged
$signalsAndSlotsToComment[] = new SignalSlotToWarningComment(\Neos\ContentRepository\Domain\Model\Node::class, 'nodePathChanged', 'The signal "nodePathChanged" on "Node" has been removed. Please check https://docs.neos.io/api/upgrade-instructions/9/signals-and-slots for further information, how to replace a signal.');
// - beforeNodeCreate
$signalsAndSlotsToComment[] = new SignalSlotToWarningComment(\Neos\ContentRepository\Domain\Model\Node::class, 'beforeNodeCreate', 'The signal "beforeNodeCreate" on "Node" has been removed. Please check https://docs.neos.io/api/upgrade-instructions/9/signals-and-slots for further information, how to replace a signal.');
// - afterNodeCreate
$signalsAndSlotsToComment[] = new SignalSlotToWarningComment(\Neos\ContentRepository\Domain\Model\Node::class, 'afterNodeCreate', 'The signal "afterNodeCreate" on "Node" has been removed. Please check https://docs.neos.io/api/upgrade-instructions/9/signals-and-slots for further information, how to replace a signal.');
// - nodeAdded
$signalsAndSlotsToComment[] = new SignalSlotToWarningComment(\Neos\ContentRepository\Domain\Model\Node::class, 'nodeAdded', 'The signal "nodeAdded" on "Node" has been removed. Please check https://docs.neos.io/api/upgrade-instructions/9/signals-and-slots for further information, how to replace a signal.');
// - nodeUpdated
$signalsAndSlotsToComment[] = new SignalSlotToWarningComment(\Neos\ContentRepository\Domain\Model\Node::class, 'nodeUpdated', 'The signal "nodeUpdated" on "Node" has been removed. Please check https://docs.neos.io/api/upgrade-instructions/9/signals-and-slots for further information, how to replace a signal.');
// - nodeRemoved
$signalsAndSlotsToComment[] = new SignalSlotToWarningComment(\Neos\ContentRepository\Domain\Model\Node::class, 'nodeRemoved', 'The signal "nodeRemoved" on "Node" has been removed. Please check https://docs.neos.io/api/upgrade-instructions/9/signals-and-slots for further information, how to replace a signal.');
// - beforeNodePropertyChange
$signalsAndSlotsToComment[] = new SignalSlotToWarningComment(\Neos\ContentRepository\Domain\Model\Node::class, 'beforeNodePropertyChange', 'The signal "beforeNodePropertyChange" on "Node" has been removed. Please check https://docs.neos.io/api/upgrade-instructions/9/signals-and-slots for further information, how to replace a signal.');
// - nodePropertyChanged
$signalsAndSlotsToComment[] = new SignalSlotToWarningComment(\Neos\ContentRepository\Domain\Model\Node::class, 'nodePropertyChanged', 'The signal "nodePropertyChanged" on "Node" has been removed. Please check https://docs.neos.io/api/upgrade-instructions/9/signals-and-slots for further information, how to replace a signal.');

$rectorConfig->ruleWithConfiguration(SignalSlotToWarningCommentRector::class, $signalsAndSlotsToComment);


/**
* Neos.Fusion:Attributes
*/
Expand Down Expand Up @@ -476,7 +535,7 @@

// We can only add one rule per class name. As workaround, we need to alias the RenameClassRector, so we are able to
// add this rule twice.
if (!class_exists(\Alias\RenameClassRectorLegacy::class)){
if (!class_exists(\Alias\RenameClassRectorLegacy::class)) {
class_alias(RenameClassRector::class, \Alias\RenameClassRectorLegacy::class);
}
$rectorConfig->ruleWithConfiguration(\Alias\RenameClassRectorLegacy::class, [
Expand Down
107 changes: 107 additions & 0 deletions src/Generic/Rules/SignalSlotToWarningCommentRector.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
<?php

declare (strict_types=1);

namespace Neos\Rector\Generic\Rules;

use Neos\Flow\SignalSlot\Dispatcher;
use Neos\Rector\Generic\ValueObject\MethodCallToWarningComment;
use Neos\Rector\Generic\ValueObject\SignalSlotToWarningComment;
use Neos\Rector\Utility\CodeSampleLoader;
use PhpParser\Node;
use PHPStan\Type\ObjectType;
use Rector\Core\Contract\Rector\ConfigurableRectorInterface;
use Rector\Core\Rector\AbstractRector;
use Rector\PostRector\Collector\NodesToAddCollector;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
use Webmozart\Assert\Assert;
use Neos\Rector\ContentRepository90\Legacy\NodeLegacyStub;

final class SignalSlotToWarningCommentRector extends AbstractRector implements ConfigurableRectorInterface
{
use AllTraits;

/**
* @var SignalSlotToWarningComment[]
*/
private array $signalSlotToWarningComments = [];

public function __construct(
private readonly NodesToAddCollector $nodesToAddCollector
)
{
}

public function getRuleDefinition(): RuleDefinition
{
return CodeSampleLoader::fromFile('"Warning comments for various non-supported signals', __CLASS__, [
new SignalSlotToWarningComment(Node::class, 'beforeMove', '!! This signal "beforeMove" on Node doesn\'t exist anymore')
]);
}

/**
* @return array<class-string<Node>>
*/
public function getNodeTypes(): array
{
return [\PhpParser\Node\Expr\MethodCall::class];
}

/**
* @param \PhpParser\Node\Expr\MethodCall $node
*/
public function refactor(Node $node): ?Node
{
assert($node instanceof Node\Expr\MethodCall);

if (!$this->isName($node->name, 'connect')) {
return null;
}

if (!$this->isObjectType($node->var, new ObjectType(Dispatcher::class))) {
return null;
}

foreach ($this->signalSlotToWarningComments as $signalSlotToWarningComment) {
$className = null;
if ($node->args[0]->value instanceof Node\Expr\ClassConstFetch) {
$className = (string) $node->args[0]->value->class;
} elseif ($node->args[0]->value instanceof Node\Scalar) {
$className = (string)$node->args[0]->value->value;
}

if ($className !== $signalSlotToWarningComment->className){
continue;
}

$methodName = null;
if ($node->args[1]->value instanceof Node\Scalar\String_) {
$methodName = (string)$node->args[1]->value->value;
}

if ($methodName !== $signalSlotToWarningComment->signalName) {
continue;
}

$this->nodesToAddCollector->addNodesBeforeNode(
[
self::todoComment($signalSlotToWarningComment->warningMessage)
],
$node
);

return $node;
}
return null;
}


/**
* @param mixed[] $configuration
*/
public function configure(array $configuration) : void
{
Assert::allIsAOf($configuration, SignalSlotToWarningComment::class);
$this->signalSlotToWarningComments = $configuration;
}
}
15 changes: 15 additions & 0 deletions src/Generic/ValueObject/SignalSlotToWarningComment.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php
declare(strict_types=1);

namespace Neos\Rector\Generic\ValueObject;

class SignalSlotToWarningComment
{
public function __construct(
public readonly string $className,
public readonly string $signalName,
public readonly string $warningMessage,
)
{
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
<?php

use Neos\Flow\Core\Bootstrap;
use Neos\Flow\Package\Package as BasePackage;
use Neos\Flow\SignalSlot\Dispatcher;
use Neos\Rector\ContentRepository90\Legacy\NodeLegacyStub;

class Package extends BasePackage
{
public function boot(Bootstrap $bootstrap)
{
/** @var Dispatcher $dispatcher */
$dispatcher = $bootstrap->getSignalSlotDispatcher();

$dispatcher->connect(
NodeLegacyStub::class,
'beforeMove',
SomeOtherClass::class,
'someMethod'
);

$dispatcher->connect(
'Neos\Rector\ContentRepository90\Legacy\NodeLegacyStub',
'afterMove',
SomeOtherClass::class,
'someMethod'
);

$dispatcher->connect(
NodeLegacyStub::class,
'otherMethod',
SomeOtherClass::class,
'someMethod'
);

$dispatcher->connect(
OtherClass::class,
'afterMove',
SomeOtherClass::class,
'someMethod'
);
}
}

?>
-----
<?php

use Neos\Flow\Core\Bootstrap;
use Neos\Flow\Package\Package as BasePackage;
use Neos\Flow\SignalSlot\Dispatcher;
use Neos\Rector\ContentRepository90\Legacy\NodeLegacyStub;

class Package extends BasePackage
{
public function boot(Bootstrap $bootstrap)
{
/** @var Dispatcher $dispatcher */
$dispatcher = $bootstrap->getSignalSlotDispatcher();
// TODO 9.0 migration: Signal "beforeMove" doesn't exist anymore


$dispatcher->connect(
NodeLegacyStub::class,
'beforeMove',
SomeOtherClass::class,
'someMethod'
);
// TODO 9.0 migration: Signal "afterMove" doesn't exist anymore


$dispatcher->connect(
'Neos\Rector\ContentRepository90\Legacy\NodeLegacyStub',
'afterMove',
SomeOtherClass::class,
'someMethod'
);

$dispatcher->connect(
NodeLegacyStub::class,
'otherMethod',
SomeOtherClass::class,
'someMethod'
);

$dispatcher->connect(
OtherClass::class,
'afterMove',
SomeOtherClass::class,
'someMethod'
);
}
}

?>
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

declare(strict_types=1);

namespace Neos\Rector\Tests\Generic\Rules\ToStringToPropertyFetchRector;

use Rector\Testing\PHPUnit\AbstractRectorTestCase;

final class SignalSlotToWarningCommentRectorTest extends AbstractRectorTestCase
{
/**
* @dataProvider provideData()
*/
public function test(string $fileInfo): void
{
$this->doTestFile($fileInfo);
}

/**
* @return \Iterator<string>
*/
public function provideData(): \Iterator
{
return $this->yieldFilesFromDirectory(__DIR__ . '/Fixture');
}

public function provideConfigFilePath(): string
{
return __DIR__ . '/config/configured_rule.php';
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

declare (strict_types=1);

use Neos\Rector\Generic\Rules\SignalSlotToWarningCommentRector;
use Neos\Rector\Generic\ValueObject\SignalSlotToWarningComment;
use Rector\Config\RectorConfig;

return static function (RectorConfig $rectorConfig) : void {
$rectorConfig->ruleWithConfiguration(SignalSlotToWarningCommentRector::class, [
new SignalSlotToWarningComment(Neos\Rector\ContentRepository90\Legacy\NodeLegacyStub::class, 'beforeMove', 'Signal "beforeMove" doesn\'t exist anymore'),
new SignalSlotToWarningComment(Neos\Rector\ContentRepository90\Legacy\NodeLegacyStub::class, 'afterMove', 'Signal "afterMove" doesn\'t exist anymore'),
]);
};
Loading
Loading