Updated to Drupal 8.5. Core Media not yet in use.
[yaffs-website] / vendor / nikic / php-parser / test / PhpParser / CodeParsingTest.php
1 <?php declare(strict_types=1);
2
3 namespace PhpParser;
4
5 use PhpParser\Node\Expr;
6 use PhpParser\Node\Stmt;
7
8 require_once __DIR__ . '/CodeTestAbstract.php';
9
10 class CodeParsingTest extends CodeTestAbstract
11 {
12     /**
13      * @dataProvider provideTestParse
14      */
15     public function testParse($name, $code, $expected, $modeLine) {
16         if (null !== $modeLine) {
17             $modes = array_fill_keys(explode(',', $modeLine), true);
18         } else {
19             $modes = [];
20         }
21
22         list($parser5, $parser7) = $this->createParsers($modes);
23         list($stmts5, $output5) = $this->getParseOutput($parser5, $code, $modes);
24         list($stmts7, $output7) = $this->getParseOutput($parser7, $code, $modes);
25
26         if (isset($modes['php5'])) {
27             $this->assertSame($expected, $output5, $name);
28             $this->assertNotSame($expected, $output7, $name);
29         } elseif (isset($modes['php7'])) {
30             $this->assertNotSame($expected, $output5, $name);
31             $this->assertSame($expected, $output7, $name);
32         } else {
33             $this->assertSame($expected, $output5, $name);
34             $this->assertSame($expected, $output7, $name);
35         }
36
37         $this->checkAttributes($stmts5);
38         $this->checkAttributes($stmts7);
39     }
40
41     public function createParsers(array $modes) {
42         $lexer = new Lexer\Emulative(['usedAttributes' => [
43             'startLine', 'endLine',
44             'startFilePos', 'endFilePos',
45             'startTokenPos', 'endTokenPos',
46             'comments'
47         ]]);
48
49         return [
50             new Parser\Php5($lexer),
51             new Parser\Php7($lexer),
52         ];
53     }
54
55     private function getParseOutput(Parser $parser, $code, array $modes) {
56         $dumpPositions = isset($modes['positions']);
57
58         $errors = new ErrorHandler\Collecting;
59         $stmts = $parser->parse($code, $errors);
60
61         $output = '';
62         foreach ($errors->getErrors() as $error) {
63             $output .= $this->formatErrorMessage($error, $code) . "\n";
64         }
65
66         if (null !== $stmts) {
67             $dumper = new NodeDumper(['dumpComments' => true, 'dumpPositions' => $dumpPositions]);
68             $output .= $dumper->dump($stmts, $code);
69         }
70
71         return [$stmts, canonicalize($output)];
72     }
73
74     public function provideTestParse() {
75         return $this->getTests(__DIR__ . '/../code/parser', 'test');
76     }
77
78     private function formatErrorMessage(Error $e, $code) {
79         if ($e->hasColumnInfo()) {
80             return $e->getMessageWithColumnInfo($code);
81         } else {
82             return $e->getMessage();
83         }
84     }
85
86     private function checkAttributes($stmts) {
87         if ($stmts === null) {
88             return;
89         }
90
91         $traverser = new NodeTraverser();
92         $traverser->addVisitor(new class extends NodeVisitorAbstract {
93             public function enterNode(Node $node) {
94                 $startLine = $node->getStartLine();
95                 $endLine = $node->getEndLine();
96                 $startFilePos = $node->getStartFilePos();
97                 $endFilePos = $node->getEndFilePos();
98                 $startTokenPos = $node->getStartTokenPos();
99                 $endTokenPos = $node->getEndTokenPos();
100                 if ($startLine < 0 || $endLine < 0 ||
101                     $startFilePos < 0 || $endFilePos < 0 ||
102                     $startTokenPos < 0 || $endTokenPos < 0
103                 ) {
104                     throw new \Exception('Missing location information on ' . $node->getType());
105                 }
106
107                 if ($endLine < $startLine ||
108                     $endFilePos < $startFilePos ||
109                     $endTokenPos < $startTokenPos
110                 ) {
111                     // Nops and error can have inverted order, if they are empty
112                     if (!$node instanceof Stmt\Nop && !$node instanceof Expr\Error) {
113                         throw new \Exception('End < start on ' . $node->getType());
114                     }
115                 }
116             }
117         });
118         $traverser->traverse($stmts);
119     }
120 }