PhpGrammar.php

<?php

namespace Tlf\Lexer\Test\Debug;


class PhpGrammar extends \Tlf\Lexer\Test\Tester {



    public function testMethodBodyIsString(){
        echo "This test is disabled because I'm currently not implementing the body capture ... it was a mess & that's a whole heck of an issue to figure out.";
        // this test probably belongs in debug()
        $this->disable();
        // this involves the test/input/php/lex/code-scrawl/IntegrationTest.php file 
        // which keeps showing ast objects in the output
        // where there should be a body string
        //
        return;


        $lexer = new \Tlf\Lexer();

        $abs_path = $this->file('test/input/php/lex/code-scrawl/IntegrationTest.php');
        
        $phpGram = new \Tlf\Lexer\PhpGrammar();
        $lexer = new \Tlf\Lexer();
        $lexer->useCache = false;
        $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->lexFile($abs_path);
        // ob_end_clean();

        // echo 'oh';
        // exit;

        print_r($ast->getTree());
        // exit;

    }

    /**
     * A block nested within a method caused the next method declaration to be incorect, so test all methods are correctly parsed in code-scrawl/Scraw2.php 
     */
    public function testScrawl2(){
        // See Issue 1, Scrawl2

        $ast = $this->get_ast('code-scrawl/Scrawl2.php');
        $methods = $this->get_ast_methods($ast);

        $target = [
            '__construct' => 'public function __construct(array $options=[])',
            'get_template' => 'public function get_template(string $name, array $args)',
            'process_str' => 'public function process_str(string $string, string $file_ext)',
            'addExtension' => 'public function addExtension(object $ext)',
            'get' => 'public function get(string $group, string $key)',
            'get_group' => 'public function get_group(string $group)',
            'set' => 'public function set(string $group, string $key, $value)',
            'parse_str' => 'public function parse_str($str, $ext)',
            'write_doc' => 'public function write_doc(string $rel_path, string $content)',
            'read_file' => 'public function read_file(string $rel_path)',
            'report' => 'public function report(string $msg)',
            'warn' => 'public function warn($header, $message)',
            'good' => 'public function good($header, $message)',
            'prepare_md_content' => 'public function prepare_md_content(string $markdown)',
        ];

        $this->compare_arrays($target,
            $methods['Tlf\\Scrawl2']
        );
    }


    /**
     *
     * Get the ast of a file in `test/input/php/lex/`
     *
     * @param $file relative path inside `test/input/php/lex/`
     * @param $debug true/false
     * @param $stop_loop loop to stop on. `-1` to not stop
     * @return an array ast 
     */
    public function get_ast($file, $debug=true, $stop_loop=-1): array{
        $in = $this->file('test/input/php/lex/');
        // $out = $this->file('test/input/php/tree/');
        $input = file_get_contents($in.$file);

        $phpGram = new \Tlf\Lexer\PhpGrammar();
        $phpGram->directives = array_merge(
            $phpGram->_string_directives,
            $phpGram->_core_directives,
        );
        $lexer = new \Tlf\Lexer();
        $lexer->stop_loop = $stop_loop;
        $lexer->debug = $debug;
        $lexer->addGrammar($phpGram, null, false);
        $lexer->addDirective($phpGram->getDirectives(':php_open')['php_open']);

        $ast = new \Tlf\Lexer\Ast('file');
        $ast = $lexer->lex($input, $ast);

        $tree = $ast->getTree();

        return $tree;
    }

    /**
     * Get the method names & declaration from an class ast
     *
     * @return `key=>value` array of `class_name=>[method_name=>method_declaration, m2=>declaration]`
     */
    public function get_ast_methods(array $ast): array{
        $all = [];
        $classes = array_merge($ast['class'] ?? [], $ast['namespace']['class'] ?? []);
        
        foreach ($classes as $c){

            foreach ($c['methods'] as $m){
                $all[$c['fqn']][$m['name']] = $m['declaration'];
            }
        }

        return $all;
    }

}