Skip to content
Permalink
Browse files

Analyse dev-tools (#249)

  • Loading branch information
kubawerlos committed Mar 6, 2020
1 parent 16ea6c7 commit cf4b50e208c470a31d0a694b652e065bf2812be9
@@ -21,15 +21,15 @@
"composer validate --strict --working-dir=..",
"composer normalize --dry-run ../composer.json",
"composer-require-checker check ../composer.json",
"phpcs --exclude=Generic.Files.LineLength --report-full --standard=PSR2 ../src ../dev-tools/src ../tests",
"types-checker ../src ../dev-tools/src ../tests",
"phpcs --exclude=Generic.Files.LineLength --report-full --standard=PSR2 ./src ../src ../tests",
"types-checker ./src ../src ../tests",
"phpmd ../src text ./phpmd.xml",
"phpstan analyse --no-progress",
"psalm --no-progress --shepherd"
],
"fix": [
"composer normalize ../composer.json",
"phpcbf --exclude=Generic.Files.LineLength --report-full --standard=PSR2 ../src ../dev-tools/src ../tests || exit 0"
"phpcbf --exclude=Generic.Files.LineLength --report-full --standard=PSR2 ./src ../src ../tests || exit 0"
],
"infection": [
"infection run --ansi --min-msi=100 --only-covered --threads=16"
@@ -1,13 +1,16 @@
parameters:
autoload_files:
- ../vendor/autoload.php
excludes_analyse:
- ./src/Readme
ignoreErrors:
- '#^Method PhpCsFixerCustomFixers\\Fixer\\[a-zA-Z]+::configure\(\) has parameter \$configuration with no value type specified in iterable type array\.$#'
- '#^Parameter \#\d+ \$[a-zA-Z]+ of method PhpCsFixer\\Tokenizer\\Tokens::insertAt\(\) expects#'
- '#^Parameter \#\d+ \$[a-zA-Z]+ of method PhpCsFixer\\Tokenizer\\Tokens::overrideRange\(\) expects#'
- '#has parameter \$tokens with no value type specified in iterable type PhpCsFixer\\Tokenizer\\Tokens\.#'
level: max
paths:
- ./src
- ../src

includes:
@@ -4,14 +4,19 @@
xmlns='https://getpsalm.org/schema/config'
xsi:schemaLocation='https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd'
allowStringToStandInForClass='true'
autoloader='../vendor/autoload.php'
findUnusedCode='true'
findUnusedVariablesAndParams='true'
strictBinaryOperands='true'
totallyTyped='true'
usePhpDocMethodsWithoutMagicCall='true'
>
<projectFiles>
<directory name='./src' />
<directory name='../src' />
<ignoreFiles>
<directory name='./src/Readme' />
</ignoreFiles>
</projectFiles>

<issueHandlers>
@@ -22,6 +27,7 @@
<LoopInvalidation errorLevel='suppress' />
<MoreSpecificReturnType>
<errorLevel type='suppress'>
<file name='./src/Fixers.php' />
<file name='../src/Fixers.php' />
</errorLevel>
</MoreSpecificReturnType>
@@ -30,6 +36,7 @@
<PossiblyNullOperand errorLevel='suppress' />
<PossiblyUnusedMethod>
<errorLevel type='suppress'>
<file name='./src/Fixer/OrderedClassElementsInternalFixer.php' />
<file name='../src/Analyzer/Analysis/SwitchAnalysis.php' />
<file name='../src/Fixer/DeprecatingFixerInterface.php' />
</errorLevel>
@@ -71,34 +71,43 @@ public function fix(\SplFileInfo $file, Tokens $tokens): void

/**
* @internal
*
* @param array<array<string>> $elements
*/
function usort(array &$elements): void
{
\usort($elements, static function (array $a, array $b) {
if ($a['type'] === 'method' && $a['visibility'] === 'public'
&& $b['type'] === 'method' && $b['visibility'] === 'public'
&& isset($a['name'], $b['name'])) {
if (!\in_array($a['name'], OrderedClassElementsInternalFixer::PUBLIC_METHODS_ORDER, true)) {
throw new \Exception(\sprintf('Method %s not in order list', $a['name']));
}
if (!\in_array($b['name'], OrderedClassElementsInternalFixer::PUBLIC_METHODS_ORDER, true)) {
throw new \Exception(\sprintf('Method %s not in order list', $b['name']));
}
foreach (OrderedClassElementsInternalFixer::PUBLIC_METHODS_ORDER as $name) {
if ($a['name'] === $name) {
return -1;
\usort(
$elements,
/**
* @param string[] $a
* @param string[] $b
*/
static function (array $a, array $b): int {
if ($a['type'] === 'method' && $a['visibility'] === 'public'
&& $b['type'] === 'method' && $b['visibility'] === 'public'
&& isset($a['name'], $b['name'])) {
if (!\in_array($a['name'], OrderedClassElementsInternalFixer::PUBLIC_METHODS_ORDER, true)) {
throw new \Exception(\sprintf('Method %s not in order list', $a['name']));
}
if ($b['name'] === $name) {
return 1;
if (!\in_array($b['name'], OrderedClassElementsInternalFixer::PUBLIC_METHODS_ORDER, true)) {
throw new \Exception(\sprintf('Method %s not in order list', $b['name']));
}
foreach (OrderedClassElementsInternalFixer::PUBLIC_METHODS_ORDER as $name) {
if ($a['name'] === $name) {
return -1;
}
if ($b['name'] === $name) {
return 1;
}
}
}
}

if ($a['position'] === $b['position']) {
return $a['start'] <=> $b['start'];
}
if ($a['position'] === $b['position']) {
return $a['start'] <=> $b['start'];
}

return $a['position'] <=> $b['position'];
});
return $a['position'] <=> $b['position'];
}
);
}
}
@@ -43,19 +43,31 @@ public function isRisky(): bool

public function fix(\SplFileInfo $file, Tokens $tokens): void
{
/** @var int[] $indices */
$indices = $tokens->findSequence([[T_EXTENDS], [T_STRING, 'AbstractFixer']]);

$classNameIndex = $tokens->getPrevMeaningfulToken(\key($indices));
/** @var int $sequencesStartIndex */
$sequencesStartIndex = \key($indices);

/** @var int $classNameIndex */
$classNameIndex = $tokens->getPrevMeaningfulToken($sequencesStartIndex);

$className = $tokens[$classNameIndex]->getContent();

/** @var int $startIndex */
$startIndex = $tokens->getNextTokenOfKind(\key($indices), ['{']);
$startIndex = $tokens->getNextTokenOfKind($sequencesStartIndex, ['{']);

$endIndex = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_CURLY_BRACE, $startIndex);

/** @var int[] $indices */
$indices = $tokens->findSequence([[T_PUBLIC], [T_FUNCTION], [T_STRING, 'getPriority']], $startIndex, $endIndex);

/** @var int $sequencesStartIndex */
$sequencesStartIndex = \key($indices);

/** @var int $startIndex */
$startIndex = $tokens->getNextTokenOfKind(\key($indices), ['{']);
$startIndex = $tokens->getNextTokenOfKind($sequencesStartIndex, ['{']);

$endIndex = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_CURLY_BRACE, $startIndex);

$commentsToInsert = $this->getCommentsToInsert($className);
@@ -73,6 +85,7 @@ public function fix(\SplFileInfo $file, Tokens $tokens): void
$tokens[$index] = \array_shift($commentsToInsert);
}

/** @var int $returnIndex */
$returnIndex = $tokens->getNextTokenOfKind($startIndex, [[T_RETURN]]);

foreach (\array_reverse($commentsToInsert) as $comment) {
@@ -85,11 +98,18 @@ public function fix(\SplFileInfo $file, Tokens $tokens): void
);
}

$priorityStartIndex = $tokens->getNextTokenOfKind($startIndex, [[T_RETURN]]) + 2;
/** @var int $nextIndex */
$nextIndex = $tokens->getNextTokenOfKind($startIndex, [[T_RETURN]]);

$priorityStartIndex = $nextIndex + 2;
if ($tokens[$priorityStartIndex]->isGivenKind(T_VARIABLE)) {
return;
}
$priorityEndIndex = $tokens->getNextTokenOfKind($priorityStartIndex, [';']) - 1;

/** @var int $nextIndex */
$nextIndex = $tokens->getNextTokenOfKind($priorityStartIndex, [';']);

$priorityEndIndex = $nextIndex - 1;

$priorityCollection = PriorityCollection::create();
$priority = $priorityCollection->getPriorityFixer($className)->getPriority();
@@ -4,20 +4,28 @@

namespace PhpCsFixerCustomFixersDev;

use PhpCsFixer\Fixer\FixerInterface;
use Symfony\Component\Finder\Finder;
use Symfony\Component\Finder\SplFileInfo;

/**
* @implements \IteratorAggregate<FixerInterface>
*
* @internal
*/
final class Fixers implements \IteratorAggregate
{
/**
* @return \Generator<FixerInterface>
*/
public function getIterator(): \Generator
{
$finder = Finder::create()
->files()
->in(__DIR__ . '/Fixer/')
->sortByName();

/** @var SplFileInfo $fileInfo */
foreach ($finder as $fileInfo) {
$className = __NAMESPACE__ . '\\Fixer\\' . $fileInfo->getBasename('.php');
yield new $className();
@@ -16,6 +16,7 @@ final class PriorityCollection

public static function create(): self
{
/** @var null|self $instance */
static $instance;

if ($instance === null) {
@@ -36,8 +37,7 @@ public function __construct()
$this->priorityFixers[(new \ReflectionObject($fixer))->getShortName()] = new PriorityFixer($fixer, null);
}

$priorityTest = new PriorityTest();
foreach ($priorityTest->providePriorityCases() as [$firstFixer, $secondFixer]) {
foreach (PriorityTest::providePriorityCases() as [$firstFixer, $secondFixer]) {
$this->priorityFixer($firstFixer)->addFixerToRunAfter($this->priorityFixer($secondFixer));
$this->priorityFixer($secondFixer)->addFixerToRunBefore($this->priorityFixer($firstFixer));
}
@@ -54,7 +54,7 @@ public function __construct()

foreach ($this->priorityFixers as $priorityFixer) {
if (!$priorityFixer->hasPriority()) {
$anythingChanged |= $priorityFixer->calculatePriority(true);
$anythingChanged = $anythingChanged || $priorityFixer->calculatePriority(true);
}
}
}
@@ -50,16 +50,27 @@ public function getPriority(): int
return $this->priority;
}

/**
* @return string[]
*/
public function getFixerToRunAfterNames(): array
{
return $this->getFixerNames($this->fixersToRunAfter);
}

/**
* @return string[]
*/
public function getFixerToRunBeforeNames(): array
{
return $this->getFixerNames($this->fixersToRunBefore);
}

/**
* @param self[] $priorityFixers
*
* @return string[]
*/
private function getFixerNames(array $priorityFixers): array
{
$fixers = \array_map(
@@ -11,6 +11,7 @@
use PhpCsFixer\FixerDefinition\CodeSample;
use PhpCsFixer\StdinFileInfo;
use PhpCsFixer\Tokenizer\Tokens;
use PhpCsFixerCustomFixers\Fixer\AbstractFixer;
use PhpCsFixerCustomFixers\Fixer\DeprecatingFixerInterface;
use PhpCsFixerCustomFixers\Fixers;
use SebastianBergmann\Diff\Differ;
@@ -29,7 +30,7 @@ final class ReadmeCommand extends BaseCommand

private const SHIELDS_HOST = 'https://img.shields.io';

protected function execute(InputInterface $input, OutputInterface $output): ?int
protected function execute(InputInterface $input, OutputInterface $output): int
{
$output->write(
\sprintf('# %s', self::NAME) . "\n\n"
@@ -166,6 +167,7 @@ private function fixers(): string
{
$output = '## Fixers';

/** @var AbstractFixer $fixer */
foreach (new Fixers() as $fixer) {
$reflection = new \ReflectionClass($fixer);

@@ -200,6 +202,7 @@ private function fixers(): string
return \sprintf('\'%s\'', $value);
}, $option->getAllowedValues());
} else {
/** @var string[] $allowed */
$allowed = $option->getAllowedTypes();
}
$output .= \sprintf(
@@ -110,6 +110,9 @@ static function (array $case): string {
self::assertSame($sorted, $cases);
}

/**
* @return array<array<FixerInterface>>
*/
public static function providePriorityCases(): iterable
{
yield [

0 comments on commit cf4b50e

Please sign in to comment.
You can’t perform that action at this time.