diff --git a/src/Barryvdh/Reflection/DocBlock/Serializer.php b/src/Barryvdh/Reflection/DocBlock/Serializer.php index 65942699..aabe06ac 100644 --- a/src/Barryvdh/Reflection/DocBlock/Serializer.php +++ b/src/Barryvdh/Reflection/DocBlock/Serializer.php @@ -36,6 +36,9 @@ class Serializer /** @var int|null The max length of a line. */ protected $lineLength = null; + /** @var bool Separate tag groups. */ + protected $separateTags = false; + /** * Create a Serializer instance. * @@ -45,17 +48,20 @@ class Serializer * @param bool $indentFirstLine Whether to indent the first line. * @param int|null $lineLength The max length of a line or NULL to * disable line wrapping. + * @param bool $separateTags Separate tag groups. */ public function __construct( $indent = 0, $indentString = ' ', $indentFirstLine = true, - $lineLength = null + $lineLength = null, + $separateTags = false ) { $this->setIndentationString($indentString); $this->setIndent($indent); $this->setIsFirstLineIndented($indentFirstLine); $this->setLineLength($lineLength); + $this->setSeparateTags($separateTags); } /** @@ -158,6 +164,29 @@ public function getLineLength() return $this->lineLength; } + /** + * Sets whether there should be an empty line between tag groups. + * + * @param bool $separateTags The new value for this setting. + * + * @return $this This serializer object. + */ + public function setSeparateTags($separateTags) + { + $this->separateTags = (bool)$separateTags; + return $this; + } + + /** + * Gets whether there should be an empty line between tag groups. + * + * @return bool Whether there should be an empty line between tag groups. + */ + public function getSeparateTags() + { + return $this->separateTags; + } + /** * Generate a DocBlock comment. * @@ -180,8 +209,12 @@ public function getDocComment(DocBlock $docblock) $comment = "{$firstIndent}/**\n{$indent} * {$text}\n{$indent} *\n"; + $tags = array_values($docblock->getTags()); + /** @var Tag $tag */ - foreach ($docblock->getTags() as $tag) { + foreach ($tags as $key => $tag) { + $nextTag = isset($tags[$key + 1]) ? $tags[$key + 1] : null; + $tagText = (string) $tag; if ($this->lineLength) { $tagText = wordwrap($tagText, $wrapLength); @@ -189,6 +222,10 @@ public function getDocComment(DocBlock $docblock) $tagText = str_replace("\n", "\n{$indent} * ", $tagText); $comment .= "{$indent} * {$tagText}\n"; + + if ($this->separateTags && $nextTag !== null && ! $tag->inSameGroup($nextTag)) { + $comment .= "{$indent} *\n"; + } } $comment .= $indent . ' */'; diff --git a/src/Barryvdh/Reflection/DocBlock/Tag.php b/src/Barryvdh/Reflection/DocBlock/Tag.php index 8665f53c..14a1a483 100644 --- a/src/Barryvdh/Reflection/DocBlock/Tag.php +++ b/src/Barryvdh/Reflection/DocBlock/Tag.php @@ -352,6 +352,39 @@ public function setLocation(Location $location = null) return $this; } + /** + * If the given tags should be together or apart. + * + * @param Tag $tag + * + * @return bool + */ + public function inSameGroup(Tag $tag) + { + $firstName = $this->getName(); + $secondName = $tag->getName(); + + if ($firstName === $secondName) { + return true; + } + + $groups = array( + array('deprecated', 'link', 'see', 'since'), + array('author', 'copyright', 'license'), + array('category', 'package', 'subpackage'), + array('property', 'property-read', 'property-write'), + array('param', 'return'), + ); + + foreach ($groups as $group) { + if (in_array($firstName, $group, true) && in_array($secondName, $group, true)) { + return true; + } + } + + return false; + } + /** * Builds a string representation of this object. *