From: C. Scott Ananian Date: Mon, 28 Oct 2019 19:52:50 +0000 (-0400) Subject: Deprecate Parser implementation methods (will be private in next release) X-Git-Tag: 1.34.0-rc.1~14 X-Git-Url: http://git.heureux-cyclage.org/?p=lhc%2Fweb%2Fwiklou.git;a=commitdiff_plain;h=e900893531e76fb8f80c1c9b5be459fd02862c3c Deprecate Parser implementation methods (will be private in next release) The following public methods were renamed and made private; the old name is hard-deprecated and calls the new renamed private method: Parser::doMagicLinks() => handleMagicLinks() Parser::doDoubleUnderscore() => handleMagicLinks() Parser::doHeadings() => handleHeadings() Parser::doAllQuotes() => handleAllQuotes() Parser::replaceExternalLinks() => handleExternalLinks() Parser::replaceInternalLinks() => handleInternalLinks() Parser::replaceInternalLinks2() => handleInternalLinks2() Parser::getVariableValue() => expandMagicVariable() Parser::initialiseVariables() => initializeVariables() Parser::formatHeadings() => finalizeHeadings() Parser::test{Pst,Preprocess,Srvus}() => fuzzTest{Pst,Preprocess,Srvus}() Additionally, the following methods are not used externally, but are used outside the Parser class by core code. They have been marked @internal: Parser::doQuotes() (used by {{#displaytitle}}), Parser::getExternalLink{Rel,Attribs}() (used by Linker), Parser::normalizeLinkUrl() (used by Special:LinkSearch and elsewhere). Parser::{brace,arg,extension}Substitution() (used by PPFrame) Code search query: https://codesearch.wmflabs.org/deployed/?q=do%28MagicLinks%7CDoubleUnderscore%7CHeadings%7CAllQuotes%29%7Creplace%28ExternalLinks%7CInternalLinks%28%7C2%29%29%7CgetVariableValue%7CinitialiseVariables%7CformatHeadings%7Ctest%28Pst%7CPreprocess%7CSrvus%29%7CdoQuotes%7CgetExternalLink%28Rel%7CAttribs%29%7CnormalizeLinkUrl%7C%28brace%2Carg%2Cextension%29Substitution&i=nope&files=&repos= Bug: T236810 Change-Id: I19a43ffc5dcfdd2981b51079c33422c964acb076 --- diff --git a/RELEASE-NOTES-1.34 b/RELEASE-NOTES-1.34 index bb4d431f27..aa974817f0 100644 --- a/RELEASE-NOTES-1.34 +++ b/RELEASE-NOTES-1.34 @@ -635,6 +635,11 @@ because of Phabricator reports. * Using the Parser without initializing its $mTitle property to non-null has been deprecated. In a future release Parser::getTitle() will throw a TypeError if $mTitle is uninitialized. +* A number of public methods of Parser were exposed only for historical + reasons and have been deprecated: doMagicLinks, doDoubleUnderscore, + doHeadings, doAllQuotes, replaceExternalLinks, replaceInternalLinks, + replaceInternalLinks2, getVariableValue, initialiseVariables, formatHeadings, + testPst, testPreprocess, testSrvus. === Other changes in 1.34 === * Added option to specify "Various authors" as author in extension credits using diff --git a/includes/parser/Parser.php b/includes/parser/Parser.php index 3aa2c69ffa..d15288af90 100644 --- a/includes/parser/Parser.php +++ b/includes/parser/Parser.php @@ -162,7 +162,7 @@ class Parser { */ public $mFirstCall = true; - # Initialised by initialiseVariables() + # Initialised by initializeVariables() /** * @var MagicWordArray @@ -469,7 +469,7 @@ class Parser { CoreParserFunctions::register( $this ); CoreTagHooks::register( $this ); - $this->initialiseVariables(); + $this->initializeVariables(); // Avoid PHP 7.1 warning from passing $this by reference $parser = $this; @@ -1233,13 +1233,25 @@ class Parser { } /** - * parse the wiki syntax used to render tables + * Parse the wiki syntax used to render tables. * * @private * @param string $text * @return string + * @deprecated since 1.34; should not be used outside parser class. */ public function doTableStuff( $text ) { + wfDeprecated( __METHOD__, '1.34' ); + return $this->handleTables( $text ); + } + + /** + * Parse the wiki syntax used to render tables. + * + * @param string $text + * @return string + */ + private function handleTables( $text ) { $lines = StringUtils::explode( "\n", $text ); $out = ''; $td_history = []; # Is currently a td tag open? @@ -1491,23 +1503,23 @@ class Parser { # properly; putting them before other transformations should keep # exciting things like link expansions from showing up in surprising # places. - $text = $this->doTableStuff( $text ); + $text = $this->handleTables( $text ); $text = preg_replace( '/(^|\n)-----*/', '\\1
', $text ); - $text = $this->doDoubleUnderscore( $text ); + $text = $this->handleDoubleUnderscore( $text ); - $text = $this->doHeadings( $text ); - $text = $this->replaceInternalLinks( $text ); - $text = $this->doAllQuotes( $text ); - $text = $this->replaceExternalLinks( $text ); + $text = $this->handleHeadings( $text ); + $text = $this->handleInternalLinks( $text ); + $text = $this->handleAllQuotes( $text ); + $text = $this->handleExternalLinks( $text ); - # replaceInternalLinks may sometimes leave behind - # absolute URLs, which have to be masked to hide them from replaceExternalLinks + # handleInternalLinks may sometimes leave behind + # absolute URLs, which have to be masked to hide them from handleExternalLinks $text = str_replace( self::MARKER_PREFIX . 'NOPARSE', '', $text ); - $text = $this->doMagicLinks( $text ); - $text = $this->formatHeadings( $text, $origText, $isMain ); + $text = $this->handleMagicLinks( $text ); + $text = $this->finalizeHeadings( $text, $origText, $isMain ); return $text; } @@ -1613,12 +1625,26 @@ class Parser { * * DML * @private + * @param string $text + * @return string + * @deprecated since 1.34; should not be used outside parser class. + */ + public function doMagicLinks( $text ) { + wfDeprecated( __METHOD__, '1.34' ); + return $this->handleMagicLinks( $text ); + } + + /** + * Replace special strings like "ISBN xxx" and "RFC xxx" with + * magic external links. + * + * DML * * @param string $text * * @return string */ - public function doMagicLinks( $text ) { + private function handleMagicLinks( $text ) { $prots = wfUrlProtocolsWithoutProtRel(); $urlChar = self::EXT_LINK_URL_CLASS; $addr = self::EXT_LINK_ADDR; @@ -1788,15 +1814,25 @@ class Parser { } /** - * Parse headers and return html + * Parse headers and return html. * * @private - * * @param string $text - * * @return string + * @deprecated since 1.34; should not be used outside parser class. */ public function doHeadings( $text ) { + wfDeprecated( __METHOD__, '1.34' ); + return $this->handleHeadings( $text ); + } + + /** + * Parse headers and return html + * + * @param string $text + * @return string + */ + private function handleHeadings( $text ) { for ( $i = 6; $i >= 1; --$i ) { $h = str_repeat( '=', $i ); // Trim non-newline whitespace from headings @@ -1813,8 +1849,21 @@ class Parser { * @param string $text * * @return string The altered text + * @deprecated since 1.34; should not be used outside parser class. */ public function doAllQuotes( $text ) { + wfDeprecated( __METHOD__, '1.34' ); + return $this->handleAllQuotes( $text ); + } + + /** + * Replace single quotes with HTML markup + * + * @param string $text + * + * @return string The altered text + */ + private function handleAllQuotes( $text ) { $outtext = ''; $lines = StringUtils::explode( "\n", $text ); foreach ( $lines as $line ) { @@ -1830,6 +1879,7 @@ class Parser { * @param string $text * * @return string + * @internal */ public function doQuotes( $text ) { $arr = preg_split( "/(''+)/", $text, -1, PREG_SPLIT_DELIM_CAPTURE ); @@ -2018,6 +2068,21 @@ class Parser { * @return string */ public function replaceExternalLinks( $text ) { + wfDeprecated( __METHOD__, '1.34' ); + return $this->handleExternalLinks( $text ); + } + + /** + * Replace external links (REL) + * + * Note: this is all very hackish and the order of execution matters a lot. + * Make sure to run tests/parser/parserTests.php if you change this code. + * + * @param string $text + * @throws MWException + * @return string + */ + private function handleExternalLinks( $text ) { $bits = preg_split( $this->mExtLinkBracketedRegex, $text, -1, PREG_SPLIT_DELIM_CAPTURE ); // @phan-suppress-next-line PhanTypeComparisonFromArray See phan issue #3161 if ( $bits === false ) { @@ -2091,6 +2156,7 @@ class Parser { * Get the rel attribute for a particular external link. * * @since 1.21 + * @internal * @param string|bool $url Optional URL, to extract the domain from for rel => * nofollow if appropriate * @param LinkTarget|null $title Optional LinkTarget, for wgNoFollowNsExceptions lookups @@ -2113,6 +2179,7 @@ class Parser { * (depending on configuration, namespace, and the URL's domain) and/or a * target attribute (depending on configuration). * + * @internal * @param string $url URL to extract the domain from for rel => * nofollow if appropriate * @return array Associative array of HTML attributes @@ -2144,6 +2211,7 @@ class Parser { * This generally follows the syntax defined in RFC 3986, with special * consideration for HTTP query strings. * + * @internal * @param string $url * @return string */ @@ -2281,26 +2349,51 @@ class Parser { /** * Process [[ ]] wikilinks * - * @param string $s + * @param string $text * * @return string Processed text * * @private + * @deprecated since 1.34; should not be used outside parser class. */ - public function replaceInternalLinks( $s ) { - $this->mLinkHolders->merge( $this->replaceInternalLinks2( $s ) ); - return $s; + public function replaceInternalLinks( $text ) { + wfDeprecated( __METHOD__, '1.34' ); + return $this->handleInternalLinks( $text ); + } + + /** + * Process [[ ]] wikilinks + * + * @param string $text + * + * @return string Processed text + */ + private function handleInternalLinks( $text ) { + $this->mLinkHolders->merge( $this->handleInternalLinks2( $text ) ); + return $text; } /** * Process [[ ]] wikilinks (RIL) - * @param string &$s + * @param string &$text * @throws MWException * @return LinkHolderArray * * @private + * @deprecated since 1.34; should not be used outside parser class. */ - public function replaceInternalLinks2( &$s ) { + public function replaceInternalLinks2( &$text ) { + wfDeprecated( __METHOD__, '1.34' ); + return $this->handleInternalLinks2( $text ); + } + + /** + * Process [[ ]] wikilinks (RIL) + * @param string &$s + * @throws MWException + * @return LinkHolderArray + */ + private function handleInternalLinks2( &$s ) { static $tc = false, $e1, $e1_img; # the % is needed to support urlencoded titles as well if ( !$tc ) { @@ -2382,7 +2475,7 @@ class Parser { && substr( $m[3], 0, 1 ) === ']' && strpos( $text, '[' ) !== false ) { - $text .= ']'; # so that replaceExternalLinks($text) works later + $text .= ']'; # so that handleExternalLinks($text) works later $m[3] = substr( $m[3], 1 ); } # fix up urlencoded title texts @@ -2468,7 +2561,7 @@ class Parser { if ( !$found ) { # we couldn't find the end of this imageLink, so output it raw # but don't ignore what might be perfectly normal links in the text we've examined - $holders->merge( $this->replaceInternalLinks2( $text ) ); + $holders->merge( $this->handleInternalLinks2( $text ) ); $s .= "{$prefix}[[$link|$text"; # note: no $trail, because without an end, there *is* no trail continue; @@ -2529,10 +2622,10 @@ class Parser { # recursively parse links inside the image caption # actually, this will parse them in any other parameters, too, # but it might be hard to fix that, and it doesn't matter ATM - $text = $this->replaceExternalLinks( $text ); - $holders->merge( $this->replaceInternalLinks2( $text ) ); + $text = $this->handleExternalLinks( $text ); + $holders->merge( $this->handleInternalLinks2( $text ) ); } - # cloak any absolute URLs inside the image markup, so replaceExternalLinks() won't touch them + # cloak any absolute URLs inside the image markup, so handleExternalLinks() won't touch them $s .= $prefix . $this->armorLinks( $this->makeImage( $nt, $text, $holders ) ) . $trail; continue; @@ -2575,7 +2668,7 @@ class Parser { [ $this, $nt, &$options, &$descQuery ] ); # Fetch and register the file (file title may be different via hooks) list( $file, $nt ) = $this->fetchFileAndTitle( $nt, $options ); - # Cloak with NOPARSE to avoid replacement in replaceExternalLinks + # Cloak with NOPARSE to avoid replacement in handleExternalLinks $s .= $prefix . $this->armorLinks( Linker::makeMediaLinkFile( $nt, $file, $text ) ) . $trail; continue; @@ -2681,8 +2774,25 @@ class Parser { * * @throws MWException * @return string + * @deprecated since 1.34; should not be used outside parser class. */ public function getVariableValue( $index, $frame = false ) { + wfDeprecated( __METHOD__, '1.34' ); + return $this->expandMagicVariable( $index, $frame ); + } + + /** + * Return value of a magic variable (like PAGENAME) + * + * @param string $index Magic variable identifier as mapped in MagicWordFactory::$mVariableIDs + * @param bool|PPFrame $frame + * + * @throws MWException + * @return string + */ + private function expandMagicVariable( $index, $frame = false ) { + // XXX This function should be moved out of Parser class for + // reuse by Parsoid/etc. if ( is_null( $this->mTitle ) ) { // If no title set, bad things are going to happen // later. Title should always be set since this @@ -3065,8 +3175,18 @@ class Parser { * initialise the magic variables (like CURRENTMONTHNAME) and substitution modifiers * * @private + * @deprecated since 1.34; should not be used outside parser class. */ public function initialiseVariables() { + wfDeprecated( __METHOD__, '1.34' ); + $this->initializeVariables(); + } + + /** + * Initialize the magic variables (like CURRENTMONTHNAME) and + * substitution modifiers. + */ + private function initializeVariables() { $variableIDs = $this->magicWordFactory->getVariableIDs(); $substIDs = $this->magicWordFactory->getSubstIDs(); @@ -3241,6 +3361,7 @@ class Parser { * @param PPFrame $frame The current frame, contains template arguments * @throws Exception * @return string|array The text of the template + * @internal */ public function braceSubstitution( $piece, $frame ) { // Flags @@ -3307,7 +3428,7 @@ class Parser { if ( !$found && $args->getLength() == 0 ) { $id = $this->mVariables->matchStartToEnd( $part1 ); if ( $id !== false ) { - $text = $this->getVariableValue( $id, $frame ); + $text = $this->expandMagicVariable( $id, $frame ); if ( $this->magicWordFactory->getCacheTTL( $id ) > -1 ) { $this->mOutput->updateCacheExpiry( $this->magicWordFactory->getCacheTTL( $id ) ); @@ -4017,7 +4138,7 @@ class Parser { /** * Triple brace replacement -- used for template arguments - * @private + * @internal * * @param array $piece * @param PPFrame $frame @@ -4075,6 +4196,7 @@ class Parser { * * @throws MWException * @return string + * @internal */ public function extensionSubstitution( $params, $frame ) { static $errorStr = ''; @@ -4202,10 +4324,22 @@ class Parser { * Fills $this->mDoubleUnderscores, returns the modified text * * @param string $text - * * @return string + * @deprecated since 1.34; should not be used outside parser class. */ public function doDoubleUnderscore( $text ) { + wfDeprecated( __METHOD__, '1.34' ); + return $this->handleDoubleUnderscore( $text ); + } + + /** + * Strip double-underscore items like __NOGALLERY__ and __NOTOC__ + * Fills $this->mDoubleUnderscores, returns the modified text + * + * @param string $text + * @return string + */ + private function handleDoubleUnderscore( $text ) { # The position of __TOC__ needs to be recorded $mw = $this->magicWordFactory->get( 'toc' ); if ( $mw->match( $text ) ) { @@ -4277,8 +4411,29 @@ class Parser { * @param bool $isMain * @return mixed|string * @private + * @deprecated since 1.34; should not be used outside parser class. */ public function formatHeadings( $text, $origText, $isMain = true ) { + wfDeprecated( __METHOD__, '1.34' ); + return $this->finalizeHeadings( $text, $origText, $isMain ); + } + + /** + * This function accomplishes several tasks: + * 1) Auto-number headings if that option is enabled + * 2) Add an [edit] link to sections for users who have enabled the option and can edit the page + * 3) Add a Table of contents on the top for users who have enabled the option + * 4) Auto-anchor headings + * + * It loops through all headlines, collects the necessary data, then splits up the + * string and re-inserts the newly formatted headlines. + * + * @param string $text + * @param string $origText Original, untouched wikitext + * @param bool $isMain + * @return mixed|string + */ + private function finalizeHeadings( $text, $origText, $isMain = true ) { # Inhibit editsection links if requested in the page if ( isset( $this->mDoubleUnderscores['noeditsection'] ) ) { $maybeShowEditLink = false; @@ -4288,7 +4443,7 @@ class Parser { # Get all headlines for numbering them and adding funky stuff like [edit] # links - this is for later, but we need the number of headlines right now - # NOTE: white space in headings have been trimmed in doHeadings. They shouldn't + # NOTE: white space in headings have been trimmed in handleHeadings. They shouldn't # be trimmed here since whitespace in HTML headings is significant. $matches = []; $numMatches = preg_match_all( @@ -5646,7 +5801,7 @@ class Parser { protected function stripAltText( $caption, $holders ) { # Strip bad stuff out of the title (tooltip). We can't just use # replaceLinkHoldersText() here, because if this function is called - # from replaceInternalLinks2(), mLinkHolders won't be up-to-date. + # from handleInternalLinks2(), mLinkHolders won't be up-to-date. if ( $holders ) { $tooltip = $holders->replaceText( $caption ); } else { @@ -6250,9 +6405,27 @@ class Parser { * @param int $outputType * * @return string + * @deprecated since 1.34; should not be used outside parser class. */ public function testSrvus( $text, Title $title, ParserOptions $options, $outputType = self::OT_HTML + ) { + wfDeprecated( __METHOD__, '1.34' ); + return $this->fuzzTestSrvus( $text, $title, $options, $outputType ); + } + + /** + * Strip/replaceVariables/unstrip for preprocessor regression testing + * + * @param string $text + * @param Title $title + * @param ParserOptions $options + * @param int $outputType + * + * @return string + */ + private function fuzzTestSrvus( $text, Title $title, ParserOptions $options, + $outputType = self::OT_HTML ) { $magicScopeVariable = $this->lock(); $this->startParse( $title, $options, $outputType, true ); @@ -6268,8 +6441,20 @@ class Parser { * @param Title $title * @param ParserOptions $options * @return string + * @deprecated since 1.34; should not be used outside parser class. */ public function testPst( $text, Title $title, ParserOptions $options ) { + wfDeprecated( __METHOD__, '1.34' ); + return $this->fuzzTestPst( $text, $title, $options ); + } + + /** + * @param string $text + * @param Title $title + * @param ParserOptions $options + * @return string + */ + private function fuzzTestPst( $text, Title $title, ParserOptions $options ) { return $this->preSaveTransform( $text, $title, $options->getUser(), $options ); } @@ -6278,9 +6463,21 @@ class Parser { * @param Title $title * @param ParserOptions $options * @return string + * @deprecated since 1.34; should not be used outside parser class. */ public function testPreprocess( $text, Title $title, ParserOptions $options ) { - return $this->testSrvus( $text, $title, $options, self::OT_PREPROCESS ); + wfDeprecated( __METHOD__, '1.34' ); + return $this->fuzzTestPreprocess( $text, $title, $options ); + } + + /** + * @param string $text + * @param Title $title + * @param ParserOptions $options + * @return string + */ + private function fuzzTestPreprocess( $text, Title $title, ParserOptions $options ) { + return $this->fuzzTestSrvus( $text, $title, $options, self::OT_PREPROCESS ); } /** diff --git a/maintenance/preprocessorFuzzTest.php b/maintenance/preprocessorFuzzTest.php index 3a43ae8b5c..bdc955bb86 100644 --- a/maintenance/preprocessorFuzzTest.php +++ b/maintenance/preprocessorFuzzTest.php @@ -23,6 +23,8 @@ use MediaWiki\MediaWikiServices; +use Wikimedia\TestingAccessWrapper; + $optionsWithoutArgs = [ 'verbose' ]; require_once __DIR__ . '/commandLine.inc'; @@ -46,7 +48,7 @@ class PPFuzzTester { public $maxLength = 20; public $maxTemplates = 5; // public $outputTypes = [ 'OT_HTML', 'OT_WIKI', 'OT_PREPROCESS' ]; - public $entryPoints = [ 'testSrvus', 'testPst', 'testPreprocess' ]; + public $entryPoints = [ 'fuzzTestSrvus', 'fuzzTestPst', 'fuzzTestPreprocess' ]; public $verbose = false; /** @@ -216,7 +218,9 @@ class PPFuzzTest { $options->setTemplateCallback( [ $this, 'templateHook' ] ); $options->setTimestamp( wfTimestampNow() ); $this->output = call_user_func( - [ MediaWikiServices::getInstance()->getParser(), $this->entryPoint ], + [ TestingAccessWrapper::newFromObject( + MediaWikiServices::getInstance()->getParser() + ), $this->entryPoint ], $this->mainText, $this->title, $options diff --git a/tests/parser/ParserTestRunner.php b/tests/parser/ParserTestRunner.php index 91c3d40de9..59597a8d39 100644 --- a/tests/parser/ParserTestRunner.php +++ b/tests/parser/ParserTestRunner.php @@ -1799,7 +1799,7 @@ class ParserTestRunner { * Fake constant timestamp to make sure time-related parser * functions give a persistent value. * - * - Parser::getVariableValue (via ParserGetVariableValueTs hook) + * - Parser::expandMagicVariable (via ParserGetVariableValueTs hook) * - Parser::preSaveTransform (via ParserOptions) */ private function getFakeTimestamp() { diff --git a/tests/parser/parserTests.txt b/tests/parser/parserTests.txt index 4f78be4a9a..9f23514538 100644 --- a/tests/parser/parserTests.txt +++ b/tests/parser/parserTests.txt @@ -24427,7 +24427,7 @@ Line two !! end !! test -Interwiki links trounced by replaceExternalLinks after early LinkHolderArray expansion +Interwiki links trounced by handleExternalLinks after early LinkHolderArray expansion !! options wgLinkHolderBatchSize=0 !! wikitext diff --git a/tests/phpunit/includes/parser/MagicVariableTest.php b/tests/phpunit/includes/parser/MagicVariableTest.php index 02a4a2583a..cc474ddf11 100644 --- a/tests/phpunit/includes/parser/MagicVariableTest.php +++ b/tests/phpunit/includes/parser/MagicVariableTest.php @@ -11,9 +11,11 @@ * @file */ +use Wikimedia\TestingAccessWrapper; + /** * @group Database - * @covers Parser::getVariableValue + * @covers Parser::expandMagicVariable */ class MagicVariableTest extends MediaWikiTestCase { /** @@ -222,7 +224,7 @@ class MagicVariableTest extends MediaWikiTestCase { $this->assertSame( $expected, - $this->testParser->getVariableValue( $magic ), + TestingAccessWrapper::newFromObject( $this->testParser )->expandMagicVariable( $magic ), $msg ); }