Skip to content

Commit

Permalink
Add forward-compatibility ParserFactory methods
Browse files Browse the repository at this point in the history
Add ParserFactory::createForNewestSupportedVersion() and
ParserFactory::createForHostVersion() for forward-compatibility
with PHP-Parser 5. These methods do not accept an externally
constructed lexer and always enable all attributes.
  • Loading branch information
nikic committed Nov 12, 2023
1 parent 402b6cf commit e453389
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 0 deletions.
32 changes: 32 additions & 0 deletions lib/PhpParser/ParserFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

namespace PhpParser;

use PhpParser\Lexer\Emulative;
use PhpParser\Parser\Php7;

class ParserFactory
{
const PREFER_PHP7 = 1;
Expand Down Expand Up @@ -41,4 +44,33 @@ public function create(int $kind, Lexer $lexer = null, array $parserOptions = []
);
}
}

/**
* Create a parser targeting the newest version supported by this library. Code for older
* versions will be accepted if there have been no relevant backwards-compatibility breaks in
* PHP.
*
* All supported lexer attributes (comments, startLine, endLine, startTokenPos, endTokenPos,
* startFilePos, endFilePos) will be enabled.
*/
public function createForNewestSupportedVersion(): Parser {
return new Php7(new Emulative($this->getLexerOptions()));
}

/**
* Create a parser targeting the host PHP version, that is the PHP version we're currently
* running on. This parser will not use any token emulation.
*
* All supported lexer attributes (comments, startLine, endLine, startTokenPos, endTokenPos,
* startFilePos, endFilePos) will be enabled.
*/
public function createForHostVersion(): Parser {
return new Php7(new Lexer($this->getLexerOptions()));
}

private function getLexerOptions(): array {
return ['usedAttributes' => [
'comments', 'startLine', 'endLine', 'startTokenPos', 'endTokenPos', 'startFilePos', 'endFilePos',
]];
}
}
24 changes: 24 additions & 0 deletions test/PhpParser/ParserFactoryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
/* This test is very weak, because PHPUnit's assertEquals assertion is way too slow dealing with the
* large objects involved here. So we just do some basic instanceof tests instead. */

use PhpParser\Node\Stmt\Echo_;

class ParserFactoryTest extends \PHPUnit\Framework\TestCase
{
/** @dataProvider provideTestCreate */
Expand Down Expand Up @@ -33,4 +35,26 @@ public function provideTestCreate() {
]
];
}

/** @dataProvider provideTestLexerAttributes */
public function testLexerAttributes(Parser $parser) {
$stmts = $parser->parse("<?php /* Bar */ echo 'Foo';");
$stmt = $stmts[0];
$this->assertInstanceOf(Echo_::class, $stmt);
$this->assertCount(1, $stmt->getComments());
$this->assertSame(1, $stmt->getStartLine());
$this->assertSame(1, $stmt->getEndLine());
$this->assertSame(3, $stmt->getStartTokenPos());
$this->assertSame(6, $stmt->getEndTokenPos());
$this->assertSame(16, $stmt->getStartFilePos());
$this->assertSame(26, $stmt->getEndFilePos());
}

public function provideTestLexerAttributes() {
$factory = new ParserFactory();
return [
[$factory->createForHostVersion()],
[$factory->createForNewestSupportedVersion()],
];
}
}

0 comments on commit e453389

Please sign in to comment.