Code Coverage
 
Classes and Traits
Functions and Methods
Lines
Total
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 3
CRAP
50.00% covered (danger)
50.00%
23 / 46
LintLogger
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 3
48.00
50.00% covered (danger)
50.00%
23 / 46
 __construct
0.00% covered (danger)
0.00%
0 / 1
2
0.00% covered (danger)
0.00%
0 / 2
 convertDSROffsets
0.00% covered (danger)
0.00%
0 / 1
9.04
92.00% covered (success)
92.00%
23 / 25
 logLintOutput
0.00% covered (danger)
0.00%
0 / 1
42
0.00% covered (danger)
0.00%
0 / 19
<?php
declare( strict_types = 1 );
namespace Wikimedia\Parsoid\Logger;
use Wikimedia\Parsoid\Config\Env;
use Wikimedia\Parsoid\Utils\PHPUtils;
use Wikimedia\Parsoid\Utils\Timing;
use Wikimedia\Parsoid\Utils\TokenUtils;
/**
 * Logger backend for linter.
 * This backend filters out logging messages with Logtype "lint/*" and
 * logs them (console, external service).
 */
class LintLogger {
    /** @var Env */
    private $env;
    /**
     * @param Env $env
     */
    public function __construct( Env $env ) {
        $this->env = $env;
    }
    /**
     * Convert DSR offsets in collected lints
     *
     * Linter offsets should always be ucs2 if the lint viewer is client-side JavaScript.
     * But, added conversion args in case callers wants some other conversion for other
     * use cases.
     *
     * @param Env $env
     * @param array &$lints
     * @param string $from
     * @param string $to
     */
    public static function convertDSROffsets(
        Env $env, array &$lints, string $from = 'byte', string $to = 'ucs2'
    ): void {
        $metrics = $env->getSiteConfig()->metrics();
        $timer = null;
        if ( $metrics ) {
            $timer = Timing::start( $metrics );
        }
        // Accumulate offsets + convert widths to pseudo-offsets
        $offsets = [];
        foreach ( $lints as &$lint ) {
            $dsr = &$lint['dsr'];
            $offsets[] = &$dsr[0];
            $offsets[] = &$dsr[1];
            // dsr[2] is a width. Convert it to an offset pointer.
            if ( ( $dsr[2] ?? 0 ) > 1 ) { // widths 0,1,null are fine
                $dsr[2] = $dsr[0] + $dsr[2];
                $offsets[] = &$dsr[2];
            }
            // dsr[3] is a width. Convert it to an offset pointer.
            if ( ( $dsr[3] ?? 0 ) > 1 ) { // widths 0,1,null are fine
                $dsr[3] = $dsr[1] - $dsr[3];
                $offsets[] = &$dsr[3];
            }
        }
        TokenUtils::convertOffsets( $env->topFrame->getSrcText(), $from, $to, $offsets );
        // Undo the conversions of dsr[2], dsr[3]
        foreach ( $lints as &$lint ) {
            $dsr = &$lint['dsr'];
            if ( ( $dsr[2] ?? 0 ) > 1 ) { // widths 0,1,null are fine
                // @phan-suppress-next-line PhanPluginDuplicateExpressionAssignmentOperation; consistency
                $dsr[2] = $dsr[2] - $dsr[0];
            }
            if ( ( $dsr[3] ?? 0 ) > 1 ) { // widths 0,1,null are fine
                $dsr[3] = $dsr[1] - $dsr[3];
            }
        }
        if ( $metrics ) {
            $timer->end( "lint.offsetconversion" );
        }
    }
    /**
     *
     */
    public function logLintOutput() {
        $env = $this->env;
        // We only want to send to the MW API if this was a request to parse
        // the full page.
        if ( !$env->logLinterData ) {
            return;
        }
        $pageConfig = $env->getPageConfig();
        // Skip linting if we cannot lint it
        if ( !$pageConfig->hasLintableContentModel() ) {
            return;
        }
        $linting = $env->getSiteConfig()->linting();
        $enabledBuffer = null;
        if ( $linting === true ) {
            $enabledBuffer = $env->getLints(); // Everything is enabled
        } elseif ( is_array( $linting ) ) {
            $enabledBuffer = array_filter( $env->getLints(), static function ( $item ) use ( &$linting ) {
                return in_array( $item['type'], $linting, true );
            } );
        } else {
            PHPUtils::unreachable( 'Why are we here? Linting is disabled.' );
        }
        // Convert offsets to ucs2
        $offsetType = $env->getCurrentOffsetType();
        if ( $offsetType !== 'ucs2' ) {
            self::convertDSROffsets( $env, $enabledBuffer, $offsetType, 'ucs2' );
        }
        $env->getDataAccess()->logLinterData( $pageConfig, $enabledBuffer );
    }
}