DumpAstCommand   A
last analyzed

Complexity

Total Complexity 10

Size/Duplication

Total Lines 69
Duplicated Lines 0 %

Coupling/Cohesion

Components 0
Dependencies 9

Importance

Changes 4
Bugs 0 Features 2
Metric Value
wmc 10
c 4
b 0
f 2
lcom 0
cbo 9
dl 0
loc 69
rs 10

2 Methods

Rating   Name   Duplication   Size   Complexity  
A configure() 0 14 1
D execute() 0 44 9
1
<?php
2
/**
3
 * DumpAstCommand.php
4
 *
5
 * MIT LICENSE
6
 *
7
 * LICENSE: This source file is subject to the MIT license.
8
 * A copy of the licenses text was distributed alongside this
9
 * file (usually the repository or package root). The text can also
10
 * be obtained through one of the following sources:
11
 * * http://opensource.org/licenses/MIT
12
 * * https://github.com/suralc/pvra/blob/master/LICENSE
13
 *
14
 * @author     suralc <[email protected]>
15
 * @license    http://opensource.org/licenses/MIT  MIT
16
 */
17
namespace Pvra\Console\Commands\Debug;
18
19
20
use PhpParser\Error;
21
use PhpParser\NodeDumper;
22
use PhpParser\NodeTraverser;
23
use PhpParser\NodeVisitor\NameResolver;
24
use PhpParser\Parser;
25
use Pvra\Lexer\ExtendedEmulativeLexer;
26
use Symfony\Component\Console\Command\Command;
27
use Symfony\Component\Console\Input\InputArgument;
28
use Symfony\Component\Console\Input\InputInterface;
29
use Symfony\Component\Console\Input\InputOption;
30
use Symfony\Component\Console\Output\OutputInterface;
31
32
/**
33
 * Class DumpAstCommand
34
 *
35
 * @package Pvra\Console\Commands
36
 */
37
class DumpAstCommand extends Command
38
{
39
    const DEFAULT_XDEBUG_DEPTH = -1;
40
    /**
41
     * @inheritdoc
42
     */
43
    protected function configure()
44
    {
45
        $this
46
            ->setName('debug:dumpAst')
47
            ->setDescription('Dumps the AST of a file generated by PHP-Parser to the console');
48
49
        $this
50
            ->addArgument('file', InputArgument::REQUIRED, 'File to dump')
51
            ->addOption('extensive', 'x', InputOption::VALUE_NONE, 'Use more extensive output format.')
52
            ->addOption('preventNameExpansion', 'p', InputOption::VALUE_NONE,
53
                'Prevent name expansion. May increase performance but sacrifices some functionality')
54
            ->addOption('xdebugMaxExtensiveDepth', 'd', InputOption::VALUE_REQUIRED,
55
                'Rendering depth of extensive output. Only used if xdebug is loaded', self::DEFAULT_XDEBUG_DEPTH);
56
    }
57
58
    /**
59
     * @inheritdoc
60
     */
61
    protected function execute(InputInterface $input, OutputInterface $output)
62
    {
63
        $file = $input->getArgument('file');
64
65
        if (!is_file($file) || !is_readable($file)) {
66
            $output->writeln(sprintf('<error>"%s" is not a valid file.</error>', $file));
67
            return 0x2;
68
        }
69
70
        $parser = new Parser(ExtendedEmulativeLexer::createDefaultInstance());
71
72
        try {
73
            $stmts = $parser->parse(file_get_contents($file));
74
            if ($stmts === null) {
75
                $output->writeln('The passed file appears to be emtpy. Ending program.');
76
                return 2;
77
            }
78
        } catch (Error $error) {
79
            $output->writeln('<error>' . $error->getMessage() . ' in ' . realpath($file) . '</error>');
80
            return 0x2;
81
        }
82
83
        if ($input->getOption('preventNameExpansion') !== true) {
84
            $traverser = new NodeTraverser();
85
            $traverser->addVisitor(new NameResolver());
86
            $stmts = $traverser->traverse($stmts);
87
        }
88
89
        if ($input->getOption('extensive')) {
90
            $depth = self::DEFAULT_XDEBUG_DEPTH;
91
            if ($hasXdebug = extension_loaded('xdebug')) {
92
                $depth = ini_get('xdebug.var_display_max_depth');
93
                ini_set('xdebug.var_display_max_depth', intval($input->getOption('xdebugMaxExtensiveDepth')));
94
            }
95
            var_dump($stmts);
96
            if ($hasXdebug) {
97
                ini_set('xdebug.var_display_max_depth', $depth);
98
            }
99
        } else {
100
            echo (new NodeDumper)->dump($stmts);
101
        }
102
103
        return 0;
104
    }
105
}
106