Commit c3fe4aa0 by Carsten Brandt

`@inheritdoc` from interfaces and params

parent 39a2e1ef
...@@ -42,6 +42,26 @@ class BaseDoc extends Object ...@@ -42,6 +42,26 @@ class BaseDoc extends Object
*/ */
public $tags = []; public $tags = [];
public function hasTag($name)
{
foreach ($this->tags as $tag) {
if (strtolower($tag->getName()) == $name) {
return true;
}
}
return false;
}
public function removeTag($name)
{
foreach ($this->tags as $i => $tag) {
if (strtolower($tag->getName()) == $name) {
unset($this->tags[$i]);
}
}
}
/** /**
* @param \phpDocumentor\Reflection\BaseReflector $reflector * @param \phpDocumentor\Reflection\BaseReflector $reflector
* @param Context $context * @param Context $context
...@@ -70,7 +90,7 @@ class BaseDoc extends Object ...@@ -70,7 +90,7 @@ class BaseDoc extends Object
'message' => "No short description for " . substr(StringHelper::basename(get_class($this)), 0, -3) . " '{$this->name}'", 'message' => "No short description for " . substr(StringHelper::basename(get_class($this)), 0, -3) . " '{$this->name}'",
]; ];
} }
$this->description = $docblock->getLongDescription(); $this->description = $docblock->getLongDescription()->getContents();
$this->phpDocContext = $docblock->getContext(); $this->phpDocContext = $docblock->getContext();
......
...@@ -164,11 +164,33 @@ class Context extends Component ...@@ -164,11 +164,33 @@ class Context extends Component
{ {
// TODO also for properties? // TODO also for properties?
foreach ($class->methods as $m) { foreach ($class->methods as $m) {
$inheritedMethod = $this->inheritMethodRecursive($m, $class); if ($m->hasTag('inheritdoc')) {
foreach (['shortDescription', 'description', 'params', 'return', 'returnType', 'returnTypes', 'exceptions'] as $property) { $inheritedMethod = $this->inheritMethodRecursive($m, $class);
if (empty($m->$property)) { foreach (['shortDescription', 'description', 'return', 'returnType', 'returnTypes', 'exceptions'] as $property) {
$m->$property = $inheritedMethod->$property; if (empty($m->$property) || is_string($m->$property) && trim($m->$property) === '') {
$m->$property = $inheritedMethod->$property;
}
} }
foreach ($m->params as $i => $param) {
if (!isset($inheritedMethod->params[$i])) {
$this->errors[] = [
'line' => $m->startLine,
'file' => $class->sourceFile,
'message' => "Method param $i does not exist in parent method, @inheritdoc not possible in {$m->name} in {$class->name}.",
];
continue;
}
if (empty($param->description) || trim($param->description) === '') {
$param->description = $inheritedMethod->params[$i]->description;
}
if (empty($param->type) || trim($param->type) === '') {
$param->type = $inheritedMethod->params[$i]->type;
}
if (empty($param->types) || trim($param->types) === '') {
$param->types = $inheritedMethod->params[$i]->types;
}
}
$m->removeTag('inheritdoc');
} }
} }
} }
...@@ -179,20 +201,50 @@ class Context extends Component ...@@ -179,20 +201,50 @@ class Context extends Component
*/ */
private function inheritMethodRecursive($method, $class) private function inheritMethodRecursive($method, $class)
{ {
if (!isset($this->classes[$class->parentClass])) { $inheritanceCandidates = array_merge(
return $method; $this->getParents($class),
} $this->getInterfaces($class)
$parent = $this->classes[$class->parentClass]; );
foreach ($method->tags as $tag) {
if (strtolower($tag->getName()) == 'inheritdoc') { $methods = [];
if (isset($parent->methods[$method->name])) { foreach($inheritanceCandidates as $candidate) {
$method = $parent->methods[$method->name]; if (isset($candidate->methods[$method->name])) {
$cmethod = $candidate->methods[$method->name];
if ($cmethod->hasTag('inheritdoc')) {
$this->inheritDocs($candidate);
} }
$methods[] = $cmethod;
}
}
return $this->inheritMethodRecursive($method, $parent); return reset($methods);
}
/**
* @param ClassDoc $class
* @return array
*/
private function getParents($class)
{
if ($class->parentClass === null || !isset($this->classes[$class->parentClass])) {
return [];
}
return array_merge([$this->classes[$class->parentClass]], $this->getParents($this->classes[$class->parentClass]));
}
/**
* @param ClassDoc $class
* @return array
*/
private function getInterfaces($class)
{
$interfaces = [];
foreach($class->interfaces as $interface) {
if (isset($this->interfaces[$interface])) {
$interfaces[] = $this->interfaces[$interface];
} }
} }
return $method; return $interfaces;
} }
/** /**
......
...@@ -77,6 +77,7 @@ use Yii; ...@@ -77,6 +77,7 @@ use Yii;
class Object class Object
{ {
/** /**
* Returns the fully qualified name of this class.
* @return string the fully qualified name of this class. * @return string the fully qualified name of this class.
*/ */
public static function className() public static function className()
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment