Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
72.73% covered (warning)
72.73%
24 / 33
33.33% covered (danger)
33.33%
1 / 3
CRAP
0.00% covered (danger)
0.00%
0 / 1
LintLogger
72.73% covered (warning)
72.73%
24 / 33
33.33% covered (danger)
33.33%
1 / 3
16.43
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
 convertDSROffsets
100.00% covered (success)
100.00%
24 / 24
100.00% covered (success)
100.00%
1 / 1
9
 logLintOutput
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 1
12
1<?php
2declare( strict_types = 1 );
3
4namespace Wikimedia\Parsoid\Logger;
5
6use Wikimedia\Parsoid\Config\Env;
7use Wikimedia\Parsoid\Utils\Timing;
8use Wikimedia\Parsoid\Utils\TokenUtils;
9
10/**
11 * Logger backend for linter.
12 * This backend filters out logging messages with Logtype "lint/*" and
13 * logs them (console, external service).
14 */
15class LintLogger {
16
17    /** @var Env */
18    private $env;
19
20    public function __construct( Env $env ) {
21        $this->env = $env;
22    }
23
24    /**
25     * Convert DSR offsets in collected lints
26     *
27     * Linter offsets should always be ucs2 if the lint viewer is client-side JavaScript.
28     * But, added conversion args in case callers wants some other conversion for other
29     * use cases.
30     *
31     * @param Env $env
32     * @param array &$lints
33     * @param ('byte'|'ucs2'|'char') $from
34     * @param ('byte'|'ucs2'|'char') $to
35     */
36    public static function convertDSROffsets(
37        Env $env, array &$lints, string $from = 'byte', string $to = 'ucs2'
38    ): void {
39        $metrics = $env->getSiteConfig()->metrics();
40        $timer = null;
41        if ( $metrics ) {
42            $timer = Timing::start( $metrics );
43        }
44
45        // Accumulate offsets + convert widths to pseudo-offsets
46        $offsets = [];
47        foreach ( $lints as &$lint ) {
48            $dsr = &$lint['dsr'];
49            $offsets[] = &$dsr[0];
50            $offsets[] = &$dsr[1];
51
52            // dsr[2] is a width. Convert it to an offset pointer.
53            if ( ( $dsr[2] ?? 0 ) > 1 ) { // widths 0,1,null are fine
54                $dsr[2] = $dsr[0] + $dsr[2];
55                $offsets[] = &$dsr[2];
56            }
57
58            // dsr[3] is a width. Convert it to an offset pointer.
59            if ( ( $dsr[3] ?? 0 ) > 1 ) { // widths 0,1,null are fine
60                $dsr[3] = $dsr[1] - $dsr[3];
61                $offsets[] = &$dsr[3];
62            }
63        }
64
65        TokenUtils::convertOffsets( $env->topFrame->getSrcText(), $from, $to, $offsets );
66
67        // Undo the conversions of dsr[2], dsr[3]
68        foreach ( $lints as &$lint ) {
69            $dsr = &$lint['dsr'];
70            if ( ( $dsr[2] ?? 0 ) > 1 ) { // widths 0,1,null are fine
71                $dsr[2] -= $dsr[0];
72            }
73            if ( ( $dsr[3] ?? 0 ) > 1 ) { // widths 0,1,null are fine
74                $dsr[3] = $dsr[1] - $dsr[3];
75            }
76        }
77
78        if ( $metrics ) {
79            $timer->end( "lint.offsetconversion" );
80        }
81    }
82
83    /**
84     *
85     */
86    public function logLintOutput() {
87        $env = $this->env;
88
89        // We only want to send to the MW API if this was a request to parse
90        // the full page.
91        if ( !$env->logLinterData ) {
92            return;
93        }
94
95        $enabledBuffer = $env->getLints();
96
97        // Convert offsets to ucs2
98        $offsetType = $env->getCurrentOffsetType();
99        if ( $offsetType !== 'ucs2' ) {
100            self::convertDSROffsets( $env, $enabledBuffer, $offsetType, 'ucs2' );
101        }
102
103        $env->getDataAccess()->logLinterData( $env->getPageConfig(), $enabledBuffer );
104    }
105
106}