Php.php

<?php

namespace Tlf\Scrawl\FileExt;

/**
 * Integrate the lexer for PHP files
 */
class Php {

    public \Tlf\Scrawl $scrawl;

    public function __construct(\Tlf\Scrawl $scrawl){
        $this->scrawl = $scrawl;
    }


    public function get_all_classes(){
        $asts = $this->scrawl->get_group('ast');
        $classes = [];
        foreach ($asts as $k=>$a){
            var_dump($k);
            if (substr($k,0,6)!='class.')continue;
            $classes[$a['fqn']] = $a;
        }

        return $classes;
    }

    public function set_ast(array $ast){
        // set class asts
        $classes = array_merge($ast['class']??[], $ast['namespace']['class']??[]);
        foreach ($classes as $c){
            $this->scrawl->set('ast','class.'.$c['name'], $c);
        }

        // set file asts
        // foreach ($ast as $a){
            // if ($a['type']=='file')
        // }

    }

    /**
     * Parsed `$str` into an ast (using the Lexer)
     * @param $str a string to parse
     * @return array ast
     */
    public function parse_str(string $str): array{

        $lexer = new \Tlf\Lexer();
        // $lexer->addGrammar(new \Tlf\Lexer\PhpGrammar());
        
        $ast = new \Tlf\Lexer\Ast('file');
        $phpGram = new \Tlf\Lexer\PhpGrammar();
        $lexer = new \Tlf\Lexer();
        $lexer->debug = false;
        $lexer->addGrammar($phpGram);

        // the first directive we're listening for
        $lexer->addDirective($phpGram->getDirectives(':php_open')['php_open']);

        ob_start();
        // runs the lexer with $ast as the head
        $ast = $lexer->lex($str, $ast);
        ob_end_clean();

        return $ast->getTree();
    }

    /**
     * Parsed `$str` into an ast (using the Lexer)
     *
     * @param $file_path a relative file path to parse (relative to dir.root). MAY be an absolute path...
     * @return array ast
     */
    public function parse_file(string $file_path): array {

        // $lexer->addGrammar(new \Tlf\Lexer\PhpGrammar());

        $abs_path = $this->scrawl->dir_root.'/'.$file_path;
        if (!file_exists($abs_path)){
            $abs_path = $file_path;
        }
        
        $phpGram = new \Tlf\Lexer\PhpGrammar();
        $phpGram->directives = array_merge(
            $phpGram->_string_directives,
            $phpGram->_core_directives,
        );
        $lexer = new \Tlf\Lexer();
        $lexer->useCache = true;
        $lexer->debug = false;
        $lexer->addGrammar($phpGram, null, false);

        // the first directive we're listening for
        $lexer->addDirective($phpGram->getDirectives(':php_open')['php_open']);

        ob_start();
        // runs the lexer with $ast as the head
        $ast = $lexer->lexFile($abs_path);
        // $ast = new \Tlf\Lexer\Ast('file');
        // $ast = $lexer->lex(file_get_contents($abs_path), $ast);
        ob_end_clean();

        return $ast->getTree();
    }


    /**
     * use the ast to create docs using the classList template
     *
     * @return array of files like `['rel/path'=>'file content']`
     */
    public function make_docs(array $ast){
        $files = [];

        $classes = $ast['class'] ?? $ast['namespace']['class'] ?? [];;
        foreach ($classes as $class){
            $out = $this->scrawl->get_template('ast/class', [null, $class, null]);
            $path = $class['fqn'];
            $path = str_replace('\\','/', $path).'.md';
            $files['class/'.$path] = $out;
        }

        $traits = $ast['trait'] ?? $ast['namespace']['trait'] ?? [];;
        foreach ($traits as $trait){
            $out = $this->scrawl->get_template('ast/class', [null, $trait, null]);
            $path = $trait['fqn'];
            $path = str_replace('\\','/', $path).'.md';
            $files['trait/'.$path] = $out;
        }

        return $files;
    }
}