Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 27
0.00% covered (danger)
0.00%
0 / 12
CRAP
0.00% covered (danger)
0.00%
0 / 1
SourceRange
0.00% covered (danger)
0.00%
0 / 27
0.00% covered (danger)
0.00%
0 / 12
156
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 expandTsrK
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
2
 expandTsrV
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
2
 join
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
2
 substr
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
2
 offset
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 to
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 length
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 fromArray
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 toJsonArray
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 newFromJsonArray
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
2
 hint
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2declare( strict_types = 1 );
3
4namespace Wikimedia\Parsoid\Tokens;
5
6use Wikimedia\Assert\Assert;
7use Wikimedia\JsonCodec\Hint;
8use Wikimedia\JsonCodec\JsonCodecable;
9use Wikimedia\JsonCodec\JsonCodecableTrait;
10use Wikimedia\Parsoid\Utils\PHPUtils;
11
12/**
13 * Represents a source offset range.
14 */
15class SourceRange implements JsonCodecable {
16    use JsonCodecableTrait;
17
18    /**
19     * Offset of the first character (range start is inclusive).
20     * @var ?int
21     */
22    public $start;
23
24    /**
25     * Offset just past the last character (range end is exclusive).
26     * @var ?int
27     */
28    public $end;
29
30    /**
31     * Create a new source offset range.
32     * @param ?int $start The starting index (UTF-8 byte count, inclusive)
33     * @param ?int $end The ending index (UTF-8 byte count, exclusive)
34     */
35    public function __construct( ?int $start, ?int $end ) {
36        $this->start = $start;
37        $this->end = $end;
38    }
39
40    /**
41     * Return a KVSourceRange where this SourceRange is the key,
42     * and the value has zero length.
43     * @return KVSourceRange
44     */
45    public function expandTsrK(): KVSourceRange {
46        return new KVSourceRange(
47            $this->start, $this->end, $this->end, $this->end
48        );
49    }
50
51    /**
52     * Return a KVSourceRange where this SourceRange is the value,
53     * and the key has zero length.
54     * @return KVSourceRange
55     */
56    public function expandTsrV(): KVSourceRange {
57        return new KVSourceRange(
58            $this->start, $this->start, $this->start, $this->end
59        );
60    }
61
62    /**
63     * Return a KVSourceRange by using this SourceRange for the key
64     * and the given SourceRange parameter for the value.
65     * @param SourceRange $value
66     * @return KVSourceRange
67     */
68    public function join( SourceRange $value ): KVSourceRange {
69        return new KVSourceRange(
70            $this->start, $this->end, $value->start, $value->end
71        );
72    }
73
74    /**
75     * Return the substring of the given string corresponding to this
76     * range.
77     * @param string $str The source text string
78     * @return string
79     */
80    public function substr( string $str ): string {
81        $start = $this->start;
82        $length = $this->length();
83        Assert::invariant( ( $start ?? -1 ) >= 0, "Bad SourceRange start" );
84        // @phan-suppress-next-line PhanCoalescingNeverNull
85        Assert::invariant( ( $length ?? -1 ) >= 0, "Bad SourceRange length" );
86        return PHPUtils::safeSubstr( $str, $start, $length );
87    }
88
89    /**
90     * Return a new source range shifted by $amount.
91     * @param int $amount The amount to shift by
92     * @return SourceRange
93     */
94    public function offset( int $amount ): SourceRange {
95        return new SourceRange( $this->start + $amount, $this->end + $amount );
96    }
97
98    /**
99     * Return a range from the end of this range to the start of the given
100     * range.
101     * @param SourceRange $sr
102     * @return SourceRange
103     */
104    public function to( SourceRange $sr ): SourceRange {
105        return new SourceRange( $this->end, $sr->start );
106    }
107
108    /**
109     * Return the length of this source range.
110     * @return int
111     */
112    public function length(): int {
113        return $this->end - $this->start;
114    }
115
116    /**
117     * Create a new source offset range from an array of
118     * integers (such as created during JSON serialization).
119     * @param int[] $sr
120     * @return SourceRange
121     * @deprecated
122     */
123    public static function fromArray( array $sr ): SourceRange {
124        // Dynamic dispatch (DomSourceRange subclasses this)
125        return static::newFromJsonArray( $sr );
126    }
127
128    /** @inheritDoc */
129    public function toJsonArray(): array {
130        return [ $this->start, $this->end ];
131    }
132
133    /** @inheritDoc */
134    public static function newFromJsonArray( array $json ): SourceRange {
135        Assert::invariant(
136            count( $json ) === 2,
137            'Wrong # of elements in SourceRange array'
138        );
139        return new SourceRange( $json[0], $json[1] );
140    }
141
142    /** JsonCodec serialization hint. */
143    public static function hint(): Hint {
144        return Hint::build( self::class, Hint::USE_SQUARE );
145    }
146}