Skip to content

Commit

Permalink
Added more phpdoc fixers
Browse files Browse the repository at this point in the history
  • Loading branch information
GrahamCampbell committed Feb 18, 2015
1 parent e798f88 commit 9f3aab8
Show file tree
Hide file tree
Showing 42 changed files with 3,904 additions and 34 deletions.
45 changes: 45 additions & 0 deletions README.rst
Expand Up @@ -327,15 +327,50 @@ Choose from the list of available fixers:
Docblocks should have the same
indentation as the documented subject.

* **phpdoc_no_empty_return** [symfony]
@return void and @return null
annotations should be omitted from
phpdocs.

* **phpdoc_no_package** [symfony]
@package and @subpackage annotations
should be omitted from phpdocs.

* **phpdoc_params** [symfony]
All items of the @param, @throws,
@return, @var, and @type phpdoc tags
must be aligned vertically.

* **phpdoc_separation** [symfony]
Annotations in phpdocs should be
grouped together so that annotations
of the same type immediately follow
each other, and annotations of a
different type are separated by a
single blank line.

* **phpdoc_short_description** [symfony]
Phpdocs short descriptions should end
in either a full stop, exclamation
mark, or question mark.

* **phpdoc_to_comment** [symfony]
Docblocks should only be used on
structural elements.

* **phpdoc_trim** [symfony]
Phpdocs should start and end with
content, excluding the very fist and
last line of the docblocks.

* **phpdoc_type_to_var** [symfony]
@type should always be written as
@var.

* **phpdoc_var_without_name** [symfony]
@var and @type annotations should not
contain the variable name.

* **remove_leading_slash_use** [symfony]
Remove leading slashes in use clauses.

Expand Down Expand Up @@ -414,6 +449,16 @@ Choose from the list of available fixers:
__construct. Warning! This could
change code behavior.

* **phpdoc_order** [contrib]
Annotations in phpdocs should be
ordered so that param annotations come
first, then throws annotations, then
return annotations.

* **phpdoc_var_to_type** [contrib]
@var should always be written as
@type.

* **short_array_syntax** [contrib]
PHP array's should use the PHP 5.4
short-syntax.
Expand Down
115 changes: 115 additions & 0 deletions Symfony/CS/DocBlock/Annotation.php
@@ -0,0 +1,115 @@
<?php

/*
* This file is part of the PHP CS utility.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/

namespace Symfony\CS\DocBlock;

/**
* This represents an entire annotation from a docblock.
*
* @author Graham Campbell <graham@mineuk.com>
*/
class Annotation
{
/**
* The lines that make up the annotation.
*
* Note that the array indexes represent the position in the docblock.
*
* @var Lines[]
*/
private $lines;

/**
* The associated tag.
*
* @var Tag|null
*/
private $tag;

/**
* Create a new line instance.
*
* @param Lines[] $lines
*/
public function __construct(array $lines)
{
$this->lines = $lines;
}

/**
* Get the start position of this annotation.
*
* @return int
*/
public function getStart()
{
$keys = array_keys($this->lines);

return $keys[0];
}

/**
* Get the end position of this annotation.
*
* @return int
*/
public function getEnd()
{
$keys = array_keys($this->lines);

return end($keys);
}

/**
* Get the associated tag.
*
* @return Tag
*/
public function getTag()
{
if (null === $this->tag) {
$values = array_values($this->lines);
$this->tag = new Tag($values[0]->getContent());
}

return $this->tag;
}

/**
* Remove this annotation by removing all its lines.
*/
public function remove()
{
foreach ($this->lines as $line) {
$line->remove();
}
}

/**
* Get the annotation content.
*
* @return string
*/
public function getContent()
{
return implode($this->lines);
}

/**
* Get the string representation of object.
*
* @return string
*/
public function __toString()
{
return $this->getContent();
}
}
188 changes: 188 additions & 0 deletions Symfony/CS/DocBlock/DocBlock.php
@@ -0,0 +1,188 @@
<?php

/*
* This file is part of the PHP CS utility.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/

namespace Symfony\CS\DocBlock;

use Symfony\CS\Utils;

/**
* This class represents a docblock.
*
* It internally splits it up into "lines" that we can manipulate.
*
* @author Graham Campbell <graham@mineuk.com>
*/
class DocBlock
{
/**
* The array of lines.
*
* @var Line[]
*/
private $lines = array();

/**
* The array of annotations.
*
* @var Annotation[]|null
*/
private $annotations;

/**
* Create a new docblock instance.
*
* @param string $content
*/
public function __construct($content)
{
foreach (Utils::splitLines($content) as $line) {
$this->lines[] = new Line($line);
}
}

/**
* Get this docblock's lines.
*
* @return Line[]
*/
public function getLines()
{
return $this->lines;
}

/**
* Get a single line.
*
* @param int $pos
*
* @return Line|null
*/
public function getLine($pos)
{
if (isset($this->lines[$pos])) {
return $this->lines[$pos];
}
}

/**
* Get this docblock's annotations.
*
* @return Annotation[]
*/
public function getAnnotations()
{
if (null === $this->annotations) {
$this->annotations = array();
$total = count($this->lines);

for ($index = 0; $index < $total; ++$index) {
if ($this->lines[$index]->containsATag()) {
// get all the lines that make up the annotation
$lines = array_slice($this->lines, $index, $this->findAnnotationLength($index), true);
$annotation = new Annotation($lines);
// move the index to the end of the annotation to avoid
// checking it again because we know the lines inside the
// current annotation cannot be part of another annotation
$index = $annotation->getEnd();
// add the current annotation to the list of annotations
$this->annotations[] = $annotation;
}
}
}

return $this->annotations;
}

private function findAnnotationLength($start)
{
$index = $start;

while ($line = $this->getLine(++$index)) {
if ($line->containsATag()) {
// we've 100% reached the end of the description if we get here
break;
}

if (!$line->containsUsefulContent()) {
// if we next line is also non-useful, or contains a tag, then we're done here
$next = $this->getLine($index + 1);
if (null === $next || !$next->containsUsefulContent() || $next->containsATag()) {
break;
}
// otherwise, continue, the annotation must have contained a blank line in its description
}
}

return $index - $start;
}

/**
* Get a single annotation.
*
* @param int $pos
*
* @return Annotation|null
*/
public function getAnnotation($pos)
{
$annotations = $this->getAnnotations();

if (isset($annotations[$pos])) {
return $annotations[$pos];
}
}

/**
* Get specific types of annotations only.
*
* If none exist, we're returning an empty array.
*
* @param string|string[] $types
*
* @return Annotations[]
*/
public function getAnnotationsOfType($types)
{
$annotations = array();
$types = (array) $types;

foreach ($this->getAnnotations() as $annotation) {
$tag = $annotation->getTag()->getName();
foreach ($types as $type) {
if ($type === $tag) {
$annotations[] = $annotation;
}
}
}

return $annotations;
}

/**
* Get the actual content of this docblock.
*
* @return string
*/
public function getContent()
{
return implode($this->lines);
}

/**
* Get the string representation of object.
*
* @return string
*/
public function __toString()
{
return $this->getContent();
}
}

0 comments on commit 9f3aab8

Please sign in to comment.