diff options
Diffstat (limited to 'includes/parser/Preprocessor_HipHop.hphp')
-rw-r--r-- | includes/parser/Preprocessor_HipHop.hphp | 106 |
1 files changed, 85 insertions, 21 deletions
diff --git a/includes/parser/Preprocessor_HipHop.hphp b/includes/parser/Preprocessor_HipHop.hphp index f5af0154..8b71a1b5 100644 --- a/includes/parser/Preprocessor_HipHop.hphp +++ b/includes/parser/Preprocessor_HipHop.hphp @@ -3,6 +3,21 @@ * A preprocessor optimised for HipHop, using HipHop-specific syntax. * vim: ft=php * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * http://www.gnu.org/copyleft/gpl.html + * * @file * @ingroup Parser */ @@ -18,6 +33,9 @@ class Preprocessor_HipHop implements Preprocessor { const CACHE_VERSION = 1; + /** + * @param $parser Parser + */ function __construct( $parser ) { $this->parser = $parser; } @@ -30,10 +48,10 @@ class Preprocessor_HipHop implements Preprocessor { } /** - * @param $args + * @param $args array * @return PPCustomFrame_HipHop */ - function newCustomFrame( array $args ) { + function newCustomFrame( $args ) { return new PPCustomFrame_HipHop( $this, $args ); } @@ -88,15 +106,18 @@ class Preprocessor_HipHop implements Preprocessor { * cache may be implemented at a later date which takes further advantage of these strict * dependency requirements. * + * @throws MWException * @return PPNode_HipHop_Tree */ - function preprocessToObj( string $text, int $flags = 0 ) { + function preprocessToObj( $text, $flags = 0 ) { wfProfileIn( __METHOD__ ); // Check cache. global $wgMemc, $wgPreprocessorCacheThreshold; - $cacheable = ($wgPreprocessorCacheThreshold !== false && strlen( $text ) > $wgPreprocessorCacheThreshold); + $lengthText = strlen( $text ); + + $cacheable = ($wgPreprocessorCacheThreshold !== false && $lengthText > $wgPreprocessorCacheThreshold); if ( $cacheable ) { wfProfileIn( __METHOD__.'-cacheable' ); @@ -220,7 +241,7 @@ class Preprocessor_HipHop implements Preprocessor { $accum->addLiteral( strval( substr( $text, $i, $literalLength ) ) ); $i += $literalLength; } - if ( $i >= strlen( $text ) ) { + if ( $i >= $lengthText ) { if ( $currentClosing === "\n" ) { // Do a past-the-end run to finish off the heading $curChar = ''; @@ -286,12 +307,12 @@ class Preprocessor_HipHop implements Preprocessor { // Unclosed comment in input, runs to end $inner = strval( substr( $text, $i ) ); $accum->addNodeWithText( 'comment', $inner ); - $i = strlen( $text ); + $i = $lengthText; } else { $endPos = intval( $variantEndPos ); // Search backwards for leading whitespace if ( $i ) { - $wsStart = $i - intval( strspn( $revText, ' ', strlen( $text ) - $i ) ); + $wsStart = $i - intval( strspn( $revText, ' ', $lengthText - $i ) ); } else { $wsStart = 0; } @@ -384,7 +405,7 @@ class Preprocessor_HipHop implements Preprocessor { } else { // No end tag -- let it run out to the end of the text. $inner = strval( substr( $text, $tagEndPos + 1 ) ); - $i = strlen( $text ); + $i = $lengthText; $haveClose = false; } } @@ -444,20 +465,21 @@ class Preprocessor_HipHop implements Preprocessor { } elseif ( $found === 'line-end' ) { $piece = $stack->getTop(); // A heading must be open, otherwise \n wouldn't have been in the search list - assert( $piece->open === "\n" ); + assert( $piece->open === "\n" ); // Passing the assert condition directly instead of string, as + // HPHP /compiler/ chokes on strings when ASSERT_ACTIVE != 0. $part = $piece->getCurrentPart(); // Search back through the input to see if it has a proper close // Do this using the reversed string since the other solutions (end anchor, etc.) are inefficient - $wsLength = intval( strspn( $revText, " \t", strlen( $text ) - $i ) ); + $wsLength = intval( strspn( $revText, " \t", $lengthText - $i ) ); $searchStart = $i - $wsLength; if ( isset( $part->commentEnd ) && $searchStart - 1 == $part->commentEnd ) { // Comment found at line end // Search for equals signs before the comment $searchStart = intval( $part->visualEnd ); - $searchStart -= intval( strspn( $revText, " \t", strlen( $text ) - $searchStart ) ); + $searchStart -= intval( strspn( $revText, " \t", $lengthText - $searchStart ) ); } $count = intval( $piece->count ); - $equalsLength = intval( strspn( $revText, '=', strlen( $text ) - $searchStart ) ); + $equalsLength = intval( strspn( $revText, '=', $lengthText - $searchStart ) ); $isTreeNode = false; $resultAccum = $accum; if ( $equalsLength > 0 ) { @@ -814,16 +836,23 @@ class PPDStack_HipHop { * @ingroup Parser */ class PPDStackElement_HipHop { - var $open, // Opening character (\n for heading) - $close, // Matching closing character + var $open, // Opening character (\n for heading) + $close, // Matching closing character $count, // Number of opening characters found (number of "=" for heading) $parts, // Array of PPDPart objects describing pipe-separated parts. $lineStart; // True if the open char appeared at the start of the input line. Not set for headings. + /** + * @param $obj PPDStackElement_HipHop + * @return PPDStackElement_HipHop + */ static function cast( PPDStackElement_HipHop $obj ) { return $obj; } + /** + * @param $data array + */ function __construct( $data = array() ) { $this->parts = array( new PPDPart_HipHop ); @@ -832,14 +861,23 @@ class PPDStackElement_HipHop { } } + /** + * @return PPDAccum_HipHop + */ function getAccum() { return PPDAccum_HipHop::cast( $this->parts[count($this->parts) - 1]->out ); } + /** + * @param $s string + */ function addPart( $s = '' ) { $this->parts[] = new PPDPart_HipHop( $s ); } + /** + * @return PPDPart_HipHop + */ function getCurrentPart() { return PPDPart_HipHop::cast( $this->parts[count($this->parts) - 1] ); } @@ -860,6 +898,7 @@ class PPDStackElement_HipHop { /** * Get the accumulator that would result if the close is not found. * + * @param $openingCount bool * @return PPDAccum_HipHop */ function breakSyntax( $openingCount = false ) { @@ -1025,12 +1064,14 @@ class PPFrame_HipHop implements PPFrame { * Create a new child frame * $args is optionally a multi-root PPNode or array containing the template arguments * - * @param $args PPNode_HipHop_Array|array - * @param $title Title|false + * @param $args PPNode_HipHop_Array|array|bool + * @param $title Title|bool + * @param $indexOffset A number subtracted from the index attributes of the arguments * + * @throws MWException * @return PPTemplateFrame_HipHop */ - function newChild( $args = false, $title = false ) { + function newChild( $args = false, $title = false, $indexOffset = 0 ) { $namedArgs = array(); $numberedArgs = array(); if ( $title === false ) { @@ -1072,12 +1113,23 @@ class PPFrame_HipHop implements PPFrame { } if ( ++$this->parser->mPPNodeCount > $this->parser->mOptions->getMaxPPNodeCount() ) { + $this->parser->limitationWarn( 'node-count-exceeded', + $this->parser->mPPNodeCount, + $this->parser->mOptions->getMaxPPNodeCount() + ); return '<span class="error">Node-count limit exceeded</span>'; } if ( $expansionDepth > $this->parser->mOptions->getMaxPPExpandDepth() ) { + $this->parser->limitationWarn( 'expansion-depth-exceeded', + $expansionDepth, + $this->parser->mOptions->getMaxPPExpandDepth() + ); return '<span class="error">Expansion depth limit exceeded</span>'; } ++$expansionDepth; + if ( $expansionDepth > $this->parser->mHighestExpansionDepth ) { + $this->parser->mHighestExpansionDepth = $expansionDepth; + } $outStack = array( '', '' ); $iteratorStack = array( false, $root ); @@ -1266,6 +1318,7 @@ class PPFrame_HipHop implements PPFrame { /** * Implode with no flags specified * This previously called implodeWithFlags but has now been inlined to reduce stack depth + * @param $sep * @return string */ function implode( $sep /*, ... */ ) { @@ -1296,6 +1349,7 @@ class PPFrame_HipHop implements PPFrame { * Makes an object that, when expand()ed, will be the same as one obtained * with implode() * + * @param $sep * @return PPNode_HipHop_Array */ function virtualImplode( $sep /*, ... */ ) { @@ -1325,6 +1379,9 @@ class PPFrame_HipHop implements PPFrame { /** * Virtual implode with brackets * + * @param $start + * @param $sep + * @param $end * @return PPNode_HipHop_Array */ function virtualBracketedImplode( $start, $sep, $end /*, ... */ ) { @@ -1445,11 +1502,11 @@ class PPTemplateFrame_HipHop extends PPFrame_HipHop { var $numberedExpansionCache, $namedExpansionCache; /** - * @param $preprocessor - * @param $parent + * @param $preprocessor Preprocessor_HipHop + * @param $parent bool * @param $numberedArgs array * @param $namedArgs array - * @param $title Title + * @param $title Title|bool */ function __construct( $preprocessor, $parent = false, $numberedArgs = array(), $namedArgs = array(), $title = false ) { parent::__construct( $preprocessor ); @@ -1696,11 +1753,15 @@ class PPNode_HipHop_Tree implements PPNode { return $this->nextSibling; } + /** + * @param $name string + * @return array + */ function getChildrenOfType( $name ) { $children = array(); for ( $child = $this->firstChild; $child; $child = $child->nextSibling ) { if ( isset( $child->name ) && $child->name === $name ) { - $children[] = $name; + $children[] = $child; } } return $children; @@ -1734,6 +1795,7 @@ class PPNode_HipHop_Tree implements PPNode { * index String index * value PPNode value * + * @throws MWException * @return array */ function splitArg() { @@ -1767,6 +1829,7 @@ class PPNode_HipHop_Tree implements PPNode { * Split an <ext> node into an associative array containing name, attr, inner and close * All values in the resulting array are PPNodes. Inner and close are optional. * + * @throws MWException * @return array */ function splitExt() { @@ -1794,6 +1857,7 @@ class PPNode_HipHop_Tree implements PPNode { /** * Split an <h> node * + * @throws MWException * @return array */ function splitHeading() { |