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