annotate vendor/nikic/php-parser/test/PhpParser/CodeParsingTest.php @ 19:fa3358dc1485 tip

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