Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
97.78% covered (success)
97.78%
44 / 45
91.67% covered (success)
91.67%
11 / 12
CRAP
0.00% covered (danger)
0.00%
0 / 1
LazyAttributes
97.78% covered (success)
97.78%
44 / 45
91.67% covered (success)
91.67%
11 / 12
27
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 init
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
2
 offsetExists
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
 offsetGet
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
 offsetSet
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
3
 offsetUnset
75.00% covered (warning)
75.00%
3 / 4
0.00% covered (danger)
0.00%
0 / 1
2.06
 getValues
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
 getObjects
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
4
 count
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
 getIterator
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
 merge
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
4
 clone
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3namespace Wikimedia\RemexHtml\Tokenizer;
4
5/**
6 * An Attributes implementation which defers interpretation of regex match
7 * results until the caller requires them.
8 *
9 * This should not be directly instantiated outside of Tokenizer.
10 */
11class LazyAttributes implements Attributes {
12    /** @var callable */
13    private $interpreter;
14
15    /** @var mixed */
16    private $data;
17
18    /** @var string[] */
19    private $attributes;
20
21    /** @var Attribute[] */
22    private $attrObjects;
23
24    public function __construct( $data, callable $interpreter ) {
25        $this->interpreter = $interpreter;
26        $this->data = $data;
27    }
28
29    /**
30     * Initialize the attributes array
31     */
32    private function init() {
33        if ( $this->attributes === null ) {
34            $func = $this->interpreter;
35            $this->attributes = $func( $this->data );
36            // @phan-suppress-next-line PhanTypeMismatchPropertyProbablyReal
37            $this->interpreter = null;
38            $this->data = null;
39        }
40    }
41
42    public function offsetExists( $offset ): bool {
43        if ( $this->attributes === null ) {
44            $this->init();
45        }
46        return isset( $this->attributes[$offset] );
47    }
48
49    public function &offsetGet( $offset ): string {
50        if ( $this->attributes === null ) {
51            $this->init();
52        }
53        return $this->attributes[$offset];
54    }
55
56    public function offsetSet( $offset, $value ): void {
57        if ( $this->attributes === null ) {
58            $this->init();
59        }
60        $this->attributes[$offset] = $value;
61        if ( $this->attrObjects !== null ) {
62            $this->attrObjects[$offset] = new Attribute( $offset, null, null, $offset, $value );
63        }
64    }
65
66    public function offsetUnset( $offset ): void {
67        if ( $this->attributes === null ) {
68            $this->init();
69        }
70        unset( $this->attributes[$offset] );
71        unset( $this->attrObjects[$offset] );
72    }
73
74    public function getValues() {
75        if ( $this->attributes === null ) {
76            $this->init();
77        }
78        return $this->attributes;
79    }
80
81    public function getObjects() {
82        if ( $this->attrObjects === null ) {
83            if ( $this->attributes === null ) {
84                $this->init();
85            }
86            $result = [];
87            foreach ( $this->attributes as $name => $value ) {
88                $result[$name] = new Attribute( $name, null, null, $name, $value );
89            }
90            $this->attrObjects = $result;
91        }
92        return $this->attrObjects;
93    }
94
95    public function count(): int {
96        if ( $this->attributes === null ) {
97            return count( $this->data );
98        }
99        return count( $this->attributes );
100    }
101
102    public function getIterator(): \ArrayIterator {
103        if ( $this->attributes === null ) {
104            $this->init();
105        }
106        return new \ArrayIterator( $this->attributes );
107    }
108
109    public function merge( Attributes $other ) {
110        if ( $this->attributes === null ) {
111            $this->init();
112        }
113        foreach ( $other as $name => $value ) {
114            if ( !isset( $this->attributes[$name] ) ) {
115                $this->attributes[$name] = $value;
116            }
117        }
118    }
119
120    public function clone() {
121        return $this;
122    }
123}