Browse Source

PhpdocAnnotationWithoutDotFixer - support more cases

Dariusz Ruminski 8 years ago
parent
commit
35bdcb42b6

+ 1 - 1
README.rst

@@ -439,7 +439,7 @@ Choose from the list of available fixers:
    must be aligned vertically.
 
 * **phpdoc_annotation_without_dot** [@Symfony]
-   Phpdocs annotation descriptions should not end with a full stop.
+   Phpdocs annotation descriptions should not be a sentence.
 
 * **phpdoc_indent** [@Symfony]
    Docblocks should have the same indentation as the documented subject.

+ 6 - 1
src/DocBlock/Annotation.php

@@ -184,6 +184,11 @@ class Annotation
         return implode($this->lines);
     }
 
+    public function supportTypes()
+    {
+        return in_array($this->getTag()->getName(), self::$tags, true);
+    }
+
     /**
      * Get the current types content.
      *
@@ -196,7 +201,7 @@ class Annotation
         if (null === $this->typesContent) {
             $name = $this->getTag()->getName();
 
-            if (!in_array($name, self::$tags, true)) {
+            if (!$this->supportTypes()) {
                 throw new \RuntimeException('This tag does not support types');
             }
 

+ 30 - 7
src/Fixer/Phpdoc/PhpdocAnnotationWithoutDotFixer.php

@@ -21,6 +21,10 @@ use PhpCsFixer\Tokenizer\Tokens;
  */
 final class PhpdocAnnotationWithoutDotFixer extends AbstractFixer
 {
+    private $configuration = array(
+        'tags' => array('throws', 'return', 'param', 'internal', 'deprecated', 'var', 'type'),
+    );
+
     /**
      * {@inheritdoc}
      */
@@ -47,16 +51,35 @@ final class PhpdocAnnotationWithoutDotFixer extends AbstractFixer
             }
 
             foreach ($annotations as $annotation) {
-                if ($annotation->getTag()->valid()) {
-                    $line = $doc->getLine($annotation->getEnd());
+                if (
+                    !$annotation->getTag()->valid()
+                    || !in_array($annotation->getTag()->getName(), $this->configuration['tags'], true)
+                ) {
+                    continue;
+                }
 
-                    $content = preg_replace('/(?<![.。])[.。](\s+)$/u', '\1', $line->getContent());
+                $content = $annotation->getContent();
 
-                    if (null !== $content) {
-                        $line->setContent($content);
-                    }
+                if (
+                    1 !== preg_match('/[.。]$/u', $content)
+                    || 0 !== preg_match('/[.。](?!$)/u', $content, $matches)
+                ) {
+                    continue;
                 }
+
+                $endLine = $doc->getLine($annotation->getEnd());
+                $endLine->setContent(preg_replace('/(?<![.。])[.。](\s+)$/u', '\1', $endLine->getContent()));
+
+                $startLine = $doc->getLine($annotation->getStart());
+                $optionalTypeRegEx = $annotation->supportTypes()
+                    ? sprintf('(?:%s\s+(?:\$\w+\s+)?)?', preg_quote(implode('|', $annotation->getTypes())))
+                    : '';
+                $content = preg_replace_callback('/^(\s*\*\s*@\w+\s+'.$optionalTypeRegEx.')(.*)$/', function (array $matches) {
+                    return $matches[1].lcfirst($matches[2]);
+                }, $startLine->getContent(), 1);
+                $startLine->setContent($content);
             }
+
             $token->setContent($doc->getContent());
         }
     }
@@ -66,6 +89,6 @@ final class PhpdocAnnotationWithoutDotFixer extends AbstractFixer
      */
     public function getDescription()
     {
-        return 'Phpdocs annotation descriptions should not end with a full stop.';
+        return 'Phpdocs annotation descriptions should not be a sentence.';
     }
 }

+ 43 - 4
tests/Fixer/Phpdoc/PhpdocAnnotationWithoutDotFixerTest.php

@@ -39,15 +39,16 @@ final class PhpdocAnnotationWithoutDotFixerTest extends AbstractFixerTestCase
      *
      * Description.
      *
-     * @param string $str        Some string
+     * @param string|null $str   some string
+     * @param string $genrb      Optional. The path to the "genrb" executable
      * @param string $ellipsis1  Ellipsis is this: ...
      * @param string $ellipsis2  Ellipsis is this: 。。。
      * @param string $ellipsis3  Ellipsis is this: …
      * @param bool   $isStr      Is it a string?
      * @param int    $int        Some multiline
-     *                           description. With many dots
+     *                           description. With many dots.
      *
-     * @return array Result array
+     * @return array result array
      *
      * @SomeCustomAnnotation This is important sentence that must not be modified.
      */',
@@ -57,7 +58,8 @@ final class PhpdocAnnotationWithoutDotFixerTest extends AbstractFixerTestCase
      *
      * Description.
      *
-     * @param string $str        Some string.
+     * @param string|null $str   Some string.
+     * @param string $genrb      Optional. The path to the "genrb" executable
      * @param string $ellipsis1  Ellipsis is this: ...
      * @param string $ellipsis2  Ellipsis is this: 。。。
      * @param string $ellipsis3  Ellipsis is this: …
@@ -76,6 +78,43 @@ final class PhpdocAnnotationWithoutDotFixerTest extends AbstractFixerTestCase
     /**
      * @var string This: '.chr(174).' is an odd character.
      * @var string This: '.chr(174).' is an odd character 2nd time。
+     */',
+            ),
+            array(
+                '<?php
+    /**
+     * @deprecated since version 2. Use emergency() which is PSR-3 compatible.
+     */',
+            ),
+            array(
+                '<?php
+    /**
+     * @internal This method is public to be usable as callback. It should not
+     *           be used in user code.
+     */',
+            ),
+            array(
+                '<?php
+    /**
+     * @deprecated this is
+     *             deprecated
+     */',
+                '<?php
+    /**
+     * @deprecated This is
+     *             deprecated.
+     */',
+            ),
+            array(
+                '<?php
+    /**
+     * @return bool|null returns `true` if the class has a single-column ID
+     *                   and Returns `false` otherwise
+     */',
+                '<?php
+    /**
+     * @return bool|null Returns `true` if the class has a single-column ID
+     *                   and Returns `false` otherwise.
      */',
             ),
         );