Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
<?php
2
namespace JmesPath;
3
 
4
/**
5
 * Provides CLI debugging information for the AST and Compiler runtimes.
6
 */
7
class DebugRuntime
8
{
9
    private $runtime;
10
    private $out;
11
    private $lexer;
12
    private $parser;
13
 
14
    public function __construct(callable $runtime, $output = null)
15
    {
16
        $this->runtime = $runtime;
17
        $this->out = $output ?: STDOUT;
18
        $this->lexer = new Lexer();
19
        $this->parser = new Parser($this->lexer);
20
    }
21
 
22
    public function __invoke($expression, $data)
23
    {
24
        if ($this->runtime instanceof CompilerRuntime) {
25
            return $this->debugCompiled($expression, $data);
26
        }
27
 
28
        return $this->debugInterpreted($expression, $data);
29
    }
30
 
31
    private function debugInterpreted($expression, $data)
32
    {
33
        return $this->debugCallback(
34
            function () use ($expression, $data) {
35
                $runtime = $this->runtime;
36
                return $runtime($expression, $data);
37
            },
38
            $expression,
39
            $data
40
        );
41
    }
42
 
43
    private function debugCompiled($expression, $data)
44
    {
45
        $result = $this->debugCallback(
46
            function () use ($expression, $data) {
47
                $runtime = $this->runtime;
48
                return $runtime($expression, $data);
49
            },
50
            $expression,
51
            $data
52
        );
53
        $this->dumpCompiledCode($expression);
54
 
55
        return $result;
56
    }
57
 
58
    private function dumpTokens($expression)
59
    {
60
        $lexer = new Lexer();
61
        fwrite($this->out, "Tokens\n======\n\n");
62
        $tokens = $lexer->tokenize($expression);
63
 
64
        foreach ($tokens as $t) {
65
            fprintf(
66
                $this->out,
67
                "%3d  %-13s  %s\n", $t['pos'], $t['type'],
68
                json_encode($t['value'])
69
            );
70
        }
71
 
72
        fwrite($this->out, "\n");
73
    }
74
 
75
    private function dumpAst($expression)
76
    {
77
        $parser = new Parser();
78
        $ast = $parser->parse($expression);
79
        fwrite($this->out, "AST\n========\n\n");
80
        fwrite($this->out, json_encode($ast, JSON_PRETTY_PRINT) . "\n");
81
    }
82
 
83
    private function dumpCompiledCode($expression)
84
    {
85
        fwrite($this->out, "Code\n========\n\n");
86
        $dir = sys_get_temp_dir();
87
        $hash = md5($expression);
88
        $functionName = "jmespath_{$hash}";
89
        $filename = "{$dir}/{$functionName}.php";
90
        fwrite($this->out, "File: {$filename}\n\n");
91
        fprintf($this->out, file_get_contents($filename));
92
    }
93
 
94
    private function debugCallback(callable $debugFn, $expression, $data)
95
    {
96
        fprintf($this->out, "Expression\n==========\n\n%s\n\n", $expression);
97
        $this->dumpTokens($expression);
98
        $this->dumpAst($expression);
99
        fprintf($this->out, "\nData\n====\n\n%s\n\n", json_encode($data, JSON_PRETTY_PRINT));
100
        $startTime = microtime(true);
101
        $result = $debugFn();
102
        $total = microtime(true) - $startTime;
103
        fprintf($this->out, "\nResult\n======\n\n%s\n\n", json_encode($result, JSON_PRETTY_PRINT));
104
        fwrite($this->out, "Time\n====\n\n");
105
        fprintf($this->out, "Total time:     %f ms\n\n", $total);
106
 
107
        return $result;
108
    }
109
}