Skip to content
Permalink
Browse files

Merge pull request #142 from kubawerlos/add-only-allowed-annotations

Add PhpdocOnlyAllowedAnnotationsFixer
  • Loading branch information...
kubawerlos committed Sep 23, 2019
2 parents 310796e + c5084a9 commit 3e488d3408b980ae38ad1fdc147e71bd20c1d060
@@ -53,24 +53,6 @@ return PhpCsFixer\Config::create()
'function_to_constant' => [
'functions' => ['get_class', 'get_called_class', 'php_sapi_name', 'phpversion', 'pi'],
],
'general_phpdoc_annotation_remove' => [
'annotations' => [
'category',
'codeCoverageIgnore',
'codeCoverageIgnoreEnd',
'codeCoverageIgnoreStart',
'copyright',
'date',
'expectedException',
'expectedExceptionCode',
'expectedExceptionMessage',
'expectedExceptionMessageRegExp',
'license',
'since',
'static',
'version',
],
],
'heredoc_to_nowdoc' => true,
'increment_style' => [
'style' => 'post',
@@ -150,6 +132,18 @@ return PhpCsFixer\Config::create()
$carry[$fixer->getName()] = true;
}
if ($fixer instanceof PhpCsFixerCustomFixers\Fixer\PhpdocOnlyAllowedAnnotationsFixer) {
$carry[$fixer->getName()] = ['elements' => [
'covers',
'dataProvider',
'deprecated',
'internal',
'param',
'return',
'var',
]];
}
return $carry;
},
[]
@@ -1,5 +1,8 @@
# CHANGELOG for PHP CS Fixer: custom fixers

## [Unreleased]
- Add PhpdocOnlyAllowedAnnotationsFixer

## v1.15.0 - *2019-08-19*
- Add CommentSurroundedBySpacesFixer
- Add DataProviderReturnTypeFixer
@@ -8,7 +8,7 @@

[![Build status](https://img.shields.io/travis/kubawerlos/php-cs-fixer-custom-fixers/master.svg)](https://travis-ci.org/kubawerlos/php-cs-fixer-custom-fixers)
[![Code coverage](https://img.shields.io/coveralls/github/kubawerlos/php-cs-fixer-custom-fixers/master.svg)](https://coveralls.io/github/kubawerlos/php-cs-fixer-custom-fixers?branch=master)
![Tests](https://img.shields.io/badge/tests-1111-brightgreen.svg)
![Tests](https://img.shields.io/badge/tests-1134-brightgreen.svg)
[![Mutation testing badge](https://badge.stryker-mutator.io/github.com/kubawerlos/php-cs-fixer-custom-fixers/master)](https://stryker-mutator.github.io)
[![Psalm type coverage](https://shepherd.dev/github/kubawerlos/php-cs-fixer-custom-fixers/coverage.svg)](https://shepherd.dev/github/kubawerlos/php-cs-fixer-custom-fixers)

@@ -346,6 +346,21 @@ There must be no superfluous parameters in PHPDoc.
function foo($b, $s) {}
```

#### PhpdocOnlyAllowedAnnotationsFixer
Only listed annotations can be in PHPDoc.
Configuration options:
- `elements` (`array`): list of annotations to keep in PHPDoc; defaults to `[]`
```diff
<?php
/**
* @author John Doe
- * @package foo
- * @subpackage bar
* @version 1.0
*/
function foo_bar() {}
```

#### PhpdocParamOrderFixer
`@param` annotations must be in the same order as function's parameters.
```diff
@@ -214,7 +214,6 @@ private function fixers(): string
if ($fixer instanceof ConfigurableFixerInterface) {
$fixer->configure($codeSample->getConfiguration());
}
$tokens = Tokens::fromCode($originalCode);
$fixer->fix(new StdinFileInfo(), $tokens);
$fixedCode = $tokens->generateCode();
@@ -0,0 +1,99 @@
<?php
declare(strict_types = 1);
namespace PhpCsFixerCustomFixers\Fixer;
use PhpCsFixer\DocBlock\DocBlock;
use PhpCsFixer\Fixer\ConfigurationDefinitionFixerInterface;
use PhpCsFixer\FixerConfiguration\FixerConfigurationResolver;
use PhpCsFixer\FixerConfiguration\FixerOptionBuilder;
use PhpCsFixer\FixerDefinition\CodeSample;
use PhpCsFixer\FixerDefinition\FixerDefinition;
use PhpCsFixer\FixerDefinition\FixerDefinitionInterface;
use PhpCsFixer\Preg;
use PhpCsFixer\Tokenizer\Token;
use PhpCsFixer\Tokenizer\Tokens;
final class PhpdocOnlyAllowedAnnotationsFixer extends AbstractFixer implements ConfigurationDefinitionFixerInterface
{
/** @var string[] */
private $elements = [];
public function getDefinition(): FixerDefinitionInterface
{
return new FixerDefinition(
'Only listed annotations can be in PHPDoc.',
[new CodeSample(
'<?php
/**
* @author John Doe
* @package foo
* @subpackage bar
* @version 1.0
*/
function foo_bar() {}
',
['elements' => ['author', 'version']]
)]
);
}
public function getConfigurationDefinition(): FixerConfigurationResolver
{
return new FixerConfigurationResolver([
(new FixerOptionBuilder('elements', 'list of annotations to keep in PHPDoc'))
->setAllowedTypes(['array'])
->setDefault($this->elements)
->getOption(),
]);
}
public function configure(?array $configuration = null): void
{
$this->elements = $configuration['elements'] ?? $this->elements;
}
public function isCandidate(Tokens $tokens): bool
{
return $tokens->isTokenKindFound(T_DOC_COMMENT);
}
public function isRisky(): bool
{
return false;
}
public function fix(\SplFileInfo $file, Tokens $tokens): void
{
foreach ($tokens as $index => $token) {
if (!$token->isGivenKind(T_DOC_COMMENT)) {
continue;
}
$docBlock = new DocBlock($token->getContent());
foreach ($docBlock->getAnnotations() as $annotation) {
Preg::match('/@([a-zA-Z0-9\Q_-\\\E]+)/', $annotation->getContent(), $matches);
if (\in_array($matches[1], $this->elements, true)) {
continue;
}
$annotation->remove();
}
if ($docBlock->getContent() === '') {
$tokens->clearTokenAndMergeSurroundingWhitespace($index);
continue;
}
$tokens[$index] = new Token([T_DOC_COMMENT, $docBlock->getContent()]);
}
}
public function getPriority(): int
{
// must be run before NoEmptyPhpdocFixer
return 6;
}
}
@@ -0,0 +1,127 @@
<?php
declare(strict_types = 1);
namespace Tests\Fixer;
use PhpCsFixer\Fixer\Phpdoc\NoEmptyPhpdocFixer;
/**
* @internal
*
* @covers \PhpCsFixerCustomFixers\Fixer\PhpdocOnlyAllowedAnnotationsFixer
*/
final class PhpdocOnlyAllowedAnnotationsFixerTest extends AbstractFixerTestCase
{
public function testPriority(): void
{
static::assertGreaterThan((new NoEmptyPhpdocFixer())->getPriority(), $this->fixer->getPriority());
}
public function testConfiguration(): void
{
$options = $this->fixer->getConfigurationDefinition()->getOptions();
static::assertArrayHasKey(0, $options);
static::assertSame('elements', $options[0]->getName());
}
public function testIsRisky(): void
{
static::assertFalse($this->fixer->isRisky());
}
/**
* @param string $expected
* @param null|string $input
* @param null|array $configuration
*
* @dataProvider provideFixCases
*/
public function testFix(string $expected, ?string $input = null, ?array $configuration = null): void
{
$this->fixer->configure($configuration);
$this->doTest($expected, $input);
}
public function provideFixCases(): iterable
{
yield [
'<?php
',
'<?php
/** @var string */
',
];
yield [
'<?php
/**
*/
',
'<?php
/**
* @param Foo $foo
* @return Bar
*/
',
];
yield [
'<?php
/**
* @param Foo $foo
*/
',
'<?php
/**
* @param Foo $foo
* @return Bar
*/
',
['elements' => ['param']],
];
yield [
'<?php
/**
* @ORM\Id
* @ORM\Column(type="integer")
*/
',
'<?php
/**
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(type="integer")
*/
',
['elements' => ['ORM\Id', 'ORM\Column']],
];
yield [
'<?php
/**
* @foo
* @bar
*/
/**
* @foo
*/
',
'<?php
/**
* @foo
* @bar
* @baz
*/
/**
* @foo
* @foobar
*/
',
['elements' => ['foo', 'bar']],
];
}
}

0 comments on commit 3e488d3

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