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
22 changes: 22 additions & 0 deletions .github/workflows/annotated_checkstyle.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# see https://github.com/staabm/annotate-pull-request-from-checkstyle
name: Anotate Checkstyle

on:
pull_request: null
push:
branches:
- master

jobs:
check_fixtures:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: shivammathur/setup-php@v1
with:
php-version: 7.2
coverage: none # disable xdebug, pcov
tools: cs2pr
- run: composer install --no-progress
- run: |
bin/rector process --config rector-ci.yaml --no-progress-bar --ansi --dry-run --output-format=checkstyle | cs2pr
1 change: 1 addition & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
"Rector\\CodeQuality\\": "rules/code-quality/src",
"Rector\\CodingStyle\\": "rules/coding-style/src",
"Rector\\ConsoleDiffer\\": "packages/console-differ/src",
"Rector\\ChangesReporting\\": "packages/changes-reporting/src",
"Rector\\DeadCode\\": "rules/dead-code/src",
"Rector\\DoctrineCodeQuality\\": "rules/doctrine-code-quality/src",
"Rector\\DoctrineGedmoToKnplabs\\": "rules/doctrine-gedmo-to-knplabs/src",
Expand Down
4 changes: 2 additions & 2 deletions docs/AllRectorsOverview.md
Original file line number Diff line number Diff line change
Expand Up @@ -7015,9 +7015,9 @@ Changes heredoc/nowdoc that contains closing word to safe wrapper name

<br>

### `SetcookieRector`
### `SetCookieRector`

- class: [`Rector\Php73\Rector\FuncCall\SetcookieRector`](/../master/rules/php-73/src/Rector/FuncCall/SetcookieRector.php)
- class: [`Rector\Php73\Rector\FuncCall\SetCookieRector`](/../master/rules/php-73/src/Rector/FuncCall/SetCookieRector.php)
- [test fixtures](/../master/rules/php-73/tests/Rector/FuncCall/SetcookieRector/Fixture)

Convert setcookie argument to PHP7.3 option array
Expand Down
11 changes: 11 additions & 0 deletions packages/changes-reporting/config/config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
services:
_defaults:
autowire: true
autoconfigure: true
public: true

Rector\ChangesReporting\:
resource: '../src'
exclude:
- '../src/Contract/*'
- '../src/ValueObject/*'
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@

declare(strict_types=1);

namespace Rector\Core\Application;
namespace Rector\ChangesReporting\Application;

use PhpParser\Node;
use PHPStan\AnalysedCodeException;
use Rector\ChangesReporting\Collector\RectorChangeCollector;
use Rector\ConsoleDiffer\DifferAndFormatter;
use Rector\Core\Application\FileSystem\RemovedAndAddedFilesCollector;
use Rector\Core\Error\ExceptionCorrector;
Expand Down Expand Up @@ -33,9 +34,9 @@ final class ErrorAndDiffCollector
private $differAndFormatter;

/**
* @var AppliedRectorCollector
* @var RectorChangeCollector
*/
private $appliedRectorCollector;
private $rectorChangeCollector;

/**
* @var ExceptionCorrector
Expand All @@ -54,13 +55,13 @@ final class ErrorAndDiffCollector

public function __construct(
DifferAndFormatter $differAndFormatter,
AppliedRectorCollector $appliedRectorCollector,
RectorChangeCollector $rectorChangeCollector,
ExceptionCorrector $exceptionCorrector,
RemovedAndAddedFilesCollector $removedAndAddedFilesCollector,
NodeRemovingCommander $nodeRemovingCommander
) {
$this->differAndFormatter = $differAndFormatter;
$this->appliedRectorCollector = $appliedRectorCollector;
$this->rectorChangeCollector = $rectorChangeCollector;
$this->exceptionCorrector = $exceptionCorrector;
$this->removedAndAddedFilesCollector = $removedAndAddedFilesCollector;
$this->nodeRemovingCommander = $nodeRemovingCommander;
Expand Down Expand Up @@ -103,14 +104,14 @@ public function addFileDiff(SmartFileInfo $smartFileInfo, string $newContent, st
return;
}

$appliedRectors = $this->appliedRectorCollector->getRectorClasses($smartFileInfo);
$rectorChanges = $this->rectorChangeCollector->getRectorChangesByFileInfo($smartFileInfo);

// always keep the most recent diff
$this->fileDiffs[$smartFileInfo->getRealPath()] = new FileDiff(
$smartFileInfo,
$this->differAndFormatter->diff($oldContent, $newContent),
$this->differAndFormatter->diffAndFormat($oldContent, $newContent),
$appliedRectors
$rectorChanges
);
}

Expand Down Expand Up @@ -148,7 +149,8 @@ public function addThrowableWithFileInfo(Throwable $throwable, SmartFileInfo $fi
if ($rectorClass) {
$this->addErrorWithRectorClassMessageAndFileInfo($rectorClass, $throwable->getMessage(), $fileInfo);
} else {
$this->addError(new Error($fileInfo, $throwable->getMessage(), $throwable->getCode()));
$error = new Error($fileInfo, $throwable->getMessage(), $throwable->getCode());
$this->addError($error);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

declare(strict_types=1);

namespace Rector\Core\Report;
namespace Rector\ChangesReporting\Collector;

use Symplify\SmartFileSystem\SmartFileInfo;

Expand Down
70 changes: 70 additions & 0 deletions packages/changes-reporting/src/Collector/RectorChangeCollector.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
<?php

declare(strict_types=1);

namespace Rector\ChangesReporting\Collector;

use PhpParser\Node;
use Rector\ChangesReporting\ValueObject\RectorWithFileAndLineChange;
use Rector\Core\Contract\Rector\RectorInterface;
use Rector\Core\Exception\ShouldNotHappenException;
use Rector\Core\Logging\CurrentRectorProvider;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Symplify\SmartFileSystem\SmartFileInfo;

final class RectorChangeCollector
{
/**
* @var RectorWithFileAndLineChange[]
*/
private $rectorWithFileAndLineChanges = [];

/**
* @var CurrentRectorProvider
*/
private $currentRectorProvider;

public function __construct(CurrentRectorProvider $currentRectorProvider)
{
$this->currentRectorProvider = $currentRectorProvider;
}

public function addRectorClassWithLine(RectorInterface $rector, SmartFileInfo $smartFileInfo, int $line): void
{
$this->rectorWithFileAndLineChanges[] = new RectorWithFileAndLineChange(
$rector,
$smartFileInfo->getRealPath(),
$line
);
}

/**
* @return RectorWithFileAndLineChange[]
*/
public function getRectorChangesByFileInfo(SmartFileInfo $smartFileInfo): array
{
return array_filter(
$this->rectorWithFileAndLineChanges,
function (RectorWithFileAndLineChange $rectorWithFileAndLineChange) use ($smartFileInfo) {
return $rectorWithFileAndLineChange->getRealPath() === $smartFileInfo->getRealPath();
}
);
}

public function notifyNodeFileInfo(Node $node): void
{
$fileInfo = $node->getAttribute(AttributeKey::FILE_INFO);
if ($fileInfo === null) {
// this file was changed before and this is a sub-new node
// array Traverse to all new nodes would have to be used, but it's not worth the performance
return;
}

$currentRector = $this->currentRectorProvider->getCurrentRector();
if ($currentRector === null) {
throw new ShouldNotHappenException();
}

$this->addRectorClassWithLine($currentRector, $fileInfo, $node->getLine());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

declare(strict_types=1);

namespace Rector\Core\Contract\Console\Output;
namespace Rector\ChangesReporting\Contract\Output;

use Rector\Core\Application\ErrorAndDiffCollector;
use Rector\ChangesReporting\Application\ErrorAndDiffCollector;

interface OutputFormatterInterface
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
<?php

declare(strict_types=1);

namespace Rector\ChangesReporting\NodeManipulator;

use PhpParser\Node;
use PhpParser\Node\Expr\Closure;
use PhpParser\Node\Expr\FuncCall;
use PhpParser\Node\Expr\MethodCall;
use PhpParser\Node\Expr\StaticCall;
use PhpParser\Node\Stmt\Class_;
use PhpParser\Node\Stmt\ClassMethod;
use PhpParser\Node\Stmt\Function_;
use Rector\ChangesReporting\Collector\RectorChangeCollector;
use Rector\Core\Exception\ShouldNotHappenException;

final class NotifyingNodeRemover
{
/**
* @var RectorChangeCollector
*/
private $rectorChangeCollector;

public function __construct(RectorChangeCollector $rectorChangeCollector)
{
$this->rectorChangeCollector = $rectorChangeCollector;
}

/**
* @param Closure|ClassMethod|Function_ $node
*/
public function removeStmt(Node $node, int $key): void
{
if ($node->stmts === null) {
throw new ShouldNotHappenException();
}

// notify about remove node
$this->rectorChangeCollector->notifyNodeFileInfo($node->stmts[$key]);

unset($node->stmts[$key]);
}

public function removeParam(ClassMethod $classMethod, int $key): void
{
if ($classMethod->params === null) {
throw new ShouldNotHappenException();
}

// notify about remove node
$this->rectorChangeCollector->notifyNodeFileInfo($classMethod->params[$key]);

unset($classMethod->params[$key]);
}

/**
* @param FuncCall|MethodCall|StaticCall $node
*/
public function removeArg(Node $node, int $key): void
{
if ($node->args === null) {
throw new ShouldNotHappenException();
}

// notify about remove node
$this->rectorChangeCollector->notifyNodeFileInfo($node->args[$key]);

unset($node->args[$key]);
}

public function removeImplements(Class_ $class, int $key): void
{
if ($class->implements === null) {
throw new ShouldNotHappenException();
}

// notify about remove node
$this->rectorChangeCollector->notifyNodeFileInfo($class->implements[$key]);

unset($class->implements[$key]);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
<?php

declare(strict_types=1);

namespace Rector\ChangesReporting\Output;

use Rector\ChangesReporting\Application\ErrorAndDiffCollector;
use Rector\ChangesReporting\Contract\Output\OutputFormatterInterface;
use Rector\Core\ValueObject\Reporting\FileDiff;
use Symfony\Component\Console\Style\SymfonyStyle;

/**
* Inspired by https://github.com/phpstan/phpstan-src/commit/fa1f416981438b80e2f39eabd9f1b62fca9a6803#diff-7a7d635d9f9cf3388e34d414731dece3
*/
final class CheckstyleOutputFormatter implements OutputFormatterInterface
{
/**
* @var string
*/
public const NAME = 'checkstyle';

/**
* @var SymfonyStyle
*/
private $symfonyStyle;

public function __construct(SymfonyStyle $symfonyStyle)
{
$this->symfonyStyle = $symfonyStyle;
}

public function getName(): string
{
return self::NAME;
}

public function report(ErrorAndDiffCollector $errorAndDiffCollector): void
{
$this->symfonyStyle->writeln('<?xml version="1.0" encoding="UTF-8"?>');
$this->symfonyStyle->writeln('<checkstyle>');

foreach ($errorAndDiffCollector->getFileDiffs() as $fileDiff) {
$this->writeFileErrors($fileDiff);
}

$this->writeNonFileErrors($errorAndDiffCollector);

$this->symfonyStyle->writeln('</checkstyle>');
}

private function escape(string $string): string
{
return htmlspecialchars($string, ENT_XML1 | ENT_COMPAT, 'UTF-8');
}

private function writeFileErrors(FileDiff $fileDiff): void
{
$this->symfonyStyle->writeln(sprintf('<file name="%s">', $this->escape($fileDiff->getRelativeFilePath())));

foreach ($fileDiff->getRectorChanges() as $rectorChange) {
$message = $rectorChange->getRectorDefinitionsDescription() . ' (Reported by: ' . $rectorChange->getRectorClass() . ')';
$message = $this->escape($message);

$error = sprintf(
' <error line="%d" column="1" severity="error" message="%s" />',
$this->escape((string) $rectorChange->getLine()),
$message
);
$this->symfonyStyle->writeln($error);
}

$this->symfonyStyle->writeln('</file>');
}

private function writeNonFileErrors(ErrorAndDiffCollector $errorAndDiffCollector): void
{
if ($errorAndDiffCollector->getErrors() !== []) {
$this->symfonyStyle->writeln('<file>');

foreach ($errorAndDiffCollector->getErrors() as $error) {
$escapedMessage = $this->escape($error->getMessage());

$this->symfonyStyle->writeln(
sprintf(' <error severity="error" message="%s" />', $escapedMessage)
);
}

$this->symfonyStyle->writeln('</file>');
}
}
}
Loading