From c66a1fa7bd0845e8da388c360001ac0cf0d41701 Mon Sep 17 00:00:00 2001 From: Carsten Brandt Date: Sun, 5 Jan 2014 07:04:08 +0100 Subject: [PATCH] finished the model layer --- .../yii/apidoc/components/OfflineRenderer.php | 8 +-- extensions/yii/apidoc/models/BaseDoc.php | 41 +++++++++--- extensions/yii/apidoc/models/ClassDoc.php | 20 +++--- extensions/yii/apidoc/models/ConstDoc.php | 13 ++++ extensions/yii/apidoc/models/Context.php | 7 ++- extensions/yii/apidoc/models/EventDoc.php | 5 +- extensions/yii/apidoc/models/FunctionDoc.php | 50 ++++++++++++++- extensions/yii/apidoc/models/InterfaceDoc.php | 8 +-- extensions/yii/apidoc/models/MethodDoc.php | 22 ++++++- extensions/yii/apidoc/models/ParamDoc.php | 27 +++++++- extensions/yii/apidoc/models/PropertyDoc.php | 51 +++++++++++++-- extensions/yii/apidoc/models/TraitDoc.php | 12 +--- extensions/yii/apidoc/models/TypeDoc.php | 72 ++++++++++++++++++++++ 13 files changed, 281 insertions(+), 55 deletions(-) create mode 100644 extensions/yii/apidoc/models/ConstDoc.php create mode 100644 extensions/yii/apidoc/models/TypeDoc.php diff --git a/extensions/yii/apidoc/components/OfflineRenderer.php b/extensions/yii/apidoc/components/OfflineRenderer.php index 0c3d2dd..509c51d 100644 --- a/extensions/yii/apidoc/components/OfflineRenderer.php +++ b/extensions/yii/apidoc/components/OfflineRenderer.php @@ -23,9 +23,9 @@ class OfflineRenderer extends BaseRenderer implements ViewContextInterface { public $targetDir; - public $layout = '@yii/phpdoc/views/layouts/offline.php'; - public $itemView = '@yii/phpdoc/views/class.php'; - public $indexView = '@yii/phpdoc/views/index.php'; + public $layout = '@yii/apidoc/views/layouts/offline.php'; + public $itemView = '@yii/apidoc/views/class.php'; + public $indexView = '@yii/apidoc/views/index.php'; public $pageTitle = 'Yii Framework 2.0 API Documentation'; @@ -177,6 +177,6 @@ class OfflineRenderer extends BaseRenderer implements ViewContextInterface */ public function findViewFile($view) { - return Yii::getAlias('@yii/phpdoc/views/' . $view); + return Yii::getAlias('@yii/apidoc/views/' . $view); } } \ No newline at end of file diff --git a/extensions/yii/apidoc/models/BaseDoc.php b/extensions/yii/apidoc/models/BaseDoc.php index fa8c709..6715015 100644 --- a/extensions/yii/apidoc/models/BaseDoc.php +++ b/extensions/yii/apidoc/models/BaseDoc.php @@ -7,38 +7,65 @@ namespace yii\apidoc\models; +use phpDocumentor\Reflection\DocBlock\Tag\DeprecatedTag; +use phpDocumentor\Reflection\DocBlock\Tag\SinceTag; use yii\base\Object; class BaseDoc extends Object { public $name; - public $since; + public $sourceFile; + public $startLine; + public $endLine; public $shortDescription; public $description; + public $since; + public $deprecatedSince; + public $deprecatedReason; + + public $tags = []; - public $sourceFile; - public $startLine; - public $endLine; /** * @param \phpDocumentor\Reflection\BaseReflector $reflector * @param array $config */ - public function __construct($reflector, $config = []) + public function __construct($reflector = null, $config = []) { + parent::__construct($config); + + if ($reflector === null) { + return; + } + // base properties $this->name = ltrim($reflector->getName(), '\\'); $this->startLine = $reflector->getNode()->getAttribute('startLine'); $this->endLine = $reflector->getNode()->getAttribute('endLine'); - // TODO docblock + $docblock = $reflector->getDocBlock(); + if ($docblock !== null) { + $this->shortDescription = $docblock->getShortDescription(); + $this->description = $docblock->getLongDescription(); - parent::__construct($config); + $this->tags = $docblock->getTags(); + foreach($this->tags as $i => $tag) { + if ($tag instanceof SinceTag) { + $this->since = $tag->getVersion(); + unset($this->tags[$i]); + } elseif ($tag instanceof DeprecatedTag) { + $this->deprecatedSince = $tag->getVersion(); + $this->deprecatedReason = $tag->getDescription(); + unset($this->tags[$i]); + } + } + } } + // TODO public function loadSource($reflection) { $this->sourcePath=str_replace('\\','/',str_replace(YII_PATH,'',$reflection->getFileName())); diff --git a/extensions/yii/apidoc/models/ClassDoc.php b/extensions/yii/apidoc/models/ClassDoc.php index 3d33568..9bb7191 100644 --- a/extensions/yii/apidoc/models/ClassDoc.php +++ b/extensions/yii/apidoc/models/ClassDoc.php @@ -10,7 +10,7 @@ namespace yii\apidoc\models; /** * Class ClassDoc */ -class ClassDoc extends BaseDoc +class ClassDoc extends TypeDoc { public $parentClass; @@ -22,9 +22,6 @@ class ClassDoc extends BaseDoc // will be set by Context::updateReferences() public $subclasses = []; - // TODO - public $properties = []; - public $methods = []; public $events = []; public $constants = []; @@ -50,9 +47,16 @@ class ClassDoc extends BaseDoc foreach($reflector->getTraits() as $trait) { $this->traits[] = ltrim($trait, '\\'); } - - // TODO methods - - // TODO properties + foreach($reflector->getConstants() as $constantReflector) { + if (strncmp($constantReflector->getShortName(), 'EVENT_', 6) == 0) { + $event = new EventDoc($constantReflector); + $event->definedBy = $this->name; + $this->events[] = $event; + } else { + $constant = new ConstDoc($constantReflector); + $constant->definedBy = $this->name; + $this->constants[] = $constant; + } + } } } \ No newline at end of file diff --git a/extensions/yii/apidoc/models/ConstDoc.php b/extensions/yii/apidoc/models/ConstDoc.php new file mode 100644 index 0000000..5eb99a9 --- /dev/null +++ b/extensions/yii/apidoc/models/ConstDoc.php @@ -0,0 +1,13 @@ +process(); foreach($reflection->getClasses() as $class) { - $class = new ClassDoc($class, $this); + $class = new ClassDoc($class); $class->sourceFile = $fileName; $this->addClass($class); } foreach($reflection->getInterfaces() as $interface) { - $interface = new InterfaceDoc($interface, $this); + $interface = new InterfaceDoc($interface); $interface->sourceFile = $fileName; $this->addInterface($interface); } foreach($reflection->getTraits() as $trait) { - $trait = new TraitDoc($trait, $this); + $trait = new TraitDoc($trait); $trait->sourceFile = $fileName; $this->addTrait($trait); } @@ -107,6 +107,7 @@ class Context extends Component } // update interfaces of subclasses foreach($this->classes as $class) { + // TODO do the same for events, constants, methods, properties $this->updateSubclassInferfacesTraits($class); } // update implementedBy and usedBy for interfaces and traits diff --git a/extensions/yii/apidoc/models/EventDoc.php b/extensions/yii/apidoc/models/EventDoc.php index 22fedc9..fbdc4d8 100644 --- a/extensions/yii/apidoc/models/EventDoc.php +++ b/extensions/yii/apidoc/models/EventDoc.php @@ -7,9 +7,6 @@ namespace yii\apidoc\models; -class EventDoc extends BaseDoc +class EventDoc extends ConstDoc { - public $isInherited; - public $definedBy; - public $trigger; } \ No newline at end of file diff --git a/extensions/yii/apidoc/models/FunctionDoc.php b/extensions/yii/apidoc/models/FunctionDoc.php index b9cee3b..d84fd01 100644 --- a/extensions/yii/apidoc/models/FunctionDoc.php +++ b/extensions/yii/apidoc/models/FunctionDoc.php @@ -7,9 +7,53 @@ namespace yii\apidoc\models; +use phpDocumentor\Reflection\DocBlock\Tag\ParamTag; +use phpDocumentor\Reflection\DocBlock\Tag\ReturnTag; +use phpDocumentor\Reflection\DocBlock\Tag\ThrowsTag; + class FunctionDoc extends BaseDoc { - public $signature; - public $input=array(); - public $output; + /** + * @var ParamDoc[] + */ + public $params = []; + public $exceptions = []; + public $return; + public $returnType; + public $returnTypes; + public $isReturnByReference; + + /** + * @param \phpDocumentor\Reflection\FunctionReflector $reflector + * @param array $config + */ + public function __construct($reflector, $config = []) + { + parent::__construct($reflector, $config); + + $this->isReturnByReference = $reflector->isByRef(); + + foreach($reflector->getArguments() as $arg) { + $arg = new ParamDoc($arg); + $this->params[$arg->name] = $arg; + } + + foreach($this->tags as $i => $tag) { + if ($tag instanceof ReturnTag) { + $this->returnType = $tag->getType(); + $this->returnTypes = $tag->getTypes(); + $this->return = $tag->getDescription(); + unset($this->tags[$i]); + } elseif ($tag instanceof ParamTag) { + $paramName = $tag->getVariableName(); + $this->params[$paramName]->description = $tag->getDescription(); + $this->params[$paramName]->type = $tag->getType(); + $this->params[$paramName]->types = $tag->getTypes(); + unset($this->tags[$i]); + } elseif ($tag instanceof ThrowsTag) { + $this->exceptions[$tag->getType()] = $tag->getDescription(); + unset($this->tags[$i]); + } + } + } } diff --git a/extensions/yii/apidoc/models/InterfaceDoc.php b/extensions/yii/apidoc/models/InterfaceDoc.php index 32f9113..8a99661 100644 --- a/extensions/yii/apidoc/models/InterfaceDoc.php +++ b/extensions/yii/apidoc/models/InterfaceDoc.php @@ -7,16 +7,13 @@ namespace yii\apidoc\models; -class InterfaceDoc extends BaseDoc +class InterfaceDoc extends TypeDoc { public $parentInterfaces = []; // will be set by Context::updateReferences() public $implementedBy = []; - // TODO - public $methods = []; - /** * @param \phpDocumentor\Reflection\InterfaceReflector $reflector * @param array $config @@ -29,6 +26,7 @@ class InterfaceDoc extends BaseDoc $this->parentInterfaces[] = ltrim($interface, '\\'); } - // TODO methods + // interface can not have properties + $this->properties = null; } } \ No newline at end of file diff --git a/extensions/yii/apidoc/models/MethodDoc.php b/extensions/yii/apidoc/models/MethodDoc.php index cd32c86..70d67ce 100644 --- a/extensions/yii/apidoc/models/MethodDoc.php +++ b/extensions/yii/apidoc/models/MethodDoc.php @@ -11,8 +11,26 @@ class MethodDoc extends FunctionDoc { public $isAbstract; public $isFinal; - public $isProtected; + public $isStatic; - public $isInherited; + + public $visibility; + + // will be set by creating class public $definedBy; + + /** + * @param \phpDocumentor\Reflection\ClassReflector\MethodReflector $reflector + * @param array $config + */ + public function __construct($reflector, $config = []) + { + parent::__construct($reflector, $config); + + $this->isAbstract = $reflector->isAbstract(); + $this->isFinal = $reflector->isFinal(); + $this->isStatic = $reflector->isStatic(); + + $this->visibility = $reflector->getVisibility(); + } } diff --git a/extensions/yii/apidoc/models/ParamDoc.php b/extensions/yii/apidoc/models/ParamDoc.php index 6fdd535..b5b664c 100644 --- a/extensions/yii/apidoc/models/ParamDoc.php +++ b/extensions/yii/apidoc/models/ParamDoc.php @@ -7,12 +7,33 @@ namespace yii\apidoc\models; -class ParamDoc +use yii\base\Object; + +class ParamDoc extends Object { public $name; - public $description; - public $type; + public $typeHint; public $isOptional; public $defaultValue; public $isPassedByReference; + + // will be set by creating class + public $description; + public $type; + public $types; + + /** + * @param \phpDocumentor\Reflection\FunctionReflector\ArgumentReflector $reflector + * @param array $config + */ + public function __construct($reflector, $config = []) + { + parent::__construct($config); + + $this->name = $reflector->getName(); + $this->typeHint = $reflector->getType(); + $this->isOptional = $reflector->getDefault() !== null; + $this->defaultValue = $reflector->getDefault(); // TODO what about null value? + $this->isPassedByReference = $reflector->isByRef(); + } } \ No newline at end of file diff --git a/extensions/yii/apidoc/models/PropertyDoc.php b/extensions/yii/apidoc/models/PropertyDoc.php index 9fd94e5..3a9b447 100644 --- a/extensions/yii/apidoc/models/PropertyDoc.php +++ b/extensions/yii/apidoc/models/PropertyDoc.php @@ -7,17 +7,58 @@ namespace yii\apidoc\models; +use phpDocumentor\Reflection\DocBlock\Tag\VarTag; + class PropertyDoc extends BaseDoc { - public $isProtected; + public $visibility; public $isStatic; - public $readOnly; - public $isInherited; - public $definedBy; public $type; - public $signature; + public $types; + public $defaultValue; + // will be set by creating class public $getter; public $setter; + + // will be set by creating class + public $definedBy; + + public function getIsReadOnly() + { + return $this->getter !== null && $this->setter === null; + } + + public function getIsWriteOnly() + { + return $this->getter === null && $this->setter !== null; + } + + /** + * @param \phpDocumentor\Reflection\ClassReflector\PropertyReflector $reflector + * @param array $config + */ + public function __construct($reflector = null, $config = []) + { + parent::__construct($reflector, $config); + + if ($reflector === null) { + return; + } + + $this->visibility = $reflector->getVisibility(); + $this->isStatic = $reflector->isStatic(); + + $this->defaultValue = $reflector->getDefault(); + + foreach($this->tags as $i => $tag) { + if ($tag instanceof VarTag) { + $this->type = $tag->getType(); + $this->types = $tag->getTypes(); + $this->description = $tag->getDescription(); + // TODO set shortDescription + } + } + } } \ No newline at end of file diff --git a/extensions/yii/apidoc/models/TraitDoc.php b/extensions/yii/apidoc/models/TraitDoc.php index eef6b4e..13ee9b9 100644 --- a/extensions/yii/apidoc/models/TraitDoc.php +++ b/extensions/yii/apidoc/models/TraitDoc.php @@ -7,7 +7,7 @@ namespace yii\apidoc\models; -class TraitDoc extends BaseDoc +class TraitDoc extends TypeDoc { // classes using the trait // will be set by Context::updateReferences() @@ -15,11 +15,6 @@ class TraitDoc extends BaseDoc public $traits = []; - // TODO - public $properties = []; - public $methods = []; - - /** * @param \phpDocumentor\Reflection\TraitReflector $reflector * @param array $config @@ -31,10 +26,5 @@ class TraitDoc extends BaseDoc foreach($reflector->getTraits() as $trait) { $this->traits[] = ltrim($trait, '\\'); } - - // TODO methods - - // TODO properties - } } \ No newline at end of file diff --git a/extensions/yii/apidoc/models/TypeDoc.php b/extensions/yii/apidoc/models/TypeDoc.php new file mode 100644 index 0000000..a1349a4 --- /dev/null +++ b/extensions/yii/apidoc/models/TypeDoc.php @@ -0,0 +1,72 @@ +tags as $i => $tag) { + if ($tag instanceof AuthorTag) { + $this->authors[$tag->getAuthorName()] = $tag->getAuthorEmail(); + unset($this->tags[$i]); + } + } + + foreach($reflector->getProperties() as $propertyReflector) { + if ($propertyReflector->getVisibility() != 'private') { + $property = new PropertyDoc($propertyReflector); + $property->definedBy = $this->name; + $this->properties[$property->name] = $property; + } + } + + foreach($reflector->getMethods() as $methodReflector) { + if ($methodReflector->getVisibility() != 'private') { + $method = new MethodDoc($methodReflector); + $method->definedBy = $this->name; + + if (!strncmp($method->name, 'set', 3)) { + $propertyName = lcfirst(substr($method->name, 3)); + if (isset($this->properties[$propertyName])) { + $property = $this->properties[$propertyName]; + if ($property->getter === null && $property->setter === null) { + throw new Exception("Property $propertyName conflicts with a defined setter {$method->name}."); + } + $property->setter = $method; + } else { +// $this->properties[$propertyName] = new PropertyDoc(null, [ +// 'name' => $propertyName, +// // TODO set description and short description +// ]); + } + } elseif (!strncmp($method->name, 'get', 3)) { + // TODO add property + } + $this->methods[$method->name] = $method; + } + } + } +} \ No newline at end of file