<?php
namespace Tlf\Scrawl\Ext\MdVerb;
class Ast implements \Tlf\Scrawl\ExtensionType\MdVerbInterface {
protected $scrawl;
public function __construct($scrawl){
$this->scrawl = $scrawl;
}
public function getVerbs(): array{
return [
'ast'=>'verbAst', //alias for @ast_class()
'classMethods'=>'getClassMethodsTemplate',
'ast_class'=> 'getAstClassInfo',
];
}
/**
*
* @param $fqn The fully qualified name, like a class name or function with its namespace
* @param $dotProperty For class, something like 'methods.methodName.docblock' to get a docblock for the given class.
*
* @example @ast(\Tlf\Scrawl\Ext\MdVerb\Ast, methods.getAstClassInfo.docblock)
* @mdverb ast
*
*/
public function getAstClassInfo(array $info, string $fqn, string $dotProperty){
// @ast(class,Phad\Test\Documentation,methods.testWriteAView.docblock)
$class = $this->scrawl->getOutput('astClass', $fqn);
// var_dump(array_keys($this->scrawl->getOutputs('astClass')));
if ($class == 'null') return "class '$fqn' not found in ast.";
$propStack = explode('.', $dotProperty);
$head = $class;
if (!is_array($head)){
$file = $info['file']->path;
// $this->scrawl->error('@ast or @ast_class in '.$file,'requires "astClass" output for fqn "'.$fqn.'" to be an array, but a '. gettype($class).' was returned.');
$this->scrawl->error("@ast($fqn, $dotProperty) failed", 'in '.$file);
return "@ast($fqn) failed";
}
foreach ($propStack as $prop){
if ($prop=='*'){
return print_r($head,true);
}
if (!isset($head[$prop])){
$options = [];
foreach ($head as $key=>$value){
if (is_numeric($key) && ($value['name']??null)==$prop){
$head = $head[$key];
continue 2;
} else if (is_numeric($key) && isset($value['name'])){
$options[] = $value['name'];
}
}
$options = array_merge($options, array_keys($head));
$msg = "Cannot find '$prop' part of '$dotProperty' on '$fqn'. You may try one of: ". implode(", ", $options);
$this->scrawl->error('@ast or @ast_class', $msg);
return $msg;
}
$head = $head[$prop];
}
if (is_array($head)){
if (isset($head['body']))return $head['body'];
else if (isset($head['description']))return $head['description'];
else if (isset($head['src']))return $head['src'];
$msg="Found an array for '$dotProperty' on '$fqn' with keys: ".implode(", ", array_keys($head));
$this->scrawl->error('@ast or @ast_class', $msg);
return $msg;
}
return $head;
}
/**
*
* @return string replacement
*/
public function verbAst($info, $className, $dotProperty){
//
// This method not currently functional. Ugggh!!!
//
// $parts = explode('.', $classDotThing);
// $class = array_shift($parts);
// return $this->getAstClassInfo($info, $class, 'method.'.implode('.',$parts));
return $this->getAstClassInfo($info, $className, $dotProperty);
// $key = $class;
// var_dump($key);
// $output = $this->scrawl->getOutput('api',$key);
//
// if (trim($output)=='')return "--ast '${class}' not found--";
//
// return $output;
}
public function getClassMethodsTemplate($verb, $argListStr, $line){
if ($verb!='classMethods')return;
$args = explode(',', $argListStr);
$className = $args[0];
$visibility = '*';
if (isset($args[1])){
$visibility = trim($args[1]);
}
$class = $this->scrawl->getOutput('astClass', $className);
$template = dirname(__DIR__,2).'/Template/classMethods.md.php';
ob_start();
require($template);
$final = ob_get_clean();
return $final;
}
}