Commit 3f1a0307 by Carsten Brandt

improved problems reporting in apidoc command

parent e2b34f2c
...@@ -105,6 +105,8 @@ class RenderController extends Controller ...@@ -105,6 +105,8 @@ class RenderController extends Controller
// render models // render models
$renderer->renderApi($context, $this); $renderer->renderApi($context, $this);
print_r($context->errors);
// render guide if specified // render guide if specified
if ($this->guide !== null) { if ($this->guide !== null) {
$renderer->renderMarkdownFiles($this->findMarkdownFiles($this->guide, ['README.md']), $this); $renderer->renderMarkdownFiles($this->findMarkdownFiles($this->guide, ['README.md']), $this);
......
...@@ -52,6 +52,10 @@ class Markdown extends \yii\helpers\Markdown ...@@ -52,6 +52,10 @@ class Markdown extends \yii\helpers\Markdown
} }
$type = static::$renderer->context->getType($typeName); $type = static::$renderer->context->getType($typeName);
if ($type === null) { if ($type === null) {
static::$renderer->context->errors[] = [
'file' => ($context !== null) ? $context->sourceFile : null,
'message' => 'broken link to ' . $typeName . '::' . $subjectName . (($context !== null) ? ' in ' . $context->name : ''),
];
return '<span style="background: #f00;">' . $typeName . '::' . $subjectName . '</span>'; return '<span style="background: #f00;">' . $typeName . '::' . $subjectName . '</span>';
} else { } else {
if (($subject = $type->findSubject($subjectName)) !== null) { if (($subject = $type->findSubject($subjectName)) !== null) {
...@@ -63,6 +67,10 @@ class Markdown extends \yii\helpers\Markdown ...@@ -63,6 +67,10 @@ class Markdown extends \yii\helpers\Markdown
} }
return static::$renderer->subjectLink($subject, $title); return static::$renderer->subjectLink($subject, $title);
} else { } else {
static::$renderer->context->errors[] = [
'file' => ($context !== null) ? $context->sourceFile : null,
'message' => 'broken link to ' . $type->name . '::' . $subjectName . (($context !== null) ? ' in ' . $context->name : ''),
];
return '<span style="background: #ff0;">' . $type->name . '</span><span style="background: #f00;">::' . $subjectName . '</span>'; return '<span style="background: #ff0;">' . $type->name . '</span><span style="background: #f00;">::' . $subjectName . '</span>';
} }
} }
...@@ -76,6 +84,10 @@ class Markdown extends \yii\helpers\Markdown ...@@ -76,6 +84,10 @@ class Markdown extends \yii\helpers\Markdown
if (($type = static::$renderer->context->getType($object)) !== null) { if (($type = static::$renderer->context->getType($object)) !== null) {
return static::$renderer->typeLink($type, $title); return static::$renderer->typeLink($type, $title);
} }
static::$renderer->context->errors[] = [
'file' => ($context !== null) ? $context->sourceFile : null,
'message' => 'broken link to ' . $object . (($context !== null) ? ' in ' . $context->name : ''),
];
return '<span style="background: #f00;">' . $object . '</span>'; return '<span style="background: #f00;">' . $object . '</span>';
}, $content); }, $content);
......
...@@ -10,6 +10,7 @@ namespace yii\apidoc\models; ...@@ -10,6 +10,7 @@ namespace yii\apidoc\models;
use phpDocumentor\Reflection\DocBlock\Tag\DeprecatedTag; use phpDocumentor\Reflection\DocBlock\Tag\DeprecatedTag;
use phpDocumentor\Reflection\DocBlock\Tag\SinceTag; use phpDocumentor\Reflection\DocBlock\Tag\SinceTag;
use yii\base\Object; use yii\base\Object;
use yii\helpers\StringHelper;
/** /**
* Base class for API documentation information. * Base class for API documentation information.
...@@ -44,9 +45,10 @@ class BaseDoc extends Object ...@@ -44,9 +45,10 @@ class BaseDoc extends Object
/** /**
* @param \phpDocumentor\Reflection\BaseReflector $reflector * @param \phpDocumentor\Reflection\BaseReflector $reflector
* @param Context $context
* @param array $config * @param array $config
*/ */
public function __construct($reflector = null, $config = []) public function __construct($reflector = null, $context = null, $config = [])
{ {
parent::__construct($config); parent::__construct($config);
...@@ -62,6 +64,13 @@ class BaseDoc extends Object ...@@ -62,6 +64,13 @@ class BaseDoc extends Object
$docblock = $reflector->getDocBlock(); $docblock = $reflector->getDocBlock();
if ($docblock !== null) { if ($docblock !== null) {
$this->shortDescription = ucfirst($docblock->getShortDescription()); $this->shortDescription = ucfirst($docblock->getShortDescription());
if (empty($this->shortDescription) && !($this instanceof PropertyDoc) && $context !== null) {
$context->errors[] = [
'line' => $this->startLine,
'file' => $this->sourceFile,
'message' => "No short description for " . substr(StringHelper::basename(get_class($this)), 0, -3) . " '{$this->name}'",
];
}
$this->description = $docblock->getLongDescription(); $this->description = $docblock->getLongDescription();
$this->phpDocContext = $docblock->getContext(); $this->phpDocContext = $docblock->getContext();
...@@ -77,6 +86,12 @@ class BaseDoc extends Object ...@@ -77,6 +86,12 @@ class BaseDoc extends Object
unset($this->tags[$i]); unset($this->tags[$i]);
} }
} }
} elseif ($context !== null) {
$context->errors[] = [
'line' => $this->startLine,
'file' => $this->sourceFile,
'message' => "No docblock for element '{$this->name}'",
];
} }
} }
......
...@@ -72,11 +72,12 @@ class ClassDoc extends TypeDoc ...@@ -72,11 +72,12 @@ class ClassDoc extends TypeDoc
/** /**
* @param \phpDocumentor\Reflection\ClassReflector $reflector * @param \phpDocumentor\Reflection\ClassReflector $reflector
* @param Context $context
* @param array $config * @param array $config
*/ */
public function __construct($reflector = null, $config = []) public function __construct($reflector = null, $context = null, $config = [])
{ {
parent::__construct($reflector, $config); parent::__construct($reflector, $context, $config);
if ($reflector === null) { if ($reflector === null) {
return; return;
......
...@@ -20,11 +20,12 @@ class ConstDoc extends BaseDoc ...@@ -20,11 +20,12 @@ class ConstDoc extends BaseDoc
/** /**
* @param \phpDocumentor\Reflection\ClassReflector\ConstantReflector $reflector * @param \phpDocumentor\Reflection\ClassReflector\ConstantReflector $reflector
* @param Context $context
* @param array $config * @param array $config
*/ */
public function __construct($reflector = null, $config = []) public function __construct($reflector = null, $context = null, $config = [])
{ {
parent::__construct($reflector, $config); parent::__construct($reflector, $context, $config);
if ($reflector === null) { if ($reflector === null) {
return; return;
......
...@@ -35,6 +35,8 @@ class Context extends Component ...@@ -35,6 +35,8 @@ class Context extends Component
*/ */
public $traits = []; public $traits = [];
public $errors = [];
public function getType($type) public function getType($type)
{ {
...@@ -57,18 +59,15 @@ class Context extends Component ...@@ -57,18 +59,15 @@ class Context extends Component
$reflection->process(); $reflection->process();
foreach($reflection->getClasses() as $class) { foreach($reflection->getClasses() as $class) {
$class = new ClassDoc($class); $class = new ClassDoc($class, $this, ['sourceFile' => $fileName]);
$class->sourceFile = $fileName;
$this->classes[$class->name] = $class; $this->classes[$class->name] = $class;
} }
foreach($reflection->getInterfaces() as $interface) { foreach($reflection->getInterfaces() as $interface) {
$interface = new InterfaceDoc($interface); $interface = new InterfaceDoc($interface, $this, ['sourceFile' => $fileName]);
$interface->sourceFile = $fileName;
$this->interfaces[$interface->name] = $interface; $this->interfaces[$interface->name] = $interface;
} }
foreach($reflection->getTraits() as $trait) { foreach($reflection->getTraits() as $trait) {
$trait = new TraitDoc($trait); $trait = new TraitDoc($trait, $this, ['sourceFile' => $fileName]);
$trait->sourceFile = $fileName;
$this->traits[$trait->name] = $trait; $this->traits[$trait->name] = $trait;
} }
} }
...@@ -160,13 +159,18 @@ class Context extends Component ...@@ -160,13 +159,18 @@ class Context extends Component
if (isset($class->properties[$propertyName])) { if (isset($class->properties[$propertyName])) {
$property = $class->properties[$propertyName]; $property = $class->properties[$propertyName];
if ($property->getter === null && $property->setter === null) { if ($property->getter === null && $property->setter === null) {
echo "Property $propertyName conflicts with a defined getter {$method->name} in {$class->name}.\n"; // TODO log these messages somewhere $this->errors[] = [
'line' => $property->startLine,
'file' => $class->sourceFile,
'message' => "Property $propertyName conflicts with a defined getter {$method->name} in {$class->name}.",
];
} }
$property->getter = $method; $property->getter = $method;
} else { } else {
$class->properties[$propertyName] = new PropertyDoc(null, [ $class->properties[$propertyName] = new PropertyDoc(null, $this, [
'name' => $propertyName, 'name' => $propertyName,
'definedBy' => $class->name, 'definedBy' => $class->name,
'sourceFile' => $class->sourceFile,
'visibility' => 'public', 'visibility' => 'public',
'isStatic' => false, 'isStatic' => false,
'type' => $method->returnType, 'type' => $method->returnType,
...@@ -184,14 +188,19 @@ class Context extends Component ...@@ -184,14 +188,19 @@ class Context extends Component
if (isset($class->properties[$propertyName])) { if (isset($class->properties[$propertyName])) {
$property = $class->properties[$propertyName]; $property = $class->properties[$propertyName];
if ($property->getter === null && $property->setter === null) { if ($property->getter === null && $property->setter === null) {
echo "Property $propertyName conflicts with a defined setter {$method->name} in {$class->name}.\n"; // TODO log these messages somewhere $this->errors[] = [
'line' => $property->startLine,
'file' => $class->sourceFile,
'message' => "Property $propertyName conflicts with a defined setter {$method->name} in {$class->name}.",
];
} }
$property->setter = $method; $property->setter = $method;
} else { } else {
$param = $this->getFirstNotOptionalParameter($method); $param = $this->getFirstNotOptionalParameter($method);
$class->properties[$propertyName] = new PropertyDoc(null, [ $class->properties[$propertyName] = new PropertyDoc(null, $this, [
'name' => $propertyName, 'name' => $propertyName,
'definedBy' => $class->name, 'definedBy' => $class->name,
'sourceFile' => $class->sourceFile,
'visibility' => 'public', 'visibility' => 'public',
'isStatic' => false, 'isStatic' => false,
'type' => $param->type, 'type' => $param->type,
......
...@@ -23,11 +23,12 @@ class EventDoc extends ConstDoc ...@@ -23,11 +23,12 @@ class EventDoc extends ConstDoc
/** /**
* @param \phpDocumentor\Reflection\ClassReflector\ConstantReflector $reflector * @param \phpDocumentor\Reflection\ClassReflector\ConstantReflector $reflector
* @param Context $context
* @param array $config * @param array $config
*/ */
public function __construct($reflector = null, $config = []) public function __construct($reflector = null, $context = null, $config = [])
{ {
parent::__construct($reflector, $config); parent::__construct($reflector, $context, $config);
if ($reflector === null) { if ($reflector === null) {
return; return;
......
...@@ -33,11 +33,12 @@ class FunctionDoc extends BaseDoc ...@@ -33,11 +33,12 @@ class FunctionDoc extends BaseDoc
/** /**
* @param \phpDocumentor\Reflection\FunctionReflector $reflector * @param \phpDocumentor\Reflection\FunctionReflector $reflector
* @param Context $context
* @param array $config * @param array $config
*/ */
public function __construct($reflector = null, $config = []) public function __construct($reflector = null, $context = null, $config = [])
{ {
parent::__construct($reflector, $config); parent::__construct($reflector, $context, $config);
if ($reflector === null) { if ($reflector === null) {
return; return;
...@@ -46,7 +47,7 @@ class FunctionDoc extends BaseDoc ...@@ -46,7 +47,7 @@ class FunctionDoc extends BaseDoc
$this->isReturnByReference = $reflector->isByRef(); $this->isReturnByReference = $reflector->isByRef();
foreach($reflector->getArguments() as $arg) { foreach($reflector->getArguments() as $arg) {
$arg = new ParamDoc($arg); $arg = new ParamDoc($arg, $context, ['sourceFile' => $this->sourceFile]);
$this->params[$arg->name] = $arg; $this->params[$arg->name] = $arg;
} }
...@@ -58,8 +59,12 @@ class FunctionDoc extends BaseDoc ...@@ -58,8 +59,12 @@ class FunctionDoc extends BaseDoc
// ignore property tag // ignore property tag
} elseif ($tag instanceof ParamTag) { } elseif ($tag instanceof ParamTag) {
$paramName = $tag->getVariableName(); $paramName = $tag->getVariableName();
if (!isset($this->params[$paramName])) { if (!isset($this->params[$paramName]) && $context !== null) {
echo 'undefined parameter documented: ' . $paramName . ' in ' . $this->name . "()\n"; // TODO log these messages somewhere $context->errors[] = [
'line' => $this->startLine,
'file' => $this->sourceFile,
'message' => "Undefined parameter documented: $paramName in {$this->name}().",
];
continue; continue;
} }
$this->params[$paramName]->description = ucfirst($tag->getDescription()); $this->params[$paramName]->description = ucfirst($tag->getDescription());
......
...@@ -22,11 +22,12 @@ class InterfaceDoc extends TypeDoc ...@@ -22,11 +22,12 @@ class InterfaceDoc extends TypeDoc
/** /**
* @param \phpDocumentor\Reflection\InterfaceReflector $reflector * @param \phpDocumentor\Reflection\InterfaceReflector $reflector
* @param Context $context
* @param array $config * @param array $config
*/ */
public function __construct($reflector = null, $config = []) public function __construct($reflector = null, $context = null, $config = [])
{ {
parent::__construct($reflector, $config); parent::__construct($reflector, $context, $config);
if ($reflector === null) { if ($reflector === null) {
return; return;
......
...@@ -27,11 +27,12 @@ class MethodDoc extends FunctionDoc ...@@ -27,11 +27,12 @@ class MethodDoc extends FunctionDoc
/** /**
* @param \phpDocumentor\Reflection\ClassReflector\MethodReflector $reflector * @param \phpDocumentor\Reflection\ClassReflector\MethodReflector $reflector
* @param Context $context
* @param array $config * @param array $config
*/ */
public function __construct($reflector = null, $config = []) public function __construct($reflector = null, $context = null, $config = [])
{ {
parent::__construct($reflector, $config); parent::__construct($reflector, $context, $config);
if ($reflector === null) { if ($reflector === null) {
return; return;
......
...@@ -28,12 +28,14 @@ class ParamDoc extends Object ...@@ -28,12 +28,14 @@ class ParamDoc extends Object
public $description; public $description;
public $type; public $type;
public $types; public $types;
public $sourceFile;
/** /**
* @param \phpDocumentor\Reflection\FunctionReflector\ArgumentReflector $reflector * @param \phpDocumentor\Reflection\FunctionReflector\ArgumentReflector $reflector
* @param Context $context
* @param array $config * @param array $config
*/ */
public function __construct($reflector = null, $config = []) public function __construct($reflector = null, $context = null, $config = [])
{ {
parent::__construct($config); parent::__construct($config);
......
...@@ -44,11 +44,12 @@ class PropertyDoc extends BaseDoc ...@@ -44,11 +44,12 @@ class PropertyDoc extends BaseDoc
/** /**
* @param \phpDocumentor\Reflection\ClassReflector\PropertyReflector $reflector * @param \phpDocumentor\Reflection\ClassReflector\PropertyReflector $reflector
* @param Context $context
* @param array $config * @param array $config
*/ */
public function __construct($reflector = null, $config = []) public function __construct($reflector = null, $context = null, $config = [])
{ {
parent::__construct($reflector, $config); parent::__construct($reflector, $context, $config);
if ($reflector === null) { if ($reflector === null) {
return; return;
...@@ -74,5 +75,12 @@ class PropertyDoc extends BaseDoc ...@@ -74,5 +75,12 @@ class PropertyDoc extends BaseDoc
} }
} }
} }
if (empty($this->shortDescription) && $context !== null) {
$context->errors[] = [
'line' => $this->startLine,
'file' => $this->sourceFile,
'message' => "No short description for element '{$this->name}'",
];
}
} }
} }
\ No newline at end of file
...@@ -23,11 +23,12 @@ class TraitDoc extends TypeDoc ...@@ -23,11 +23,12 @@ class TraitDoc extends TypeDoc
/** /**
* @param \phpDocumentor\Reflection\TraitReflector $reflector * @param \phpDocumentor\Reflection\TraitReflector $reflector
* @param Context $context
* @param array $config * @param array $config
*/ */
public function __construct($reflector = null, $config = []) public function __construct($reflector = null, $context = null, $config = [])
{ {
parent::__construct($reflector, $config); parent::__construct($reflector, $context, $config);
if ($reflector === null) { if ($reflector === null) {
return; return;
......
...@@ -155,11 +155,12 @@ class TypeDoc extends BaseDoc ...@@ -155,11 +155,12 @@ class TypeDoc extends BaseDoc
/** /**
* @param \phpDocumentor\Reflection\InterfaceReflector $reflector * @param \phpDocumentor\Reflection\InterfaceReflector $reflector
* @param Context $context
* @param array $config * @param array $config
*/ */
public function __construct($reflector = null, $config = []) public function __construct($reflector = null, $context = null, $config = [])
{ {
parent::__construct($reflector, $config); parent::__construct($reflector, $context, $config);
$this->namespace = StringHelper::dirname($this->name); $this->namespace = StringHelper::dirname($this->name);
...@@ -176,7 +177,7 @@ class TypeDoc extends BaseDoc ...@@ -176,7 +177,7 @@ class TypeDoc extends BaseDoc
foreach($reflector->getProperties() as $propertyReflector) { foreach($reflector->getProperties() as $propertyReflector) {
if ($propertyReflector->getVisibility() != 'private') { if ($propertyReflector->getVisibility() != 'private') {
$property = new PropertyDoc($propertyReflector); $property = new PropertyDoc($propertyReflector, $context, ['sourceFile' => $this->sourceFile]);
$property->definedBy = $this->name; $property->definedBy = $this->name;
$this->properties[$property->name] = $property; $this->properties[$property->name] = $property;
} }
...@@ -184,7 +185,7 @@ class TypeDoc extends BaseDoc ...@@ -184,7 +185,7 @@ class TypeDoc extends BaseDoc
foreach($reflector->getMethods() as $methodReflector) { foreach($reflector->getMethods() as $methodReflector) {
if ($methodReflector->getVisibility() != 'private') { if ($methodReflector->getVisibility() != 'private') {
$method = new MethodDoc($methodReflector); $method = new MethodDoc($methodReflector, $context, ['sourceFile' => $this->sourceFile]);
$method->definedBy = $this->name; $method->definedBy = $this->name;
$this->methods[$method->name] = $method; $this->methods[$method->name] = $method;
} }
......
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