Вход Регистрация
Файл: gapps/vendor/nikic/php-parser/lib/PhpParser/PrettyPrinter/Standard.php
Строк: 1752
<?php

namespace PhpParserPrettyPrinter;

use 
PhpParserPrettyPrinterAbstract;
use 
PhpParserNode;
use 
PhpParserNodeScalar;
use 
PhpParserNodeScalarMagicConst;
use 
PhpParserNodeExpr;
use 
PhpParserNodeExprAssignOp;
use 
PhpParserNodeExprBinaryOp;
use 
PhpParserNodeExprCast;
use 
PhpParserNodeStmt;
use 
PhpParserNodeName;

class 
Standard extends PrettyPrinterAbstract
{
    
// Special nodes

    
public function pParam(NodeParam $node) {
        return (
$node->type $this->pType($node->type) . ' ' '')
             . (
$node->byRef '&' '')
             . (
$node->variadic '...' '')
             . 
'$' $node->name
             
. ($node->default ' = ' $this->p($node->default) : '');
    }

    public function 
pArg(NodeArg $node) {
        return (
$node->byRef '&' '') . ($node->unpack '...' '') . $this->p($node->value);
    }

    public function 
pConst(NodeConst_ $node) {
        return 
$node->name ' = ' $this->p($node->value);
    }

    
// Names

    
public function pName(Name $node) {
        return 
implode('\', $node->parts);
    }

    public function pName_FullyQualified(NameFullyQualified $node) {
        return '
\' . implode('\', $node->parts);
    }

    public function pName_Relative(NameRelative $node) {
        return '
namespace\' . implode('\', $node->parts);
    }

    // Magic Constants

    public function pScalar_MagicConst_Class(MagicConstClass_ $node) {
        return '
__CLASS__';
    }

    public function pScalar_MagicConst_Dir(MagicConstDir $node) {
        return '
__DIR__';
    }

    public function pScalar_MagicConst_File(MagicConstFile $node) {
        return '
__FILE__';
    }

    public function pScalar_MagicConst_Function(MagicConstFunction_ $node) {
        return '
__FUNCTION__';
    }

    public function pScalar_MagicConst_Line(MagicConstLine $node) {
        return '
__LINE__';
    }

    public function pScalar_MagicConst_Method(MagicConstMethod $node) {
        return '
__METHOD__';
    }

    public function pScalar_MagicConst_Namespace(MagicConstNamespace_ $node) {
        return '
__NAMESPACE__';
    }

    public function pScalar_MagicConst_Trait(MagicConstTrait_ $node) {
        return '
__TRAIT__';
    }

    // Scalars

    public function pScalar_String(ScalarString_ $node) {
        $kind = $node->getAttribute('
kind', ScalarString_::KIND_SINGLE_QUOTED);
        switch ($kind) {
            case ScalarString_::KIND_NOWDOC:
                $label = $node->getAttribute('
docLabel');
                if ($label && !$this->containsEndLabel($node->value, $label)) {
                    if ($node->value === '') {
                        return $this->pNoIndent("<<<'
$label'n$label") . $this->docStringEndToken;
                    }

                    return $this->pNoIndent("<<<'
$label'n$node->valuen$label")
                         . $this->docStringEndToken;
                }
                /* break missing intentionally */
            case ScalarString_::KIND_SINGLE_QUOTED:
                return ''' 
$this->pNoIndent(addcslashes($node->value''\')) . ''';
            case 
ScalarString_::KIND_HEREDOC:
                
$label $node->getAttribute('docLabel');
                if (
$label && !$this->containsEndLabel($node->value$label)) {
                    if (
$node->value === '') {
                        return 
$this->pNoIndent("<<<$labeln$label") . $this->docStringEndToken;
                    }

                    
$escaped $this->escapeString($node->valuenull);
                    return 
$this->pNoIndent("<<<$labeln$escaped ."n$label")
                         . 
$this->docStringEndToken;
                }
            
/* break missing intentionally */
            
case ScalarString_::KIND_DOUBLE_QUOTED:
                return 
'"' $this->escapeString($node->value'"') . '"';
        }
        throw new 
Exception('Invalid string kind');
    }

    public function 
pScalar_Encapsed(ScalarEncapsed $node) {
        if (
$node->getAttribute('kind') === ScalarString_::KIND_HEREDOC) {
            
$label $node->getAttribute('docLabel');
            if (
$label && !$this->encapsedContainsEndLabel($node->parts$label)) {
                if (
count($node->parts) === 1
                    
&& $node->parts[0] instanceof ScalarEncapsedStringPart
                    
&& $node->parts[0]->value === ''
                
) {
                    return 
$this->pNoIndent("<<<$labeln$label") . $this->docStringEndToken;
                }

                return 
$this->pNoIndent(
                    
"<<<$labeln$this->pEncapsList($node->partsnull) . "n$label"
                
) . $this->docStringEndToken;
            }
        }
        return 
'"' $this->pEncapsList($node->parts'"') . '"';
    }

    public function 
pScalar_LNumber(ScalarLNumber $node) {
        
$str = (string) $node->value;
        switch (
$node->getAttribute('kind'ScalarLNumber::KIND_DEC)) {
            case 
ScalarLNumber::KIND_BIN:
                return 
'0b' base_convert($str102);
            case 
ScalarLNumber::KIND_OCT:
                return 
'0' base_convert($str108);
            case 
ScalarLNumber::KIND_DEC:
                return 
$str;
            case 
ScalarLNumber::KIND_HEX:
                return 
'0x' base_convert($str1016);
        }
        throw new 
Exception('Invalid number kind');
    }

    public function 
pScalar_DNumber(ScalarDNumber $node) {
        
$stringValue sprintf('%.16G'$node->value);
        if (
$node->value !== (double) $stringValue) {
            
$stringValue sprintf('%.17G'$node->value);
        }

        
// ensure that number is really printed as float
        
return preg_match('/^-?[0-9]+$/'$stringValue) ? $stringValue '.0' $stringValue;
    }

    
// Assignments

    
public function pExpr_Assign(ExprAssign $node) {
        return 
$this->pInfixOp('Expr_Assign'$node->var' = '$node->expr);
    }

    public function 
pExpr_AssignRef(ExprAssignRef $node) {
        return 
$this->pInfixOp('Expr_AssignRef'$node->var' =& '$node->expr);
    }

    public function 
pExpr_AssignOp_Plus(AssignOpPlus $node) {
        return 
$this->pInfixOp('Expr_AssignOp_Plus'$node->var' += '$node->expr);
    }

    public function 
pExpr_AssignOp_Minus(AssignOpMinus $node) {
        return 
$this->pInfixOp('Expr_AssignOp_Minus'$node->var' -= '$node->expr);
    }

    public function 
pExpr_AssignOp_Mul(AssignOpMul $node) {
        return 
$this->pInfixOp('Expr_AssignOp_Mul'$node->var' *= '$node->expr);
    }

    public function 
pExpr_AssignOp_Div(AssignOpDiv $node) {
        return 
$this->pInfixOp('Expr_AssignOp_Div'$node->var' /= '$node->expr);
    }

    public function 
pExpr_AssignOp_Concat(AssignOpConcat $node) {
        return 
$this->pInfixOp('Expr_AssignOp_Concat'$node->var' .= '$node->expr);
    }

    public function 
pExpr_AssignOp_Mod(AssignOpMod $node) {
        return 
$this->pInfixOp('Expr_AssignOp_Mod'$node->var' %= '$node->expr);
    }

    public function 
pExpr_AssignOp_BitwiseAnd(AssignOpBitwiseAnd $node) {
        return 
$this->pInfixOp('Expr_AssignOp_BitwiseAnd'$node->var' &= '$node->expr);
    }

    public function 
pExpr_AssignOp_BitwiseOr(AssignOpBitwiseOr $node) {
        return 
$this->pInfixOp('Expr_AssignOp_BitwiseOr'$node->var' |= '$node->expr);
    }

    public function 
pExpr_AssignOp_BitwiseXor(AssignOpBitwiseXor $node) {
        return 
$this->pInfixOp('Expr_AssignOp_BitwiseXor'$node->var' ^= '$node->expr);
    }

    public function 
pExpr_AssignOp_ShiftLeft(AssignOpShiftLeft $node) {
        return 
$this->pInfixOp('Expr_AssignOp_ShiftLeft'$node->var' <<= '$node->expr);
    }

    public function 
pExpr_AssignOp_ShiftRight(AssignOpShiftRight $node) {
        return 
$this->pInfixOp('Expr_AssignOp_ShiftRight'$node->var' >>= '$node->expr);
    }

    public function 
pExpr_AssignOp_Pow(AssignOpPow $node) {
        return 
$this->pInfixOp('Expr_AssignOp_Pow'$node->var' **= '$node->expr);
    }

    
// Binary expressions

    
public function pExpr_BinaryOp_Plus(BinaryOpPlus $node) {
        return 
$this->pInfixOp('Expr_BinaryOp_Plus'$node->left' + '$node->right);
    }

    public function 
pExpr_BinaryOp_Minus(BinaryOpMinus $node) {
        return 
$this->pInfixOp('Expr_BinaryOp_Minus'$node->left' - '$node->right);
    }

    public function 
pExpr_BinaryOp_Mul(BinaryOpMul $node) {
        return 
$this->pInfixOp('Expr_BinaryOp_Mul'$node->left' * '$node->right);
    }

    public function 
pExpr_BinaryOp_Div(BinaryOpDiv $node) {
        return 
$this->pInfixOp('Expr_BinaryOp_Div'$node->left' / '$node->right);
    }

    public function 
pExpr_BinaryOp_Concat(BinaryOpConcat $node) {
        return 
$this->pInfixOp('Expr_BinaryOp_Concat'$node->left' . '$node->right);
    }

    public function 
pExpr_BinaryOp_Mod(BinaryOpMod $node) {
        return 
$this->pInfixOp('Expr_BinaryOp_Mod'$node->left' % '$node->right);
    }

    public function 
pExpr_BinaryOp_BooleanAnd(BinaryOpBooleanAnd $node) {
        return 
$this->pInfixOp('Expr_BinaryOp_BooleanAnd'$node->left' && '$node->right);
    }

    public function 
pExpr_BinaryOp_BooleanOr(BinaryOpBooleanOr $node) {
        return 
$this->pInfixOp('Expr_BinaryOp_BooleanOr'$node->left' || '$node->right);
    }

    public function 
pExpr_BinaryOp_BitwiseAnd(BinaryOpBitwiseAnd $node) {
        return 
$this->pInfixOp('Expr_BinaryOp_BitwiseAnd'$node->left' & '$node->right);
    }

    public function 
pExpr_BinaryOp_BitwiseOr(BinaryOpBitwiseOr $node) {
        return 
$this->pInfixOp('Expr_BinaryOp_BitwiseOr'$node->left' | '$node->right);
    }

    public function 
pExpr_BinaryOp_BitwiseXor(BinaryOpBitwiseXor $node) {
        return 
$this->pInfixOp('Expr_BinaryOp_BitwiseXor'$node->left' ^ '$node->right);
    }

    public function 
pExpr_BinaryOp_ShiftLeft(BinaryOpShiftLeft $node) {
        return 
$this->pInfixOp('Expr_BinaryOp_ShiftLeft'$node->left' << '$node->right);
    }

    public function 
pExpr_BinaryOp_ShiftRight(BinaryOpShiftRight $node) {
        return 
$this->pInfixOp('Expr_BinaryOp_ShiftRight'$node->left' >> '$node->right);
    }

    public function 
pExpr_BinaryOp_Pow(BinaryOpPow $node) {
        return 
$this->pInfixOp('Expr_BinaryOp_Pow'$node->left' ** '$node->right);
    }

    public function 
pExpr_BinaryOp_LogicalAnd(BinaryOpLogicalAnd $node) {
        return 
$this->pInfixOp('Expr_BinaryOp_LogicalAnd'$node->left' and '$node->right);
    }

    public function 
pExpr_BinaryOp_LogicalOr(BinaryOpLogicalOr $node) {
        return 
$this->pInfixOp('Expr_BinaryOp_LogicalOr'$node->left' or '$node->right);
    }

    public function 
pExpr_BinaryOp_LogicalXor(BinaryOpLogicalXor $node) {
        return 
$this->pInfixOp('Expr_BinaryOp_LogicalXor'$node->left' xor '$node->right);
    }

    public function 
pExpr_BinaryOp_Equal(BinaryOpEqual $node) {
        return 
$this->pInfixOp('Expr_BinaryOp_Equal'$node->left' == '$node->right);
    }

    public function 
pExpr_BinaryOp_NotEqual(BinaryOpNotEqual $node) {
        return 
$this->pInfixOp('Expr_BinaryOp_NotEqual'$node->left' != '$node->right);
    }

    public function 
pExpr_BinaryOp_Identical(BinaryOpIdentical $node) {
        return 
$this->pInfixOp('Expr_BinaryOp_Identical'$node->left' === '$node->right);
    }

    public function 
pExpr_BinaryOp_NotIdentical(BinaryOpNotIdentical $node) {
        return 
$this->pInfixOp('Expr_BinaryOp_NotIdentical'$node->left' !== '$node->right);
    }

    public function 
pExpr_BinaryOp_Spaceship(BinaryOpSpaceship $node) {
        return 
$this->pInfixOp('Expr_BinaryOp_Spaceship'$node->left' <=> '$node->right);
    }

    public function 
pExpr_BinaryOp_Greater(BinaryOpGreater $node) {
        return 
$this->pInfixOp('Expr_BinaryOp_Greater'$node->left' > '$node->right);
    }

    public function 
pExpr_BinaryOp_GreaterOrEqual(BinaryOpGreaterOrEqual $node) {
        return 
$this->pInfixOp('Expr_BinaryOp_GreaterOrEqual'$node->left' >= '$node->right);
    }

    public function 
pExpr_BinaryOp_Smaller(BinaryOpSmaller $node) {
        return 
$this->pInfixOp('Expr_BinaryOp_Smaller'$node->left' < '$node->right);
    }

    public function 
pExpr_BinaryOp_SmallerOrEqual(BinaryOpSmallerOrEqual $node) {
        return 
$this->pInfixOp('Expr_BinaryOp_SmallerOrEqual'$node->left' <= '$node->right);
    }

    public function 
pExpr_BinaryOp_Coalesce(BinaryOpCoalesce $node) {
        return 
$this->pInfixOp('Expr_BinaryOp_Coalesce'$node->left' ?? '$node->right);
    }

    public function 
pExpr_Instanceof(ExprInstanceof_ $node) {
        return 
$this->pInfixOp('Expr_Instanceof'$node->expr' instanceof '$node->class);
    }

    
// Unary expressions

    
public function pExpr_BooleanNot(ExprBooleanNot $node) {
        return 
$this->pPrefixOp('Expr_BooleanNot''!'$node->expr);
    }

    public function 
pExpr_BitwiseNot(ExprBitwiseNot $node) {
        return 
$this->pPrefixOp('Expr_BitwiseNot''~'$node->expr);
    }

    public function 
pExpr_UnaryMinus(ExprUnaryMinus $node) {
        return 
$this->pPrefixOp('Expr_UnaryMinus''-'$node->expr);
    }

    public function 
pExpr_UnaryPlus(ExprUnaryPlus $node) {
        return 
$this->pPrefixOp('Expr_UnaryPlus''+'$node->expr);
    }

    public function 
pExpr_PreInc(ExprPreInc $node) {
        return 
$this->pPrefixOp('Expr_PreInc''++'$node->var);
    }

    public function 
pExpr_PreDec(ExprPreDec $node) {
        return 
$this->pPrefixOp('Expr_PreDec''--'$node->var);
    }

    public function 
pExpr_PostInc(ExprPostInc $node) {
        return 
$this->pPostfixOp('Expr_PostInc'$node->var'++');
    }

    public function 
pExpr_PostDec(ExprPostDec $node) {
        return 
$this->pPostfixOp('Expr_PostDec'$node->var'--');
    }

    public function 
pExpr_ErrorSuppress(ExprErrorSuppress $node) {
        return 
$this->pPrefixOp('Expr_ErrorSuppress''@'$node->expr);
    }

    public function 
pExpr_YieldFrom(ExprYieldFrom $node) {
        return 
$this->pPrefixOp('Expr_YieldFrom''yield from '$node->expr);
    }

    public function 
pExpr_Print(ExprPrint_ $node) {
        return 
$this->pPrefixOp('Expr_Print''print '$node->expr);
    }

    
// Casts

    
public function pExpr_Cast_Int(CastInt_ $node) {
        return 
$this->pPrefixOp('Expr_Cast_Int''(int) '$node->expr);
    }

    public function 
pExpr_Cast_Double(CastDouble $node) {
        return 
$this->pPrefixOp('Expr_Cast_Double''(double) '$node->expr);
    }

    public function 
pExpr_Cast_String(CastString_ $node) {
        return 
$this->pPrefixOp('Expr_Cast_String''(string) '$node->expr);
    }

    public function 
pExpr_Cast_Array(CastArray_ $node) {
        return 
$this->pPrefixOp('Expr_Cast_Array''(array) '$node->expr);
    }

    public function 
pExpr_Cast_Object(CastObject_ $node) {
        return 
$this->pPrefixOp('Expr_Cast_Object''(object) '$node->expr);
    }

    public function 
pExpr_Cast_Bool(CastBool_ $node) {
        return 
$this->pPrefixOp('Expr_Cast_Bool''(bool) '$node->expr);
    }

    public function 
pExpr_Cast_Unset(CastUnset_ $node) {
        return 
$this->pPrefixOp('Expr_Cast_Unset''(unset) '$node->expr);
    }

    
// Function calls and similar constructs

    
public function pExpr_FuncCall(ExprFuncCall $node) {
        return 
$this->pCallLhs($node->name)
             . 
'(' $this->pCommaSeparated($node->args) . ')';
    }

    public function 
pExpr_MethodCall(ExprMethodCall $node) {
        return 
$this->pDereferenceLhs($node->var) . '->' $this->pObjectProperty($node->name)
             . 
'(' $this->pCommaSeparated($node->args) . ')';
    }

    public function 
pExpr_StaticCall(ExprStaticCall $node) {
        return 
$this->pDereferenceLhs($node->class) . '::'
             
. ($node->name instanceof Expr
                
? ($node->name instanceof ExprVariable
                   
$this->p($node->name)
                   : 
'{' $this->p($node->name) . '}')
                : 
$node->name)
             . 
'(' $this->pCommaSeparated($node->args) . ')';
    }

    public function 
pExpr_Empty(ExprEmpty_ $node) {
        return 
'empty(' $this->p($node->expr) . ')';
    }

    public function 
pExpr_Isset(ExprIsset_ $node) {
        return 
'isset(' $this->pCommaSeparated($node->vars) . ')';
    }

    public function 
pExpr_Eval(ExprEval_ $node) {
        return 
'eval(' $this->p($node->expr) . ')';
    }

    public function 
pExpr_Include(ExprInclude_ $node) {
        static 
$map = array(
            
ExprInclude_::TYPE_INCLUDE      => 'include',
            
ExprInclude_::TYPE_INCLUDE_ONCE => 'include_once',
            
ExprInclude_::TYPE_REQUIRE      => 'require',
            
ExprInclude_::TYPE_REQUIRE_ONCE => 'require_once',
        );

        return 
$map[$node->type] . ' ' $this->p($node->expr);
    }

    public function 
pExpr_List(ExprList_ $node) {
        
$pList = array();
        foreach (
$node->vars as $var) {
            if (
null === $var) {
                
$pList[] = '';
            } else {
                
$pList[] = $this->p($var);
            }
        }

        return 
'list(' implode(', '$pList) . ')';
    }

    
// Other

    
public function pExpr_Variable(ExprVariable $node) {
        if (
$node->name instanceof Expr) {
            return 
'${' $this->p($node->name) . '}';
        } else {
            return 
'$' $node->name;
        }
    }

    public function 
pExpr_Array(ExprArray_ $node) {
        
$syntax $node->getAttribute('kind',
            
$this->options['shortArraySyntax'] ? ExprArray_::KIND_SHORT ExprArray_::KIND_LONG);
        if (
$syntax === ExprArray_::KIND_SHORT) {
            return 
'[' $this->pCommaSeparated($node->items) . ']';
        } else {
            return 
'array(' $this->pCommaSeparated($node->items) . ')';
        }
    }

    public function 
pExpr_ArrayItem(ExprArrayItem $node) {
        return (
null !== $node->key $this->p($node->key) . ' => ' '')
             . (
$node->byRef '&' '') . $this->p($node->value);
    }

    public function 
pExpr_ArrayDimFetch(ExprArrayDimFetch $node) {
        return 
$this->pDereferenceLhs($node->var)
             . 
'[' . (null !== $node->dim $this->p($node->dim) : '') . ']';
    }

    public function 
pExpr_ConstFetch(ExprConstFetch $node) {
        return 
$this->p($node->name);
    }

    public function 
pExpr_ClassConstFetch(ExprClassConstFetch $node) {
        return 
$this->p($node->class) . '::' $node->name;
    }

    public function 
pExpr_PropertyFetch(ExprPropertyFetch $node) {
        return 
$this->pDereferenceLhs($node->var) . '->' $this->pObjectProperty($node->name);
    }

    public function 
pExpr_StaticPropertyFetch(ExprStaticPropertyFetch $node) {
        return 
$this->pDereferenceLhs($node->class) . '::$' $this->pObjectProperty($node->name);
    }

    public function 
pExpr_ShellExec(ExprShellExec $node) {
        return 
'`' $this->pEncapsList($node->parts'`') . '`';
    }

    public function 
pExpr_Closure(ExprClosure $node) {
        return (
$node->static 'static ' '')
             . 
'function ' . ($node->byRef '&' '')
             . 
'(' $this->pCommaSeparated($node->params) . ')'
             
. (!empty($node->uses) ? ' use(' $this->pCommaSeparated($node->uses) . ')''')
             . (
null !== $node->returnType ' : ' $this->pType($node->returnType) : '')
             . 
' {' $this->pStmts($node->stmts) . "n" '}';
    }

    public function 
pExpr_ClosureUse(ExprClosureUse $node) {
        return (
$node->byRef '&' '') . '$' $node->var;
    }

    public function 
pExpr_New(ExprNew_ $node) {
        if (
$node->class instanceof StmtClass_) {
            
$args $node->args '(' $this->pCommaSeparated($node->args) . ')' '';
            return 
'new ' $this->pClassCommon($node->class$args);
        }
        return 
'new ' $this->p($node->class) . '(' $this->pCommaSeparated($node->args) . ')';
    }

    public function 
pExpr_Clone(ExprClone_ $node) {
        return 
'clone ' $this->p($node->expr);
    }

    public function 
pExpr_Ternary(ExprTernary $node) {
        
// a bit of cheating: we treat the ternary as a binary op where the ?...: part is the operator.
        // this is okay because the part between ? and : never needs parentheses.
        
return $this->pInfixOp('Expr_Ternary',
            
$node->cond' ?' . (null !== $node->if ' ' $this->p($node->if) . ' ' '') . ': '$node->else
        
);
    }

    public function 
pExpr_Exit(ExprExit_ $node) {
        
$kind $node->getAttribute('kind'ExprExit_::KIND_DIE);
        return (
$kind === ExprExit_::KIND_EXIT 'exit' 'die')
             . (
null !== $node->expr '(' $this->p($node->expr) . ')' '');
    }

    public function 
pExpr_Yield(ExprYield_ $node) {
        if (
$node->value === null) {
            return 
'yield';
        } else {
            
// this is a bit ugly, but currently there is no way to detect whether the parentheses are necessary
            
return '(yield '
                 
. ($node->key !== null $this->p($node->key) . ' => ' '')
                 . 
$this->p($node->value)
                 . 
')';
        }
    }

    
// Declarations

    
public function pStmt_Namespace(StmtNamespace_ $node) {
        if (
$this->canUseSemicolonNamespaces) {
            return 
'namespace ' $this->p($node->name) . ';' "n" $this->pStmts($node->stmtsfalse);
        } else {
            return 
'namespace' . (null !== $node->name ' ' $this->p($node->name) : '')
                 . 
' {' $this->pStmts($node->stmts) . "n" '}';
        }
    }

    public function 
pStmt_Use(StmtUse_ $node) {
        return 
'use ' $this->pUseType($node->type)
             . 
$this->pCommaSeparated($node->uses) . ';';
    }

    public function 
pStmt_GroupUse(StmtGroupUse $node) {
        return 
'use ' $this->pUseType($node->type) . $this->pName($node->prefix)
             . 
'{' $this->pCommaSeparated($node->uses) . '};';
    }

    public function 
pStmt_UseUse(StmtUseUse $node) {
        return 
$this->pUseType($node->type) . $this->p($node->name)
             . (
$node->name->getLast() !== $node->alias ' as ' $node->alias '');
    }

    private function 
pUseType($type) {
        return 
$type === StmtUse_::TYPE_FUNCTION 'function '
            
: ($type === StmtUse_::TYPE_CONSTANT 'const ' '');
    }

    public function 
pStmt_Interface(StmtInterface_ $node) {
        return 
'interface ' $node->name
             
. (!empty($node->extends) ? ' extends ' $this->pCommaSeparated($node->extends) : '')
             . 
"n" '{' $this->pStmts($node->stmts) . "n" '}';
    }

    public function 
pStmt_Class(StmtClass_ $node) {
        return 
$this->pClassCommon($node' ' $node->name);
    }

    public function 
pStmt_Trait(StmtTrait_ $node) {
        return 
'trait ' $node->name
             
"n" '{' $this->pStmts($node->stmts) . "n" '}';
    }

    public function 
pStmt_TraitUse(StmtTraitUse $node) {
        return 
'use ' $this->pCommaSeparated($node->traits)
             . (empty(
$node->adaptations)
                ? 
';'
                
' {' $this->pStmts($node->adaptations) . "n" '}');
    }

    public function 
pStmt_TraitUseAdaptation_Precedence(StmtTraitUseAdaptationPrecedence $node) {
        return 
$this->p($node->trait) . '::' $node->method
             
' insteadof ' $this->pCommaSeparated($node->insteadof) . ';';
    }

    public function 
pStmt_TraitUseAdaptation_Alias(StmtTraitUseAdaptationAlias $node) {
        return (
null !== $node->trait $this->p($node->trait) . '::' '')
             . 
$node->method ' as'
             
. (null !== $node->newModifier ' ' rtrim($this->pModifiers($node->newModifier), ' ') : '')
             . (
null !== $node->newName     ' ' $node->newName                        '')
             . 
';';
    }

    public function 
pStmt_Property(StmtProperty $node) {
        return (
=== $node->type 'var ' $this->pModifiers($node->type)) . $this->pCommaSeparated($node->props) . ';';
    }

    public function 
pStmt_PropertyProperty(StmtPropertyProperty $node) {
        return 
'$' $node->name
             
. (null !== $node->default ' = ' $this->p($node->default) : '');
    }

    public function 
pStmt_ClassMethod(StmtClassMethod $node) {
        return 
$this->pModifiers($node->type)
             . 
'function ' . ($node->byRef '&' '') . $node->name
             
'(' $this->pCommaSeparated($node->params) . ')'
             
. (null !== $node->returnType ' : ' $this->pType($node->returnType) : '')
             . (
null !== $node->stmts
                
"n" '{' $this->pStmts($node->stmts) . "n" '}'
                
';');
    }

    public function 
pStmt_ClassConst(StmtClassConst $node) {
        return 
'const ' $this->pCommaSeparated($node->consts) . ';';
    }

    public function 
pStmt_Function(StmtFunction_ $node) {
        return 
'function ' . ($node->byRef '&' '') . $node->name
             
'(' $this->pCommaSeparated($node->params) . ')'
             
. (null !== $node->returnType ' : ' $this->pType($node->returnType) : '')
             . 
"n" '{' $this->pStmts($node->stmts) . "n" '}';
    }

    public function 
pStmt_Const(StmtConst_ $node) {
        return 
'const ' $this->pCommaSeparated($node->consts) . ';';
    }

    public function 
pStmt_Declare(StmtDeclare_ $node) {
        return 
'declare (' $this->pCommaSeparated($node->declares) . ')'
             
. (null !== $node->stmts ' {' $this->pStmts($node->stmts) . "n" '}' ';');
    }

    public function 
pStmt_DeclareDeclare(StmtDeclareDeclare $node) {
        return 
$node->key '=' $this->p($node->value);
    }

    
// Control flow

    
public function pStmt_If(StmtIf_ $node) {
        return 
'if (' $this->p($node->cond) . ') {'
             
$this->pStmts($node->stmts) . "n" '}'
             
$this->pImplode($node->elseifs)
             . (
null !== $node->else $this->p($node->else) : '');
    }

    public function 
pStmt_ElseIf(StmtElseIf_ $node) {
        return 
' elseif (' $this->p($node->cond) . ') {'
             
$this->pStmts($node->stmts) . "n" '}';
    }

    public function 
pStmt_Else(StmtElse_ $node) {
        return 
' else {' $this->pStmts($node->stmts) . "n" '}';
    }

    public function 
pStmt_For(StmtFor_ $node) {
        return 
'for ('
             
$this->pCommaSeparated($node->init) . ';' . (!empty($node->cond) ? ' ' '')
             . 
$this->pCommaSeparated($node->cond) . ';' . (!empty($node->loop) ? ' ' '')
             . 
$this->pCommaSeparated($node->loop)
             . 
') {' $this->pStmts($node->stmts) . "n" '}';
    }

    public function 
pStmt_Foreach(StmtForeach_ $node) {
        return 
'foreach (' $this->p($node->expr) . ' as '
             
. (null !== $node->keyVar $this->p($node->keyVar) . ' => ' '')
             . (
$node->byRef '&' '') . $this->p($node->valueVar) . ') {'
             
$this->pStmts($node->stmts) . "n" '}';
    }

    public function 
pStmt_While(StmtWhile_ $node) {
        return 
'while (' $this->p($node->cond) . ') {'
             
$this->pStmts($node->stmts) . "n" '}';
    }

    public function 
pStmt_Do(StmtDo_ $node) {
        return 
'do {' $this->pStmts($node->stmts) . "n"
             
'} while (' $this->p($node->cond) . ');';
    }

    public function 
pStmt_Switch(StmtSwitch_ $node) {
        return 
'switch (' $this->p($node->cond) . ') {'
             
$this->pStmts($node->cases) . "n" '}';
    }

    public function 
pStmt_Case(StmtCase_ $node) {
        return (
null !== $node->cond 'case ' $this->p($node->cond) : 'default') . ':'
             
$this->pStmts($node->stmts);
    }

    public function 
pStmt_TryCatch(StmtTryCatch $node) {
        return 
'try {' $this->pStmts($node->stmts) . "n" '}'
             
$this->pImplode($node->catches)
             . (
$node->finallyStmts !== null
                
' finally {' $this->pStmts($node->finallyStmts) . "n" '}'
                
'');
    }

    public function 
pStmt_Catch(StmtCatch_ $node) {
        return 
' catch (' $this->p($node->type) . ' $' $node->var ') {'
             
$this->pStmts($node->stmts) . "n" '}';
    }

    public function 
pStmt_Break(StmtBreak_ $node) {
        return 
'break' . ($node->num !== null ' ' $this->p($node->num) : '') . ';';
    }

    public function 
pStmt_Continue(StmtContinue_ $node) {
        return 
'continue' . ($node->num !== null ' ' $this->p($node->num) : '') . ';';
    }

    public function 
pStmt_Return(StmtReturn_ $node) {
        return 
'return' . (null !== $node->expr ' ' $this->p($node->expr) : '') . ';';
    }

    public function 
pStmt_Throw(StmtThrow_ $node) {
        return 
'throw ' $this->p($node->expr) . ';';
    }

    public function 
pStmt_Label(StmtLabel $node) {
        return 
$node->name ':';
    }

    public function 
pStmt_Goto(StmtGoto_ $node) {
        return 
'goto ' $node->name ';';
    }

    
// Other

    
public function pStmt_Echo(StmtEcho_ $node) {
        return 
'echo ' $this->pCommaSeparated($node->exprs) . ';';
    }

    public function 
pStmt_Static(StmtStatic_ $node) {
        return 
'static ' $this->pCommaSeparated($node->vars) . ';';
    }

    public function 
pStmt_Global(StmtGlobal_ $node) {
        return 
'global ' $this->pCommaSeparated($node->vars) . ';';
    }

    public function 
pStmt_StaticVar(StmtStaticVar $node) {
        return 
'$' $node->name
             
. (null !== $node->default ' = ' $this->p($node->default) : '');
    }

    public function 
pStmt_Unset(StmtUnset_ $node) {
        return 
'unset(' $this->pCommaSeparated($node->vars) . ');';
    }

    public function 
pStmt_InlineHTML(StmtInlineHTML $node) {
        return 
'?>' $this->pNoIndent("n" $node->value) . '<?php ';
    }

    public function 
pStmt_HaltCompiler(StmtHaltCompiler $node) {
        return 
'__halt_compiler();' $node->remaining;
    }

    public function 
pStmt_Nop(StmtNop $node) {
        return 
'';
    }

    
// Helpers

    
protected function pType($node) {
        return 
is_string($node) ? $node $this->p($node);
    }

    protected function 
pClassCommon(StmtClass_ $node$afterClassToken) {
        return 
$this->pModifiers($node->type)
        . 
'class' $afterClassToken
        
. (null !== $node->extends ' extends ' $this->p($node->extends) : '')
        . (!empty(
$node->implements) ? ' implements ' $this->pCommaSeparated($node->implements) : '')
        . 
"n" '{' $this->pStmts($node->stmts) . "n" '}';
    }

    protected function 
pObjectProperty($node) {
        if (
$node instanceof Expr) {
            return 
'{' $this->p($node) . '}';
        } else {
            return 
$node;
        }
    }

    protected function 
pModifiers($modifiers) {
        return (
$modifiers StmtClass_::MODIFIER_PUBLIC    'public '    '')
             . (
$modifiers StmtClass_::MODIFIER_PROTECTED 'protected ' '')
             . (
$modifiers StmtClass_::MODIFIER_PRIVATE   'private '   '')
             . (
$modifiers StmtClass_::MODIFIER_STATIC    'static '    '')
             . (
$modifiers StmtClass_::MODIFIER_ABSTRACT  'abstract '  '')
             . (
$modifiers StmtClass_::MODIFIER_FINAL     'final '     '');
    }

    protected function 
pEncapsList(array $encapsList$quote) {
        
$return '';
        foreach (
$encapsList as $element) {
            if (
$element instanceof ScalarEncapsedStringPart) {
                
$return .= $this->escapeString($element->value$quote);
            } else {
                
$return .= '{' $this->p($element) . '}';
            }
        }

        return 
$return;
    }

    protected function 
escapeString($string$quote) {
        if (
null === $quote) {
            
// For doc strings, don't escape newlines
            
$escaped addcslashes($string"tfv$\");
        } else {
            
$escaped = addcslashes($string, "nrtfv$" . $quote . "\");
        }

        // Escape other control characters
        return preg_replace_callback('/([-1016-37])(?=([0-7]?))/', function (
$matches) {
            
$oct = decoct(ord($matches[1]));
            if (
$matches[2] !== '') {
                // If there is a trailing digit, use the full three character form
                return '\' . str_pad(
$oct, 3, '0', STR_PAD_LEFT);
            }
            return '\' . 
$oct;
        }, 
$escaped);
    }

    protected function containsEndLabel(
$string$label$atStart = true, $atEnd = true) {
        
$start = $atStart ? '(?:^|[rn])' : '[rn]';
        
$end = $atEnd ? '(?:$|[;rn])' : '[;rn]';
        return false !== strpos(
$string$label)
            && preg_match('/' . 
$start . $label . $end . '/', $string);
    }

    protected function encapsedContainsEndLabel(array 
$parts$label) {
        foreach (
$parts as $i => $part) {
            
$atStart = $i === 0;
            
$atEnd = $i === count($parts) - 1;
            if (
$part instanceof ScalarEncapsedStringPart
                && 
$this->containsEndLabel($part->value$label$atStart$atEnd)
            ) {
                return true;
            }
        }
        return false;
    }

    protected function pDereferenceLhs(Node 
$node) {
        if (
$node instanceof ExprVariable
            || 
$node instanceof Name
            || 
$node instanceof ExprArrayDimFetch
            || 
$node instanceof ExprPropertyFetch
            || 
$node instanceof ExprStaticPropertyFetch
            || 
$node instanceof ExprFuncCall
            || 
$node instanceof ExprMethodCall
            || 
$node instanceof ExprStaticCall
            || 
$node instanceof ExprArray_
            || 
$node instanceof ScalarString_
            || 
$node instanceof ExprConstFetch
            || 
$node instanceof ExprClassConstFetch
        ) {
            return 
$this->p($node);
        } else  {
            return '(' . 
$this->p($node) . ')';
        }
    }

    protected function pCallLhs(Node 
$node) {
        if (
$node instanceof Name
            || 
$node instanceof ExprVariable
            || 
$node instanceof ExprArrayDimFetch
            || 
$node instanceof ExprFuncCall
            || 
$node instanceof ExprMethodCall
            || 
$node instanceof ExprStaticCall
            || 
$node instanceof ExprArray_
        ) {
            return 
$this->p($node);
        } else  {
            return '(' . 
$this->p($node) . ')';
        }
    }
}
Онлайн: 1
Реклама