Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 43
0.00% covered (danger)
0.00%
0 / 4
CRAP
0.00% covered (danger)
0.00%
0 / 1
Tracer
0.00% covered (danger)
0.00%
0 / 43
0.00% covered (danger)
0.00%
0 / 4
210
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 trace
0.00% covered (danger)
0.00%
0 / 14
0.00% covered (danger)
0.00%
0 / 1
30
 log
0.00% covered (danger)
0.00%
0 / 10
0.00% covered (danger)
0.00%
0 / 1
2
 formatArgs
0.00% covered (danger)
0.00%
0 / 18
0.00% covered (danger)
0.00%
0 / 1
56
1<?php
2declare( strict_types = 1 );
3
4namespace Wikimedia\Parsoid\Wt2Html;
5
6use InvalidArgumentException;
7use Wikimedia\WikiPEG\Tracer as ITracer;
8
9/**
10 * FIXME: DefaultTracer should make some things protected
11 */
12class Tracer implements ITracer {
13    /** @var int */
14    private $indentLevel = 0;
15    private string $text;
16
17    public function __construct( string $text ) {
18        $this->text = $text;
19    }
20
21    /**
22     * @param array $event
23     */
24    public function trace( $event ): void {
25        switch ( $event['type'] ) {
26            case 'rule.enter':
27                $this->log( $event );
28                $this->indentLevel++;
29                break;
30
31            case 'rule.match':
32                $this->indentLevel--;
33                $this->log( $event );
34                break;
35
36            case 'rule.fail':
37                $this->indentLevel--;
38                $this->log( $event );
39                break;
40
41            default:
42                throw new InvalidArgumentException( "Invalid event type {$event['type']}" );
43        }
44    }
45
46    /**
47     * @param array $event
48     */
49    private function log( $event ) {
50        $offset = $event['location']->start->offset;
51        print str_pad(
52            '' . $event['location'],
53            20
54        )
55            . str_pad( 'c:' . json_encode( $this->text[$offset] ?? '' ), 10 )
56            . str_pad( $event['type'], 10 ) . ' '
57            . str_repeat( ' ', $this->indentLevel ) . $event['rule']
58            . $this->formatArgs( $event['args'] ?? null )
59            . "\n";
60    }
61
62    /**
63     * @param ?array $argMap
64     * @return string
65     */
66    private function formatArgs( $argMap ) {
67        if ( !$argMap ) {
68            return '';
69        }
70
71        $argParts = [];
72        foreach ( $argMap as $argName => $argValue ) {
73            if ( $argName === '$silence' ) {
74                continue;
75            }
76            if ( $argName === '$boolParams' ) {
77                $argParts[] = '0x' . base_convert( (string)$argValue, 10, 16 );
78            } else {
79                $displayName = str_replace( '$param_', '', $argName );
80                if ( $displayName[0] === '&' ) {
81                    $displayName = substr( $displayName, 1 );
82                    $ref = '&';
83                } else {
84                    $ref = '';
85                }
86                $argParts[] = "$displayName=$ref" .
87                           json_encode( $argValue, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE );
88            }
89        }
90        if ( $argParts ) {
91            return '<' . implode( ', ', $argParts ) . '>';
92        } else {
93            return '';
94        }
95    }
96}