Blame view

vendor/nikic/php-parser/bin/php-parse 5.96 KB
c4650843   Etienne Pallier   Ajout du dossier ...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#!/usr/bin/env php
<?php

foreach ([__DIR__ . '/../../../autoload.php', __DIR__ . '/../vendor/autoload.php'] as $file) {
    if (file_exists($file)) {
        require $file;
        break;
    }
}

ini_set('xdebug.max_nesting_level', 3000);

// Disable XDebug var_dump() output truncation
ini_set('xdebug.var_display_max_children', -1);
ini_set('xdebug.var_display_max_data', -1);
ini_set('xdebug.var_display_max_depth', -1);

list($operations, $files, $attributes) = parseArgs($argv);

/* Dump nodes by default */
if (empty($operations)) {
    $operations[] = 'dump';
}

if (empty($files)) {
    showHelp("Must specify at least one file.");
}

d06254b2   Etienne Pallier   bugfix plugin mig...
29
$lexer = new PhpParser\Lexer\Emulative(array('usedAttributes' => array(
c4650843   Etienne Pallier   Ajout du dossier ...
30
    'startLine', 'endLine', 'startFilePos', 'endFilePos', 'comments'
d06254b2   Etienne Pallier   bugfix plugin mig...
31
)));
c4650843   Etienne Pallier   Ajout du dossier ...
32
33
34
35
36
37
38
39
40
$parser = (new PhpParser\ParserFactory)->create(
    PhpParser\ParserFactory::PREFER_PHP7,
    $lexer
);
$dumper = new PhpParser\NodeDumper([
    'dumpComments' => true,
    'dumpPositions' => $attributes['with-positions'],
]);
$prettyPrinter = new PhpParser\PrettyPrinter\Standard;
d06254b2   Etienne Pallier   bugfix plugin mig...
41
$serializer = new PhpParser\Serializer\XML;
c4650843   Etienne Pallier   Ajout du dossier ...
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84

$traverser = new PhpParser\NodeTraverser();
$traverser->addVisitor(new PhpParser\NodeVisitor\NameResolver);

foreach ($files as $file) {
    if (strpos($file, '<?php') === 0) {
        $code = $file;
        echo "====> Code $code\n";
    } else {
        if (!file_exists($file)) {
            die("File $file does not exist.\n");
        }

        $code = file_get_contents($file);
        echo "====> File $file:\n";
    }

    if ($attributes['with-recovery']) {
        $errorHandler = new PhpParser\ErrorHandler\Collecting;
        $stmts = $parser->parse($code, $errorHandler);
        foreach ($errorHandler->getErrors() as $error) {
            $message = formatErrorMessage($error, $code, $attributes['with-column-info']);
            echo $message . "\n";
        }
        if (null === $stmts) {
            continue;
        }
    } else {
        try {
            $stmts = $parser->parse($code);
        } catch (PhpParser\Error $error) {
            $message = formatErrorMessage($error, $code, $attributes['with-column-info']);
            die($message . "\n");
        }
    }

    foreach ($operations as $operation) {
        if ('dump' === $operation) {
            echo "==> Node dump:\n";
            echo $dumper->dump($stmts, $code), "\n";
        } elseif ('pretty-print' === $operation) {
            echo "==> Pretty print:\n";
            echo $prettyPrinter->prettyPrintFile($stmts), "\n";
d06254b2   Etienne Pallier   bugfix plugin mig...
85
86
87
        } elseif ('serialize-xml' === $operation) {
            echo "==> Serialized XML:\n";
            echo $serializer->serialize($stmts), "\n";
c4650843   Etienne Pallier   Ajout du dossier ...
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
        } elseif ('var-dump' === $operation) {
            echo "==> var_dump():\n";
            var_dump($stmts);
        } elseif ('resolve-names' === $operation) {
            echo "==> Resolved names.\n";
            $stmts = $traverser->traverse($stmts);
        }
    }
}

function formatErrorMessage(PhpParser\Error $e, $code, $withColumnInfo) {
    if ($withColumnInfo && $e->hasColumnInfo()) {
        return $e->getMessageWithColumnInfo($code);
    } else {
        return $e->getMessage();
    }
}

function showHelp($error = '') {
    if ($error) {
        echo $error . "\n\n";
    }
    die(<<<OUTPUT
Usage: php-parse [operations] file1.php [file2.php ...]
   or: php-parse [operations] "<?php code"
Turn PHP source code into an abstract syntax tree.

Operations is a list of the following options (--dump by default):

    -d, --dump              Dump nodes using NodeDumper
    -p, --pretty-print      Pretty print file using PrettyPrinter\Standard
d06254b2   Etienne Pallier   bugfix plugin mig...
119
        --serialize-xml     Serialize nodes using Serializer\XML
c4650843   Etienne Pallier   Ajout du dossier ...
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
        --var-dump          var_dump() nodes (for exact structure)
    -N, --resolve-names     Resolve names using NodeVisitor\NameResolver
    -c, --with-column-info  Show column-numbers for errors (if available)
    -P, --with-positions    Show positions in node dumps
    -r, --with-recovery     Use parsing with error recovery
    -h, --help              Display this page

Example:
    php-parse -d -p -N -d file.php

    Dumps nodes, pretty prints them, then resolves names and dumps them again.


OUTPUT
    );
}

function parseArgs($args) {
d06254b2   Etienne Pallier   bugfix plugin mig...
138
139
140
    $operations = array();
    $files = array();
    $attributes = array(
c4650843   Etienne Pallier   Ajout du dossier ...
141
142
143
        'with-column-info' => false,
        'with-positions' => false,
        'with-recovery' => false,
d06254b2   Etienne Pallier   bugfix plugin mig...
144
    );
c4650843   Etienne Pallier   Ajout du dossier ...
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162

    array_shift($args);
    $parseOptions = true;
    foreach ($args as $arg) {
        if (!$parseOptions) {
            $files[] = $arg;
            continue;
        }

        switch ($arg) {
            case '--dump':
            case '-d':
                $operations[] = 'dump';
                break;
            case '--pretty-print':
            case '-p':
                $operations[] = 'pretty-print';
                break;
d06254b2   Etienne Pallier   bugfix plugin mig...
163
164
            case '--serialize-xml':
                $operations[] = 'serialize-xml';
c4650843   Etienne Pallier   Ajout du dossier ...
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
                break;
            case '--var-dump':
                $operations[] = 'var-dump';
                break;
            case '--resolve-names':
            case '-N';
                $operations[] = 'resolve-names';
                break;
            case '--with-column-info':
            case '-c';
                $attributes['with-column-info'] = true;
                break;
            case '--with-positions':
            case '-P':
                $attributes['with-positions'] = true;
                break;
            case '--with-recovery':
            case '-r':
                $attributes['with-recovery'] = true;
                break;
            case '--help':
            case '-h';
                showHelp();
                break;
            case '--':
                $parseOptions = false;
                break;
            default:
                if ($arg[0] === '-') {
                    showHelp("Invalid operation $arg.");
                } else {
                    $files[] = $arg;
                }
        }
    }

d06254b2   Etienne Pallier   bugfix plugin mig...
201
    return array($operations, $files, $attributes);
c4650843   Etienne Pallier   Ajout du dossier ...
202
}