Commit 5ede58fe by Carsten Brandt

finished the property feature

parent 53b3198d
...@@ -103,10 +103,16 @@ class Context extends Component ...@@ -103,10 +103,16 @@ class Context extends Component
} }
} }
} }
// update properties, methods, contants and events of subclasses // inherit properties, methods, contants and events to subclasses
foreach($this->classes as $class) { foreach($this->classes as $class) {
$this->updateSubclassInheritance($class); $this->updateSubclassInheritance($class);
} }
// add properties from getters and setters
foreach($this->classes as $class) {
$this->handlePropertyFeature($class);
}
// TODO reference exceptions to methods where they are thrown
} }
/** /**
...@@ -138,4 +144,115 @@ class Context extends Component ...@@ -138,4 +144,115 @@ class Context extends Component
$this->updateSubclassInheritance($subclass); $this->updateSubclassInheritance($subclass);
} }
} }
/**
* Add properties for getters and setters if class is subclass of [[yii\base\Object]].
* @param ClassDoc $class
*/
protected function handlePropertyFeature($class)
{
if (!$this->isSubclassOf($class, 'yii\base\Object')) {
return;
}
foreach($class->getPublicMethods() as $name => $method) {
if (!strncmp($name, 'get', 3) && $this->paramsOptional($method)) {
$propertyName = '$' . lcfirst(substr($method->name, 3));
if (isset($class->properties[$propertyName])) {
$property = $class->properties[$propertyName];
if ($property->getter === null && $property->setter === null) {
echo "Property $propertyName conflicts with a defined getter {$method->name} in {$class->name}."; // TODO log these messages somewhere
}
$property->getter = $method;
} else {
$class->properties[$propertyName] = new PropertyDoc(null, [
'name' => $propertyName,
'definedBy' => $class->name,
'visibility' => 'public',
'isStatic' => false,
'type' => $method->returnType,
'types' => $method->returnTypes,
'shortDescription' => (($pos = strpos($method->return, '.')) !== false) ?
substr($method->return, 0, $pos) : $method->return,
'description' => $method->return,
'getter' => $method
// TODO set default value
]);
}
}
if (!strncmp($name, 'set', 3) && $this->paramsOptional($method, 1)) {
$propertyName = '$' . lcfirst(substr($method->name, 3));
if (isset($class->properties[$propertyName])) {
$property = $class->properties[$propertyName];
if ($property->getter === null && $property->setter === null) {
echo "Property $propertyName conflicts with a defined setter {$method->name} in {$class->name}."; // TODO log these messages somewhere
}
$property->setter = $method;
} else {
$param = $this->getFirstNotOptionalParameter($method);
$class->properties[$propertyName] = new PropertyDoc(null, [
'name' => $propertyName,
'definedBy' => $class->name,
'visibility' => 'public',
'isStatic' => false,
'type' => $param->type,
'types' => $param->types,
'shortDescription' => (($pos = strpos($param->description, '.')) !== false) ?
substr($param->description, 0, $pos) : $param->description,
'description' => $param->description,
'setter' => $method
]);
}
}
}
}
/**
* @param MethodDoc $method
* @param integer $number number of not optional parameters
* @return bool
*/
private function paramsOptional($method, $number = 0)
{
foreach($method->params as $param) {
if (!$param->isOptional && $number-- <= 0) {
return false;
}
}
return true;
}
/**
* @param MethodDoc $method
* @return ParamDoc
*/
private function getFirstNotOptionalParameter($method)
{
foreach($method->params as $param) {
if (!$param->isOptional) {
return $param;
}
}
return null;
}
/**
* @param ClassDoc $classA
* @param ClassDoc $classB
*/
protected function isSubclassOf($classA, $classB)
{
if (is_object($classB)) {
$classB = $classB->name;
}
if ($classA->name == $classB) {
return true;
}
while($classA->parentClass !== null && isset($this->classes[$classA->parentClass])) {
$classA = $this->classes[$classA->parentClass];
if ($classA->name == $classB) {
return true;
}
}
return false;
}
} }
\ No newline at end of file
...@@ -54,7 +54,7 @@ class FunctionDoc extends BaseDoc ...@@ -54,7 +54,7 @@ class FunctionDoc extends BaseDoc
$this->exceptions[$tag->getType()] = $tag->getDescription(); $this->exceptions[$tag->getType()] = $tag->getDescription();
unset($this->tags[$i]); unset($this->tags[$i]);
} elseif ($tag instanceof PropertyTag) { } elseif ($tag instanceof PropertyTag) {
// TODO handle 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])) {
......
...@@ -178,25 +178,6 @@ class TypeDoc extends BaseDoc ...@@ -178,25 +178,6 @@ class TypeDoc extends BaseDoc
if ($methodReflector->getVisibility() != 'private') { if ($methodReflector->getVisibility() != 'private') {
$method = new MethodDoc($methodReflector); $method = new MethodDoc($methodReflector);
$method->definedBy = $this->name; $method->definedBy = $this->name;
// TODO only set property when subclass of Object
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; $this->methods[$method->name] = $method;
} }
} }
......
...@@ -302,20 +302,17 @@ abstract class Renderer extends BaseRenderer implements ViewContextInterface ...@@ -302,20 +302,17 @@ abstract class Renderer extends BaseRenderer implements ViewContextInterface
*/ */
public function renderPropertySignature($property) public function renderPropertySignature($property)
{ {
return $this->typeLink($property->types) . ' ' . $property->name . ' = ' . ($property->defaultValue === null ? 'null' : $property->defaultValue); if ($property->getter !== null || $property->setter !== null) {
// TODO $sig = [];
if(!empty($property->signature)) if ($property->getter !== null) {
return $property->signature; $sig[] = $this->renderMethodSignature($property->getter);
$sig=''; }
if(!empty($property->getter)) if ($property->setter !== null) {
$sig=$property->getter->signature; $sig[] = $this->renderMethodSignature($property->setter);
if(!empty($property->setter)) }
{ return implode('<br />', $sig);
if($sig!=='')
$sig.='<br/>';
$sig.=$property->setter->signature;
} }
return $sig; return $this->typeLink($property->types) . ' ' . $property->name . ' = ' . ($property->defaultValue === null ? 'null' : $property->defaultValue);
} }
/** /**
...@@ -334,7 +331,7 @@ abstract class Renderer extends BaseRenderer implements ViewContextInterface ...@@ -334,7 +331,7 @@ abstract class Renderer extends BaseRenderer implements ViewContextInterface
return ($method->isReturnByReference ? '<b>&</b>' : '') return ($method->isReturnByReference ? '<b>&</b>' : '')
. ($method->returnType === null ? 'void' : $this->typeLink($method->returnTypes)) . ($method->returnType === null ? 'void' : $this->typeLink($method->returnTypes))
. ' ' . $method->name . '( ' . ' ' . $this->subjectLink($method, $method->name) . '( '
. implode(', ', $params) . implode(', ', $params)
. ' )'; . ' )';
} }
......
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