mirror of
https://github.com/phabelio/PHP-Parser.git
synced 2024-11-26 20:14:46 +01:00
Extend Name::slice() to support negative length+offset
This commit is contained in:
parent
818ef2e692
commit
c9fea2ef67
@ -165,17 +165,31 @@ class Name extends NodeAbstract
|
||||
* If the slice is empty, a Name with an empty parts array is returned. While this is
|
||||
* meaningless in itself, it works correctly in conjunction with concat().
|
||||
*
|
||||
* @param int $offset Offset to start the slice at
|
||||
* Offset and length have the same meaning as in array_slice().
|
||||
*
|
||||
* @param int $offset Offset to start the slice at (may be negative)
|
||||
* @param int|null $length Length of the slice (may be negative)
|
||||
*
|
||||
* @return static Sliced name
|
||||
*/
|
||||
public function slice($offset) {
|
||||
// TODO negative offset and length
|
||||
if ($offset < 0 || $offset > count($this->parts)) {
|
||||
public function slice($offset, $length = null) {
|
||||
$numParts = count($this->parts);
|
||||
|
||||
$realOffset = $offset < 0 ? $offset + $numParts : $offset;
|
||||
if ($realOffset < 0 || $realOffset > $numParts) {
|
||||
throw new \OutOfBoundsException(sprintf('Offset %d is out of bounds', $offset));
|
||||
}
|
||||
|
||||
return new static(array_slice($this->parts, $offset), $this->attributes);
|
||||
if (null === $length) {
|
||||
$realLength = $numParts - $realOffset;
|
||||
} else {
|
||||
$realLength = $length < 0 ? $length + $numParts - $realOffset : $length;
|
||||
if ($realLength < 0 || $realLength > $numParts) {
|
||||
throw new \OutOfBoundsException(sprintf('Length %d is out of bounds', $length));
|
||||
}
|
||||
}
|
||||
|
||||
return new static(array_slice($this->parts, $realOffset, $realLength), $this->attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -96,20 +96,53 @@ class NameTest extends \PHPUnit_Framework_TestCase
|
||||
}
|
||||
|
||||
public function testSlice() {
|
||||
$name = new Name('foo\bar');
|
||||
$this->assertEquals(new Name('foo\bar'), $name->slice(0));
|
||||
$this->assertEquals(new Name('bar'), $name->slice(1));
|
||||
$this->assertEquals(new Name([]), $name->slice(2));
|
||||
$name = new Name('foo\bar\baz');
|
||||
$this->assertEquals(new Name('foo\bar\baz'), $name->slice(0));
|
||||
$this->assertEquals(new Name('bar\baz'), $name->slice(1));
|
||||
$this->assertEquals(new Name([]), $name->slice(3));
|
||||
$this->assertEquals(new Name('foo\bar\baz'), $name->slice(-3));
|
||||
$this->assertEquals(new Name('bar\baz'), $name->slice(-2));
|
||||
$this->assertEquals(new Name('foo\bar'), $name->slice(0, -1));
|
||||
$this->assertEquals(new Name([]), $name->slice(0, -3));
|
||||
$this->assertEquals(new Name('bar'), $name->slice(1, -1));
|
||||
$this->assertEquals(new Name([]), $name->slice(1, -2));
|
||||
$this->assertEquals(new Name('bar'), $name->slice(-2, 1));
|
||||
$this->assertEquals(new Name('bar'), $name->slice(-2, -1));
|
||||
$this->assertEquals(new Name([]), $name->slice(-2, -2));
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \OutOfBoundsException
|
||||
* @expectedExceptionMessage Offset 4 is out of bounds
|
||||
*/
|
||||
public function testSliceException() {
|
||||
public function testSliceOffsetTooLarge() {
|
||||
(new Name('foo\bar\baz'))->slice(4);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \OutOfBoundsException
|
||||
* @expectedExceptionMessage Offset -4 is out of bounds
|
||||
*/
|
||||
public function testSliceOffsetTooSmall() {
|
||||
(new Name('foo\bar\baz'))->slice(-4);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \OutOfBoundsException
|
||||
* @expectedExceptionMessage Length 4 is out of bounds
|
||||
*/
|
||||
public function testSliceLengthTooLarge() {
|
||||
(new Name('foo\bar\baz'))->slice(0, 4);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \OutOfBoundsException
|
||||
* @expectedExceptionMessage Length -4 is out of bounds
|
||||
*/
|
||||
public function testSliceLengthTooSmall() {
|
||||
(new Name('foo\bar\baz'))->slice(0, -4);
|
||||
}
|
||||
|
||||
public function testConcat() {
|
||||
$this->assertEquals(new Name('foo\bar\baz'), Name::concat('foo', 'bar\baz'));
|
||||
$this->assertEquals(
|
||||
|
Loading…
Reference in New Issue
Block a user