Add get{Start,End}{Line,TokenPos,FilePos}() methods

This commit is contained in:
Nikita Popov 2017-09-29 17:34:15 +02:00
parent 3d4621bbea
commit cc328a4c9c
5 changed files with 153 additions and 14 deletions

View File

@ -19,12 +19,70 @@ interface Node
public function getSubNodeNames() : array;
/**
* Gets line the node started in.
* Gets line the node started in (alias of getStartLine).
*
* @return int Line
* @return int Start line (or -1 if not available)
*/
public function getLine() : int;
/**
* Gets line the node started in.
*
* Requires the 'startLine' attribute to be enabled in the lexer (enabled by default).
*
* @return int Start line (or -1 if not available)
*/
public function getStartLine() : int;
/**
* Gets the line the node ended in.
*
* Requires the 'endLine' attribute to be enabled in the lexer (enabled by default).
*
* @return int End line (or -1 if not available)
*/
public function getEndLine() : int;
/**
* Gets the token offset of the first token that is part of this node.
*
* The offset is an index into the array returned by Lexer::getTokens().
*
* Requires the 'startTokenPos' attribute to be enabled in the lexer (DISABLED by default).
*
* @return int Token start position (or -1 if not available)
*/
public function getStartTokenPos() : int;
/**
* Gets the token offset of the last token that is part of this node.
*
* The offset is an index into the array returned by Lexer::getTokens().
*
* Requires the 'endTokenPos' attribute to be enabled in the lexer (DISABLED by default).
*
* @return int Token end position (or -1 if not available)
*/
public function getEndTokenPos() : int;
/**
* Gets the file offset of the first character that is part of this node.
*
* Requires the 'startFilePos' attribute to be enabled in the lexer (DISABLED by default).
*
* @return int File start position (or -1 if not available)
*/
public function getStartFilePos() : int;
/**
* Gets the file offset of the last character that is part of this node.
*
* Requires the 'endFilePos' attribute to be enabled in the lexer (DISABLED by default).
*
* @return int File end position (or -1 if not available)
*/
public function getEndFilePos() : int;
/**
* Gets all comments directly preceding this node.
*

View File

@ -25,14 +25,84 @@ abstract class NodeAbstract implements Node, \JsonSerializable
}
/**
* Gets line the node started in.
* Gets line the node started in (alias of getStartLine).
*
* @return int Line
* @return int Start line (or -1 if not available)
*/
public function getLine() : int {
return $this->attributes['startLine'] ?? -1;
}
/**
* Gets line the node started in.
*
* Requires the 'startLine' attribute to be enabled in the lexer (enabled by default).
*
* @return int Start line (or -1 if not available)
*/
public function getStartLine() : int {
return $this->attributes['startLine'] ?? -1;
}
/**
* Gets the line the node ended in.
*
* Requires the 'endLine' attribute to be enabled in the lexer (enabled by default).
*
* @return int End line (or -1 if not available)
*/
public function getEndLine() : int {
return $this->attributes['endLine'] ?? -1;
}
/**
* Gets the token offset of the first token that is part of this node.
*
* The offset is an index into the array returned by Lexer::getTokens().
*
* Requires the 'startTokenPos' attribute to be enabled in the lexer (DISABLED by default).
*
* @return int Token start position (or -1 if not available)
*/
public function getStartTokenPos() : int {
return $this->attributes['startTokenPos'] ?? -1;
}
/**
* Gets the token offset of the last token that is part of this node.
*
* The offset is an index into the array returned by Lexer::getTokens().
*
* Requires the 'endTokenPos' attribute to be enabled in the lexer (DISABLED by default).
*
* @return int Token end position (or -1 if not available)
*/
public function getEndTokenPos() : int {
return $this->attributes['endTokenPos'] ?? -1;
}
/**
* Gets the file offset of the first character that is part of this node.
*
* Requires the 'startFilePos' attribute to be enabled in the lexer (DISABLED by default).
*
* @return int File start position (or -1 if not available)
*/
public function getStartFilePos() : int {
return $this->attributes['startFilePos'] ?? -1;
}
/**
* Gets the file offset of the last character that is part of this node.
*
* Requires the 'endFilePos' attribute to be enabled in the lexer (DISABLED by default).
*
* @return int File end position (or -1 if not available)
*/
public function getEndFilePos() : int {
return $this->attributes['endFilePos'] ?? -1;
}
/**
* Gets all comments directly preceding this node.
*

View File

@ -176,13 +176,13 @@ class NodeDumper
return null;
}
$start = $node->getAttribute('startLine');
$end = $node->getAttribute('endLine');
$start = $node->getStartLine();
$end = $node->getEndLine();
if ($node->hasAttribute('startFilePos') && $node->hasAttribute('endFilePos')
&& null !== $this->code
) {
$start .= ':' . $this->toColumn($this->code, $node->getAttribute('startFilePos'));
$end .= ':' . $this->toColumn($this->code, $node->getAttribute('endFilePos'));
$start .= ':' . $this->toColumn($this->code, $node->getStartFilePos());
$end .= ':' . $this->toColumn($this->code, $node->getEndFilePos());
}
return "[$start - $end]";
}

View File

@ -495,8 +495,8 @@ abstract class PrettyPrinterAbstract
return $this->pFallback($node);
}
$startPos = $origNode->getAttribute('startTokenPos', -1);
$endPos = $origNode->getAttribute('endTokenPos', -1);
$startPos = $origNode->getStartTokenPos();
$endPos = $origNode->getEndTokenPos();
if ($startPos < 0 || $endPos < 0) {
// Shouldn't happen
return $this->pFallback($node);
@ -550,8 +550,8 @@ abstract class PrettyPrinterAbstract
$extraLeft = '';
$extraRight = '';
if ($origSubNode !== null) {
$subStartPos = $origSubNode->getAttribute('startTokenPos', -1);
$subEndPos = $origSubNode->getAttribute('endTokenPos', -1);
$subStartPos = $origSubNode->getStartTokenPos();
$subEndPos = $origSubNode->getEndTokenPos();
if ($subStartPos < 0 || $subEndPos < 0) {
// Shouldn't happen
return $this->pFallback($node);
@ -663,8 +663,8 @@ abstract class PrettyPrinterAbstract
return null;
}
$itemStartPos = $origArrItem->getAttribute('startTokenPos', -1);
$itemEndPos = $origArrItem->getAttribute('endTokenPos', -1);
$itemStartPos = $origArrItem->getStartTokenPos();
$itemEndPos = $origArrItem->getEndTokenPos();
if ($itemStartPos < 0 || $itemEndPos < 0) {
// Shouldn't happen
return null;

View File

@ -29,6 +29,11 @@ class NodeAbstractTest extends TestCase
public function provideNodes() {
$attributes = [
'startLine' => 10,
'endLine' => 11,
'startTokenPos' => 12,
'endTokenPos' => 13,
'startFilePos' => 14,
'endFilePos' => 15,
'comments' => [
new Comment('// Comment' . "\n"),
new Comment\Doc('/** doc comment */'),
@ -50,6 +55,12 @@ class NodeAbstractTest extends TestCase
$this->assertSame('Dummy', $node->getType());
$this->assertSame(['subNode1', 'subNode2'], $node->getSubNodeNames());
$this->assertSame(10, $node->getLine());
$this->assertSame(10, $node->getStartLine());
$this->assertSame(11, $node->getEndLine());
$this->assertSame(12, $node->getStartTokenPos());
$this->assertSame(13, $node->getEndTokenPos());
$this->assertSame(14, $node->getStartFilePos());
$this->assertSame(15, $node->getEndFilePos());
$this->assertSame('/** doc comment */', $node->getDocComment()->getText());
$this->assertSame('value1', $node->subNode1);
$this->assertSame('value2', $node->subNode2);